[HOW-TO] Easily switch audio outputs and settings.

  Thread Rating:
  • 0 Votes - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Post Reply
teeedubb Offline
Donor
Posts: 2,351
Joined: Mar 2010
Reputation: 58
Location: Down Under
Music  [HOW-TO] Easily switch audio outputs and settings.
Post: #1
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 by teeedubb
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 by teeedubb
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!

My Add-ons, only available for XBMC:
Steam Launcher|Music Party Mode|Reboot2oOS|Triple J Radio
(This post was last modified: 2014-07-12 10:39 by teeedubb.)
find quote
Ned Scott Offline
Team-XBMC Wiki Guy
Posts: 19,828
Joined: Jan 2011
Reputation: 247
Location: Arizona, USA
Post: #2
Very nice!

You can make easy links to the XBMC wiki using double brackets around common XBMC words: [[debug log]] = debug log, [[Video library]] = Video library, [[SMB]] = SMB , [[userdata]] = userdata, etc
find quote
teeedubb Offline
Donor
Posts: 2,351
Joined: Mar 2010
Reputation: 58
Location: Down Under
Post: #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.

My Add-ons, only available for XBMC:
Steam Launcher|Music Party Mode|Reboot2oOS|Triple J Radio
find quote
bluenote Offline
Senior Member
Posts: 288
Joined: May 2010
Reputation: 0
Post: #4
Awesome, I'll be trying this, thanks.
find quote
Ed76 Offline
Senior Member
Posts: 127
Joined: Oct 2012
Reputation: 1
Location: Germany
Post: #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\li​b;C:\Users\Normi\AppData\Roaming\XBMC\addons\script.module.t0mm0.common\lib;C:\U​sers\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\XB​MC\addons\script.module.addon.common\lib;C:\Program Files (x86)\XBMC\addons\script.module.pil\lib;C:\Users\Normi\AppData\Roaming\XBMC\addo​ns\script.common.plugin.cache\lib;C:\Users\Normi\AppData\Roaming\XBMC\addons\scr​ipt.module.simple.downloader\lib;C:\Users\Normi\AppData\Roaming\XBMC\addons\scri​pt.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.xbm​cswift2\lib;C:\Users\Normi\AppData\Roaming\XBMC\addons\script.module.requests2\l​ib;C:\Users\Normi\AppData\Roaming\XBMC\addons\script.module.metahandler\lib;C:\P​rogram 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
find quote
Ed76 Offline
Senior Member
Posts: 127
Joined: Oct 2012
Reputation: 1
Location: Germany
Post: #6
ok, found the failure. it was a format failure because of "copy&paste". there was a space at the beginning of each line....
find quote
Ed76 Offline
Senior Member
Posts: 127
Joined: Oct 2012
Reputation: 1
Location: Germany
Post: #7
got it to work as it should be. thanks again! this is by far the most perfect way to switch the audio outputs.
(This post was last modified: 2014-07-10 23:04 by Ed76.)
find quote
Ed76 Offline
Senior Member
Posts: 127
Joined: Oct 2012
Reputation: 1
Location: Germany
Post: #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)
find quote
teeedubb Offline
Donor
Posts: 2,351
Joined: Mar 2010
Reputation: 58
Location: Down Under
Post: #9
I think you need to drop the quote around the boolean value, as they dont need to be quoted, eg: "value":1

My Add-ons, only available for XBMC:
Steam Launcher|Music Party Mode|Reboot2oOS|Triple J Radio
find quote
Ed76 Offline
Senior Member
Posts: 127
Joined: Oct 2012
Reputation: 1
Location: Germany
Post: #10
i changed the script to

"value":0

and

"value":1

but this didnt work. i get the same error message.
find quote
teeedubb Offline
Donor
Posts: 2,351
Joined: Mar 2010
Reputation: 58
Location: Down Under
Post: #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.

My Add-ons, only available for XBMC:
Steam Launcher|Music Party Mode|Reboot2oOS|Triple J Radio
find quote
Ed76 Offline
Senior Member
Posts: 127
Joined: Oct 2012
Reputation: 1
Location: Germany
Post: #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/Normi/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/Normi/AppData/Roaming/XBMC/Bilder/Proxy.png"}, "id":1}')
#edit above here
os.remove(tempfile0)
(This post was last modified: 2014-07-13 16:17 by Ed76.)
find quote