Mediatomb: Custom folders

Many rooms in our house have an UPnP capable internet radio device, and I'm using Mediatomb to distribute music and radio to them. ​

Mediatomb automatically categorizes music files into different virtual folders: ​

UPnP directory root
├ Audio
│ ├ Albums
│ ├ All - full name
│ ├ All Audio
│ ├ Artists
│ ├ Genres
│ └ Year
├ PC Directory
└ Photos​

This is fine for music albums, but not for radio plays, podcasts, single tracks I don't have the full album for and kid's tales. ​

Luckily mediatomb allows one to completely customize how those virtual folders are setup. ​

Plan​

Files for our kids fall in two categories: Music and tales/stories. Thus beside the "Audio" and "Photos" folder, there shall be a "Kid's Music" and "Kid's Stories" folder. They should not be indexed in the Audio folder. ​

I've got Podcasts and adult radio plays as well, and they should also not be in the Audio folder, but in their own ones. ​

Finally, single songs shall be put into "Audio/Singles" without any futher indexing. ​

UPnP directory root
├ Audio
│ ├ Albums
│ ├ All - full name
│ ├ All Audio
│ ├ Artists
│ ├ Genres
│ ├ Singles
│ └ Year
├ Kid's Music
├ Kid's Stories
├ Podcasts
├ PC Directory
├ Radio plays
└ Photos​

I've already sorted them in the real directories that way: ​

$ ls -1 /var/spool/music
Albums
Singles
Radio plays
Kid's music
Kid's tales
Podcasts​

With that, I only have to configure mediatomb to act a bit differently depending on the folder the audio file is in. ​

Mediatomb configuration​

At first mediatomb has to use a custom import script. The documentation tells us that we have to use a virtual layout of type js, and can configure the import script there: ​

<virtual-layout type="js">
  <import-script>/etc/mediatomb/import-cweiske.js</import-script>
</virtual-layout>

import-cweiske.js is a copy of /usr/share/mediatomb/js/import.js with some small changes. The scripting docs helped here: ​

$ diff -u /usr/share/mediatomb/js/import.js /etc/mediatomb/import-cweiske.js 
--- /usr/share/mediatomb/js/import.js  2012-06-09 20:59:50.000000000 +0200
+++ /etc/mediatomb/import-cweiske.js   2015-04-09 21:56:33.000000000 +0200
@@ -108,6 +108,28 @@
     // comment the following line out if you uncomment the stuff above  :)
     var track = '';
 
+    if (obj.location.indexOf('/Albums/') === -1) {
+        //no Music Album, so keep them in separate folders
+        if (obj.location.indexOf('/Singles/') !== -1) {
+            chain = new Array('Audio', 'Singles');
+            obj.title = title;
+            addCdsObject(obj, createContainerChain(chain));
+        } else if (obj.location.indexOf('/Radio plays/') !== -1) {
+            chain = new Array('Radio plays', album);
+            obj.title = track + title;
+            addCdsObject(obj, createContainerChain(chain), UPNP_CLASS_CONTAINER_MUSIC_ALBUM);
+        } else if (obj.location.indexOf("/Kid's stories/") !== -1) {
+            chain = new Array("Kid's stories", album);
+            obj.title = track + title;
+            addCdsObject(obj, createContainerChain(chain), UPNP_CLASS_CONTAINER_MUSIC_ALBUM);
+        } else if (obj.location.indexOf("/Kid's music/") !== -1) {
+            chain = new Array("Kid's music", artist, album);
+            obj.title = track + title;
+            addCdsObject(obj, createContainerChain(chain), UPNP_CLASS_CONTAINER_MUSIC_ALBUM);
+        }
+        return;
+    }
+
     var chain = new Array('Audio', 'All Audio');
     obj.title = title;
     addCdsObject(obj, createContainerChain(chain));

The adjustments to the addAudio function do the following: ​

  1. If the file's location (full path) does not contain "Albums", the special handling starts. ​
  2. If the file's location contains "Singles", the track gets put into the Audio/Singles/ folder. This folder is a normal folder, which means it gets sorted alphabetically. ​
  3. If the file's location contains "Radio plays", the track gets put into Radio plays/$album name/. This folder is a music album folder which means tracks get sorted by the track number and not alphabetically. ​
  4. .. and so on ​
  5. At the end, we simply return from the function, which prevents the normal virtual folder handling for those files. ​

Written by Christian Weiske.

Comments? Please send an e-mail.