Skip to content

Instantly share code, notes, and snippets.

@chaorace
Created June 10, 2020 02:53
Show Gist options
  • Save chaorace/b07f45d40702bf2f1a5039564c4e3c68 to your computer and use it in GitHub Desktop.
Save chaorace/b07f45d40702bf2f1a5039564c4e3c68 to your computer and use it in GitHub Desktop.
Linux pacmd (PulseAudio) output device sink toggler script
#!/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