mirror of
https://github.com/krateng/maloja.git
synced 2023-08-10 21:12:55 +03:00
Simplified scrobbler code
This commit is contained in:
parent
ce5e342212
commit
9bcd701287
12
README.md
12
README.md
@ -6,15 +6,15 @@ Simple self-hosted music scrobble database to create personal listening statisti
|
||||
|
||||
### Why not Last.fm / Libre.fm?
|
||||
|
||||
Maloja is self-hosted. You will always be able to access your data, and not have to trust anyone to provide an API for it. Your library is not synced with any public of official music database, so you can follow your own tagging schema or even group acts together for the purpose of artist charts (e.g. HyunA, 4Minute and Trouble Maker).
|
||||
Maloja is self-hosted. You will always be able to access your data, and not have to trust anyone to provide an API for it. Your library is not synced with any public or official music database, so you can follow your own tagging schema or even group associated artists together in your charts.
|
||||
|
||||
### Why not GNU FM?
|
||||
|
||||
Maloja gets rid of all the extra stuff: social networking, radios, recommendations, etc. It only keeps track of your listening history and lets you analyze it. This focus on its core allow it to potentially implement much better database features. One example: Maloja supports multiple artists per track. This means artists like Laura Brehm who are often just "featuring" in the track title get a place in your charts, and collaborations between several of your favorite artists finally get credited to all participants.
|
||||
Maloja gets rid of all the extra stuff: social networking, radios, recommendations, etc. It only keeps track of your listening history and lets you analyze it. This focus on its core allows it to potentially implement much better database features. One example: Maloja supports multiple artists per track. This means artists who are often just "featuring" in the track title get a place in your charts, and collaborations between several artists finally get credited to all participants.
|
||||
|
||||
### Why not use the established API?
|
||||
|
||||
Compatibility creates overhead effort. I only made this for myself, so I have no need to support lots of music players and scrobblers. Maloja has a significantly smaller API that allows it to be much simpler.
|
||||
Compatibility creates overhead effort. I only made this for myself, so I have no need to support lots of music players and scrobblers. Maloja has a significantly smaller API that allows it to be much simpler and implement its additional features.
|
||||
|
||||
### Why Maloja?
|
||||
|
||||
@ -31,7 +31,11 @@ I wouldn't recommend it yet. But if you want to test Maloja, it's fairly easy:
|
||||
1) Put it anywhere and start server.py
|
||||
2) (Recommended) Put your server behind a reverse proxy for SSL encryption. Configure that proxy to rewrite /db/ requests to the database port. In nginx this would look as follows:
|
||||
|
||||
location / {
|
||||
proxy_pass http://yoururl:42010;
|
||||
}
|
||||
|
||||
location /db {
|
||||
rewrite ^/db(.*)$ $1 break;
|
||||
proxy_pass http://yoururl:12349;
|
||||
proxy_pass http://yoururl:42011;
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ from cleanup import *
|
||||
|
||||
log = open(sys.argv[1])
|
||||
|
||||
outputlog = open(sys.argv[2],"a")
|
||||
outputlog = open(sys.argv[2],"w")
|
||||
|
||||
c = CleanerAgent()
|
||||
|
||||
|
@ -43,7 +43,7 @@ function party(tab) {
|
||||
function onPlaybackUpdate(request,sender) {
|
||||
//console.log("Got update from Plex Web!")
|
||||
if (request.type == "stopPlayback" && currentlyPlaying) {
|
||||
stopPlayback();
|
||||
stopPlayback(request.artist,request.title);
|
||||
}
|
||||
else if (request.type == "startPlayback") {
|
||||
startPlayback(request.artist,request.title,request.duration);
|
||||
@ -60,6 +60,88 @@ var alreadyScrobbled = false;
|
||||
|
||||
|
||||
function startPlayback(artist,title,seconds) {
|
||||
|
||||
|
||||
// CASE 1: Resuming playback of previously played title
|
||||
if (artist == currentArtist && title == currentTitle && !currentlyPlaying) {
|
||||
console.log("Resuming playback")
|
||||
|
||||
// Already played full song
|
||||
while (alreadyPlayed > currentLength) {
|
||||
alreadyPlayed = alreadyPlayed - currentLength
|
||||
scrobble(currentArtist,currentTitle,currentLength)
|
||||
}
|
||||
|
||||
setUpdate()
|
||||
currentlyPlaying = true
|
||||
|
||||
}
|
||||
|
||||
// CASE 2: New track is being played
|
||||
else if (artist != currentArtist || title != currentTitle) {
|
||||
|
||||
//first inform ourselves that the previous track has now been stopped for good
|
||||
stopPlayback(artist,title)
|
||||
//then initialize new playback
|
||||
console.log("New track")
|
||||
setUpdate()
|
||||
alreadyPlayed = 0
|
||||
currentTitle = title
|
||||
currentArtist = artist
|
||||
currentLength = seconds
|
||||
console.log(artist + " - " + title + " is playing!")
|
||||
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
|
||||
function stopPlayback(artist,title) {
|
||||
|
||||
//CASE 1: Playback just paused OR CASE 2: Playback ended
|
||||
if (currentlyPlaying) {
|
||||
d = setUpdate()
|
||||
alreadyPlayed = alreadyPlayed + d
|
||||
console.log(d + " seconds played since last update, " + alreadyPlayed + " seconds played overall")
|
||||
}
|
||||
|
||||
|
||||
// Already played full song
|
||||
while (alreadyPlayed > currentLength) {
|
||||
alreadyPlayed = alreadyPlayed - currentLength
|
||||
scrobble(currentArtist,currentTitle,currentLength)
|
||||
}
|
||||
|
||||
currentlyPlaying = false
|
||||
|
||||
|
||||
|
||||
//ONLY CASE 2: Playback ended
|
||||
if (artist != currentArtist || title != currentTitle) {
|
||||
if (alreadyPlayed > currentLength / 2) {
|
||||
scrobble(currentArtist,currentTitle,alreadyPlayed)
|
||||
alreadyPlayed = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function ostopPlayback(artist,title) {
|
||||
currentlyPlaying = false
|
||||
console.log("Playback stopped!")
|
||||
d = new Date()
|
||||
t = Math.floor(d.getTime()/1000)
|
||||
delta = t - lastUpdate
|
||||
console.log("Since the last update, " + delta + " seconds of music have been played")
|
||||
alreadyPlayed = alreadyPlayed + delta
|
||||
console.log(alreadyPlayed + " seconds of this track have been played overall")
|
||||
if ((alreadyPlayed > currentLength/2) && !alreadyScrobbled) {
|
||||
console.log("Enough to scrobble: " + currentArtist + " - " + currentTitle)
|
||||
scrobble(currentArtist,currentTitle)
|
||||
alreadyScrobbled = true
|
||||
}
|
||||
}
|
||||
|
||||
function ostartPlayback(artist,title,seconds) {
|
||||
|
||||
console.log("Playback started!")
|
||||
if (artist == currentArtist && title == currentTitle && !currentlyPlaying) {
|
||||
@ -116,26 +198,21 @@ function startPlayback(artist,title,seconds) {
|
||||
}
|
||||
}
|
||||
|
||||
function stopPlayback() {
|
||||
currentlyPlaying = false
|
||||
console.log("Playback stopped!")
|
||||
d = new Date()
|
||||
t = Math.floor(d.getTime()/1000)
|
||||
delta = t - lastUpdate
|
||||
console.log("Since the last update, " + delta + " seconds of music have been played")
|
||||
alreadyPlayed = alreadyPlayed + delta
|
||||
console.log(alreadyPlayed + " seconds of this track have been played overall")
|
||||
if ((alreadyPlayed > currentLength/2) && !alreadyScrobbled) {
|
||||
console.log("Enough to scrobble: " + currentArtist + " - " + currentTitle)
|
||||
scrobble(currentArtist,currentTitle)
|
||||
alreadyScrobbled = true
|
||||
}
|
||||
}
|
||||
|
||||
function scrobble(artist,title) {
|
||||
|
||||
function scrobble(artist,title,seconds) {
|
||||
console.log("Scrobbling " + artist + " - " + title + "; " + seconds + " seconds playtime")
|
||||
artiststring = encodeURIComponent(artist)
|
||||
titlestring = encodeURIComponent(title)
|
||||
var xhttp = new XMLHttpRequest();
|
||||
xhttp.open("GET","http://localhost:12345/db/newscrobble?artist=" + artiststring + "&title=" + titlestring,true);
|
||||
xhttp.open("GET","http://localhost:42010/db/newscrobble?artist=" + artiststring + "&title=" + titlestring,true);
|
||||
xhttp.send()
|
||||
}
|
||||
|
||||
function setUpdate() {
|
||||
d = new Date()
|
||||
t = Math.floor(d.getTime()/1000)
|
||||
delta = t - lastUpdate
|
||||
lastUpdate = t
|
||||
return delta
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
bar = document.querySelector("div[class*=PlayerControls]")
|
||||
if (bar == null) {
|
||||
console.log("Nothing playing right now!")
|
||||
chrome.runtime.sendMessage({type:"stopPlayback"})
|
||||
chrome.runtime.sendMessage({type:"stopPlayback",artist:"",title:""})
|
||||
exit()
|
||||
}
|
||||
|
||||
@ -15,7 +15,7 @@ durationSeconds = parseInt(duration.split(":")[0]) * 60 + parseInt(duration.spli
|
||||
control = bar.querySelector("div[class*=PlayerControls-buttonGroupCenter] > button:nth-child(2)").getAttribute("title")
|
||||
if (control == "Play") {
|
||||
console.log("Not playing right now")
|
||||
chrome.runtime.sendMessage({type:"stopPlayback"})
|
||||
chrome.runtime.sendMessage({type:"stopPlayback",artist:artist,title:title})
|
||||
//stopPlayback()
|
||||
}
|
||||
else if (control == "Pause") {
|
||||
|
@ -11,26 +11,7 @@
|
||||
"background.js"
|
||||
]
|
||||
},
|
||||
"content_scripts":
|
||||
[
|
||||
{
|
||||
"matches":
|
||||
[
|
||||
"http://app.plex.tv/*",
|
||||
"https://app.plex.tv/*"
|
||||
],
|
||||
"include_globs":
|
||||
[
|
||||
"http://plex.*",
|
||||
"https://plex.*"
|
||||
],
|
||||
"js":
|
||||
[
|
||||
"contentScript.js"
|
||||
]
|
||||
}
|
||||
|
||||
],
|
||||
|
||||
"browser_action":
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user