Overcoming Mediatombs disabled javascript import filters in Ubuntu 14.04 LTS

Nearly three years ago I wrote about how I had managed to re-enable the Javascript import filters for Mediatomb, that allowed one to control how Mediatomb imported (and represented) files in its database. Lots of people have followed the same approach, but when I moved to Ubuntu 14.04 LTS, I found it much harder than before because of the addition of various fixes, and the increasing age of the version of Spidermonkey that Mediatomb was tied to. I decided to follow a new path, which I document here.

The basic approach is to rebuild the shipped package of Mediatomb, but rather than trying to enable the Javascript support, we’ll update the in-built default C++ importer so it does what we need. This gets us away from needing to enable an ancient version of Spidermonkey, or having to rollback several fixes that have been made to Mediatomb by the Ubuntu maintainers. Here’s what you need to do:

  1. cd;mkdir temp;cd temp
  2. sudo apt-get install build-essential, to install the tools you will need to build packages on Ubuntu
  3. sudo apt-get build-dep mediatomb, to install all the dependencies needed for mediatomb to compile
  4. sudo apt-get source mediatomb, to get the source code for mediatomb, and unpack it into a convenient subdirectory
  5. cd mediatomb-0.12.1/src/layout, to get into the directory where we are going to make our changes
  6. cp fallback_layout.cc fallback_layout.cc.backup, to take a backup, just in case something should go wrong

In Mediatomb you define a series of directories (& optionally subdirectories) that should be scanned for media that can be included into Mediatombs database. When there is no Javascript importer, a routine in this file gets called for each found piece of media that is “video” in nature (there are also similar routines for audio and pictures in this same file).

If you open up fallback_layout.cc in a text editor (vi or gedit, or similar) and scroll down to (approximately) line 86 you will find a routine called “FallbackLayout::addVideo”. This gets passed an object that describes the video file that the server is trying to import into its database, along with (I think) the base directory from the “scan” that made Mediatomb include this object (file). In practice, I never saw that base directory path set to anything, but that may just be the way I have Mediatomb configured.

So, what I do is alter this routine, to:

  1. Tidy up the name of the file as reported in the Mediatomb database
  2. Build a proper expanding tree structure for my database, based on the directory structure where I store my videos

Hopefully this commented version of my FallbackLayout::addVideo import routine will make clear how this works. Much of the cleverness is already in the support functions provided by Mediatomb, especially addContainerChain(), and all I need to do is some fairly simple text manipulation. This should work for you too; you could simply replace the routine in your file with this one. I think that the only place you would need to make a change is the line dir = dir.substring(17); where you need to change the 17 to however many leading characters of your directory structure you want to remove from the Mediatomb GUI.


void FallbackLayout::addVideo(zmm::Ref obj, String rootpath) {

Ref f2i = StringConverter::f2i();
String dir;
String title;

// Grab the title (its filename) from the object obj, and tidy it up, converting
// underscores to spaces, and removing the filetype
title = obj->getTitle();
title = title.replaceChar('_', ' ');
title = title.substring(0, title.rindex('.') );

// Write the result back as the objects new title
obj->setTitle(title);

// Get location (eg "/srv/media/video/Films/12/James_Bond/Living Daylights.mp4" )
dir = f2i->convert(obj->getLocation());
// Remove leading directories (eg "/srv/media/video/" -> "Films/12/James_Bond/Living Daylights.mp4")
dir = dir.substring(17);
// Remove filename and trailing slash (eg "/Living Daylights.mp4" -> "Films/12/James_Bond")
dir = dir.substring(0, dir.rindex('/'));
// Convert underscores to spaces -> "Films/12/James Bond"
dir = dir.replaceChar('_', ' ');

if (string_ok(dir))
{
// Iterate through the string, building the chain from the constituent parts,
// escaping the text parts as necessary for Mediatomb:
// ie: esc("Films")+"/"+esc("12")+"/"+esc("James Bond")
//
String container, Chain;
int p;

while ( (p = dir.index(0, '/')) > 0 ) {
container = dir.substring(0,p); // Grab the topmost directory name (container)
Chain = Chain + "/" + esc(container); // Add it to the chain
dir = dir.substring(p+1); // Cut off the container (and trailing slash)
}
Chain = Chain + "/" + esc(dir); // Add final directory to chain

// Add the new chain (addContainerChain takes care of duplication / overlaps etc)
int id = ContentManager::getInstance()->addContainerChain(_("/Video") + Chain );

// Now add the object (ie the file) to the chain, using its tidied up name etc
if (obj->getID() != INVALID_OBJECT_ID)
{
obj->setRefID(obj->getID());
add(obj, id);
}
else
{
add(obj, id);
obj->setRefID(obj->getID());
}
}
}

And now we need to compile, install and test it. Though depending on what changes you need to make for your environment, and how rusty your C++ skills are, you may need to iterate around the edit / compile / test phases a few times until it all compiles and works cleanly.

  1. cd ~/temp/mediatomb-0.12.1 and then sudo ./configure. Lots of content will scroll past, but at the end there should be a summary; check that all your dependancies are satisfied.
  2. Start the compilation with sudo fakeroot debian/rules binary. Lots of compilation messages should scroll past.
  3. When it stops, you should have three .deb files in ~/temp. You can install them with sudo dpkg -i mediatomb*.deb

Finally, switch to root (sudo su) and then issue the command echo packagename hold | dpkg –set-selections for each of mediatomb, mediatomb-common and mediatomb-daemon. Then drop back to your user by entering control-D. This will prevent your customised packages being overwritten as part of the normal update processes (they will be “held”.)

Advertisements

4 thoughts on “Overcoming Mediatombs disabled javascript import filters in Ubuntu 14.04 LTS

  1. Like you, I’ve used Mediatomb for a number of years. I found the Javascript functionality excellent, as it allowed me to select a year for a music playlist without it dropping the odd chapter of an audiobook which happened to be produced in the same year.

    Now i am in the situation where I am rebuilding the mediaserver, I have (yet again) hit the mediatomb / javascript feature, and, prompted by your blog post, I feel empowered to update my copy of the server to support configurable entries.

    I opt to go for something much simpler than Javascript or Python though, and configure using XML – It should be really simple using string substitutions in the fallback_layout.cc file, and making use of the xml parser which is already in mediatomb.

    Any thoughts on the concept would be greatfully received.

    Here is a snippet of a sample XML file, and I should note that the $VARIABLES are automatically expanded, most should be obvious. The $XXXABC variables are simply either [abc], [def] etc. depending on the first letter of the Artist / Album etc.

    defaultmusic
    Radioradio

    /Folder/$PATH/$FILENAME
    /Music/Artist/$ARTISTABC/$ARTIST/ – All Songs -/$TITLE
    /Music/Artist/$ARTISTABC/$ARTIST/$ALBUM/$TRACKNUM. $TITLE
    /Music/Album/$ALBUMABC/$ALBUM/ – All Songs -/$TITLE
    /Music/Album/$ALBUMABC/$ALBUM ($ARTIST)/$TRACKNUM. $TITLE
    /Music/Genre/$GENRE/ – All Songs -/$TITLE ($ARTIST, $ALBUM)
    /Music/Genre/$GENRE/Artist/$ARTISTABC/$ARTIST/$ALBUM/$TRACKNUM. $TITLE
    /Music/Genre/$GENRE/Album/ – All Albums -/$ALBUM/$TRACKNUM. $TITLE
    /Music/Genre/$GENRE/Album/$ALBUMABC/$ALBUM/$TRACKNUM. $TITLE
    /Music/Genre/$GENRE/Year/$YEAR/$TITLE ($ARTIST, $ALBUM)

    Steve

    • Hi Steve,
      Sounds really interesting. It’s been a while since I was digging around in there, but I’m currently starting to plan a complete rebuild of my home server, including moving to Ubuntu 16.04, so I’m probably about to face this issue again. I would be keen to understand a bit more detail about how you will implement what you are proposing, and also how I can take advantage of it, because my solution (of modifying the C++ code) is a bit inflexible.
      BTW, love your domain-name. We are clearly of a similar age 🙂

      • Hi Richard,

        I’ve made a start, and have modified the configuration file parser to include an xml option (as well as builtin / js), and have added an xml file.

        At present, I’ve not done the xml file parsing. I have, however, written layout/xml_layout.cc and layout/xml_config.cc (this one is a placeholder), and have successfully implemented $VARIABLE substitution as above.

        If you can drop me an email, I’m happy to share the current hacks – long term aim is to pass this back to the mediatomb team as a patch.

        Steve

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s