Python to replace AppleScript targeting Apple Music

Posted on
Fri Jan 06, 2023 9:40 am
Different Computers offline
User avatar
Posts: 2541
Joined: Jan 02, 2016
Location: East Coast

Python to replace AppleScript targeting Apple Music

Since the iTunes plugin doesn't work any more, and iTunes Local Control doesn't return track info, and AirFoil Pro is flaky as hell on my network while AirPlay works just fine, I'm trying to figure out how to get track info into Indigo, including being able to trigger on play pause.

Anyone achieving this currently?

My fumbling and ChatAI-assisted attempt has gotten close, but still generates errors I can't work around:
Code: Select all
tell application "Music"
   set currentTrack to current track
   set trackName to name of currentTrack
   set artistName to artist of currentTrack
   set trackInfo to trackName & "|" & artistName
   
end tell

set pythonScript to "insert_track_info.py"
set pythonPath to "/Library/Frameworks/Python.framework/Versions/3.10/bin/python3"
set scriptPath to quoted form of "/Library/Application Support/Perceptive Automation/Scripts/" & pythonScript
set trackInfo to trackName & "|" & artistName
#do shell script quoted form of pythonPath & " " & quoted form of scriptPath & " " & quoted form of trackInfo
do shell script quoted form of "/Library/Application Support/Perceptive Automation/Scripts/insert_track_info.py"
(This generates errors relative to the path, hence the two different tries at getting the path. The true error seems to be related to the various Python installs on and which should be used.)

That AppleScript is supposed to target this Python:
Code: Select all
import indigo
import sys

trackInfo = sys.argv[1]
trackName, artistName = trackInfo.split("|")

indigo.variable.updateValue(trackVariableId, value=trackName)
indigo.variable.updateValue(artistVariableId, value=artistName)
Apparently "import indigo" is a wrong answer from ChatAI?

My current thought about moving forward is super kludgy and would involve a repeating Indigo Schedule running every 15 seconds or so, running a python script that looks for changes in a file created by AppleScript with the Apple Music info I want, and that then updates variables if the file has changed.

Hopefully there's a better way. This seems like a thing someone out there who actually understands Python would already have working. :D

SmartThings refugee, so happy to be on Indigo. Monterey on a base M1 Mini w/Harmony Hub, Hue, DomoPad, Dynamic URL, Device Extensions, HomeKitLink, Grafana, Plex, uniFAP, Fantastic Weather, Nanoleaf, LED Simple Effects, Bond Home, Camect.

Posted on
Fri Jan 06, 2023 10:05 am
Different Computers offline
User avatar
Posts: 2541
Joined: Jan 02, 2016
Location: East Coast

Re: Python to replace AppleScript targeting Apple Music

Is this stumbling in the right direction? Python modified from https://wiki.indigodomo.com/doku.php?id ... strategies

Code: Select all
tell application "Music"
   set currentTrack to current track
   set trackName to name of currentTrack
   set artistName to artist of currentTrack
   set trackInfo to trackName & "|" & artistName
    return trackInfo

   
end tell

Code: Select all
import applescript

# From a file
path_to_script_file = "/Library/Application Support/Perceptive Automation/Scripts/Send_Current_Track_to_Indigo.scpt"
AscriptTrackInfo = applescript.AppleScript(path=path_to_script_file)
AscriptTrackInfo = AscriptTrackInfo.call("trackInfo")


Right now that's generating a "general" error. Maybe a path to the AppleScript problem?

SmartThings refugee, so happy to be on Indigo. Monterey on a base M1 Mini w/Harmony Hub, Hue, DomoPad, Dynamic URL, Device Extensions, HomeKitLink, Grafana, Plex, uniFAP, Fantastic Weather, Nanoleaf, LED Simple Effects, Bond Home, Camect.

Posted on
Fri Jan 06, 2023 10:15 am
jay (support) offline
Site Admin
User avatar
Posts: 18219
Joined: Mar 19, 2008
Location: Austin, Texas

Re: Python to replace AppleScript targeting Apple Music

Yes, glad you read through that article.

Here's a couple of tweaks to keep you moving forward:

Code: Select all
import applescript

# From a file
path_to_script_file = "/Library/Application Support/Perceptive Automation/Scripts/Send_Current_Track_to_Indigo.scpt"
track_info_script = applescript.AppleScript(path=path_to_script_file)
reply = track_info_script.run()
track_name, artist_name = reply.split("|")

indigo.variable.updateValue(trackVariableId, value= track_name)
indigo.variable.updateValue(artistVariableId, value= artist_name)


Should be close though I didn't test it.

Jay (Indigo Support)
Twitter | Facebook | LinkedIn

Posted on
Fri Jan 06, 2023 10:38 am
Different Computers offline
User avatar
Posts: 2541
Joined: Jan 02, 2016
Location: East Coast

Re: Python to replace AppleScript targeting Apple Music

Worked great!

I now have the track and Artist values in Indigo :lol:

Now to figure out how to trigger an update when the track changes.

SmartThings refugee, so happy to be on Indigo. Monterey on a base M1 Mini w/Harmony Hub, Hue, DomoPad, Dynamic URL, Device Extensions, HomeKitLink, Grafana, Plex, uniFAP, Fantastic Weather, Nanoleaf, LED Simple Effects, Bond Home, Camect.

Posted on
Fri Jan 06, 2023 11:03 am
Different Computers offline
User avatar
Posts: 2541
Joined: Jan 02, 2016
Location: East Coast

Re: Python to replace AppleScript targeting Apple Music

Looks like I need to incorporate something like
Code: Select all
on trackChanged()
   tell application "Music"
      set currentTrack to current track
      set trackName to name of currentTrack
      set artistName to artist of currentTrack
      set trackInfo to trackName & "|" & artistName
      return trackInfo
      return trackName
      return artistName
   end tell
end trackChanged
on run
   -- This line registers the trackChanged() function to be called
   -- whenever the currently playing track changes
   set track_change_handler to trackChanged
   # tell application "Music" to set current track's name current track
end run


Hmmmm, no, that generates an error.
Code: Select all
  Script Error                    action group "Get Current Track Info" embedded script error:
   Script Error                    'NSAppleEventDescriptor' object has no attribute 'split'
   Script Error                    Exception Traceback (most recent call shown last):

     embedded script, line 7, at top level
AttributeError: 'NSAppleEventDescriptor' object has no attribute 'split'

Guessing the on run command is preventing the trackInfo from being preserved. Or something's not being passed properly.

That gets me to the AppleScript running whenever the track changes. I'd sure like to avoid polling to make the Python run.

SmartThings refugee, so happy to be on Indigo. Monterey on a base M1 Mini w/Harmony Hub, Hue, DomoPad, Dynamic URL, Device Extensions, HomeKitLink, Grafana, Plex, uniFAP, Fantastic Weather, Nanoleaf, LED Simple Effects, Bond Home, Camect.

Posted on
Fri Jan 06, 2023 11:12 am
jay (support) offline
Site Admin
User avatar
Posts: 18219
Joined: Mar 19, 2008
Location: Austin, Texas

Re: Python to replace AppleScript targeting Apple Music

I don't know anything about registering functions and the Music AppleScript (that's not Python and I've never heard of it in AppleScript either - did you get that from ChatAI too?).

If you can get that to work, then you'd want to use the Indigo Control AppleScript approach to updating the variable. Basically, the AppleScript would be the one driving the update rather than the Indigo python script driving the change.

Jay (Indigo Support)
Twitter | Facebook | LinkedIn

Posted on
Fri Jan 06, 2023 11:46 am
Different Computers offline
User avatar
Posts: 2541
Joined: Jan 02, 2016
Location: East Coast

Re: Python to replace AppleScript targeting Apple Music

yeah it seems to be a false lead.

ChatAI contradicted itself when I pointed out to it that it generated an error. Seems it confused a custom handler with one that had baked-in functionality.

I can't find any info on "trackChanged" in the Music dictionary or anywhere else.

But this works. However, I think I need to make it an application to keep it running.... and then I don't think the python script can get what it returns. Can it?
Code: Select all
property previousTrack : ""

on run
   set currentTrack to getCurrentTrack()
   if currentTrack is not previousTrack then
      set previousTrack to currentTrack
      trackChanged()
   end if
   my doEvery(5)
end run

on trackChanged()
   tell application "Music"
      set currentTrack to current track
      set trackName to name of currentTrack
      set artistName to artist of currentTrack
      set trackInfo to trackName & "|" & artistName
      return trackInfo
   end tell
end trackChanged

on getCurrentTrack()
   tell application "Music"
      set currentTrack to current track
      set trackName to name of currentTrack
      set artistName to artist of currentTrack
      set trackInfo to trackName & "|" & artistName
      return trackInfo
   end tell
end getCurrentTrack

on doEvery(interval)
   repeat interval times
      set currentTrack to getCurrentTrack()
      if currentTrack is not previousTrack then
         set previousTrack to currentTrack
         trackChanged()
      end if
   end repeat
end doEvery

SmartThings refugee, so happy to be on Indigo. Monterey on a base M1 Mini w/Harmony Hub, Hue, DomoPad, Dynamic URL, Device Extensions, HomeKitLink, Grafana, Plex, uniFAP, Fantastic Weather, Nanoleaf, LED Simple Effects, Bond Home, Camect.

Posted on
Fri Jan 06, 2023 1:17 pm
jay (support) offline
Site Admin
User avatar
Posts: 18219
Joined: Mar 19, 2008
Location: Austin, Texas

Re: Python to replace AppleScript targeting Apple Music

Please -don't use ChatAI for this sort of thing, it will lead you astray every time.

Your script doesn't do anything other than repeat 5 times in rapid succession (getting the track data), probably with a millisecond between calls (which will likely impact system performance if you let it runaway). It has nothing to do with changes in the track data. getCurrentTrack is just a duplicate of trackChanged so is unnecessary. Making it an application will not help in its current form.

You have two options as I see it:

  1. Write an AppleScript application that polls the Music app periodically (every few seconds) to see if there's been a track change and if there is update the Indigo variables
  2. Run the python script that you have running above in an Indigo Schedule that just periodically gets the track data and updates the variables

In either instance you are polling, the difference is that the AppleScript application is doing it in the first one and Indigo is doing it in the second one.

I personally would do the second - running a script like this every few seconds from a schedule is fine.

Note that in either case if someone quits the Music app it will just automatically relaunch (AppleScript does that automagically). If that's not the behavior you want, then you'll need to add some extra code to first check to see if the Music app is running before trying to do an AppleScript tell to it.

Jay (Indigo Support)
Twitter | Facebook | LinkedIn

Posted on
Sun Jan 08, 2023 4:45 pm
Different Computers offline
User avatar
Posts: 2541
Joined: Jan 02, 2016
Location: East Coast

Re: Python to replace AppleScript targeting Apple Music

I'm still fumbling along.

Relying more on stack overflow :wink:

So this works fine:
Code: Select all
tell application "Music"
   set myArtwork to first artwork of current track
   if format of myArtwork is JPEG picture then set myPicture to data of myArtwork
   set myFile to (open for access file ((path to desktop as text) & "some.jpeg") with write permission)
   set eof myFile to 0
   write myPicture to myFile
   close access myFile
end tell


But when I try to make the path something useful, it fails:
Code: Select all
set filePath to "/Library/Application Support/Perceptive Automation/Indigo 2022.1/Web Assets/public/x/test.png"
set fileRef to open for access filePath with write permission
tell application "Music"
   set myArtwork to first artwork of current track
   if format of myArtwork is JPEG picture then set myPicture to data of myArtwork
   set myFile to fileRef
   set eof myFile to 0
   write myPicture to myFile
   close access myFile
end tell
it gives error "File file Macintosh HD:Library:Application Support:Perceptive Automation:Indigo 2022.1:Web Assets:public:x:test.png is already open." number -49 from file "Macintosh HD:Library:Application Support:Perceptive Automation:Indigo 2022.1:Web Assets:public:sst:test.png"

Any help? inserting various "close access" commands in various places didn't seem to help.

SmartThings refugee, so happy to be on Indigo. Monterey on a base M1 Mini w/Harmony Hub, Hue, DomoPad, Dynamic URL, Device Extensions, HomeKitLink, Grafana, Plex, uniFAP, Fantastic Weather, Nanoleaf, LED Simple Effects, Bond Home, Camect.

Posted on
Sun Jan 08, 2023 4:55 pm
Different Computers offline
User avatar
Posts: 2541
Joined: Jan 02, 2016
Location: East Coast

Re: Python to replace AppleScript targeting Apple Music

I also tried
Code: Select all
set fileRef to (open for access filePath with write permission)

SmartThings refugee, so happy to be on Indigo. Monterey on a base M1 Mini w/Harmony Hub, Hue, DomoPad, Dynamic URL, Device Extensions, HomeKitLink, Grafana, Plex, uniFAP, Fantastic Weather, Nanoleaf, LED Simple Effects, Bond Home, Camect.

Posted on
Mon Jan 09, 2023 9:48 am
Different Computers offline
User avatar
Posts: 2541
Joined: Jan 02, 2016
Location: East Coast

Re: Python to replace AppleScript targeting Apple Music

I probably shouldn't have been testing it when Music wasn't running. :oops:

Working now.

SmartThings refugee, so happy to be on Indigo. Monterey on a base M1 Mini w/Harmony Hub, Hue, DomoPad, Dynamic URL, Device Extensions, HomeKitLink, Grafana, Plex, uniFAP, Fantastic Weather, Nanoleaf, LED Simple Effects, Bond Home, Camect.

Posted on
Fri Nov 17, 2023 5:51 pm
Korey offline
User avatar
Posts: 813
Joined: Jun 04, 2008
Location: Henderson, NV

Re: Python to replace AppleScript targeting Apple Music

Did you find a way to return if Music is Playing / Paused / Stopped?

I'm still running indigo 2022.2 realizing that it is going to break the iTunes plugin if I upgrade. This would be a huge fail on the WAF. :(

Indigo with iTunes, Spotify and Airfoil is a core function of Indigo in our house.

Still running OSX 10.14 on a 2012 Mac mini, but looking at a M1 Studio down the road..

I need a way to tell if iTunes and eventually (Apple Music) is playing, I have a script for Spotify that does this and I run it every 10 seconds, one of the wonderful four members helped convert it to python ages ago. (it would be lovely to have a Spotify Plugin! )

Anyone know if it's possible to do this with Apple Music /iTunes with the new version of Py3 only Indigo?

Thanks!


Code: Select all

'''
Some notes:
 - I've removed all the stuff in the script that tried to make it generic and just
   focused on the Spotify specifics
 - As part of the above, your variables must already exist
 - strStation was never set from Spotify in your script so I just skipped trying to set it
'''

import applescript

spotifyScript = '''
tell application "Spotify"
  set strState to (get player state) as string
  set strTrack to (get name of current track) as string
  set strArtist to (get artist of current track) as string
  set strAlbum to (get album of current track) as string
end tell
set blnPlaying to (strState is equal to "playing" or strState is equal to "paused")
set returnRec to {SpotifyPlayerState:strState}
set returnRec to returnRec & {SpotifyIsPlaying:blnPlaying as string}
if (blnPlaying) then
   set returnRec to returnRec & {CurrentArtist:strArtist}
   set returnRec to returnRec & {CurrentAlbum:strAlbum}
   set returnRec to returnRec & {CurrentTrack:strTrack}
end if

return returnRec
'''

a_script = applescript.AppleScript(source=spotifyScript)
reply = a_script.run()

for var_name, value in reply.items():
    indigo.variable.updateValue(str(var_name), value=value)

--
Korey

Posted on
Sat Nov 18, 2023 10:09 am
jay (support) offline
Site Admin
User avatar
Posts: 18219
Joined: Mar 19, 2008
Location: Austin, Texas

Re: Python to replace AppleScript targeting Apple Music

https://stackoverflow.com/questions/311 ... pplescript

You might also check the iTunes Local Control plugin, it may do (I don't know for sure).

Jay (Indigo Support)
Twitter | Facebook | LinkedIn

Posted on
Sat Nov 18, 2023 2:14 pm
Different Computers offline
User avatar
Posts: 2541
Joined: Jan 02, 2016
Location: East Coast

Re: Python to replace AppleScript targeting Apple Music

Korey,

I don't have anything that specifically checks for "running" et al. But I do have something that checks to see if track info has changed. put this script in an action group:
Code: Select all
import applescript

# From a file
path_to_script_file = "/Library/Application Support/Perceptive Automation/Scripts/Send_Current_Track_to_Indigo.scpt"
track_info_script = applescript.AppleScript(path=path_to_script_file)
reply = track_info_script.run()
track_name, artist_name = reply.split("|")

indigo.variable.updateValue(1336843372, value= track_name)
indigo.variable.updateValue(1192881436, value= artist_name)


The referenced AppleScript is:
Code: Select all
tell application "Music"
   if player state is playing then
      set currentTrack to current track
      set trackName to name of currentTrack
      set artistName to artist of currentTrack
      set trackInfo to trackName & "|" & artistName
      return trackInfo
   else
      return "It's quiet|Nothing playing"
   end if
end tell


Run that action group on whatever schedule you want.

You could capture the "It's quiet|Nothing playing" variable value to trigger things.

SmartThings refugee, so happy to be on Indigo. Monterey on a base M1 Mini w/Harmony Hub, Hue, DomoPad, Dynamic URL, Device Extensions, HomeKitLink, Grafana, Plex, uniFAP, Fantastic Weather, Nanoleaf, LED Simple Effects, Bond Home, Camect.

Posted on
Sat Nov 18, 2023 2:45 pm
Korey offline
User avatar
Posts: 813
Joined: Jun 04, 2008
Location: Henderson, NV

Re: Python to replace AppleScript targeting Apple Music

Thanks to you both!

I'll play with this once I have time!


:D

--
Korey

Who is online

Users browsing this forum: No registered users and 4 guests