Created
June 10, 2020 02:53
-
-
Save chaorace/b07f45d40702bf2f1a5039564c4e3c68 to your computer and use it in GitHub Desktop.
Linux pacmd (PulseAudio) output device sink toggler script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/node | |
// You will need node.js installed to run this! | |
// Invoke this script to toggle between the two configured devices | |
// Make sure the following is configured in /etc/pulse/default.pa: | |
// load-module module-stream-restore restore_device=false | |
// Configure the two devices to toggle between here | |
// Use "pacmd list-sinks" to find device names to use here, the script won't work if you don't! | |
const myDevices = [ | |
'alsa_output.pci-0000_0a_00.4.analog-stereo', // Headphones | |
'alsa_output.pci-0000_08_00.1.hdmi-stereo-extra4', // Speakers | |
] | |
const { promisify } = require('util'); | |
const exec = promisify(require('child_process').exec) | |
const activeSinkRegex = /\* index: .+\n.*name: <(.+?)>/ | |
const sinkInputsRegex = /index: ([0-9]+)/g | |
const rawSinksP = exec('pacmd list-sinks') | |
const rawSinkInputsP = exec('pacmd list-sink-inputs') | |
const setNewDevice = async deviceIndex => { | |
// Set the given index as the default audio sink | |
const changeDefaultP = exec(`pacmd set-default-sink ${deviceIndex}`) | |
const { stdout: rawSinkInputs } = await rawSinkInputsP | |
const sinkInputIndices = [...(rawSinkInputs.matchAll(sinkInputsRegex))].map(_ => _[1]) | |
await changeDefaultP | |
return Promise.all(sinkInputIndices.map( | |
// Move each Sink input to the new default sink | |
inputIndex => exec(`pacmd move-sink-input ${inputIndex} ${deviceIndex}`) | |
)) | |
} | |
const currentDeviceP = rawSinksP.then( | |
({ stdout: rawSinks }) => rawSinks.match(activeSinkRegex)[1] | |
) | |
const newDeviceIndexP = currentDeviceP.then( | |
// Get device name | |
currentDevice => myDevices.find(device => device !== currentDevice) | |
).then(newDeviceName => rawSinksP.then(({ stdout: rawSinks }) => { | |
// Find and return the index for the new device name | |
const newDeviceRegex = new RegExp(`index: ([0-9]+)\n.*name: <${newDeviceName}>`) | |
return rawSinks.match(newDeviceRegex)[1] | |
})) | |
newDeviceIndexP.then(setNewDevice) | |
newDeviceIndexP.then(newSinkIndex => console.log(`Switching to sink with index ${newSinkIndex}...`)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment