Select Git revision
CONTRIBUTORS
player.js 11.92 KiB
// player.js
// Player
djr.Player = function(backend, selector) {
this.backend = backend;
this.player = $(selector);
this.playlist = new djr.Playlist();
this.old_songs = [];
this.cur_song = null;
// Setup the jPlayer interface.
this.player.jPlayer({
swfPath: '/static/js',
ready: function() {
djr.debug('player ready');
}
});
this.player.bind($.jPlayer.event.ended + '.djr',
function () {djr.state.player.nextSong(); });
this.player.bind($.jPlayer.event.error + '.djr',
function() {djr.state.player.reportError(); });
};
djr.Player.prototype.hideAllChunks = function() {
$('.chunk .chunk_inner').hide();
};
// Callback for removechunk click.
djr.Player.prototype.removeChunk = function(chunk_id) {
this.playlist.removeChunk(chunk_id);
this.savePlaylist();
$('#chunk_' + chunk_id).remove();
};
// Remove a single song.
djr.Player.prototype.removeSong = function(song) {
$('#song_' + song).remove();
var chunk_to_remove = this.playlist.removeSong(song);
this.savePlaylist();
if (chunk_to_remove > 0) {
$('#chunk_' + chunk_to_remove).remove();
}
};
// Save the current playlist.
djr.Player.prototype.savePlaylist = function() {
this.backend.savePlaylist(this.playlist.uuid, this.playlist.allSongs());
};
// Completely clear out the current playlist, and replace it with
// a new empty one.
djr.Player.prototype.clearPlaylist = function() {
this.playlist = new djr.Playlist();
$('#playlistDiv').empty();
};
// Merge all chunks into a single one.
djr.Player.prototype.mergePlaylistChunks = function() {
// Reduce the playlist to a single chunk.
this.playlist = this.playlist.merge();
// Shuffle the HTML data around (so we don't have to necessarily
// fetch it again from the server). This is done in a few steps:
// 1) Copy all .chunk_inner data in a temp
var plhtml = [];
$('.chunk .chunk_inner').each(function(idx) {
plhtml.push($(this).html());
});
// 2) Remove all the .chunk divs.
$('#playlistDiv').empty();
// also: $('.chunk').remove();
// 3) Create a new chunk div.
var chunk_id = this.playlist.chunks[0];
var chunk = this.playlist.chunk_map[chunk_id];
this.setChunkHtml(chunk, chunk_id, plhtml.join(''));
};
// Search!
djr.Player.prototype.search = function(query) {
var player = this;
this.backend.search(query, function(results) {
var songs = [];
$.each(results, function(idx, item) {
songs.push(item.sha1);
});
if (songs.length == 0) {
djr.debug('No results found.');
return;
}
// Create a chunk of unique new songs.
player.createChunk(songs, query);
});
};
// Request N last uploaded songs
djr.Player.prototype.lastPlaylist = function(num) {
var player = this;
var title = "Last " + num + " Songs Uploaded";
this.backend.lastPlaylist(num, function(results) {
var songs = results;
if (songs.length == 0) {
djr.debug('No results found.');
return;
}
// Create a chunk of unique new songs.
player.createChunk(songs, title);
});
};
djr.Player.prototype.randomPlaylist = function(num) {
var player = this;
var title = "" + num + " Random Songs ";
this.backend.randomPlaylist(num, function(results) {
var songs = results;
if (songs.length == 0) {
djr.debug('No results found.');
return;
}
// Create a chunk of unique new songs.
player.createChunk(songs, title);
});
};
djr.Player.prototype.neverPlayedPlaylist = function(num) {
var player = this;
var title = "" + num + " Never Played Songs";
this.backend.neverPlayedPlaylist(num, function(results) {
var songs = [];
if (songs.length == 0) {
djr.debug('No results found.');
return;
}
// Create a chunk of unique new songs.
player.createChunk(songs, title);
});
};
djr.Player.prototype.mostPlayedPlaylist = function(num) {
var player = this;
var title = "" + num + " Most Played Songs";
this.backend.mostPlayedPlaylist(num, function(results) {
var songs = [];
$.each(results, function(idx, item) {
songs.push(item.sha1);
});
if (songs.length == 0) {
djr.debug('No results found.');
return;
}
// Create a chunk of unique new songs.
player.createChunk(songs, title);
});
};
// Extend the current playlist with suggestions.
djr.Player.prototype.extendCurrentPlaylist = function() {
var player = this;
var cur_songs = this.playlist.allSongs();
this.backend.moreLikeThese(cur_songs, function(results) {
player.createChunk(results, 'suggestions');
});
};
djr.Player.prototype.createChunk = function(songs, chunk_title) {
// Create the new chunk, with unique songs.
var chunk = this.playlist.createUniqueChunk(songs, chunk_title);
if (!chunk) {
djr.debug('All the results are already in the playlist');
return;
}
// If there's more than one chunk in the playlist, merge (that is,
// replace the current playlist with a new, merged one).
if (this.playlist.chunks.length > 1) {
this.mergePlaylistChunks();
}
// Add the new chunk.
var chunk_id = this.playlist.addChunk(chunk);
// Save the current playlist.
this.savePlaylist();
// Load the HTML fragment for the chunk and display it. Also,
// minimize all the other chunks.
this.backend.getHtmlForSongs(songs, function(songs_html) {
var chunk_div = 'chunk_' + chunk_id;
this.hideAllChunks();
this.setChunkHtml(chunk, chunk_id, songs_html);
}, this);
};
// Set the HTML contents of a chunk object, and the related event hooks.
djr.Player.prototype.setChunkHtml = function(chunk, chunk_id, songs_html) {
var inner_html = chunk.wrapHtml(chunk_id, songs_html);
$('#playlistDiv').append(inner_html);
var player = this;
var chunk_div = $('#chunk_' + chunk_id);
// Add onclick handlers to chunk title, song title, song album.
chunk_div.find('.song_a').click(function() {
player.play($(this).attr('id').substr(5));
});
chunk_div.find('.album_a').click(function() {
player.search('(album:\"' + $(this).text() + '\")');
});
chunk_div.find('.chunk_title').click(function() {
chunk_div.find('.chunk_inner').toggle();
});
// Add onclick and hover handlers to the chunk control box.
chunk_div.hover(function() {
$(this).find('.chunk_ctl_wrap .ctlbox').show();
}, function() {
$(this).find('.chunk_ctl_wrap .ctlbox').hide();
});
chunk_div.find('.chunk_ctl_wrap .ctlbox .ctl_remove').click(function() {
djr.debug('removing chunk ' + chunk_id);
player.removeChunk(chunk_id);
});
// Add onclick handlers to the song control boxes.
chunk_div.find('.chunk_inner .song').hover(function() {
$(this).find('.ctlbox').show();
}, function() {
$(this).find('.ctlbox').hide();
});
chunk_div.find('.chunk_inner .ctlbox .ctl_remove').click(function() {
// What a horrible way of finding the song SHA1...
var sha1 = $(this).parent().parent().attr('id').substr(5);
player.removeSong(sha1);
});
};
// Start playing a specific song.
djr.Player.prototype.play = function(song) {
djr.debug('play ' + song);
if (this.cur_song) {
this.old_songs.push(this.cur_song);
if (this.old_songs.length > 5) {
this.old_songs.shift();
}
}
this.cur_song = song;
$('.song').removeClass('playing');
$('#song_' + song).addClass('playing');
var url = '/dl/' + song;
this.player.jPlayer('setMedia',
{mp3: url}).jPlayer('play');
// Load song info in the player UI. We cheat by stealing the data
// from the existing <div> instead than from the server.
var artist = $('#song_' + song + ' .artist').text();
var album = $('#song_' + song + ' .album').text();
$('#jp_playlist_1').html(
$('#song_' + song + ' .title').text() + '<br>'
+ artist + '<br>'
+ '<small>' + album + '</small>'
);
// Load album art full-screen.
var album_art_url = '/album_image/' + escape(artist) + '/' + escape(album);
$('#albumart_fs').attr('src', album_art_url);
$('#albumart_fs').fullBg();
$('#albumart_fs').show();
// Report the new song being played.
this.backend.nowPlaying(song, this.old_songs);
};
// Start playing the next song.
djr.Player.prototype.nextSong = function() {
this.play(this.playlist.getNextSong(this.cur_song));
};
// Activate streaming of the current playlist.
djr.Player.prototype.streamCurrentPlaylist = function(enable) {
// Nothing for now.
};
djr.state = {
backend: null,
player: null
};
djr.init = function () {
djr.state.backend = new djr.Backend();
djr.state.player = new djr.Player(djr.state.backend, '#djr_player');
// Add onclick hooks to the playlist controls.
$('#playlistClearBtn').click(function() {
djr.state.player.clearPlaylist();
});
$('#playlistStreamBtn').click(function() {
djr.state.player.streamCurrentPlaylist();
});
$('#playlistExtendBtn').click(function() {
djr.state.player.extendCurrentPlaylist();
});
$('#playlistLast5').click(function() {
djr.state.player.lastPlaylist(5);
});
$('#playlistLast25').click(function() {
djr.state.player.lastPlaylist(25);
});
$('#playlistRandom5').click(function() {
djr.state.player.randomPlaylist(5);
});
$('#playlistRandom25').click(function() {
djr.state.player.randomPlaylist(25);
});
$('#playlistMost5').click(function() {
djr.state.player.mostPlayedPlaylist(5);
});
$('#playlistMost25').click(function() {
djr.state.player.mostPlayedPlaylist(25);
});
$('#playlistNever5').click(function() {
djr.state.player.neverPlayedPlaylist(5);
});
$('#playlistNever25').click(function() {
djr.state.player.neverPlayedPlaylist(25);
});
$('#wikibtn').click(function () {
var stitle = $('#song_' + djr.state.player.cur_song + ' .artist').text();
if ( $('#wikipedia').is(':visible') == false ) {
if ( stitle != "" ) {
stitle = stitle.split(' ').join('+');
$('#wikipedia').show('slow');
//$('#wikipedia').attr("src", "/ext?url=" + escape("http://en.wikipedia.org/wiki/Special:Search?search=" + stitle + "&go=Go"));
$('#wikipedia').attr("src", "http://en.m.wikipedia.org/w/index.php?search=" + stitle);
}
} else {
$('#wikipedia').hide('slow')
}
});
$('#lastfmbtn').click(function () {
var stitle = $('#song_' + djr.state.player.cur_song + ' .title').text();
var sartist = $('#song_' + djr.state.player.cur_song + ' .artist').text();
if ( $('#lastfm').is(':visible') == false ) {
if ( stitle != "" ) {
stitle = stitle.split(' ').join('+');
sartist = sartist.split(' ').join('+');
$('#lastfm').show('slow');
//$('#lastfm').attr("src", "/ext?url=" + escape("http://www.lastfm.com/#&q=" + stitle + sartist));
$('#lastfm').attr("src", "http://m.last.fm/search?q=" + stitle + sartist );
}
} else {
$('#lastfm').hide('slow')
}
});
$('#lyricsbtn').click(function () {
var stitle = $('#song_' + djr.state.player.cur_song + ' .title').text();
if ( $('#lyrics').is(':visible') == false ) {
if ( stitle != "" ) {
stitle = stitle.split(' ').join('+');
$('#lyrics').show('slow');
//$('#lyrics').attr("src", "/ext?url=" + escape("http://www.lyrics.com/#&q=" + stitle));
$('#lyrics').attr("src", "http://lyrics.wikia.com/index.php?search=" + stitle + "&fulltext=0" );
}
} else {
$('#lyrics').hide('slow')
}
});
// Set the album art image to auto-fullscreen on load.
$('#albumart_fs').load(function() {
$(this).fullBg();
$(this).show();
});
};
// Export the player for quick onclick access
djr.player = function() {
return djr.state.player;
};
// Debugging.
djr.debug = function(msg) {
$('#debug').append(msg + '<br>');
};
// ------ OLD --------
/**
// An error has occurred in the player.
djr.Player.prototype.reportError = function(event) {
switch(event.jPlayer.error.type) {
case $.jPlayer.error.URL:
djr.debug('error downloading song, moving on');
this.nextSong();
break;
case $.jPlayer.error.NO_SOLUTION:
djr.debug('unexpected error!');
break;
}
};
**/
// Fine