Furkan Mudanyalı's Personal Webpage

Blog

Home Contact Blog Projects

No More Defaults: Auto-Selecting Japanese Subtitles & Stereo, with help of AI

One of the ways I study Japanese is the immersion method. What it basically is that you consume a content in target language without any aid, and try understanding it. It may sound ridiculous but thats literally how I, along with many people I know, learned English in the first place! The easiest way to do it is watching anime with Japanese subtitles, or no subtitles at all. The problem is though, as far as I know, MPV does not provide a way to do this at the time of writing. I can only nudge it to give me Japanese subtitles if they're available, else it just defaults to whatever subtitle there is. While trying to troubleshoot this with ChatGPT, it offered me to write a plugin for MPV to handle this, I figured why not. It gave me a short script and told me to put it in my mpv config, so I did. And to my surprise, it actually worked!

~/.config/mpv/scripts/subtitle.lua

local function choose_audio_and_subs() local tracks = mp.get_property_native("track-list") or {} local sid = nil for _, t in ipairs(tracks) do if t.type == "sub" and t.lang == "ja" then sid = t.id break end end if sid then mp.msg.info("select-tracks: selecting JA subtitle #"..sid) mp.set_property_number("sid", sid) else mp.msg.info("select-tracks: no JA subs, disabling") mp.set_property("sub", "no") end end mp.register_event("file-loaded", function() local tracks = mp.get_property_native("track-list") or {} for _, t in ipairs(tracks) do if t.type == "sub" and t.lang == "ja" then mp.set_property_number("sid", t.id) return end end mp.set_property("sub", "no") end)

After seeing the potential, I figured I should also ask one of the pet peeves I have; I do not have and do not plan to have any surround setup. I am strictly stereo only. I want stereo audio. But the thing is, video files often have several audio channel tracks for a given language, and they almost always default to the one with most channels. This causes the media player to downmix the audio, resulting in a subpar experience compared to the stereo track. I can't hear them people speaking! So I asked ChatGPT about it, and after some trial and error, it also managed to do it, incredible!

~/.config/mpv/scripts/stereo.lua

-- mpv script: if the selected audio track for a given language is multichannel, switch to its stereo counterpart with detailed logging local mp = require("mp") -- Get the native track list local function get_tracks() return mp.get_property_native("track-list") or {} end -- Find an audio track by id local function find_audio_track_by_id(id) for _, t in ipairs(get_tracks()) do if t.id == id and t.type == "audio" then return t end end return nil end -- Attempt to switch to stereo for the same language local function switch_to_stereo_if_needed() local tracks = get_tracks() -- Get current audio track id local aid_prop = mp.get_property("aid") local current_id = tonumber(aid_prop) if not current_id then return end local sel = find_audio_track_by_id(current_id) if not sel then return end local ch = sel["audio-channels"] or 0 -- Only act on multichannel if ch <= 2 then return end -- Find stereo counterpart for _, t in ipairs(tracks) do local tchan = t["audio-channels"] or 0 if t.type == "audio" and t.lang == sel.lang and tchan == 2 and t.id ~= current_id then mp.commandv("set", "aid", tostring(t.id)) return end end end -- Hook into MPV events mp.observe_property("aid", "string", function(name, value) switch_to_stereo_if_needed() end) mp.register_event("file-loaded", switch_to_stereo_if_needed)

You can also see it in action when I launch MPV from command line.

Switched to stereo audio and japanese subtitle:

stereo audio + japanese subtitles

Switched to stereo audio and disabled subtitles:

stereo audio + no subtitles

The takeaway is that the AI helped me avoid digging through MPV documentation to write these simple scripts, so I'm grateful for that. It feels like a slippery slope though, as if you depend on it too much, you will be at a loss when it doesn't work. My embedded software developer friend abused Claude for a week and got rate limited, now he's struggling to write any code.