Stupid coding tricks: Homebrew MTV

Four music videos running on my local music video channel.

This year, after thinking about it casually for a long time, I finally got around to building a home media server. Worries about the ever-shifting libraries of streaming services and the general degradation of the internet into increasingly isolated walled gardens has convinced me to hoard as much data as I feasibly can, lest it all disappear on me one day. Or something like that.

This line of thinking led to me going through the music videos I’d collected over the years. Shoving them all into Plex, a video-on-demand server, felt lacking. Plex feels specifically suited for watching TV shows and movies, something where you’ll sit down and pick a specific thing to watch for a few hours. But you don’t really sit down for a good session of picking a music video to watch. In the golden age of music videos, they just came to you in a stream, no picking and choosing required.

Building your own music video channel

It turns out there are several software packages designed to turn parts of your media library into a linear television network stream. If you wanted to, you could take all your episodes of old cartoons and make your own Cartoon Network, complete with whatever bumpers and commercials you could source. I ended up using ErsatzTV to build my own music video channel using my own video library.

ErsatzTV has a few features specifically suited to playing music videos, the most obvious of which is the ability to display music credits like the artist name and song title over each video. So of course, after getting the basics set up and the metadata sorted (a process that took longer than expected), I spent a whole ton of time tweaking the credits to look good.

Music video credits: obviously the most important part

There are three built-in options for credits. One mimics the old MTV style of credits, which is great except a) it only displays credits at the beginning of each song, not the end, and b) I don’t have any nostalgia for MTV because I’m not American, and Kabel isn’t my favourite font. The other two implement the ability to display credits at both the beginning and the end of each video, but they both use Roboto and then squish it horizontally, which is a type crime of the highest order. Neither of them place the credits at the bottom-left of the screen, either.

Luckily, ErsatzTV also allows you to customize the credits styling and placement, though this isn’t very well documented. Some quick notes on this:

  • Credits are implemented as subtitles, so knowing Advanced Substation Alpha subtitle formatting is super helpful here.
  • You need to place your subtitle file in a specific place, and it’s not obvious where this should be. Depending on your OS, this location will be different, and it’s not contained in the folder you dropped the ErsatzTV files in. On Windows, the directory ended up being in my user directory: C:\Users\[username]\AppData\Local\ersatztv\cache\templates\music-video-credits\ (which you might have to create if it doesn’t already exist). I assume for other OSes the location will similarly be somewhere in the user home directory.
  • Advanced Substation Alpha is the syntax for all the subtitle markup, but there’s also scripting courtesy of Scriban, a text templating language commonly used with .NET. Scriban scripting is how stuff like injecting the artist/song title is done, as well as handling showing subtitles at the beginning and end of a music video no matter how long it is.
  • You can technically use whatever font you like for the subtitles, as long as you have the relevant font file. ErsatzTV comes with a version of Kabel (the MTV font) and Roboto by default, but if you can get your hands on an OpenType OTF or TruType TTF file, you can drop that in the ErsatzTV user config directories (ex. C:\Users\[username]\AppData\Local\ersatztv\cache\streams\fonts\). Then you can reference the font in the subtitle file’s styles.

After a while I managed to get something relatively clean and compact, while displaying all the information I wanted to:

Handling non-Latin scripts

Only one thing, though. I have a bunch of Japanese and Korean videos in my library, and anyone who’s had to deal with a lot of music written in places where they don’t use Latin characters has probably faced the question of how to store artist, song and album names. Do you keep them in the original language, or do you romanize them? Nearly every system I’ve seen for handling music never considers this particular conundrum, instead forcing you to choose one to display by virtue of only having one artist or title field for each song.

But for once, I have control over both the metadata format for each song AND the means to display that metadata. I can do better. Well, sort of. Technically, music video metadata is stored in an NFO file to Kodi spec, and as usual, the spec only allows for a single <artist>, song <title> and <album> title field. It certainly doesn’t allow you to do anything like specify multiple fields with a language attribute or anything like that. So it seems like we’re stuck.

Except that there’s one field in the Kodi spec that doesn’t seem particularly useful for music videos, but is nonetheless imported by ErsatzTV and even passed to the music video subtitle generator: <plot>. I can’t imagine ever really wanting to use <plot> to explain the plot of a music video, let alone displaying that alongside the song credits when a music video starts. So let’s instead use it as bulk storage for our own adhoc tagging system! I added a string to some of the <plot> fields that looks something like this:

<plot>~titleRoman:Labyrinth,albumRoman:Reborn Again and Always Starting New~</plot>

This allows me to add up to three romanizations: one for the artist name, one for the song title, and one for the album title. Above is a line that can override the song and album title for Mondo Grosso’s “Labyrinth”.

After a whole bunch of scripting (and troubleshooting facilitated by this online Scriban parser) I managed to build a setup that does the following:

  1. check for the existence of anything in the <plot> field that looks like romanization data;
  2. if the data exists, populate up to three new variables with the romanizations;
  3. create a new set of subtitles with the romanizations, then set it to fade in right when the original subtitles fade out (and do this both at the beginning of a video and the end of a video)
Animation showing the transition of music video credits of a Japanese music video, showing the Japanese text first before cross-fading into English text.

The result is surprisingly satisfying. Watching the romanized text replace the original language text works better than I expected, and the one-second transition where the two subtitles overlap turned out not to be much of an issue visually. And for the music videos where the metadata is all in English or another Latin-alphabet language, it works exactly like it did before.

What’s next?

I’m pretty happy with where the channel setup is now, so the first obvious thing to do is put more music videos into it. After spending a few days with it on in the background for hours at a time, I realized that even 200 or so music videos means you run into repeats really quickly. There’s also the fundamental issue that if you’re curating all the music videos yourself, there’s no real sense of discovery; you know everything that’s in the library already. That’s a problem for down the road, but it’s something I want to think about solving at least.

The other thing is that right now the channel is exclusively music videos. One of the fun things about people making their own MTV, or Cartoon Network, or whatever channel they want, is all the stuff that goes in between the actual content: station bumpers, commercials, etc. Since the channel I’m building isn’t entirely a nostalgia ploy, I don’t feel like it’s quite right to find a bunch of commercials from MuchMusic in the 90s and slam them in wholesale. But I’m also not really sure what I’d want to use in their place.