maddox / itunes-api

🎵 A simple server providing a RESTful service for controlling iTunes
MIT License
200 stars 46 forks source link

Command failed: osascript #46

Open scstraus opened 3 years ago

scstraus commented 3 years ago

I'm getting the below error when trying to turn speakers on and off on iTunes 12.10. Any idea why?

'[2020-10-22T16:23:57.649Z] - ::ffff:10.10.10.20 - PUT /airplay_devices/40-3c-fc-05-7f-38/off 200 123.164 ms - 207b'
Error: Command failed: osascript -l JavaScript -e 'var old = console.log; console.log = function () { Array.prototype.unshift.call(arguments, "<brandonhorst:node-osa>"); Array.prototype.push.call(arguments, "</brandonhorst:node-osa>"); old.apply(console, arguments); }; JSON.stringify((function (id, selected){    itunes = Application('\''iTunes'\'');    id = id.replace(/-/g, '\'':'\'');    foundAirPlayDevice = null;    deviceData = {};    airPlayDevices = itunes.airplayDevices();    for (i = 0; i < airPlayDevices.length; i++) {      airPlayDevice = airPlayDevices[i];      if (airPlayDevice.networkAddress() == id || airPlayDevice.name() == id) {        foundAirPlayDevice = airPlayDevice;        break;      }    }    if (foundAirPlayDevice) {      foundAirPlayDevice.selected = selected;      if (foundAirPlayDevice.networkAddress()) {        deviceData["id"] = foundAirPlayDevice.networkAddress().replace(/:/g, '\''-'\'');      } else {        deviceData["id"] = foundAirPlayDevice.name();      }      deviceData["name"] = foundAirPlayDevice.name();      deviceData["kind"] = foundAirPlayDevice.kind();      deviceData["active"] = foundAirPlayDevice.active();      deviceData["selected"] = foundAirPlayDevice.selected();      deviceData["sound_volume"] = foundAirPlayDevice.soundVolume();      deviceData["supports_video"] = foundAirPlayDevice.supportsVideo();      deviceData["supports_audio"] = foundAirPlayDevice.supportsAudio();      deviceData["network_address"] = foundAirPlayDevice.networkAddress();    }    return deviceData;  })("Computer",false));'
0:1496: execution error: Error on line 1: Error: Parameter error. (-50)

    at ChildProcess.exithandler (child_process.js:308:12)
    at ChildProcess.emit (events.js:314:20)
    at maybeClose (internal/child_process.js:1051:16)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:287:5) {
  killed: false,
  code: 1,
  signal: null,
  cmd: `osascript -l JavaScript -e 'var old = console.log; console.log = function () { Array.prototype.unshift.call(arguments, "<brandonhorst:node-osa>"); Array.prototype.push.call(arguments, "</brandonhorst:node-osa>"); old.apply(console, arguments); }; JSON.stringify((function (id, selected){    itunes = Application('\\''iTunes'\\'');    id = id.replace(/-/g, '\\'':'\\'');    foundAirPlayDevice = null;    deviceData = {};    airPlayDevices = itunes.airplayDevices();    for (i = 0; i < airPlayDevices.length; i++) {      airPlayDevice = airPlayDevices[i];      if (airPlayDevice.networkAddress() == id || airPlayDevice.name() == id) {        foundAirPlayDevice = airPlayDevice;        break;      }    }    if (foundAirPlayDevice) {      foundAirPlayDevice.selected = selected;      if (foundAirPlayDevice.networkAddress()) {        deviceData["id"] = foundAirPlayDevice.networkAddress().replace(/:/g, '\\''-'\\'');      } else {        deviceData["id"] = foundAirPlayDevice.name();      }      deviceData["name"] = foundAirPlayDevice.name();      deviceData["kind"] = foundAirPlayDevice.kind();      deviceData["active"] = foundAirPlayDevice.active();      deviceData["selected"] = foundAirPlayDevice.selected();      deviceData["sound_volume"] = foundAirPlayDevice.soundVolume();      deviceData["supports_video"] = foundAirPlayDevice.supportsVideo();      deviceData["supports_audio"] = foundAirPlayDevice.supportsAudio();      deviceData["network_address"] = foundAirPlayDevice.networkAddress();    }    return deviceData;  })("Computer",false));'`
scstraus commented 3 years ago

So, it turns out this was due to sending a change volume request too quickly after a play playlist request against the latest version of iTunes. This was also compounded by some other issues with iTunes failing to turn on some speakers in time and needing to retry pressing play again after some time. I ended up making an app daemon that chooses the speakers and adjusts the volumes when playing a playlist and then will retry pressing play every 10 seconds until it works. Now I no longer get this error.

So if anyone else has this problem, they could use my app daemon playlist launcher and airplay speaker manager (let me know and I will clean it up for use by the general public as it's kind of a dumpster fire right now although it works). You can find it here.

The right way to fix this would be for itunes-api to operate more synchonously and queue messages to itunes such as playing a playlist until after volume changes of speakers had processed, and retrying playing a playlist if it errors out due to airtunes timeouts. Unfortunately despite having looked at the code quite a lot, I don't understand the applescript side of it well enough to do this. I'm unfortunately not a good enough programmer to do this myself. So I will leave this open..