概要
指定したディレクトリ直下にある、.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 件のコメント:
コメントを投稿