Gerbera (旧mediatomb)のimport.js

mediatombを長年愛用してきましたが、後継のGerberaにようやく移行。
DLNAサーバーソフトなら、miniDLNAやらps3mediaserverやらがあるんでしょうが、mediatombを使い続けていたのは強力なインポート機能があるからでした。
で、防備録としてインポート機能のカスタマイズを記録。

javascriptを用いたインポート機能を利用するには、まず、config.xmlでvirtual-layout typeをデフォルトのbuilt-inからjsに変更しなければなりません。

<virtual-layout type="js">
    <import-script>/usr/share/gerbera/js/import.js</import-script>
</virtual-layout>

で、デフォルトでは/usr/share/gerbera/js/import.jsにあるファイルを編集します。なお、このファイル、Gerberaをアップデートインストールするたびに上書きインストールされるため、カスタマイズしたものをバックアップを取っておくか、別な場所にファイル指定しておくなどの対策が必要です。

さて、まずはアルバム内を表示したときに、曲名の先頭にトラック番号を付ける処理です。
こうすることで、DLNADMC側でABC順に再生する機器でも、曲名の先頭に01など数字から始まる曲名が着いていることで、曲順がアルバム内の順番通りに再生されます。
これは、import.js内にコメントアウトとコメント化する箇所が指定されています。

// uncomment this if you want to have track numbers in front of the title
// in album view


    var track = obj.meta[M_TRACKNUMBER];
    if (!track) {
        track = '';
    } else {
        if (track.length == 1) {
            track = '0' + track;
        }
        track = track + ' ';
    }

    // comment the following line out if you uncomment the stuff above  :)
//    var track = '';

これで、ArtistからAlbumを選択して再生した場合や、そのままAlbumを直接選択して再生した場合などは、曲名の先頭に01から始まるトラック番号が付与されました。

しかしです、mediatombやGerberaには、"All - full name"という、便利なカテゴリがあります。この配下には、"アーティスト名 アルバム名 曲名"という名前で曲名が表示されます。特定のアーティストの曲を前アルバム全て再生したい!と言うときなどに便利です。が、ここにトラック番号が入っていません。

そこで、"All - full name"配下の曲名にもトラック番号を表示するようにします。

    chain = ['Audio', 'All - full name'];
    var temp = '';
    if (artist_full) {
        temp = artist_full;
    }

    if (album_full) {
        temp = temp + ' - ' + album_full + ' - ';
    } else {
        temp = temp + ' - ';
    }

    obj.title = temp + track + title; //ここを変更
    addCdsObject(obj, createContainerChain(chain));

    chain = ['Audio', 'Artists', artist, 'All - full name'];
    addCdsObject(obj, createContainerChain(chain));

上記の13行目は元々は、obj.title = temp + title;となっており、tempには、その直前に指定しているとおり、artist_fullとalbum_fullが入っています。アルバム名と曲名の間にtrackを挟むことで、

「アーティスト名 アルバム名 トラック番号 曲名」

という表示になり、アルバムの曲順通りに再生できるようになります。

そして、このバーチャルレイアウト、困るのが指定したディレクトリ配下にある音楽を全てimport.jsの指定通りの箱に入れようとします。そうすると、今までCDリッピングしまくったシングル曲、DATからリッピングした懐かしのユーロビート、自分はあまり聞かない妻のロック、有象無象がすべて同じところに格納され、Artist名は膨大な数になってしまい、スクロールするのも大変になってしまいます。
そこで、大まかなところまではディレクトリ名を反映させることにします。

ウチのサーバーの場合、
/home/mp3/Album
/home/mp3/Single
/home/mp3/SuperEurobeat
/home/mp3/Wife
という、4つのフォルダに分けて格納されています。この第3階層をバーチャルレイアウトに表示させようと思います。

変数宣言の最初の方で、適当な変数にフォルダ名を"/"(スラッシュ)で分けて配列格納し、第三階層が格納されている第3配列のみを取り出し、変数u_pathに格納します。

function addAudio(obj) {

    var desc = obj.location; //インポートファイルのフルパスを変数descに格納
    var arr = desc.split('/'); //フルパスをスラッシュで分離しarrという配列に格納
    var u_path = arr[3]; //arr配列の3番目を変数u_pathに格納
    var desc = ''; //変数descをnullに
    var artist_full;
    var album_full;

これを、この後に出てくる実際のバーチャルレイアウトへの格納時に、u_pathの階層をを作ってあげます。

    var chain = ['Audio', u_path, 'All Audio'];
    obj.title = title;
    addCdsObject(obj, createContainerChain(chain));

    chain = ['Audio', u_path, 'Artists', artist, 'All Songs'];
    addCdsObject(obj, createContainerChain(chain));

    chain = ['Audio', u_path, 'All - full name'];
    var temp = '';
    if (artist_full) {
        temp = artist_full;
    }

    if (album_full) {
        temp = temp + ' - ' + album_full + ' - ';
    } else {
        temp = temp + ' - ';
    }

    obj.title = temp + track + title;
    addCdsObject(obj, createContainerChain(chain));

    chain = ['Audio', u_path, 'Artists', artist, 'All - full name'];
    addCdsObject(obj, createContainerChain(chain));

    chain = ['Audio', u_path, 'Artists', artist, album];
    obj.title = track + title;
    addCdsObject(obj, createContainerChain(chain), UPNP_CLASS_CONTAINER_MUSIC_ALBUM);

    chain = ['Audio', u_path, 'Albums', album];
    obj.title = track + title;
    addCdsObject(obj, createContainerChain(chain), UPNP_CLASS_CONTAINER_MUSIC_ALBUM);

    chain = ['Audio', u_path, 'Genres', genre];
    addCdsObject(obj, createContainerChain(chain), UPNP_CLASS_CONTAINER_MUSIC_GENRE);

    chain = ['Audio', u_path, 'Year', date];
    addCdsObject(obj, createContainerChain(chain));

    chain = ['Audio', u_path, 'Composers', composer];
    addCdsObject(obj, createContainerChain(chain), UPNP_CLASS_CONTAINER_MUSIC_COMPOSER);
}

これで、"Audio"を選択した後に、"Album" "Single" "SuperEurobeat" "Wife"の階層が現れ、それぞれの階層ではそのフォルダに保存されている音楽しか表示されないので、アーティスト名が多すぎて検索が大変!! ということがなくなります。(それでもSingleフォルダは大変な多さですが・・・。)

Gerberaをほぼ音楽サーバーとしか使っていないので、VideoやPhotosはいじっていません。
できれば、mp3配下に入っているアルバムアートなどのJPGを除外し、本当に表示したい写真だけを配信できるようにしたいところですが、「写真をテレビに表示して見る!」ということもないので、当面実施しないことでしょう。