Display iTunes Cover & Currently Playing Track

This will show the currently playing track album cover and name:

The example is available here: https://share.folivora.ai/sharedPreset/b659eebf-77c1-4457-9264-be63ef251f25

Credits to https://stackoverflow.com/questions/16995273/getting-artwork-from-current-track-in-applescript and
https://github.com/folivoraAI/BetterTouchTool/issues/1589#issue-263698967

I've tried pasting in BTT, and can't get it to display the image?
The image is saving and updating in Application Support. Just not showing in the TouchBar.

Is yours still working?

@liamb, which version of BTT are you using? Possibly try the latest alpha (v2.406)

1 Like

Hi Andreas,
I'm currently running v2.503

Here's the final scripting code I'm using. Based on your reply in Switch Logo with code. I can change the background colour, but the icon isn't recognised or showing?

The Album art is updating in the correct location though. I'm not sure what I'm missing?

{
  "BTTWidgetName" : "iTunes Current Track & Cover",
  "BTTTriggerType" : 639,
  "BTTTriggerTypeDescription" : "Apple Script Widget",
  "BTTTriggerClass" : "BTTTriggerTypeTouchBar",
  "BTTPredefinedActionType" : -1,
  "BTTPredefinedActionName" : "No Action",
  "BTTEnabled2" : 1,
  "BTTEnabled" : 1,
  "BTTOrder" : 7,
  "BTTTriggerConfig" : {
    "BTTTouchBarItemIconHeight" : 22,
    "BTTTouchBarItemIconWidth" : 22,
    "BTTTouchBarItemPadding" : 0,
    "BTTTouchBarFreeSpaceAfterButton" : "5.000000",
    "BTTTouchBarButtonColor" : "75.323769, 75.323769, 75.323769, 255.000000",
    "BTTTouchBarAlwaysShowButton" : "0",
    "BTTTouchBarAppleScriptString" : "tell application \"System Events\"\r\tset num to count (every process whose name is \"iTunes\")\rend tell\rset maxSize to 20\r\rif num > 0 then\r\t\r\ttell application \"iTunes\" to tell artwork 1 of current track\r\t\tset srcBytes to raw data\r\t\t-- figure out the proper file extension\r\t\tif format is «class PNG » then\r\t\t\tset ext to \".png\"\r\t\telse\r\t\t\tset ext to \".jpg\"\r\t\tend if\r\tend tell\r\t\r\t\r\tset fileName to ((((path to application support folder from user domain) as text) & \"BetterTouchTool:\" as text) & \"itunes_cover\" & ext)\r\t-- write to file\r\tset outFile to open for access file fileName with write permission\r\t-- truncate the file\r\tset eof outFile to 0\r\t-- write the image bytes to the file\r\twrite srcBytes to outFile\r\tclose access outFile\r\t\r\t\r\ttell application \"iTunes\"\r\t\tset playState to (player state as text)\r\t\tif playState is equal to \"playing\" then\r\t\t\tset trackName to name of current track\r\t\t\tset artistName to artist of current track\r\t\t\tset albumName to album of current track\r\t\t\tif length of trackName is greater than maxSize then\r\t\t\t\tset trackName to text 1 thru (maxSize - 3) of trackName & \"...\"\r\t\t\tend if\r\t\t\tif length of artistName is greater than maxSize then\r\t\t\t\tset artistName to text 1 thru (maxSize - 3) of artistName & \"...\"\r\t\t\tend if\r\t\t\tset trackInfo to trackName & \" | \" & artistName\r\t\telse\r\t\t\tset trackInfo to \"\"\r\t\tend if\r\t\treturn \"{\\\"text\\\":\\\"\" & trackInfo & \"\\\",\\\"icon_data\\\": \\\"base64_icon_data\\\", \\\"icon_path\\\":\\\"\" & (POSIX path of fileName as text) & \"\\\", \n\\\"background_color\\\": \\\"255,85,100,255\\\"}\"\r\tend tell\relse\r\tset trackInfo to \"iTunes close\"\r\treturn trackInfo\rend if",
    "BTTTouchBarAlternateBackgroundColor" : "128.829533, 128.829533, 128.829533, 255.000000",
    "BTTTouchBarScriptUpdateInterval" : 5
  }
}

Ah sorry I also missed what's wrong in your widget but see it now:
You are returning the base64 icon data AND a path to an icon. You should only return the path:

tell application "System Events"
	set num to count (every process whose name is "iTunes")
end tell
set maxSize to 20

if num > 0 then
	
	tell application "iTunes" to tell artwork 1 of current track
		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
	
	
	tell application "iTunes"
		set playState to (player state as text)
		if playState is equal to "playing" then
			set trackName to name of current track
			set artistName to artist of current track
			set albumName to album of current track
			if length of trackName is greater than maxSize then
				set trackName to text 1 thru (maxSize - 3) of trackName & "..."
			end if
			if length of artistName is greater than maxSize then
				set artistName to text 1 thru (maxSize - 3) of artistName & "..."
			end if
			set trackInfo to trackName & " | " & artistName
		else
			set trackInfo to ""
		end if
		return "{\"text\":\"" & trackInfo & "\", \"icon_path\":\"" & (POSIX path of fileName as text) & "\", 
\"background_color\": \"255,85,100,255\"}"
	end tell
else
	set trackInfo to "iTunes close"
	return trackInfo
end if

Amazing thank you so much!
I've combined this with a Spotify and YouTube Script to change and show depending on what program is running. If you have any tips on how to improve this, that'd be greatly appreciated!

A way that checks which one is actually playing would be ideal but I'm not sure if it's possible.

if application "Spotify" is running then
	tell application "Spotify"
		if player state is playing then
			set sName to (get name of current track)
			if (length of sName) > 15 then
				set sName to text 1 thru 15 of sName & "..."
			else
				set sName to (get name of current track)
			end if
			set nowPlaying to sName & " - " & (get artist of current track)
			set artworkURL to artwork url of current track
			do shell script "curl " & artworkURL & " -o /Users/WITHHELD/Library/Application\\ Support/BetterTouchTool/spotify_cover.png"
			if (length of nowPlaying) > 25 then
				set nowPlaying to text 1 thru 25 of nowPlaying & "..."
			end if
			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) & "\" }"
		else
			return ""
		end if
	end tell
end if
if application "iTunes" is running then
	tell application "iTunes" to tell artwork 1 of current track
		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
	
	tell application "iTunes"
		set playState to (player state as text)
		if playState is equal to "playing" then
			set trackName to name of current track
			set artistName to artist of current track
			set albumName to album of current track
			if length of trackName is greater than maxSize then
				set trackName to text 1 thru (maxSize - 3) of trackName & "..."
			end if
			if length of artistName is greater than maxSize then
				set artistName to text 1 thru (maxSize - 3) of artistName & "..."
			end if
			set trackInfo to trackName & " | " & artistName
		else
			set trackInfo to ""
		end if
		return "{\"text\":\"" & trackInfo & "\", \"icon_path\":\"" & (POSIX path of fileName as text) & "\", 
\"background_color\": \"255,85,100,255\"}"
	end tell
end if
if application "Google Chrome" is running then
	tell application "Google Chrome"
		repeat with t in tabs of windows
			tell t
				if URL starts with "http://www.youtube.com/watch" or URL starts with "https://www.youtube.com/watch" then
					tell t to set nowPlaying to execute javascript "document.getElementById('info-contents').getElementsByClassName('title')[0]. textContent"
					if length of nowPlaying > 15 then
						set nowPlaying to text 1 thru 15 of nowPlaying
						set nowPlaying to nowPlaying & "..."
					end if
					set fileName to ((((path to application support folder from user domain) as text) & "BetterTouchTool:" as text) & "youtube.png")
					return "{\"text\":\"" & nowPlaying & "\", \"icon_path\":\"" & (POSIX path of fileName as text) & "\"}"
					
					
				end if
			end tell
		end repeat
	end tell
end if
return ""
2 Likes

Very nice! I'll see if it can be improved, but looks quite good already!

1 Like

Hoping to revamp the now playing controls on my preset by using this, but the Spotify script causes the app to continually relaunch. Does this happen for you?

Also, I solve the "what player is playing" issue by having separate now playing widgets per-app with if statements to control the visibility of each widget so that only one shows at a time.

Are you on Mojave? The spotify thing sounds like an Apple Script bug in the current Mojave beta.

1 Like

Yep, I am indeed. Guess that solves that! :stuck_out_tongue:

1 Like

Using a similar version of the Spotify script above, but having the same issue as GoldenChaos. The script seems to cause Spotify to relaunch whenever it's quit, but I'm only running Sierra. Any reason why this could be?

Hello! I've been using this preset and I've discovered the widget doesn't display at all if I'm streaming something that I haven't added to my library from Apple Music. Is it possible to fix this?

This is actually normal behavior. Since it uses an AppleScript with a tell command, it will launch the app whenever BTT runs the script. To get Spotify to stay closed, force quit the app.

Weird it doesn't do that for me (on High Sierra) if it's wrapped in

if application "Spotify" is running then

end if

is included. Spotify seems to stay closed.

It's never worked that way for me, even on High Sierra :thinking: :crazy_face: maybe I was doing something wrong?

Hmm.. I did a bit of messing around with the script execution interval and it seems like it does seem to have an effect on this issue, but only sometimes. Generally an interval of >3 seconds seems to do the trick and lets Spotify close permanently, but even then it sometimes relaunches. The script I'm running does use
if application "Spotify" is running then
end if
but this doesn't seem to help when intervals are lower.

I'm wondering if this may be because I just updated to 2.513 from 2.422 today, and prior to being on 2.513 this relaunching never happened.

@GoldenChaos thanks for the suggestion and force quitting does indeed work, but I feel like this only works as a temporary fix

the BTT version shouldn't matter as the Apple Script execution is handled by the system.
Maybe try this method of checking whether an app is running:

tell application "System Events"
	set num to count (every process whose name is "iTunes")
end tell
set maxSize to 20

if num > 0 then
 // here the script code that should be executed if iTunes is running
end if

Logically putting the script in the code you recommended above should resolve the problem, but weirdly Spotify seems to be stubborn and still relaunches. I honestly can't figure out why this is, I wonder if this is a bug on my end or something related to this stack overflow thread. At the moment I have changed the widget so that it is actually just a one line bashscript that runs the pre-compiled .scpt file:

osascript ~/path to script/script.scpt

Even with this workaround the relaunching phenomenon occurs, but generally works better than just having the widget as an applescript. What confuses me the most is the inconsistent behavior, sometimes it relaunches sometimes it doesn't. For now I think I'll just let this be, as it's ultimately really not a big deal, but I appreciate all the help anyways.

@GoldenChaos I haven't faced issues with Spotify, although it for some reason has converted Spotify to Spotify (Old) in my script? Then again the Spotify app has changed to Spotify (Old) for me too. Not sure what's happened. I rarely use Spotify though so hard to comment on.

I did come across an issue with iTunes if you use Apple Music. As the artwork is streamed it creates some issues searching for it. I was able to fix by checking if an artwork is available first though. Full iTunes code can be seen here:

if application "iTunes" is running then
	tell application "iTunes" to 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 support folder from user domain) as text) & "BetterTouchTool:" as text) & "itunes.png")
		end if
	end tell
	set maxSize to 25
	tell application "iTunes"
		set playState to (player state as text)
		if playState is equal to "playing" then
			set trackName to name of current track
			set artistName to artist of current track
			set albumName to album of current track
			if length of trackName is greater than maxSize then
				set trackName to text 1 thru (maxSize - 3) of trackName & "..."
			end if
			if length of artistName is greater than maxSize then
				set artistName to text 1 thru (maxSize - 3) of artistName & "..."
			end if
			set trackInfo to trackName & " | " & artistName
		else
			set trackInfo to ""
		end if
		return "{\"text\":\"" & trackInfo & "\", \"icon_path\":\"" & (POSIX path of fileName as text) & "\"}"
	end tell
end if
1 Like