• 1(current)
  • 2
  • 3
  • 4
  • 5
  • 7
[HOW-TO] Easily switch audio outputs, settings, etc.
#1
Music 
I can't post in the how-to section so I've put it here.

A new addition to XBMC 13 is the ability to alter settings via the JSON-RPC API, making it easy to switch settings via remote controls, menu shortcuts etc. With a python script you can toggle between different groups of settings, such as audio settings, plus it uses XBMC's internal python so it should work on all OS's. A list of settings that can be modified, provided by joethefox, can be found here (note it does not contain every setting across all OS's, it is specific to Linux, but should cover the majority).

The following instruction are for Windows, so you need adapt file paths to your operating system. In your favourite text editor create a python script:
C:\Users\td\Dropbox\docs\audio_switch.py
Code:
#audio toggle script for xbmc
import xbmc
import os

tempdir = xbmc.translatePath('special://temp/')
tempfile0 = os.path.join(tempdir, 'audiooutput0')

print("CURRENT AUDIO DEVICE:")
print(xbmc.executeJSONRPC('{"jsonrpc":"2.0","method":"Settings.GetSettingValue", "params":{"setting":"audiooutput.audiodevice"},"id":1}'))

if not os.path.isfile(tempfile0):
#settings group 0
#edit below here
    xbmc.executeJSONRPC('{"jsonrpc":"2.0", "method":"Settings.SetSettingValue", "params":{"setting":"audiooutput.audiodevice", "value":"WASAPI:default"}, "id":1}')
    xbmc.executeJSONRPC('{"jsonrpc":"2.0", "method":"Settings.SetSettingValue", "params":{"setting":"audiooutput.passthrough","value":true}, "id":1}')
    xbmc.executeJSONRPC('{"jsonrpc":"2.0", "method":"Settings.SetSettingValue", "params":{"setting":"audiooutput.channels","value":8}, "id":1}')
    xbmc.executeJSONRPC('{"jsonrpc":"2.0", "method":"GUI.ShowNotification", "params":{"title":"AUDIO OUTPUT", "message":"WASAPI", "image":"C:/Users/td/AppData/Roaming/XBMC/addons/metadata.common.last.fm/icon.png"}, "id":1}')
#edit above here
    file = open(tempfile0, "a")
    file.close()
else:
#settings group 1
#edit below here
    xbmc.executeJSONRPC('{"jsonrpc":"2.0", "method":"Settings.SetSettingValue", "params":{"setting":"audiooutput.audiodevice", "value":"DIRECTSOUND:default"}, "id":1}')
    xbmc.executeJSONRPC('{"jsonrpc":"2.0", "method":"Settings.SetSettingValue", "params":{"setting":"audiooutput.passthrough","value":false}, "id":1}')
    xbmc.executeJSONRPC('{"jsonrpc":"2.0", "method":"Settings.SetSettingValue", "params":{"setting":"audiooutput.channels","value":1}, "id":1}')
    xbmc.executeJSONRPC('{"jsonrpc":"2.0", "method":"GUI.ShowNotification", "params":{"title":"AUDIO OUTPUT", "message":"DS", "image":"C:/Users/td/AppData/Roaming/XBMC/addons/metadata.common.last.fm/icon.png"}, "id":1}')        
#edit above here
    os.remove(tempfile0)

The above script toggles between two groups of settings - the audio device (The default WASAPI/DISRECTSOUND device), pass-through (true/false), number of channels (8(5.1ch)/1(2ch)) and displays a on-screen notification (link to a speaker icon to use). You need to edit the lines beginning with xbmc.executeJSONRPC and you can add/remove lines if necessary. To find current the audio output devices look in the XBMC log file after running the script (it doesn't matter if it isn't configured properly yet), it prints the current selected audio device to the log file in a JSON-RPC friendly string (search for "CURRENT AUDIO DEVICE:").

Above toggles between two groups of settings, below is an example of a script to toggle between 3 groups of settings (you can expand it for more than 3 groups):
Code:
#audio toggle script for xbmc
import xbmc
import os

tempdir = xbmc.translatePath('special://temp/')
tempfile0 = os.path.join(tempdir, 'audiooutput0')
tempfile1 = os.path.join(tempdir, 'audiooutput1')

print("CURRENT AUDIO DEVICE:")
print(xbmc.executeJSONRPC('{"jsonrpc":"2.0","method":"Settings.GetSettingValue", "params":{"setting":"audiooutput.audiodevice"},"id":1}'))

if not os.path.isfile(tempfile0):
    xbmc.executeJSONRPC('{"jsonrpc":"2.0", "method":"GUI.ShowNotification", "params":{"title":"AUDIO OUTPUT", "message":"WASAPI", "image":"C:/Users/td/AppData/Roaming/XBMC/addons/metadata.common.last.fm/icon.png"}, "id":1}')
    file = open(tempfile0, "a")
    file.close()
elif not os.path.isfile(tempfile1):
    xbmc.executeJSONRPC('{"jsonrpc":"2.0", "method":"GUI.ShowNotification", "params":{"title":"AUDIO OUTPUT", "message":"AUDIO2", "image":"C:/Users/td/AppData/Roaming/XBMC/addons/metadata.common.last.fm/icon.png"}, "id":1}')
    file = open(tempfile1, "a")
    file.close()
else:
    xbmc.executeJSONRPC('{"jsonrpc":"2.0", "method":"GUI.ShowNotification", "params":{"title":"AUDIO OUTPUT", "message":"DS", "image":"C:/Users/td/AppData/Roaming/XBMC/addons/metadata.common.last.fm/icon.png"}, "id":1}')        
    os.remove(tempfile0)
    os.remove(tempfile1)

Now to run the script within XBMC use the RunScript() function, which can be used in keyboard/remote keymaps, skin shortcuts etc:
Code:
RunScript("C:\Users\td\Dropbox\docs\audio_switch.py")


That does it, now enjoy easily switching audio outputs and settings!
Reply
#2
Very nice!
Reply
#3
Updated scripts in first post to print the currently used audio output device into the xbmc.log file in a json-rpc friendly string, should make selecting devices a lot easier.
Reply
#4
Awesome, I'll be trying this, thanks.
Reply
#5
hi,
at first: thank you teeedubb!!!!

i was trying that but i had a little problem: at first i created a shortcut py-script to keyboard button/remote. for me the gen.xml looks like that and it seems to work:

<keymap>
<global>
<keyboard>
<key id="61511">RunScript("C:\AudioSwitch\audioswitch.py")</key>
</keyboard>
</global>
</keymap>

if someone needs help with that please look here: http://forum.xbmc.org/showthread.php?tid=164498


the problem is, it seems the "current audio device" isnt printed. i get a error. below you find the relevant parts of a debug log. do you have any ideas? thanks for help in advance!!!

18:56:09 T:2212 DEBUG: CApplication::OnKey: g (0xf047) pressed, action is RunScript("C:\AudioSwitch\audioswitch.py")
18:56:09 T:2212 DEBUG: ------ Window Deinit (Pointer.xml) ------
18:56:09 T:1300 NOTICE: Thread LanguageInvoker start, auto delete: false
18:56:09 T:1300 INFO: initializing python engine.
18:56:09 T:1300 DEBUG: CPythonInvoker(4, C:\AudioSwitch\audioswitch.py): start processing
18:56:09 T:1300 NOTICE: -->Python Interpreter Initialized<--
18:56:09 T:1300 DEBUG: CPythonInvoker(4, C:\AudioSwitch\audioswitch.py): the source file to load is C:\AudioSwitch\audioswitch.py
18:56:09 T:1300 DEBUG: CPythonInvoker(4, C:\AudioSwitch\audioswitch.py): setting the Python path to C:\AudioSwitch;C:\Users\Normi\AppData\Roaming\XBMC\addons\script.module.pyamf\lib;C:\Users\Normi\AppData\Roaming\XBMC\addons\script.module.t0mm0.common\lib;C:\Users\Normi\AppData\Roaming\XBMC\addons\script.module.chardet\lib;C:\Users\Normi\AppData\Roaming\XBMC\addons\script.module.simplejson\lib;C:\Users\Normi\AppData\Roaming\XBMC\addons\script.module.myconnpy\lib;C:\Users\Normi\AppData\Roaming\XBMC\addons\script.module.addon.common\lib;C:\Program Files (x86)\XBMC\addons\script.module.pil\lib;C:\Users\Normi\AppData\Roaming\XBMC\addons\script.common.plugin.cache\lib;C:\Users\Normi\AppData\Roaming\XBMC\addons\script.module.simple.downloader\lib;C:\Users\Normi\AppData\Roaming\XBMC\addons\script.module.requests\lib;C:\Users\Normi\AppData\Roaming\XBMC\addons\script.module.urlresolver\lib;C:\Users\Normi\AppData\Roaming\XBMC\addons\script.module.mutagen\lib;C:\Program Files (x86)\XBMC\addons\xbmc.debug\;C:\Users\Normi\AppData\Roaming\XBMC\addons\script.module.parsedom\lib;C:\Users\Normi\AppData\Roaming\XBMC\addons\script.module.xbmcswift2\lib;C:\Users\Normi\AppData\Roaming\XBMC\addons\script.module.requests2\lib;C:\Users\Normi\AppData\Roaming\XBMC\addons\script.module.metahandler\lib;C:\Program Files (x86)\XBMC\system\python\DLLs;C:\Program Files (x86)\XBMC\system\python\Lib;C:\Program Files (x86)\XBMC\python27.zip;C:\Program Files (x86)\XBMC\system\python\lib\plat-win;C:\Program Files (x86)\XBMC\system\python\lib\lib-tk;C:\Program Files (x86)\XBMC;C:\Program Files (x86)\XBMC\system\python;C:\Program Files (x86)\XBMC\system\python\lib\site-packages
18:56:09 T:1300 DEBUG: CPythonInvoker(4, C:\AudioSwitch\audioswitch.py): entering source directory C:\AudioSwitch
18:56:09 T:1300 ERROR: EXCEPTION Thrown (PythonToCppException) : -->Python callback/script returned the following error<--
- NOTE: IGNORING THIS CAN LEAD TO MEMORY LEAKS!
Error Type: <type 'exceptions.IndentationError'>
Error Contents: ('unexpected indent', ('C:\\AudioSwitch\\audioswitch.py', 2, 1, ' import xbmc\n'))
IndentationError: ('unexpected indent', ('C:\\AudioSwitch\\audioswitch.py', 2, 1, ' import xbmc\n'))
-->End of Python script error report<--
18:56:09 T:1300 INFO: Python script stopped
18:56:09 T:1300 DEBUG: Thread LanguageInvoker 1300 terminating
Reply
#6
ok, found the failure. it was a format failure because of "copy&paste". there was a space at the beginning of each line....
Reply
#7
got it to work as it should be. thanks again! this is by far the most perfect way to switch the audio outputs.
Reply
#8
@teeedubb

i want to make a script that turns on/off xbmcs build in proxy. i had a look in the "list of settings" and i think i found the relevant entry. but script didnt work. debug log says:

"13:52:39 T:2108 DEBUG: JSONRPC: Value does not match any of the enum values in type"


here is my script, do you have any ideas? thanks in advance!:

#proxy toggle script
import xbmc
import os

tempdir = xbmc.translatePath('special://temp/')
tempfile0 = os.path.join(tempdir, 'output0')

if not os.path.isfile(tempfile0):
#settings group 0
#edit below here
xbmc.executeJSONRPC('{"jsonrpc":"2.0", "method":"Settings.SetSettingValue", "params":{"setting":"network.usehttpproxy", "value":"0"}, "id":1}')
xbmc.executeJSONRPC('{"jsonrpc":"2.0", "method":"GUI.ShowNotification", "params":{"title":"PROXY", "message":"Aus", "image":"C:/Users/Normi/AppData/Roaming/XBMC/addons/metadata.common.last.fm/Speaker.png"}, "id":1}')
#edit above here
file = open(tempfile0, "a")
file.close()
else:
#settings group 1
#edit below here
xbmc.executeJSONRPC('{"jsonrpc":"2.0", "method":"Settings.SetSettingValue", "params":{"setting":"network.usehttpproxy", "value":"1"}, "id":1}')
xbmc.executeJSONRPC('{"jsonrpc":"2.0", "method":"GUI.ShowNotification", "params":{"title":"PROXY", "message":"Ein", "image":"C:/Users/Normi/AppData/Roaming/XBMC/addons/metadata.common.last.fm/Speaker.png"}, "id":1}')
#edit above here
os.remove(tempfile0)
Reply
#9
I think you need to drop the quote around the boolean value, as they dont need to be quoted, eg: "value":1
Reply
#10
i changed the script to

"value":0

and

"value":1

but this didnt work. i get the same error message.
Reply
#11
Change the line in the script that prints out the current audio device to show the current setting of the item you want to change.
Reply
#12
thanks again! got it to work. if anyone need this, here is the script:


#proxy toggle script
import xbmc
import os

tempdir = xbmc.translatePath('special://temp/')
tempfile0 = os.path.join(tempdir, 'output0')

if not os.path.isfile(tempfile0):
#settings group 0
#edit below here
xbmc.executeJSONRPC('{"jsonrpc":"2.0", "method":"Settings.SetSettingValue", "params":{"setting":"network.usehttpproxy", "value":false}, "id":1}')
xbmc.executeJSONRPC('{"jsonrpc":"2.0", "method":"GUI.ShowNotification", "params":{"title":"PROXY", "message":"Aus", "image":"C:/Users/xxx/AppData/Roaming/XBMC/Bilder/Proxy.png"}, "id":1}')
#edit above here
file = open(tempfile0, "a")
file.close()
else:
#settings group 1
#edit below here
xbmc.executeJSONRPC('{"jsonrpc":"2.0", "method":"Settings.SetSettingValue", "params":{"setting":"network.usehttpproxy", "value":true}, "id":1}')
xbmc.executeJSONRPC('{"jsonrpc":"2.0", "method":"GUI.ShowNotification", "params":{"title":"PROXY", "message":"Ein", "image":"C:/Users/xxx/AppData/Roaming/XBMC/Bilder/Proxy.png"}, "id":1}')
#edit above here
os.remove(tempfile0)
Reply
#13
@teeedubb - This is very cool. I am not seeing any mention of "CURRENT AUDIO DEVICE:" in my log. Can you post your log or have a look at mine and suggest a surrogate?

Log: https://gist.github.com/graysky2/09a6c9144d0493baf1e1

I would like to have a single function toggle between: Built-in Audio Digital Stereo (HDMI) and Built-in Audio Analog Stereo

Thanks!
Need help programming a Streamzap remote?
Reply
#14
I can't see the script being run, how are you running it?
One of your audio devices is:

10:38:02 T:140005741262592 NOTICE: PulseAudio: Opened device alsa_output.pci-0000_00_03.0.hdmi-stereo in pcm mode with Buffersize 150 ms
Reply
#15
Sorry, I haven't run it since I don't know how to modify it. Again, I don't see, "CURRENT AUDIO DEVICE:" in my log at all. Can you post the log of your machine with that line so I can try to retroengineer it for my machine? Or can you post a best guess based on my log?
Need help programming a Streamzap remote?
Reply
  • 1(current)
  • 2
  • 3
  • 4
  • 5
  • 7

Logout Mark Read Team Forum Stats Members Help
[HOW-TO] Easily switch audio outputs, settings, etc.3