Leon's Weblog

March 30, 2010

Streaming media library to PS3 with MediaTomb

Filed under: Personal,Software Dev — Leon @ 2:13 am

One of the goals that I had for my media center was to have the ability to directly play music and movies from my Linux Server. The PS3 provided half of this functionality by supporting wireless streaming and connections to UPnP A/V servers. MediaTomb filled the gap by enabling my Linux Server to stream my entire media library. Below are the details of my configuration and solutions to some of the issues that I encountered.

Once the PS3 is connected to your local network, it will detect the presence of any media server automatically. The hard part for me was getting to this point. MediaTomb installed without a problem but my media was still not accessible. I found that a good way to test whether problems were caused by compatibility issues between the PS3 and MediaTomb or improper configuration was to setup an alternate UPnP client to test the MediaTomb configuration. I used Cidero which is a free Windows/Linux UPnP A/V controller written in Java.

The first fix involved opening the UPnP ports on the Linux firewall. Port 1900 needs to be open for Cidero to work. I specified a particular port for MediaTomb to use and opened that port in the firewall as well. At this point, Cidero was able to connect to something that resembled my media collection (unfortunately, no so for the PS3). It turns out that, for whatever reason, MediaTomb defaulted to binding to an IP address for a different network that the PS3. This was fixed by explicitly specifying the interface parameter in MediaTomb’s configuration. Bellow are some of the key parameters that I had to change in the configuration.

<server>
  <port>123456</port>
  <interface>eth0</interface>
  <ui enabled="no"></ui><!-- Disabled for security -->
  <protocolInfo extend="yes"/><!-- For PS3 support change to "yes" -->
  <pc-directory upnp-hide="yes"/>
</server>
  <import hidden-files="no">
  <scripting script-charset="UTF-8">
    <virtual-layout type="js"><!-- Change to "js" -->
      <import-script>/path/to/import.js</import-script>
    </virtual-layout>
  </scripting>
  <autoscan use-inotify="auto">
    <directory location="/path/to/media/library" mode="inotify" recursive="yes" hidden-files="no"/>
  </autoscan>
</import>

Setting the port, interface, and protocolInfo was enough to establish a connection from the PS3; however, not all of my files were showing. Browsing the library by album or artists was too tedious on the PS3 because the list was too large. I preferred using the “PC Directory” tree to browse to the desired files directly. Unfortunately, this features starts browsing from the server’s root folder each time and my media was buried several directories deep. Besides the inconvenience, I realized that I had reached the folder depth limit that the PS3 allowed and could not see files beyond that limit. To fix this, I wrote a custom import script (see below) that created a virtual path similar to the built in PC Directory but was much more convenient. In the configuration above, I hid the PC Directory because it didn’t work for me anyway (plus it’s more secure to not broadcast your PC folder structure over UPnP) and set the virtual layout type to “js”.

function addHierarchy(obj) {
  var chain = new Array('Browse Files');
  var path = obj.location;
  var extension = path.substring(path.lastIndexOf('.')+1);
  var filter=0;

  //determine path of file
  if (path.indexOf('music')>0 && extension in {'mp3':0,'wav':0,'wma':0,'ogg':0,'m4a':0} ) {
    path=path.substring(path.indexOf('music')+6, path.lastIndexOf('/'));
    chain.push('Music');
  } else if (path.indexOf('pictures')>0 )  {
    path=path.substring(path.indexOf('pictures')+14, path.lastIndexOf('/'));
    chain.push('Pictures');
  } else if (path.indexOf('music')>0 && extension in {'avi':0,'mpg':0} ) {
    path=path.substring(path.indexOf('music')+6, path.lastIndexOf('/'));
    chain.push('Videos');
  } else {
    filter=1; //don't include file
  }

  //set display name
  if (obj.meta[M_ARTIST]) {
    obj.title = obj.meta[M_ARTIST] + ' - ' + obj.title;
  }

  //insert item into it's own folder as well as virtual "all files" folder
  if (filter != 1) {
    chain = chain.concat(path.split('/'));
    addCdsObject(obj, createContainerChain(chain), UPNP_CLASS_CONTAINER_MUSIC);
    while (chain.length>3) {
      chain.push('--All Files--');
      addCdsObject(obj, createContainerChain(chain), UPNP_CLASS_CONTAINER_MUSIC);
      chain.pop();
      chain.pop();
    }
  }
}

There are several advantages for me in organizing my media library using this import script. First, it let me access all the files quicker by not having to dig so many levels deep. Also, I was able to separate the content into music, pictures, and videos folders even though I had stored the files in the same place on the server. The script filters out files that are not playable automatically. Finally, I created virtual “all files” folders at each level in the folder hierarchy that collect all files in all sub-folders recursively. This way, I can use the “all files” folder as a play list and have the PS3 shuffle through the files on its own (PS3 doesn’t support playing all the songs in a hierarchy of folders so this is gets around the problem). There are other MediaTomb features that I want to play with in the future such as transcoding and YouTube support; but, I’m happy with the configuration for now.

5 Comments »

  1. Hi, you’re doing something I’m kind of trying to do. I’m not using a PS3 but I am trying to only show certain folders to serve up, and I’m pretty new to linux, but where in that last script do you point to which directories you want to serve up?

    Comment by Paul — April 7, 2010 @ 3:54 am
  2. Paul,
    You define the location of your media collection in the <directory> tag of the import section in the MediaTomb config file.
    See http://mediatomb.cc/pages/documentation#id2858022.
    If you only need to display the directories, you may not need a custom script at all.

    Comment by leon — April 7, 2010 @ 6:06 am
  3. hey man, just letting you know I get an error

    mediatomb not compiled with “js” when i try to use it now..

    Comment by erik the vegan hack — November 29, 2010 @ 3:27 am
  4. 2010-11-29 00:21:46 INFO: Loading configuration from: /home/step/.mediatomb/config.xml
    2010-11-29 00:21:46 INFO: Checking configuration…
    2010-11-29 00:21:46 INFO: Setting filesystem import charset to UTF-8
    2010-11-29 00:21:46 INFO: Setting metadata import charset to UTF-8
    2010-11-29 00:21:46 INFO: Setting playlist charset to UTF-8
    2010-11-29 00:21:46 ERROR: MediaTomb was compiled without js support, however you specified “js” to be used for the virtual-layout.

    Comment by erik the vegan hack — November 29, 2010 @ 3:29 am
  5. Hi Eric,
    Yes you definitely need JS support. I use SuSE Linux and the package that I got had it built in. If your distribution does not provide you with a copy of MediaTomb with JS support you will have to compile the program from source yourself…

    Comment by leon — November 29, 2010 @ 5:49 pm

RSS feed for comments on this post. TrackBack URI

Leave a comment