local server = require("server"); local timer = require("timer"); local http = require("http"); local data = require("data"); local utf8 = require("utf8"); local fs = require("fs"); playing = false; playing_uri = ""; playing_duration = 0; playing_volume = 0; playing_shuffle = false; playing_repeat = false; ------------------------------------------------------------------------------------------- -- Spotify Cover Art Grabber ------------------------------------------------------------------------------------------- function get_cover_art_url (uri, callback) local url = "https://embed.spotify.com/oembed/?url=" .. uri; http.get(url, function(err, resp) if (err) then callback(err, nil); else local json = data.fromjson(resp); local result = utf8.replace(json.thumbnail_url, "cover", "320"); callback(nil, result); end end); end function get_cover_art (uri, callback) if (uri ~= nil and settings.last_cover_uri == uri) then -- Return cached data local data = fs.read("latest_coverart.png"); callback(nil, data); return; end get_cover_art_url(uri, function(err, url) http.get(url, function(err, raw) callback(err, raw); -- Save for later fs.write("latest_coverart.png", raw); settings.last_cover_uri = uri; end); end); end ------------------------------------------------------------------------------------------- -- Update ------------------------------------------------------------------------------------------- local quiet = false; function update_quiet () quiet = true; end function update () if (quiet) then quiet = false; timer.timeout(update, 1000); return; end webhelper_get_status(function (status) if (stop) then print("Stopping update"); return; end playing = (status.playing ~= 0); local volume = 0; local track = ""; local artist = ""; local album = ""; local pos = 0; local duration = 0; local uri = ""; if (status.volume ~= nil) then volume = math.ceil(status.volume * 100); end if (status.track ~= nil) then uri = status.track.track_resource.uri; pos = math.ceil(status.playing_position); duration = math.ceil(status.track.length); if (status.track.artist_resource ~= nil) then artist = status.track.artist_resource.name; else artist = "Unknown"; end if (status.track.track_resource ~= nil) then track = status.track.track_resource.name; else track = "Unknown"; end if (status.track.album_resource ~= nil) then album = status.track.album_resource.name; else album = ""; end end if (uri ~= playing_uri) then playing_uri = uri; playlist_update_playing(); timer.timeout(function () get_cover_art(uri, function(err, img) if (err) then print("Failed to load image for track " + uri); else server.update({ id = "currimg", image = img }); end end); end, 100); end local name = track .. " - " .. artist; if (track == "" and artist == "") then name = "[Not Playing]"; end Playing = playing; playing_duration = duration; playing_volume = volume; if (status["shuffle"] ~= nil) then playing_shuffle = status["shuffle"] > 0; end if (status["repeat"] ~= nil) then playing_repeat = status["repeat"] > 0; end local duraction_text = data.sec2span(pos) .. " / " .. data.sec2span(duration); server.update( { id = "currtitle", text = name }, { id = "currvol", progress = volume }, { id = "currpos", progress = math.floor(pos), progressMax = duration, text = duraction_text } ); server_update_play_state(); timer.timeout(update, 1000); -- Call any platform specific update functions if(actions.after_update ~= nil) then actions.after_update(); end end); end function server_update_play_state() local icon = ""; if (not Playing) then icon = "play"; else icon = "pause"; end server.update( { id = "play", icon = icon }, { id = "shuffle", checked = playing_shuffle } ); end ------------------------------------------------------------------------------------------- -- Format string utils ------------------------------------------------------------------------------------------- function format_artists(artists) local builder = {}; if (#artists == 1) then return artists[1].name end for i = 1, #artists do table.insert(builder, artists[i].name); end return utf8.join(", ", builder); end function format_track(item) return format_artists(item.artists) .. " - " .. item.name; end function format_track_2line(item) return item.name .. "\n" .. format_artists(item.artists); end function format_playlist(playlist) return playlist.name .. "\n" .. playlist.tracks.total .. " tracks"; end function format_album(album) return album.name .. "\n(" .. album.album_type .. ")"; end function format_artist(artist) return artist.name .. "\n" .. "Popularity: " .. artist.popularity .. " / 100"; end ------------------------------------------------------------------------------------------- -- State ------------------------------------------------------------------------------------------- events.focus = function() ensure_connect(); webhelper_init(function (err) if (err) then print(err); layout.currtitle.text = "[Not Running]"; return; end stop = false; playing_uri = ""; playlist_init(); if (actions.after_focus ~= nil) then actions.after_focus(); end update(); end) end events.blur = function () stop = true; end ------------------------------------------------------------------------------------------- -- Actions ------------------------------------------------------------------------------------------- actions.connect_dialog = function(i) os.open("http://localhost:9510/web/#/status/connect"); end actions.selected = function(index) playlist_select(index); end --@help Navigate back actions.back = function() playlist_back(); end --@help Start playback actions.play = function() if (not Playing) then webhelper_resume(); Playing = true; server_update_play_state(); end end --@help Pause playback actions.pause = function() if (Playing) then webhelper_pause(); Playing = false; server_update_play_state(); end end --@help Toggle playback state actions.play_pause = function() if (Playing) then actions.pause(); else actions.play(); end end actions.volume_down = function () playing_volume = math.max(playing_volume - 10, 0); server.update( { id = "currvol", progress = volume } ); actions.volchange(playing_volume); end actions.volume_up = function () playing_volume = math.min(playing_volume + 10, 100); server.update( { id = "currvol", progress = volume } ); actions.volchange(playing_volume); end