2013年3月8日金曜日

PodCast用のRSS出力ページをASP.NETで作ってみた

何となく作ってみた。(^_^;)

概要


指定したディレクトリ直下にある、.mp3 .m4a .m4v .mp4 .wma .wmv .jpg をPodCast用のRSSを出力する。
キーワードによる絞り込み、除外フィルタを行う。

コンパイルが必要無いようにASP.NETのWebFormでインラインで記述。
使用言語はC#
IISと.NET Framework 3.5 以上が導入されていること。

使い方


ファイル名に、「やまだ」または「すずき」を含むものを抽出する場合は、keyword=やまだ|すずき を引数で指定する。
逆にフィルタしたい場合は、fillter=やまだ|すずき を指定する。
「やまだ たろう」 「やまだ じろう」 「やまだ さぶろう」 とファイルがあって、さぶろうを除外したい場合は、keyword=やまだ&filter=さぶろう と指定する。

当初、ファイルは非公開ディレクトリに配置してダウンロード用のASPXを介してダウンロードさせようと思ったが、iTunesの場合、URLのファイルの拡張子とメディアタイプが不一致だと、アイテムを表示しないような仕様のため、ダウンロード用のファイルは公開ディレクトリに配置する必要がある。

MVCを使えば、URLを/test/podcast/hoge.mp4 のようにすることが出来るので上手くいけそうだが、ひとまずコンパイルしたくなかったので今回は見送った。

ソース

<%@ Page Language="C#"  Debug="true" %>
<%@ Import Namespace="System" %>
<%@ Import Namespace="System.Text" %>
<%@ Import Namespace="System.Web" %>
<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="System.Text.RegularExpressions" %>
<%@ Import Namespace="System.Linq" %>
<%@ Import Namespace="System.Collections.Generic" %>
<%@ Import Namespace="System.Xml" %>
<%@ Import Namespace="System.ServiceModel.Syndication" %>
<script runat="server">
    // タイトル
    private string castTilte = "Tilte";
    //キャストの説明
    private string castDescription = "Description";
    // 格納ディレクトリ
    private string searchDir = @"c:\test";
    // 配信URL
    private string castUrl = "http://xxx.xxx.xxx.xxx/test/";
    // ファイルタイプ
    private Dictionary<string, string> fileTypes  = new Dictionary<string, string>()
    {
        {".mp3", "audio/x-mp3"},
        {".m4a", "audio/x-m4a"},
        {".m4v", "video/x-m4v"},
        {".mp4", "video/x-mp4"},
        {".jpg", "video/x-mp4"},
        {".wma", "audio/x-ms-wma"},
        {".wmv", "video/x-ms-wmv"}
    };
      
    protected void Page_Load(object sender, EventArgs e)
    {
        string keyword = (string) Request.QueryString["keyword"];
        string filter = (string) Request.QueryString["filter"];
        Response.ContentType = "application/rss+xml";
        Response.ContentEncoding = System.Text.Encoding.UTF8;
        XmlTextWriter xmlWriter = new XmlTextWriter(Response.Output);
        SyndicationFeed feed = new SyndicationFeed();
        feed.Title = new TextSyndicationContent(castTilte);
        feed.Description = new TextSyndicationContent(castDescription);
        List<syndicationitem> items = new List<syndicationitem>();
        
        searchFile(searchDir, items, keyword, filter);
        
        feed.Items = items;
        feed.SaveAsRss20(xmlWriter);
        Response.End();
    }
    
    // ファイルを検索してフィードアイテムを作成する
    private void searchFile(string dir, List<syndicationitem>items, string keyword, string filter)
    {
        IEnumerable<fileinfo> fileList = Directory.GetFiles(dir, "*.*", System.IO.SearchOption.AllDirectories).Select(x => new FileInfo(x));
        Regex keyRegex = new Regex(String.Format(@"({0}).*\.mp3|({0}).*\.m4a|({0}).*\.m4v|({0}).*\.mp4|({0}).*\.wma|({0}).*\.wmv|({0}).*\.jpg", keyword), RegexOptions.IgnoreCase);
        IEnumerable<fileinfo> keyFiles = null;
        keyFiles =
            from file in fileList
            where keyRegex.IsMatch(file.Name)
            orderby file.LastWriteTime descending
            select file;
        IEnumerable<fileinfo> filterFiles = null;
        if (filter == null)
        {
            filterFiles = keyFiles;
        }
        else
        {
            Regex filterRegex = new Regex(String.Format(@"^(?!.*({0})).+$", filter), RegexOptions.IgnoreCase);
            filterFiles =
                from file in keyFiles
                where filterRegex.IsMatch(file.Name)
                orderby file.LastWriteTime descending
                select file;
        }
        
        foreach (FileInfo target in filterFiles)
        {
            string fname = Path.GetFileNameWithoutExtension(target.Name);
            string extension = target.Extension;
            string fileType = fileTypes[extension.ToLower()];
            SyndicationItem item = new SyndicationItem();
            string title = fname;
            item.Title = new TextSyndicationContent(title);
            item.PublishDate = new DateTimeOffset(target.LastWriteTime);
            SyndicationLink link = SyndicationLink.CreateMediaEnclosureLink(new Uri(castUrl + HttpUtility.UrlEncode(fname) + extension), fileType, target.Length);
            item.Links.Add(link);
            items.Add(item);
        }
    }
</script>

0 件のコメント:

コメントを投稿