automated mediatomb playlists

Because of my work I rarely get to see the evening news. Hereabouts PBS begins at 6 PM and the 3 commercial networks at 6:30 PM. None of these repeat those broadcasts later. But now I have a solution.


The house media server is mediatomb, which we use to host content accessed by a couple of Seagate FreeAgent Theater+ boxes connected to the HDTV’s (Seagate no longer makes the FreeAgent — a real shame because the things really rock as media clients, we got ours for around $50 each when they were still in production).

While mediatomb supports making links to external media (“External URL” objects), the software doesn’t provide any way of automating their creation. After scouring the Internets for an answer, I came across the suggestion that a simple text playlist could serve the same purpose.

It took a couple of days, but I finally came up with a script to create playlist files in a dedicated directory that mediatomb is configured to scan whenever content is added or modified.

So here’s the script:

#!/usr/bin/perl
use strict;
use XML::FeedPP;

my $HOME = $ENV{'HOME'};
my $PLAY_HOME = "/data/share/media/playlists";
our(%sources);
require "$HOME/etc/playlists.conf";
my @indices = (0);
my @rssurls = values %sources;
foreach my $rssurl(@rssurls) {
  my $feed = XML::FeedPP->new($rssurl);
  my $title = $feed->title();
  print $title, "n";
  my %names = reverse %sources;
  my $filename = $names{$rssurl};
  my $outfile = $PLAY_HOME . "/" . $filename . ".m3u";
  print $outfile, "n";
  open FH, ">$outfile" or die $!;
  print FH "#EXTM3Un";
  foreach my $index(@indices) {
     my $item = $feed->get_item($index);
     if($item) {
	my $itemtitle = $item->title();
	print FH "#EXTINF:", $itemtitle, "n";
        my $medialink = $item->get('enclosure@url');
        print FH $medialink, "n";
     }
 	 print FH "n";
  }
  close FH;
}
__END__;

A couple of things about the above. First, for something so important the “$item->get(‘enclosure@url’)” syntax isn’t documented anywhere. I found it in a post someone did to a mailing list. Second, the “indices” array was put in to control the number of links published in a playlist. Right now it only pulls in the first, but additional values could be added (e.g. “0, 1, 2”) if desired. Finally, the “reverse” pragma used to flip around the key/value data in the configuration file hash was something I never saw before. Now that I know about it, I’m sure to use it again.

This is the config file (playlists.conf):

# Config file for makeplaylists.pl
%sources = (
 'newshour','http://feeds.feedburner.com/NewshourFullProgramPodcast?format=xml',
 'cbs_enews','http://www.cbsnews.com/common/includes/podcast/podcast_eveningnews_video_1.rss',
 'nbc_nn','http://podcastfeeds.nbcnews.com/audio/podcast/MSNBC-NN-NETCAST-M4V.xml',
 'tw_nasa','http://www.nasa.gov/rss/TWAN_vodcast.rss',
 'yourweekly','http://www.whitehouse.gov/podcast/video/weekly-addresses/rss.xml'
);
1;

Each of these is an .rss or .xml file obtained from media publisher sites. The hash pairing of a short file name key with a url value is a lot more efficient than other methods I tried. As I wrote above, that “reverse” pragma really did come in handy on this project.

And finally, here’s the mediatomb config on the playlist container:

Seeing the system actually work with “inotify” and a a “full” scan (which causes the app to scan on both adds and modifies of content — “basic” only scans for “adds”) was a pleasant surprise. Previous versions of Red Hat Linux had not supported inotify, but it was a feature I really needed for this project (a cron job runs the script at 18:00 and 22:00 hours, the first to set up some public broadcasting lists and the second for the major network newscasts).