forked from web-scrobbler/web-scrobbler
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy path8tracks.js
More file actions
140 lines (115 loc) · 4.11 KB
/
Copy path8tracks.js
File metadata and controls
140 lines (115 loc) · 4.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/*
* Chrome-Last.fm-Scrobbler 8tracks Connector
*
* Matt Runkle - matt[at]mrunkle[dot]com
*
*/
/*** Configuration ***/
// Additions to this div will trigger update
WATCHED_CONTAINER = "#tracks_played";
// Returns the currently playing artist name
function getArtist( ) {
return cleanLabel( $("#now_playing div.title_artist > span.a:first").text() );
}
// Returns the currently playing track title
function getTrack( ) {
return cleanLabel( $("#now_playing div.title_artist > span.t:first").text() );
}
function getAlbum( ) {
return cleanLabel( $("#now_playing div.album > span.detail:first").text() );
}
// Returns the number of pixels denoting the time expired in the song
function getPercentDone( ) {
var width = parseInt( $("div#player_progress_bar").width() );
return parseInt( $("div#player_progress_bar_meter").width() ) / width;
}
// Perform some common cleanup of artist/song/album strings
function cleanLabel( label ) {
label = label.replace( '&', '&' );
return $.trim( label );
}
/*** Scrobbler Interface ***/
LAST_TRACK = "";
TIMEOUT = "";
TIME_PERCENT = 10;
START_TIME = 0;
// Since we can't just pull the song duration from the DOM
// we need to estimate. Luckily there is a nice progress bar
function tryScrobble() {
var ratio = getPercentDone();
if ( ratio > (1/TIME_PERCENT) ) {
// Measured enough, estimate time and scrobble
var endTime = new Date().getTime();
var elapsed = (endTime - START_TIME) / 1000;
TIMEOUT = "";
START_TIME = 0;
updateNowPlaying(elapsed);
return;
}
// Set timeout based on about how long we have left, max 50s / percent
TIMEOUT = setTimeout( tryScrobble, Math.min(500 / ratio, 50000 / TIME_PERCENT) );
}
// Validates and scrobbles the currently playing song
function updateNowPlaying(elapsed) {
elapsed = Math.floor(elapsed);
var duration = elapsed * TIME_PERCENT;
var title = getTrack();
var artist = getArtist();
var album = getAlbum();
var newTrack = title + " " + artist;
// Update scrobbler if necessary
if ( newTrack != " " && newTrack != LAST_TRACK ) {
//console.log("Submitting a now playing request. artist: "+artist+", title: "+title+", album: " + album + ", duration: " + duration);
LAST_TRACK = newTrack;
chrome.runtime.sendMessage({type: 'validate', artist: artist, track: title}, function(response) {
if (response != false) {
// submit the validated song for scrobbling
var song = response;
chrome.runtime.sendMessage({type: 'nowPlaying', artist: song.artist, track: song.track,
album: (album === "") ? null : album, currentTime: elapsed, duration: duration});
} else {
// on failure send nowPlaying 'unknown song'
console.log( "Song validation failed!" );
chrome.runtime.sendMessage({type: 'nowPlaying', currentTime: elapsed, duration: duration});
}
});
}
}
function triggerUpdate() {
var nowPlaying = getTrack() + " " + getArtist();
if ( nowPlaying != " " && nowPlaying != LAST_TRACK ) {
START_TIME = new Date().getTime();
// Stop any non-scrobbled songs (i.e. song skipped)
if( TIMEOUT != "" ) {
clearTimeout( TIMEOUT );
}
// Schedule the next scrobble
TIMEOUT = setTimeout( tryScrobble, 500 );
return;
}
}
// Attach listener for song changes, filter out duplicate event firings
$(function(){
console.log("8tracks module starting up");
// Attach listener to "recently played" song list
$(WATCHED_CONTAINER).live('DOMNodeInserted', function(e) {
setTimeout( triggerUpdate, 500 ); // let player update
});
$(window).unload(function() {
chrome.runtime.sendMessage({type: 'reset'});
return true;
});
});
/**
* Listen for requests from scrobbler.js
*/
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
switch(request.type) {
// background calls this to see if the script is already injected
case 'ping':
sendResponse(true);
break;
}
}
);