├── _includes
├── img
│ ├── album
│ │ └── empty
│ └── site
│ │ ├── loading.png
│ │ ├── audio_volume_high.png
│ │ ├── audio_volume_low.png
│ │ ├── ajax-loader-transparent.gif
│ │ ├── sprite_play_controls_24.png
│ │ ├── bg_gradient_black-transparent_24.png
│ │ └── bg_gradient_transparent-black_24.png
├── applescripts
│ ├── pause.applescript
│ ├── next.applescript
│ ├── previous.applescript
│ ├── volume-down.applescript
│ ├── volume-up.applescript
│ ├── volume.applescript
│ ├── play.applescript
│ ├── toggle.applescript
│ └── status.applescript
├── icons
│ ├── apple.png
│ └── favicon.ico
├── php
│ ├── Ajax.php
│ ├── SpotifyRemote.php
│ └── PageBuilder.php
├── js
│ └── site
│ │ ├── init.js
│ │ └── spotify-remote.js
└── css
│ └── site
│ └── screen.css
├── .gitignore
├── index.php
└── README.md
/_includes/img/album/empty:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | _includes/img/album/album.jpg
2 | _includes/img/album/album.tiff
--------------------------------------------------------------------------------
/_includes/applescripts/pause.applescript:
--------------------------------------------------------------------------------
1 | tell application "Spotify"
2 | pause
3 | end tell
--------------------------------------------------------------------------------
/_includes/applescripts/next.applescript:
--------------------------------------------------------------------------------
1 | tell application "Spotify"
2 | next track
3 | end tell
--------------------------------------------------------------------------------
/_includes/applescripts/previous.applescript:
--------------------------------------------------------------------------------
1 | tell application "Spotify"
2 | previous track
3 | end tell
--------------------------------------------------------------------------------
/_includes/icons/apple.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/orangespaceman/spotify-remote/master/_includes/icons/apple.png
--------------------------------------------------------------------------------
/_includes/icons/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/orangespaceman/spotify-remote/master/_includes/icons/favicon.ico
--------------------------------------------------------------------------------
/_includes/img/site/loading.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/orangespaceman/spotify-remote/master/_includes/img/site/loading.png
--------------------------------------------------------------------------------
/_includes/img/site/audio_volume_high.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/orangespaceman/spotify-remote/master/_includes/img/site/audio_volume_high.png
--------------------------------------------------------------------------------
/_includes/img/site/audio_volume_low.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/orangespaceman/spotify-remote/master/_includes/img/site/audio_volume_low.png
--------------------------------------------------------------------------------
/_includes/img/site/ajax-loader-transparent.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/orangespaceman/spotify-remote/master/_includes/img/site/ajax-loader-transparent.gif
--------------------------------------------------------------------------------
/_includes/img/site/sprite_play_controls_24.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/orangespaceman/spotify-remote/master/_includes/img/site/sprite_play_controls_24.png
--------------------------------------------------------------------------------
/_includes/applescripts/volume-down.applescript:
--------------------------------------------------------------------------------
1 | tell application "Spotify"
2 | set _volume to sound volume
3 | set sound volume to _volume - 5
4 | end tell
5 |
--------------------------------------------------------------------------------
/_includes/applescripts/volume-up.applescript:
--------------------------------------------------------------------------------
1 | tell application "Spotify"
2 | set _volume to sound volume
3 | set sound volume to _volume + 5
4 | end tell
5 |
--------------------------------------------------------------------------------
/_includes/img/site/bg_gradient_black-transparent_24.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/orangespaceman/spotify-remote/master/_includes/img/site/bg_gradient_black-transparent_24.png
--------------------------------------------------------------------------------
/_includes/img/site/bg_gradient_transparent-black_24.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/orangespaceman/spotify-remote/master/_includes/img/site/bg_gradient_transparent-black_24.png
--------------------------------------------------------------------------------
/_includes/applescripts/volume.applescript:
--------------------------------------------------------------------------------
1 | on run args
2 | local arg
3 | set arg to item 1 of args
4 | tell application "Spotify"
5 | set sound volume to arg
6 | end tell
7 | end run
--------------------------------------------------------------------------------
/index.php:
--------------------------------------------------------------------------------
1 | buildPage();
--------------------------------------------------------------------------------
/_includes/applescripts/play.applescript:
--------------------------------------------------------------------------------
1 | on run args
2 | try
3 | tell application "Spotify"
4 | play
5 | set output to "play"
6 | end tell
7 |
8 | on error error_message
9 | set output to "{
10 | \"state\" : \"" & error_message & "\"
11 | }"
12 | end try
13 |
14 | end run
--------------------------------------------------------------------------------
/_includes/applescripts/toggle.applescript:
--------------------------------------------------------------------------------
1 | on run args
2 | try
3 | tell application "Spotify"
4 | playpause
5 | set output to "toggled"
6 | end tell
7 |
8 | on error error_message
9 | --set output to "{
10 | -- \"state\" : \"" & error_message & "\"
11 | --}"
12 | set output to error_message
13 | end try
14 |
15 | end run
--------------------------------------------------------------------------------
/_includes/php/Ajax.php:
--------------------------------------------------------------------------------
1 | 0) {
3 |
4 | // check what to do
5 | require_once("./SpotifyRemote.php");
6 | $spotifyRemote = new SpotifyRemote;
7 |
8 | $method = $_POST['method'];
9 | unset($_POST['method']);
10 |
11 | if (isset($_POST['args'])) {
12 | $args = $_POST['args'];
13 | unset($_POST['args']);
14 | } else {
15 | $args = array();
16 | }
17 |
18 | // run command
19 | $result = $spotifyRemote->command($method, $args);
20 | echo $result;
21 | }
22 |
23 |
--------------------------------------------------------------------------------
/_includes/js/site/init.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Site global JS file
3 | */
4 |
5 | /**
6 | * on Dom ready functionality
7 | */
8 | $(document).ready(function() {
9 |
10 | // add an extra class to the
element for JS-only styling
11 | $("html").addClass("js");
12 |
13 | // init vol control
14 | spotifyRemote.init({
15 | ajaxPath: "./_includes/php/Ajax.php",
16 | interval: 1
17 | });
18 | });
19 |
20 |
21 | /*
22 | * Window load calls for all pages
23 | */
24 | $(window).load(function() {
25 |
26 | });
--------------------------------------------------------------------------------
/_includes/php/SpotifyRemote.php:
--------------------------------------------------------------------------------
1 | 'play',
13 | 'pause' => 'pause',
14 | 'next' => 'next',
15 | 'previous' => 'previous',
16 | 'status' => 'status',
17 | 'toggle' => 'toggle',
18 | 'volume-up' => 'volume-up',
19 | 'volume-down' => 'volume-down'
20 | );
21 |
22 |
23 | /*
24 | *
25 | */
26 | public function __construct() {
27 |
28 | }
29 |
30 |
31 | /*
32 | * Check to see if the command is valid
33 | *
34 | *
35 | */
36 | public function command($command, $args = "") {
37 | if (array_key_exists($command, $this->commands)) {
38 | return $this->_command($this->commands[$command], $args);
39 | }
40 | }
41 |
42 |
43 | /*
44 | * Run command
45 | *
46 | *
47 | */
48 | private function _command($command, $args) {
49 | $cmd = 'osascript ../applescripts/'.$command.'.applescript';
50 | if ($args) {
51 | $cmd .= ' "'.$args.'"';
52 | }
53 | return shell_exec($cmd);
54 | }
55 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Spotify Remote
2 |
3 | A basic browser-based remote control for Spotify, optimised for mobile and desktop browsers
4 |
5 |
6 | ## Support
7 |
8 | Should work on a mac that has Spotify, Apache and PHP.
9 |
10 |
11 | ## Installation
12 |
13 | Just copy these files into a local mac web server
14 |
15 | If it doesn't work (possibly with error 10810) then you might need to run it via MAMP
16 |
17 |
18 |
19 | ## Ability
20 |
21 | Setters:
22 |
23 | * Play/Pause
24 | * Next Track
25 | * Previous Track
26 | * Change volume
27 |
28 | Status:
29 |
30 | * Artist
31 | * Track
32 | * Album
33 | * Time elapsed
34 | * Total time
35 | * Album artwork
36 |
37 |
38 | ## Inspiration
39 |
40 | * https://github.com/ferranselles/My-Geeklets/blob/5b017b7b7ba9d293badcf034bae206ba36f905b3/spotify/spotify.applescript
41 | * https://github.com/alexandernilsson/Moody/blob/master/Moody.applescript
42 | * http://www.leancrew.com/all-this/2011/07/spotify-info-on-the-desktop-via-nerdtool/
43 | * http://blog.lifeupnorth.co.uk/post/8311267208/spotify-and-applescript
44 | * http://www.macosxtips.co.uk/geeklets/music/spotify-now-playing/
45 | * https://github.com/swinton/spotipy
46 |
--------------------------------------------------------------------------------
/_includes/php/PageBuilder.php:
--------------------------------------------------------------------------------
1 |
22 |
23 |
24 | Spotimote
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
[loading]
50 |
51 |
52 |
53 |
58 |
59 |
60 |
61 |
62 |
74 |
75 |
76 |
77 |
78 |
79 | ';
80 |
81 | return $return;
82 | }
83 | }
--------------------------------------------------------------------------------
/_includes/applescripts/status.applescript:
--------------------------------------------------------------------------------
1 | -- Init
2 | on run args
3 |
4 | -- is Spotify running?
5 | try
6 |
7 | tell application "Spotify"
8 |
9 | set _state to player state
10 |
11 | -- is Spotify playing?
12 | if _state is not stopped
13 |
14 | local current_album
15 |
16 | -- passed parameter (current album)
17 | set current_album to album of current track
18 | set current_album_escaped to my string_replace("\\\\'", "'", current_album)
19 |
20 | -- set up album artwork directories/parameters
21 | tell application "Finder"
22 | set script_path to container of (path to me) as text
23 | set artwork_dir to script_path & ":img:album:"
24 | set artwork_path to artwork_dir & "album.tiff"
25 | end tell
26 |
27 | -- save track details
28 | set _track to name of current track
29 | set _artist to artist of current track
30 | set _album to album of current track
31 | set _track_number to track number of current track
32 | set _duration to duration of current track
33 | set _position to player position as text
34 | set _volume to sound volume
35 |
36 | set _position to my string_replace(",", ".", _position)
37 |
38 | -- condition : only get artwork if it's a new track
39 | if current_album_escaped is not album of current track then
40 | set album_changed to true
41 | set _artwork to artwork of current track
42 | my save_image(_artwork, artwork_path)
43 | my convert_tiff_to_jpeg(artwork_path, "album.jpg", artwork_dir)
44 | else
45 | set album_changed to false
46 | end if
47 |
48 | set track_escaped to my string_replace("\"", "'", _track)
49 |
50 | -- format JSON
51 | set output to "{
52 | \"running\" : true,
53 | \"playing\" : true,
54 | \"state\" : \"" & _state & "\",
55 | \"track\": \"" & track_escaped & "\",
56 | \"artist\": \"" & _artist & "\",
57 | \"album\": \"" & _album & "\",
58 | \"duration\": " & _duration & ",
59 | \"position\": " & _position & ",
60 | \"track_number\": " & _track_number & ",
61 | \"volume\": " & _volume & ",
62 | \"album_changed\": " & album_changed & ",
63 | \"current_album\": \"" & current_album & "\"
64 | }"
65 |
66 | -- Spotify not playing
67 | else
68 | set output to "{
69 | \"state\" : \"" & _state & "\"
70 | }"
71 | end if
72 |
73 | end tell
74 |
75 | -- Spotify not running
76 | on error error_message
77 | set output to "{
78 | \"state\" : \"" & error_message & "\"
79 | }"
80 | end try
81 |
82 | end run
83 |
84 |
85 |
86 | -- function to save tiff image from spotify
87 | on save_image(artwork, artwork_path)
88 | set fileRef to (open for access artwork_path with write permission)
89 | try
90 | write artwork to fileRef
91 | close access fileRef
92 | on error errorMsg
93 | try
94 | close access fileRef
95 | end try
96 | error errorMsg
97 | end try
98 | end saveImage
99 |
100 |
101 | -- convert tiff to jpeg for web display
102 | on convert_tiff_to_jpeg(source_file, new_name, results_folder)
103 | try
104 | set target_path to ((results_folder as string) & new_name) as string
105 | with timeout of 15 seconds
106 | tell application "Image Events"
107 | launch
108 |
109 | set this_image to open file (source_file as string)
110 | save this_image as JPEG in file target_path
111 | close this_image
112 |
113 | end tell
114 | end timeout
115 | on error error_message
116 | -- hi!
117 | end try
118 | end convert_tiff_to_jpeg
119 |
120 |
121 | -- function to find and replace
122 | on string_replace(needle, haystack, str)
123 | set AppleScript's text item delimiters to needle
124 | set new_str to text items of str
125 | set AppleScript's text item delimiters to haystack
126 | set str to new_str as string
127 | return the str
128 | end string_replace
--------------------------------------------------------------------------------
/_includes/css/site/screen.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Screen CSS
3 | */
4 | /* quick reset */
5 | * { margin:0; padding:0; }
6 |
7 | /* Hide only visually, but have it available for screenreaders: h5bp.com/v */
8 | .visuallyhidden { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; }
9 |
10 | body {
11 | font:62.5%/1.25 Helvetica, Arial, sans-serif;
12 | background:#000;
13 | color:#fff;
14 | }
15 |
16 | p { font-size:12px; }
17 | a { text-decoration:none; color:#fff; }
18 |
19 |
20 | /* layout */
21 | html,
22 | body,
23 | #horizon,
24 | #wrapper {
25 | background:#000;
26 | width:100%;
27 | height:100%;
28 | overflow:hidden;
29 | }
30 |
31 |
32 | /* header */
33 | #head {
34 | position:absolute;
35 | top:0;
36 | left:0;
37 | padding-top:25px; /* iOS toolbar */
38 | height:120px;
39 | width:100%;
40 | text-align:center;
41 | z-index:2;
42 | background:url(../../img/site/bg_gradient_black-transparent_24.png) transparent repeat-x left bottom;
43 | }
44 |
45 | /* track details */
46 | #track-name {
47 | font-weight:bold;
48 | }
49 | #album {
50 | font-style:italic;
51 | }
52 |
53 |
54 | /* progress bar */
55 | #progress {
56 | margin-top:5px;
57 | }
58 |
59 | #time-elapsed,
60 | #time-remaining {
61 | display:inline-block;
62 | }
63 |
64 | .progress-bar {
65 | display:inline-block;
66 | position:relative;
67 | height:6px;
68 | width:70%;
69 | margin:0 10px;
70 | top:-1px;
71 | background:#333;
72 | -moz-border-radius: 3px;
73 | -webkit-border-radius: 3px;
74 | border-radius: 3px;
75 | -moz-background-clip: padding; -webkit-background-clip: padding-box; background-clip: padding-box; /* stop leaking */
76 | }
77 |
78 | .progress-bar-fill {
79 | position:absolute;
80 | left:0;
81 | top:0;
82 | height:6px;
83 | background:#ccc;
84 | margin-left:-1px;
85 | padding-left:2px;
86 | min-width:1px;
87 | -moz-border-radius: 3px;
88 | -webkit-border-radius: 3px;
89 | border-radius: 3px;
90 | -moz-background-clip: padding; -webkit-background-clip: padding-box; background-clip: padding-box; /* stop leaking */
91 | }
92 |
93 |
94 | /* album art */
95 | #status {
96 | position:absolute;
97 | top:0;
98 | left:0;
99 | width:100%;
100 | height:100%;
101 | z-index:1;
102 | background-repeat:no-repeat;
103 | background-position:50% 50%;
104 | background-attachment:fixed;
105 | background-size:contain;
106 | }
107 |
108 |
109 | /* footer */
110 | #foot {
111 | position:absolute;
112 | bottom:0;
113 | left:0;
114 | height:70px;
115 | padding-top:20px;
116 | padding-bottom:10px;
117 | width:100%;
118 | text-align:center;
119 | z-index:2;
120 | background:url(../../img/site/bg_gradient_transparent-black_24.png) transparent repeat-x left top;
121 | }
122 |
123 | /* volume */
124 | #volume {
125 | margin-bottom:5px;
126 | }
127 |
128 | #volume p {
129 | display:inline-block;
130 | position:relative;
131 | top:4px;
132 | }
133 |
134 | #volume a {
135 | display:block;
136 | width:16px;
137 | height:16px;
138 | background:url(../../img/site/audio_volume_low.png) transparent no-repeat;
139 | }
140 |
141 | #volume p#volume-up a {
142 | background-image:url(../../img/site/audio_volume_high.png);
143 | }
144 |
145 |
146 | /* buttons */
147 | #play-pause,
148 | #next,
149 | #previous {
150 | display:inline-block;
151 | }
152 |
153 | #play-pause a,
154 | #next a,
155 | #previous a {
156 | display:block;
157 | width:50px;
158 | height:50px;
159 | margin:0 5px;
160 | background:url(../../img/site/sprite_play_controls_24.png) #f90 no-repeat;
161 | border-radius:25px;
162 | }
163 |
164 | .playing #play-pause a { background-position:0 -100px; }
165 | #next a { background-position:0 -200px; }
166 | #previous a { background-position:0 -300px; }
167 |
168 |
169 | /* loader */
170 | span#loading {
171 | position:absolute;
172 | right:10px;
173 | bottom:10px;
174 | display:block;
175 | width:16px;
176 | height:16px;
177 | background-image:url(../../img/site/ajax-loader-transparent.gif);
178 | background-position:right bottom;
179 | background-repeat:no-repeat;
180 | display:none;
181 | z-index:5;
182 | }
183 |
184 | span#loading.show {
185 | display:block;
186 | }
187 |
188 |
189 | /*
190 | * play states
191 | */
192 | .loading #status,
193 | .loading #artist,
194 | .loading #album,
195 | .loading #time-elapsed,
196 | .loading #time-remaining,
197 | .loading #progress,
198 | .loading #volume,
199 | .loading #controls,
200 |
201 | .closed #status,
202 | .closed #artist,
203 | .closed #album,
204 | .closed #time-elapsed,
205 | .closed #time-remaining,
206 | .closed #progress,
207 | .closed #volume,
208 | .closed #controls,
209 |
210 | .stopped #status,
211 | .stopped #artist,
212 | .stopped #album,
213 | .stopped #time-elapsed,
214 | .stopped #time-remaining,
215 | .stopped #progress,
216 | .stopped #volume {
217 | display:none;
218 | }
219 |
--------------------------------------------------------------------------------
/_includes/js/site/spotify-remote.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @fileoverview Spotify Remote
3 | *
4 | */
5 | var spotifyRemote = function(){
6 |
7 | // obj: status checking interval
8 | var statusInterval = null,
9 |
10 | // obj: loading element
11 | $loader = null,
12 |
13 | // get all command elements
14 | $commands = null,
15 |
16 | // misc HTML elements
17 | $play = null,
18 | $body = null,
19 | $status = null,
20 | $trackName = null,
21 | $artist = null,
22 | $album = null,
23 | $timeElapsed = null,
24 | $timeRemaining = null,
25 | $progress = null,
26 | $volume = null,
27 |
28 | // the current album (not non-null default)
29 | currentAlbum = ".",
30 |
31 | /**
32 | * The options passed through to this function
33 | *
34 | * @var Object
35 | * @private
36 | */
37 | options = {
38 |
39 | /**
40 | * The location of the AJAX script on the server
41 | *
42 | * @var String
43 | */
44 | ajaxPath : null,
45 |
46 | /**
47 | * The interval time (in seconds) between status checks
48 | *
49 | *
50 | */
51 | interval : 1
52 | },
53 |
54 |
55 | /**
56 | * Initialise the functionality
57 | * @param {Object} options The initialisation options
58 | * @return void
59 | * @public
60 | */
61 | init = function(initOptions) {
62 |
63 | // save any options sent through to the intialisation script, if set
64 | for (var option in options) {
65 | if (!!initOptions[option] || initOptions[option] === false) {
66 | options[option] = initOptions[option];
67 | }
68 |
69 | // error check, if no element is specified then stop
70 | if (!options[option] && options[option] !== false && options[option] !== 0) {
71 | throw('Required option not specified: ' + option);
72 | //return false;
73 | }
74 | }
75 |
76 | // get elements for later use
77 | $body = $("body");
78 | $status = $("#status");
79 | $trackName = $("#track-name");
80 | $artist = $("#artist");
81 | $album = $("#album");
82 | $timeElapsed = $("#time-elapsed");
83 | $timeRemaining = $("#time-remaining");
84 | $progress = $("#progress");
85 | $volume = $("#volume");
86 |
87 | // hide things initially
88 | $body.addClass("loading");
89 |
90 |
91 | // get all command elements
92 | $commands = $("a[data-command]");
93 | $commands.bind("click", function(e){
94 | e.preventDefault();
95 | runCommand($(this).data('command'));
96 | });
97 |
98 |
99 | // add loader
100 | $loader = $("")
101 | .attr('id', 'loading')
102 | .appendTo('#wrapper');
103 |
104 |
105 | // check status every x seconds
106 | statusInterval = setInterval(getStatus, options.interval * 1000);
107 | },
108 |
109 |
110 |
111 | /*
112 | * Check status
113 | */
114 | getStatus = function() {
115 | _ajax("status", currentAlbum);
116 | },
117 |
118 |
119 |
120 | /*
121 | * Run a command
122 | */
123 | runCommand = function(command) {
124 | _ajax(command);
125 | },
126 |
127 |
128 |
129 | /*
130 | * Ajax!
131 | */
132 | _ajax = function(method, args) {
133 |
134 | showLoader();
135 |
136 | var postData, response, result;
137 |
138 | postData = 'method='+method;
139 |
140 | // if specific arguments have been sent through, append
141 | if (!!args) {
142 | args = args.replace(/\'/g, "\\'");
143 | args = encodeURIComponent(args);
144 | postData += '&args='+args;
145 | }
146 |
147 | postData += '&random='+Math.random();
148 |
149 | // submit request
150 | response = $.post(
151 | options.ajaxPath,
152 | postData,
153 | function(data, textStatus){
154 |
155 | hideLoader();
156 | result = $.parseJSON(data);
157 |
158 | // if this is a status update, update display
159 | if (method == "status") {
160 | updateDisplay(result);
161 | }
162 | });
163 | },
164 |
165 |
166 | /*
167 | * show...loader
168 | */
169 | showLoader = function() {
170 | $loader.addClass('show');
171 | },
172 |
173 |
174 |
175 | /*
176 | * hide...loader
177 | */
178 | hideLoader = function() {
179 | $loader.removeClass('show');
180 | },
181 |
182 |
183 | /*
184 | * update display based on ajax json return
185 | */
186 | updateDisplay = function(status) {
187 |
188 | var bodyClass;
189 |
190 | // set state
191 | if (status && status.state) {
192 |
193 | // switch on status types
194 | switch(status.state) {
195 |
196 | case "stopped":
197 | $trackName.text("Spotify ain't playing!");
198 | bodyClass = status.state;
199 | break;
200 |
201 | case "playing":
202 | case "paused":
203 |
204 | var position = Math.round(status.position);
205 |
206 | // set text values
207 | $trackName.text(status.track);
208 | $artist.text(status.artist);
209 | $album.text(status.album);
210 | $timeElapsed.text(secondsToMinutes(position));
211 | $timeRemaining.text(secondsToMinutes(status.duration - position));
212 |
213 | // progress bar
214 | var progressBarWidth = ((status.position / status.duration) * 100).toFixed(2);
215 | $progress.find(".progress-bar-fill").css({ width: progressBarWidth+"%"});
216 |
217 | // volume bar
218 | $volume.find(".progress-bar-fill").css({ width: status.volume+"%"});
219 |
220 | // load new image?
221 | if (status.album_changed) {
222 | var time = new Date().getTime();
223 | $status.animate({opacity:0}, 250, function(){
224 | $status
225 | .delay(1000)
226 | .css({ "background-image":"url(./_includes/img/album/album.jpg?"+time+")"})
227 | .animate({opacity:1}, 250);
228 | });
229 | }
230 |
231 | // store current album, if set - for checking next time
232 | if (status && status['album']) {
233 | currentAlbum = status.album;
234 | }
235 |
236 | bodyClass = status.state;
237 |
238 | break;
239 |
240 | case "closed":
241 | $trackName.text("Spotify ain't running!");
242 | bodyClass = status.state;
243 | break;
244 |
245 |
246 | default:
247 | $trackName.text("Error: " + status.state);
248 | bodyClass = "closed";
249 | break;
250 | }
251 |
252 |
253 | $body.attr("class", bodyClass);
254 | }
255 | },
256 |
257 |
258 | /*
259 | * convert seconds to minutes (and seconds)
260 | */
261 | secondsToMinutes = function(secs) {
262 | var mins = Math.floor(secs/60);
263 | secs = secs - (mins*60);
264 | if (mins < 10) { mins = "0"+mins; }
265 | if (secs < 10) { secs = "0"+secs; }
266 | return mins+":"+secs;
267 | };
268 |
269 |
270 | /*
271 | * Return value, expose certain methods above
272 | */
273 | return {
274 | init: init
275 | };
276 | }();
--------------------------------------------------------------------------------