Skip to content

Instantly share code, notes, and snippets.

@bitingsock
Last active January 29, 2024 03:10
Show Gist options
  • Star 21 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save bitingsock/ad58ee5da560ecb922fa4a867ac0ecfd to your computer and use it in GitHub Desktop.
Save bitingsock/ad58ee5da560ecb922fa4a867ac0ecfd to your computer and use it in GitHub Desktop.
Cycle through available audio devices with key binds(shift+a,ctrl+a). Change "wasapi" on line 1 to your relevant audio api.
local api = "wasapi"
local deviceList = mp.get_property_native("audio-device-list")
local aid = 1
local function cycle_adevice(s, e, d)
mp.enable_messages("error")
while s ~= e + d do -- until the loop would cycle back to the number we started on
if string.find(mp.get_property("audio-device"), deviceList[s].name, 1, true) then
while true do
if s + d == 0 then --the device list starts at 1; 0 means we iterated to far
s = #deviceList + 1 --so lets restart at the last device
elseif s + d == #deviceList + 1 then --we iterated past the last device
s = 0 --then start from the beginning
end
s = s + d --next device
if string.find(deviceList[s].name, api, 1, true) then
mp.set_property("audio-device", deviceList[s].name)
deviceList[s].description = "•" .. string.match(deviceList[s].description, "[^%(]+")
local list = "AUDIO DEVICE:\n"
for i = 1, #deviceList do
if string.find(deviceList[i].name, api, 1, true) then
if deviceList[i].name ~= deviceList[s].name then list = list .. "◦" end
list = list .. string.match(deviceList[i].description, "[^%(]+") .. "\n"
end
end
if mp.get_property("vid") == "no" then
print("audio=" .. deviceList[s].description)
else
mp.osd_message(list, 3)
end
mp.set_property("aid", aid)
mp.command("seek 0 exact")
return
end
end
end
s = s + d
end
end
mp.observe_property("aid", function(id)
if id ~= "no" then aid = id end
end)
mp.register_event("log-message", function(event)
if event.text:find("Try unsetting it") then
mp.set_property("audio-device", "auto")
mp.set_property("aid", aid)
end
end)
mp.add_key_binding("A", "cycle_adevice", function()
deviceList = mp.get_property_native("audio-device-list")
cycle_adevice(1, #deviceList, 1) --'s'tart at device 1, 'e'nd at last device, iterate forward 'd'elta=1
end)
mp.add_key_binding("Ctrl+a", "cycleBack_adevice", function()
deviceList = mp.get_property_native("audio-device-list")
cycle_adevice(#deviceList, 1, -1) --'s'tart at last device, 'e'nd at device 1, iterate backward 'd'elta=-1
end)
@bitingsock
Copy link
Author

while it doesn't really 'solve' the issue, I'll leave it for now until someone else brings it up.

@HairyOtter
Copy link

HairyOtter commented Aug 25, 2023

while it doesn't really 'solve' the issue, I'll leave it for now until someone else brings it up.

I did some further testing today and it does not resolve the issue.

My use case needs audio passthrough via HDMI for one of the audio devices. For that to work pulse audio needs to be disabled.
With pulse audio disabled, the switching for alsa doesn't work (it only switches between 2 virtual devices).

Since I have a static use case, I've got it to work by hardcoding one of 2 audio devices (the HDMI connection to the AVR) in mpv.conf, where I've also added:

audio-device=<devicename>
audio-spdif=ac3,eac3,dts,dts-hd,truehd
audio-channels=7.1,5.1,stereo

for audio-passthrough and multichannel to work over HDMI.
mpv --audio-device=help showed me which devices to add.

I then added the second one to audio-dupe.lua in the start_child function, replacing "--audio-device=" .. mp.get_property("audio-device"), with "--audio-device=<devicename>",

That way the default is the HDMI passthrough to the TV in case I watch something alone and only need one audio device.
And the subprocess starts on the headphones, in case 2 different tracks are needed at the same time.

While that works well for me so far, it eliminates a part of the flexibility of your scripts.

I just thought I'd add my workaround if someone else desires a "static" version until/if you deem it important enough to look into the alsa problem further.

I'm very grateful for your scripts as they allow me to watch TV with my father again without one of us being frustrated.

He gets the German dub that he needs (poor English comprehension and he can't read quickly enough for subs any more either) via headphones in a volume of his choosing and I get the original audio over speakers. I've looked for a solution like this for literally years.

Thanks again!

@bitingsock
Copy link
Author

dude, that's awesome

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment