Display iTunes Cover & Currently Playing Track

This isn't getting the artwork from Apple Music tracks, though? Right now, for me, this displays whatever the last album art displayed was before streaming began. Would be great to be able to get the actual artwork.

I'd image there's a way to get the artwork url? It's possible through Spotify. I'll look into it further.

Apparently not possible: https://stackoverflow.com/posts/37473465/revisions

Maybe one day!

Possibly the Discogs API could be used to retrieve cover art in that case: https://www.discogs.com/developers/ (sorry I don't have a lot of time for BTT until end of next week, our wedding party is coming up this weekend :-))

3 Likes

No stress! You're allowed to take some time for yourself, you do plenty for us :grinning:

Congratulations! :champagne: Enjoy your weekend, and I hope the wedding was/goes amazing!

Is it possible to do the same for Spotify? Display artwork of playing track.

Yup!

if application "Spotify" is running then
	tell application "Spotify"
		if player state is playing then
			set sName to (get name of current track)
			set sArtist to (get artist of current track)
			if (length of sName) > 25 then
				set sName to text 1 thru 22 of sName & "..."
			else
				set sName to (get name of current track)
			end if
			if (length of sArtist) > 25 then
				set sArtist to text 1 thru 22 of sArtist & "..."
			else
				set sArtist to (get artist of current track)
			end if
			set nowPlaying to sName & "  —  " & sArtist
			set artworkURL to artwork url of current track
			do shell script "curl " & artworkURL & " -o ~/Library/Application\\ Support/BetterTouchTool/spotify_cover.png"
			set fileName to ((((path to application support folder from user domain) as text) & "BetterTouchTool:" as text) & "spotify_cover.png")
			return "{\"text\":\"" & nowPlaying & "\", \"icon_path\":\"" & (POSIX path of fileName as text) & "\" }"
			return nowPlaying
		else
			return "Paused"
		end if
	end tell
else
	return ""
end if

Hi there, I have tried this and 3 other ways to get an iTunes now playing widget to work in Mojave dev beta 6 - is it the case that AppleScript is not functioning correctly in the beta yet? I just cannot get any widget to appear at all.

Has anybody tried combining this with a play/pause function? That would be epic!

Update: forgot I could do this simply with btt actions

Does anybody have a fix for Apple Music? the entire buttons disappears as the script fails to run when playing from non-downloaded music

1 Like

Hi @Philip_Aarseth!
Scroll up a little ways, I found a way to work with this:

1 Like

Awesome, thanks @liamb!

I have a problem with spotify, the cover art is flickering on touch bar. Is it me only?

This script is rather inefficient regenerating the artwork and fetching the data upon each check. Personally I use an (old) script/app I wrote that polls when the track changes (and also uses non-embedded artwork).

However here's an updated script for iTunes that avoids much of the overhead by simply checking if the track actually changed before going off and doing stuff—so not unduly expensive on a frequency of say 8 seconds. Recommended with action of 'Play/Pause', icon size of 30, 0 radius, black background, and font size of 12 because it displays album, track and artist on two lines. (Does not change on pause.)

A similar approach should be possible with other apps, but if they don't provide an ID or URL you can just check if the album name changed. Could reuse the same BTT variable across apps although better as string if so.

if application "iTunes" is running then
tell application "BetterTouchTool" to set priorTrackId to get_number_variable "trackId"
tell application "iTunes"
	if player state is playing and id of current track is not priorTrackId then
		tell current track
			if exists (every artwork) then
				tell artwork 1
					set srcBytes to raw data
					-- figure out the proper file extension
					if format is «class PNG » then
						set ext to ".png"
					else
						set ext to ".jpg"
					end if
				end tell
				set fileName to ((((path to application support folder from user domain) as text) & "BetterTouchTool:" as text) & "itunes_cover" & ext)
				-- write to file
				set outFile to open for access file fileName with write permission
				-- truncate the file
				set eof outFile to 0
				-- write the image bytes to the file
				write srcBytes to outFile
				close access outFile
			else
				set fileName to (((path to application "iTunes") as text) & "Contents:Resources:iTunes.icns")
			end if
			set maxSize to 60
			set artistName to artist
			set albumName to album
			set trackName to name
			-- must escape double quotes such as in «12" mix»
			set delimiters to AppleScript's text item delimiters
			set AppleScript's text item delimiters to "\""
			set trackName to every text item of trackName
			set albumName to every text item of albumName
			set artistName to every text item of artistName
			set AppleScript's text item delimiters to "\\\""
			set trackName to trackName as string
			set albumName to albumName as string
			set artistName to artistName as string
			set AppleScript's text item delimiters to delimiters
			if length of trackName is greater than (maxSize / 2) then
				set trackName to text 1 thru (maxSize / 2) of trackName & "
"
			end if
			if length of artistName is greater than (maxSize / 2) then
				set artistName to text 1 thru (maxSize / 2) of artistName & "
"
			end if
			set trackRating to "  "
			repeat (rating / 20) times
				set trackRating to trackRating & "⭑"
			end repeat
			if length of (albumName & trackRating) is greater than maxSize then
				set albumName to text 1 thru (maxSize - (length of trackRating)) of albumName & "
"
			end if
			set trackInfo to albumName & trackRating & "\\n‘" & trackName & "’ by " & artistName
			set trackId to id
			tell application "BetterTouchTool" to set_number_variable "trackId" to trackId
		end tell
		return "{\"text\":\"" & trackInfo & "\", \"icon_path\":\"" & (POSIX path of fileName as text) & "\"}"
	end if
end tell
end if
1 Like

I've got this same issue. Works great for music I have put into my Library, but if I am listening to non-downloaded/non-library music, the icon disappears.

Edit: I am an idiot and did not read replied posts. :slight_smile: . Nevermind.

Here is my version of the code which downloads the artwork from Apple Music using the iTunes search API. I couldn't make it work otherwise.

What it does is basically taking the name, artist and album, sending the request as follows:

itunes.apple.com/search?term=Name+Artist+Album&limit=1

Note: It uses JSON Helper
http://www.mousedown.net/mouseware/JSONHelper.html

if application "iTunes" is running then
	tell application "BetterTouchTool" to set priorTrackId to get_number_variable "trackId"
	tell application "iTunes"
		if player state is playing and id of current track is not priorTrackId then
			tell current track
				if exists (every artwork) then
					tell artwork 1
						set srcBytes to raw data
						-- figure out the proper file extension
						if format is «class PNG » then
							set ext to ".png"
						else
							set ext to ".jpg"
						end if
					end tell
					set fileName to ((((path to application support folder from user domain) as text) & "BetterTouchTool:" as text) & "itunes_cover" & ext)
					-- write to file
					set outFile to open for access file fileName with write permission
					-- truncate the file
					set eof outFile to 0
					-- write the image bytes to the file
					write srcBytes to outFile
					close access outFile
				else
					set searchTerm to name & " " & artist & " " & album
					set responseJson to do shell script "curl --data-urlencode \"term=" & searchTerm & "\" --data-urlencode \"limit=1\" https://itunes.apple.com/search"
					tell application "JSON Helper"
						set responseData to read JSON from responseJson
						set resultCount to resultCount of responseData
						if (resultCount is not 0) then
							set previewUrl to artworkUrl60 of item 1 of results of responseData
							do shell script "curl " & previewUrl & " > $HOME/Library/Application\\ Support/BetterTouchTool/itunes_cover.jpg"
						end if
					end tell
					if (resultCount is not 0) then
						set fileName to ((((path to application support folder from user domain) as text) & "BetterTouchTool:" as text) & "itunes_cover" & ".jpg")
					else
						set fileName to (((path to application "iTunes") as text) & "Contents:Resources:iTunes.icns")
					end if
				end if
				set maxSize to 60
				set artistName to artist
				set albumName to album
				set trackName to name
				set trackInfo to artistName & " - " & trackName
				set trackId to id
				tell application "BetterTouchTool" to set_number_variable "trackId" to trackId
			end tell
			return "{\"text\":\"" & trackInfo & "\", \"icon_path\":\"" & (POSIX path of fileName as text) & "\"}"
		end if
	end tell
else
	return "{\"text\":\"\"}"
end if
1 Like

Very very nice!! I'm desperately failing to do something like this for weeks now!
Would you mind if I added this to my next Preset update? Credits given at the end of the code of course. Man I love this!!

Edit: I encounter an error that seems to appear randomly: The script gets an error displaying "Can’t get resultCount of ""." (second line after using the JSON helper). :thinking:

I will look into it, can you please give me an example for a track that causes this error?

Right now it works (typical :expressionless:). If it bugs it happens because the Script is unable to get the ID of current track (like with the Riddle).
Perdermi by Zero Assoluto returns the iTunes cover.
The Riddle by Nik Kershaw prevents showing anything, neither the cover with your script, nor the song information through mine :hushed:


Same thing for Postcards by James Blunt :man_shrugging:t2:

Old Town Road [Remix] by Lil Nas X, Billy Ray Cyrus works sometimes (the iTunes icon and the cover run both exactly the same script).


Once the song changes they synchronise again.


Also: I use the widget twice, once in my main strip, and in a group. If I change the song to another album while one of them is hidden, the hidden one won't update when it becomes visible - so basically I have always one showing the album of the previous song (yes, 1sec interval refreshment is active, and so is the "Always run when widget becomes visible" box). But this might be rather a #bug-reports for @Andreas_Hegenberg? idk

Also: I use the widget twice, once in my main strip, and in a group. If I change the song to another album while one of them is hidden, the hidden one won't update when it becomes visible - so basically I have always one showing the album of the previous song

This is [probably] because this version of the script checks wether the current song has already been handled to avoid running it multiple times at every X seconds based on your settings. See this line:

if player state is playing and id of current track is not priorTrackId then

You have two scripts. The first one will run, setting the priorTrackID to the current song. The second script will start running a few seconds later, and the current track will be the same with "prior track", so it will do nothing. To check if this is the problem, you can change that line on both scripts to:

if player state is playing then

This isn't very good performance-wise. Could be improved by keeping the actual track data, maybe I'll add an updated version tomorrow if this fixes your problem.


Regarding the artwork problem. On some songs, the iTunes Search API has no data, IDK why. You can check that out doing the curl in Terminal manually or using Postman. For instance, there's no record for Perdermi by Zero Assoluto. The others work fine for me both with the script or by manually sending the request :confused:

1 Like

Yeah, I found that line, I had done the same quite early :wink:
Replaced it, and here we go with:


Don't hate me :smiley:
Happens now with absolutely any song from outside my library :man_shrugging:t2: