Mac PHP/JS Spotify Remote Control - Spotimote
Overview
Another pointless project along the lines of the Mac Volume Control thing I put together a while ago. As ever, the source for this is available from github.
In a similar vein to the iTunes remote iOS app, this lets you (partially) control Spotify remotely.
Spotify recently announced a basic Applescript dictionary which enables simple commands, and returns some information for the currently playing track.
A couple of evenings of tinkering, and I have managed to knock together a basic mobile-optimsed web app that allows these to be called remotely via a browser. On an iOS device you can also install it as a web app on the home screen.
Installation is really simple, if you have PHP running on your Mac just grab the code for the spotify remote from Github, put it somewhere on your local web server, and visit it in a browser.
It uses the same principles as my Volume Control and Ghetto Blaster labs - JavaScript intercepting a click on an HTML link, sends an Ajax call to a PHP script that executes a command line call via shell_exec to trigger an Applescript.
Most of the Applescript files are very simple:
1
2
3
tell application "Spotify"
next track
end tell
In addition to this, a “status” Applescript is called every second to update the current display. If a new album starts, it saves the new image data from Spotify (which comes through as a TIFF file), converts it to a JPG, and updates the background image.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
-- Init
on run args
-- is Spotify running?
if isRunning("Spotify") then
tell application "Spotify"
set _state to player state
-- is Spotify playing?
if _state is not stopped
local current_album
-- passed parameter (current album)
set current_album to item 1 of args
set current_album_escaped to my string_replace("\\\\\\\\'", "'", current_album)
-- set up album artwork directories/parameters
tell application "Finder"
set script_path to container of (path to me) as text
set artwork_dir to script_path & ":img:album:"
set artwork_path to artwork_dir & "album.tiff"
end tell
-- save track details
set _track to name of current track
set _artist to artist of current track
set _album to album of current track
set _track_number to track number of current track
set _duration to duration of current track
set _position to player position
set _volume to sound volume
-- condition : only get artwork if it's a new track
if current_album_escaped is not album of current track then
set album_changed to true
set _artwork to artwork of current track
my save_image(_artwork, artwork_path)
my convert_tiff_to_jpeg(artwork_path, "album.jpg", artwork_dir)
else
set album_changed to false
end if
-- format JSON
set output to "{
\\"running\\" : true,
\\"playing\\" : true,
\\"state\\" : \\"" & _state & "\\",
\\"track\\": \\"" & _track & "\\",
\\"artist\\": \\"" & _artist & "\\",
\\"album\\": \\"" & _album & "\\",
\\"duration\\": " & _duration & ",
\\"position\\": " & _position & ",
\\"track_number\\": " & _track_number & ",
\\"volume\\": " & _volume & ",
\\"album_changed\\": " & album_changed & ",
\\"current_album\\": \\"" & current_album & "\\"
}"
-- Spotify not playing
else
set output to "{
\\"state\\" : \\"" & _state & "\\"
}"
end if
end tell
-- Spotify not running
else
set output to "{
\\"state\\" : \\"closed\\"
}"
end if
end run
-- function to save tiff image from spotify
on save_image(artwork, artwork_path)
set fileRef to (open for access artwork_path with write permission)
try
write artwork to fileRef
close access fileRef
on error errorMsg
try
close access fileRef
end try
error errorMsg
end try
end saveImage
-- convert tiff to jpeg for web display
on convert_tiff_to_jpeg(source_file, new_name, results_folder)
try
set the target_path to ((results_folder as string) & new_name) as string
with timeout of 15 seconds
tell application "Image Events"
launch
set this_image to open file (source_file as string)
save this_image as JPEG in file target_path with icon
close this_image
end tell
end timeout
on error error_message
-- hi!
end try
end convert_tiff_to_jpeg
-- function to find and replace
on string_replace(needle, haystack, str)
set AppleScript's text item delimiters to needle
set new_str to text items of str
set AppleScript's text item delimiters to haystack
set str to new_str as string
return the str
end string_replace
-- Function to check if an application is running
on isRunning(appName)
tell application "System Events" to (name of processes) contains appName
end isRunning