Haiku playlists + Android


Since I started using Haiku, there's one existentially vital use-case I've wrestled with: Keeping playlists synced between MediaPlayer and VLC on Android. Y'see, on paper this should be easy: Make the playlist, save the playlist, send the playlist. In practice though, it's very slightly more tricky.

MediaPlayer saves to a pretty Haiku-specific binary format for playlists (a flattened BMessage) and can read M3U and PLS (thanks to a new patch), whereas VLC can take M3U, ASX, XSPF, and B4S as input. There's no use in worrying about VLC's output― VLC on Android saves all modifications to an internal database file, so it's easier to just edit all playlists PC-side.


The method I used for a long while was just writing M3U files for VLC by hand, listing one file per line, then converting that into a MediaPlayer playlist (by appending each track and then saving).

An M3U file might look like this:


… etc.

You can normally just open a M3U file directly with MediaPlayer, but if for some reason that's not working (weird relative paths that just aren't being treated properly), you can do it by force with the terminal:

$ IFS="
$ MediaPlayer $(grep -v "^#" playlist.m3u)

If the M3U works normally for you and you don't mind editing text-files, you could forego the Haiku playlist format entirely, no problem. c:<


But honestly, that's kind of annoying. When I'm listening to music, the last thing I want to do is bother finding the text file, figuring out the song's path… no, that's too much work. I'd much rather just drag-and-drop files from Tracker to modify playlists with MediaPlayer's window. But since MediaPlayer can only save to the binary format, I thought there wasn't much to be done― at least until recently, when I realized that a recent scripting patch opened the door to a workaround.

Picture of MediaPlayer's Playlist window
The Playlist window. Way better than text, right?

You can open/edit a playlist with MediaPlayer, then get all the paths with a scripting command to convert into M3U. Here are the functions I use for this:

playlist_uris() {
    local win="$1"
    local count="$(hey -o MediaPlayer let Window "$win" do count PlaylistTrack)"

    local i=0
    while test "$i" -lt "$count"; do
        hey -o MediaPlayer let Window "$win" do get URI of PlaylistTrack "$i"

playlist_m3u() {
    local win="$1"
    local title="$2"

    if test -n "$title"; then
        echo "#PLAYLIST:$title"
    playlist_uris "$win" \
    | sed 's%file://%%' \
    | sed 's%.*/music/%../%'

Saving playlists as M3U/PLS directly would probably be a good patch and much better way of going about it. But for now… here's this. :P

Dynamic playlists

I also sometimes make "genre" playlists, ones that contain every track of specific artists― I tend to make those with a small script, like so:

echo "#PLAYLIST:A multi-artist playlist"
tree --noreport -NnifF \
    | grep -v ".txt" \
    | grep -v ".jpg"  \
    | grep -v ".png" \
    | grep '/' \
    | grep -v '/$' \
    | grep "/.*/"

Of course, this sorta assumes you sort music in ./$artist/$album/$track format… but why wouldn't you?

rsync is cool

For the actual syncing, I use rsync with Termux, because it's great. But you probably already know that, and it's not worth me writing about. But then again, you probably already knew everything in this post, so there probably wasn't any use in me writing any of it, and I'm not sure why it'd be of any use writing anything about anything. But it's too late now, so I might as well paste the command I use in case it's of use:

$ rsync -auvr --delete user@$HOST:/boot/home/Desktop/Music/ /storage/emulated/0/Music