chrome.tabs.onUpdated.addListener(onTabUpdated); chrome.tabs.onRemoved.addListener(onTabRemoved); //chrome.tabs.onActivated.addListener(onTabChanged); chrome.runtime.onMessage.addListener(onInternalMessage); tabManagers = {} pages = { "Plex Web":{ "patterns":[ "https://app.plex.tv", "http://app.plex.tv", "https://plex.", "http://plex." ], "script":"plex.js" }, "YouTube Music":{ "patterns":[ "https://music.youtube.com", "http://music.youtube.com" ], "script":"ytmusic.js" } } function onTabUpdated(tabId, changeInfo, tab) { // still same page? //console.log("Update to tab " + tabId + "!") if (tabManagers.hasOwnProperty(tabId)) { //console.log("Yes!") page = tabManagers[tabId].page patterns = pages[page]["patterns"] //console.log("Page was managed by a " + page + " manager") for (var i=0;i { this.actuallyupdate(); },800); //this.actuallyupdate(); } } actuallyupdate() { this.messageID++; //console.log("Update! Our page is " + this.page + ", our tab id " + this.tabId) chrome.tabs.executeScript(this.tabId,{"file":"sites/" + pages[this.page]["script"]}); chrome.tabs.executeScript(this.tabId,{"file":"sitescript.js"}); this.alreadyQueued = false; } // an actual update message from the script has arrived playbackUpdate(request) { if (request.time < self.lastMessage) { console.log("Got message out of order, discarding!") return } self.lastMessage = request.time //console.log("Update message from our tab " + this.tabId + " (" + this.page + ")") if (request.type == "stopPlayback" && this.currentlyPlaying) { this.stopPlayback(request.artist,request.title); } else if (request.type == "startPlayback") { this.startPlayback(request.artist,request.title,request.duration); } } startPlayback(artist,title,seconds) { // CASE 1: Resuming playback of previously played title if (artist == this.currentArtist && title == this.currentTitle && !this.currentlyPlaying) { console.log("Resuming playback of " + this.currentTitle) // Already played full song while (this.alreadyPlayed > this.currentLength) { this.alreadyPlayed = this.alreadyPlayed - this.currentLength scrobble(this.currentArtist,this.currentTitle,this.currentLength) } this.setUpdate() this.currentlyPlaying = true } // CASE 2: New track is being played else if (artist != this.currentArtist || title != this.currentTitle) { //first inform ourselves that the previous track has now been stopped for good this.stopPlayback(artist,title); //then initialize new playback console.log("New track"); this.setUpdate(); this.alreadyPlayed = 0; this.currentTitle = title; this.currentArtist = artist; if (Number.isInteger(seconds)) { this.currentLength = seconds; } else { this.currentLength = 300; // avoid excessive scrobbling when the selector breaks } console.log(artist + " - " + title + " is playing! (" + this.currentLength + " seconds)"); this.currentlyPlaying = true; } } // the artist and title arguments are not attributes of the track being stopped, but of the track active now // they are here to recognize whether the playback has been paused or completely ended / replaced stopPlayback(artist,title) { //CASE 1: Playback just paused OR CASE 2: Playback ended if (this.currentlyPlaying) { var d = this.setUpdate() this.alreadyPlayed = this.alreadyPlayed + d console.log(d + " seconds played since last update, " + this.alreadyPlayed + " seconds played overall") } // Already played full song while (this.alreadyPlayed > this.currentLength) { this.alreadyPlayed = this.alreadyPlayed - this.currentLength scrobble(this.currentArtist,this.currentTitle,this.currentLength) } this.currentlyPlaying = false //ONLY CASE 2: Playback ended if (artist != this.currentArtist || title != this.currentTitle) { if (this.alreadyPlayed > this.currentLength / 2) { scrobble(this.currentArtist,this.currentTitle,this.alreadyPlayed) this.alreadyPlayed = 0 } } } // sets last updated to now and returns how long since then setUpdate() { var d = new Date() var t = Math.floor(d.getTime()/1000) var delta = t - this.lastUpdate this.lastUpdate = t return delta } } function scrobble(artist,title,seconds) { console.log("Scrobbling " + artist + " - " + title + "; " + seconds + " seconds playtime") artiststring = encodeURIComponent(artist) titlestring = encodeURIComponent(title) chrome.storage.local.get("apikey",function(result) { APIKEY = result["apikey"] chrome.storage.local.get("serverurl",function(result) { URL = result["serverurl"] var xhttp = new XMLHttpRequest(); xhttp.open("POST",URL + "/api/newscrobble",true); xhttp.send("artist=" + artiststring + "&title=" + titlestring + "&duration=" + seconds + "&key=" + APIKEY) }); }); }