-- put this script in startup/ -- install morefonts in / -- also ask me for a sanjuuni.sad.ovh password or selfhost it -- change the last.fm username in checkTrack, and my name in doLastfm -- https://git.sad.ovh/sophie/convert local mf = require("../morefonts") local function drawImage(monitor, image, dx, dy, palette) if image == nil then printError('Image passed to drawImage was nil.') return end frame = image[1] -- for _, frame in ipairs(image) do for y, row in ipairs(frame) do monitor.setCursorPos(dx+1, dy+y) monitor.blit(table.unpack(row)) end if frame.palette then for i = 0, #frame.palette do local c = frame.palette[i] if type(c) == "table" then monitor.setPaletteColor(2^i, table.unpack(c)) else monitor.setPaletteColor(2^i, c) end end end if image.animation then sleep(frame.duration or image.secondsPerFrame or 0.05) end -- end monitor.setBackgroundColor(colors.black) monitor.setTextColor(colors.white) monitor.setCursorPos(1, 1) end local function playAudio(title, artist) if title == '' or artist == '' then print("empty 'audio' sent out") return end local audioReq = http.post({ url = "https://sanjuuni.sad.ovh/youtube", body = textutils.serialiseJSON({ ["title"] = title, ["artist"] = artist }), headers = { ["Content-Type"] = "application/json", ["Authorization"] = "<..>" } }) if audioReq == nil then -- usually works on the second one, not sure what's broken audioReq = http.post({ url = "https://sanjuuni.sad.ovh/youtube", body = textutils.serialiseJSON({ ["title"] = title, ["artist"] = artist }), headers = { ["Content-Type"] = "application/json", ["Authorization"] = "<..>" } }) end local speaker = peripheral.find("speaker") local decoder = require("cc.audio.dfpwm").make_decoder() local play = true parallel.waitForAny( function () while decoder do local chunk = audioReq.read(16 * 1024) if not chunk then break end local decoded = decoder(chunk) while not speaker.playAudio(decoded) do os.pullEvent("speaker_audio_empty") end end end, function () while play do event, title, artist = os.pullEvent("audio") os.queueEvent("audio", title, artist) print("play = false") play = false end end ) end local function doLastfm(track) if not track["@attr"] then local monitor = peripheral.find("monitor") local width, height = monitor.getSize() monitor.clear() os.queueEvent('audio', '', '') mf.writeOn(monitor, "Nothing is being played.", nil, nil, {font="Dogica",anchorHor="center",anchorVer="center", wrapWidth = 2 * width}) return end local artist = track["artist"]["#text"] local album = track["album"]["#text"] local title = track["name"] os.queueEvent('audio', title, artist) print('Displaying ' .. artist .. ' - ' .. title .. ' (on ' .. album ..')') local image = track["image"][1]["#text"] local imageReq = http.post({ url = "https://sanjuuni.sad.ovh/render", body = textutils.serialiseJSON({ ["imageUrl"] = image }), headers = { ["Content-Type"] = "application/json", ["Authorization"] = "<..>" } }) if imageReq == nil then return end local monitor = peripheral.find("monitor") local width, height = monitor.getSize() monitor.clear() monitor.setCursorPos(2,2) monitor.write("Loading..") local data = imageReq.readAll() -- actually read the data. monitor.setTextScale(0.5) data = textutils.unserialize(data) -- convert the string file data into a usable lua object drawImage(monitor, data, 0, 0) mf.writeOn(monitor, "Sophie is playing", 20, 4, {font="fonts/3x3-Mono", wrapWidth = 35}) local _, b = mf.writeOn(monitor, string.sub(title, 1, 14), nil, nil, {font="Dogica", dy = 8, anchorHor = "center", wrapWidth = 2 * width}) mf.writeOn(monitor, string.sub(artist, 1, 15), nil, nil, {font="Dogica", dy = 11+b, anchorHor = "center", wrapWidth = 2 * width}) end local lastTrack = nil; local timer = os.startTimer(1); local function checkTrack() local req = http.get("https://ws.audioscrobbler.com/2.0/?api_key=816cfe50ddeeb73c9987b85de5c19e71&method=User.getrecenttracks&user=yourfriendoss&format=json&limit=1") if req == nil then return end local rawData = req.readAll(); local data = textutils.unserialiseJSON(rawData) local track = data["recenttracks"]["track"][1]; if lastTrack ~= nil then if lastTrack["name"] == track["name"] then return; end end lastTrack = track; doLastfm(track) end local function updateLastfm() while true do event, id = os.pullEvent("timer") if timer == id then checkTrack() timer = os.startTimer(1) end end end local function playAudioEvent() while true do event, title, artist = os.pullEvent("audio") parallel.waitForAll(function () playAudio(title, artist) end) end end parallel.waitForAll(updateLastfm, playAudioEvent)