Populate a WCF syndication podcast using MP3 ID3 metadata tags

Posted by brian_ritchie on ASP.net Weblogs See other posts from ASP.net Weblogs or by brian_ritchie
Published on Tue, 01 Mar 2011 03:28:00 GMT Indexed on 2011/03/01 7:25 UTC
Read the original article Hit count: 432

Filed under:
|
|
|
|
|

In the last post, I showed how to create a podcast using WCF syndication.  A podcast is an RSS feed containing a list of audio files to which users can subscribe.  The podcast not only contains links to the audio files, but also metadata about each episode.  A cool approach to building the feed is reading this metadata from the ID3 tags on the MP3 files used for the podcast.

One library to do this is TagLib-Sharp.  Here is some sample code:

   1:  var taggedFile = TagLib.File.Create(f);
   2:  var fileInfo = new FileInfo(f);
   3:  var item = new iTunesPodcastItem()
   4:  {
   5:      title = taggedFile.Tag.Title,
   6:      size = fileInfo.Length,
   7:      url = feed.baseUrl + fileInfo.Name,
   8:      duration = taggedFile.Properties.Duration,
   9:      mediaType = feed.mediaType,
  10:      summary = taggedFile.Tag.Comment,
  11:      subTitle = taggedFile.Tag.FirstAlbumArtist,
  12:      id = fileInfo.Name
  13:  };
  14:  if (!string.IsNullOrEmpty(taggedFile.Tag.Album))
  15:      item.publishedDate = DateTimeOffset.Parse(taggedFile.Tag.Album);

This reads the ID3 tags into an object for later use in creating the syndication feed.  When the MP3 is created, these tags are set...or they can be set after the fact using the Properties dialog in Windows Explorer.  The only "hack" is that there isn't an easily accessible tag for "subtitle" or "published date" so I used other tags in this example. Feel free to change this to meet your purposes.  You could remove the subtitle & use the file modified data for example.

That takes care of the episodes, for the feed level settings we'll load those from an XML file:

   1:  <?xml version="1.0" encoding="utf-8" ?>
   2:  <iTunesPodcastFeed
   3:    baseUrl =""
   4:    title=""
   5:    subTitle=""
   6:    description=""
   7:    copyright=""
   8:    category=""
   9:    ownerName=""
  10:    ownerEmail=""
  11:    mediaType="audio/mp3"
  12:    mediaFiles="*.mp3"
  13:    imageUrl=""
  14:    link=""
  15:    />

Here is the full code put together.

  • Read the feed XML file and deserialize it into an iTunesPodcastFeed class
  • Loop over the files in a directory reading the ID3 tags from the audio files
   1:  public static iTunesPodcastFeed CreateFeedFromFiles(string podcastDirectory, string podcastFeedFile)
   2:  {
   3:       XmlSerializer serializer = new XmlSerializer(typeof(iTunesPodcastFeed));
   4:       iTunesPodcastFeed feed;
   5:       using (var fs = File.OpenRead(Path.Combine(podcastDirectory, podcastFeedFile)))
   6:       {
   7:           feed = (iTunesPodcastFeed)serializer.Deserialize(fs);
   8:       }
   9:       foreach (var f in Directory.GetFiles(podcastDirectory, feed.mediaFiles))
  10:       {
  11:           try
  12:           {
  13:               var taggedFile = TagLib.File.Create(f);
  14:               var fileInfo = new FileInfo(f);
  15:               var item = new iTunesPodcastItem()
  16:                      {
  17:                          title = taggedFile.Tag.Title,
  18:                          size = fileInfo.Length,
  19:                          url = feed.baseUrl + fileInfo.Name,
  20:                          duration = taggedFile.Properties.Duration,
  21:                          mediaType = feed.mediaType,
  22:                          summary = taggedFile.Tag.Comment,
  23:                          subTitle = taggedFile.Tag.FirstAlbumArtist,
  24:                          id = fileInfo.Name
  25:                      };
  26:               if (!string.IsNullOrEmpty(taggedFile.Tag.Album))
  27:                    item.publishedDate = DateTimeOffset.Parse(taggedFile.Tag.Album);
  28:               feed.Items.Add(item);
  29:           }
  30:           catch
  31:           {
  32:            // ignore files that can't be accessed successfully
  33:           }
  34:      }
  35:      return feed;
  36:  }

Usually putting a "try...catch" like this is bad, but in this case I'm just skipping over files that are locked while they are being uploaded to the web site.

Here is the code from the last couple of posts.

 

© ASP.net Weblogs or respective owner

Related posts about .NET

Related posts about c#