794 lines
29 KiB
JavaScript
794 lines
29 KiB
JavaScript
function playerController() {
|
|
|
|
var self = this;
|
|
var updatetimer = null;
|
|
var progresstimer = null;
|
|
var safetytimer = 500;
|
|
var previoussongid = -1;
|
|
var AlanPartridge = 0;
|
|
var plversion = null;
|
|
var openpl = null;
|
|
var oldplname;
|
|
var thenowplayinghack = false;
|
|
var lastsearchcmd = "search";
|
|
var stateChangeCallbacks = new Array();
|
|
|
|
function updateStreamInfo() {
|
|
|
|
// When playing a stream, mpd returns 'Title' in its status field.
|
|
// This usually has the form artist - track. We poll this so we know when
|
|
// the track has changed (note, we rely on radio stations setting their
|
|
// metadata reliably)
|
|
|
|
// Note that mopidy doesn't quite work this way. It sets Title and possibly Name
|
|
// - I fixed that bug once but it got broke again
|
|
|
|
if (playlist.getCurrent('type') == "stream") {
|
|
// debug.trace('STREAMHANDLER','Playlist:',playlist.getCurrent('Title'),playlist.getCurrent('Album'),playlist.getCurrent('trackartist'));
|
|
var temp = playlist.getCurrentTrack();
|
|
if (player.status.Title) {
|
|
var parts = player.status.Title.split(" - ");
|
|
if (parts[0] && parts[1]) {
|
|
temp.trackartist = parts.shift();
|
|
temp.Title = parts.join(" - ");
|
|
temp.metadata.artists = [{name: temp.trackartist, musicbrainz_id: ""}];
|
|
temp.metadata.track = {name: temp.Title, musicbrainz_id: ""};
|
|
} else if (player.status.Title && player.status.Artist) {
|
|
temp.trackartist = player.status.Artist;
|
|
temp.Title = player.status.Title;
|
|
temp.metadata.artists = [{name: temp.trackartist, musicbrainz_id: ""}];
|
|
temp.metadata.track = {name: temp.Title, musicbrainz_id: ""};
|
|
}
|
|
}
|
|
if (player.status.Name && !player.status.Name.match(/^\//) && temp.Album == rompr_unknown_stream) {
|
|
// NOTE: 'Name' is returned by MPD - it's the station name as read from the station's stream metadata
|
|
debug.shout('STREAMHANDLER',"Checking For Stream Name Update");
|
|
checkForUpdateToUnknownStream(playlist.getCurrent('StreamIndex'), player.status.Name);
|
|
temp.Album = player.status.Name;
|
|
temp.metadata.album = {name: temp.Album, musicbrainz_id: ""};
|
|
}
|
|
// debug.trace('STREAMHANDLER','Current:',temp.Title,temp.Album,temp.trackartist);
|
|
if (playlist.getCurrent('Title') != temp.Title ||
|
|
playlist.getCurrent('Album') != temp.Album ||
|
|
playlist.getCurrent('trackartist') != temp.trackartist)
|
|
{
|
|
debug.log("STREAMHANDLER","Detected change of track",temp);
|
|
var aa = new albumart_translator('');
|
|
temp.key = aa.getKey('stream', '', temp.Album);
|
|
playlist.setCurrent({Title: temp.Title, Album: temp.Album, trackartist: temp.trackartist });
|
|
nowplaying.newTrack(temp, true);
|
|
}
|
|
}
|
|
}
|
|
|
|
function checkForUpdateToUnknownStream(streamid, name) {
|
|
// If our playlist for this station has 'Unknown Internet Stream' as the
|
|
// station name, let's see if we can update it from the metadata.
|
|
debug.log("STREAMHANDLER","Checking For Update to Stream",streamid,name, name);
|
|
var m = playlist.getCurrent('Album');
|
|
if (m.match(/^Unknown Internet Stream/)) {
|
|
debug.shout("PLAYLIST","Updating Stream",name);
|
|
yourRadioPlugin.updateStreamName(streamid, name, playlist.getCurrent('file'), playlist.repopulate);
|
|
}
|
|
}
|
|
|
|
function setTheClock(callback, timeout) {
|
|
clearProgressTimer();
|
|
progresstimer = setTimeout(callback, timeout);
|
|
}
|
|
|
|
function initialised(data) {
|
|
for(var i =0; i < data.length; i++) {
|
|
var h = data[i].replace(/\:\/\/$/,'');
|
|
debug.log("PLAYER","URL Handler : ",h);
|
|
player.urischemes[h] = true;
|
|
}
|
|
if (!player.canPlay('spotify')) {
|
|
$('div.textcentre.textunderline:contains("Music From Spotify")').remove();
|
|
}
|
|
checkSearchDomains();
|
|
doMopidyCollectionOptions();
|
|
playlist.radioManager.init();
|
|
// Need to call this with a callback when we start up so that checkprogress doesn't get called
|
|
// before the playlist has repopulated.
|
|
self.do_command_list([],self.ready);
|
|
if (!player.collectionLoaded) {
|
|
debug.log("MPD", "Checking Collection");
|
|
collectionHelper.checkCollection(false, false);
|
|
}
|
|
}
|
|
|
|
this.initialise = function() {
|
|
$.ajax({
|
|
type: 'GET',
|
|
url: 'player/mpd/geturlhandlers.php',
|
|
dataType: 'json'
|
|
})
|
|
.done(initialised)
|
|
.fail(function(data) {
|
|
debug.error("MPD","Failed to get URL Handlers",data);
|
|
infobar.permerror(language.gettext('error_noplayer'));
|
|
});
|
|
}
|
|
|
|
this.ready = function() {
|
|
debug.mark("MPD","Player is ready");
|
|
var t = "Connected to "+getCookie('currenthost')+" ("+prefs.player_backend.capitalize() +
|
|
" at " + player_ip + ")";
|
|
infobar.notify(t);
|
|
self.reloadPlaylists();
|
|
}
|
|
|
|
this.do_command_list = function(list, callback) {
|
|
// Note, if you call this with a callback, your callback MUST call player.controller.checkProgress
|
|
$.ajax({
|
|
type: 'POST',
|
|
url: 'player/mpd/postcommand.php',
|
|
data: JSON.stringify(list),
|
|
// contentType of false prevents jQuery from re-encoding our data, where it
|
|
// converts %20 to +, which seems to be a bug in jQuery 3.0
|
|
contentType: false,
|
|
dataType: 'json',
|
|
timeout: 30000
|
|
})
|
|
.done(function(data) {
|
|
if (data) {
|
|
debug.debug("PLAYER",data);
|
|
if (data.state) {
|
|
// Clone the object so as not to leave this closure in memory
|
|
player.status = cloneObject(data);
|
|
['radiomode', 'radioparam', 'radiomaster', 'radioconsume'].forEach(function(e) {
|
|
prefs[e] = player.status[e];
|
|
});
|
|
if (player.status.playlist !== plversion) {
|
|
debug.blurt("PLAYER","Player has marked playlist as changed");
|
|
plversion = player.status.playlist;
|
|
playlist.repopulate();
|
|
}
|
|
infobar.setStartTime(player.status.elapsed);
|
|
checkStateChange();
|
|
}
|
|
}
|
|
})
|
|
.fail(function(jqXHR, textStatus, errorThrown) {
|
|
debug.error("MPD","Command List Failed",list,textStatus,errorThrown);
|
|
if (list.length > 0) {
|
|
infobar.error(language.gettext('error_sendingcommands', [prefs.player_backend]));
|
|
}
|
|
})
|
|
.always(function() {
|
|
post_command_list(callback);
|
|
});
|
|
}
|
|
|
|
function post_command_list(callback) {
|
|
if (callback) {
|
|
callback();
|
|
} else {
|
|
self.checkProgress();
|
|
}
|
|
infobar.updateWindowValues();
|
|
}
|
|
|
|
this.isConnected = function() {
|
|
return true;
|
|
}
|
|
|
|
this.addStateChangeCallback = function(sc) {
|
|
if (player.status.state == sc.state) {
|
|
sc.callback();
|
|
} else {
|
|
stateChangeCallbacks.push(sc);
|
|
}
|
|
}
|
|
|
|
function checkStateChange() {
|
|
for (var i = 0; i < stateChangeCallbacks.length ; i++) {
|
|
if (stateChangeCallbacks[i].state == player.status.state) {
|
|
// If we're looking for a state change to play, check that elapsed > 5. This works around Mopidy's
|
|
// buffering issue where playback can take a long time to start with streams and ends up starting a
|
|
// long time after we've started ramping the alarm clock volume
|
|
debug.log('PLAYER', 'State Change Check. State is',player.status.state,'Elapsed is',player.status.elapsed);
|
|
if (player.status.state != 'play' || player.status.elapsed > 5) {
|
|
debug.mark('PLAYER', 'Calling state change callback for state',player.status.state);
|
|
stateChangeCallbacks[i].callback();
|
|
stateChangeCallbacks.splice(i, 1);
|
|
i--;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
this.reloadPlaylists = function() {
|
|
var openplaylists = [];
|
|
$('#storedplaylists').find('i.menu.openmenu.playlist.icon-toggle-open').each(function() {
|
|
openplaylists.push($(this).attr('name'));
|
|
})
|
|
$.get("player/mpd/loadplaylists.php", function(data) {
|
|
$("#storedplaylists").html(data);
|
|
layoutProcessor.postAlbumActions();
|
|
$('b:contains("'+language.gettext('button_loadplaylist')+'")').parent('.configtitle').append('<a href="https://fatg3erman.github.io/RompR/Using-Saved-Playlists" target="_blank"><i class="icon-info-circled playlisticonr tright"></i></a>');
|
|
for (var i in openplaylists) {
|
|
$('i.menu.openmenu.playlist.icon-toggle-closed[name="'+openplaylists[i]+'"]').click();
|
|
}
|
|
if (openplaylists.length > 0) {
|
|
infobar.markCurrentTrack();
|
|
}
|
|
$('#addtoplaylistmenu').load('player/mpd/loadplaylists.php?addtoplaylistmenu');
|
|
});
|
|
}
|
|
|
|
this.loadPlaylist = function(name) {
|
|
self.do_command_list([['load', name]]);
|
|
return false;
|
|
}
|
|
|
|
this.loadPlaylistURL = function(name) {
|
|
if (name == '') {
|
|
return false;
|
|
}
|
|
var data = {url: encodeURIComponent(name)};
|
|
$.ajax({
|
|
type: "GET",
|
|
url: "utils/getUserPlaylist.php",
|
|
cache: false,
|
|
data: data,
|
|
dataType: "xml"
|
|
})
|
|
.done(function() {
|
|
self.reloadPlaylists();
|
|
self.addTracks([{type: 'remoteplaylist', name: name}], null, null);
|
|
})
|
|
.fail(function(data, status) {
|
|
playlist.repopulate();
|
|
debug.error("MPD","Failed to save user playlist URL");
|
|
});
|
|
return false;
|
|
}
|
|
|
|
this.deletePlaylist = function(name, callback) {
|
|
openpl = null;
|
|
name = decodeURIComponent(name);
|
|
if (callback) {
|
|
self.do_command_list([['rm',name]], callback);
|
|
} else {
|
|
self.do_command_list([['rm',name]], function() {
|
|
self.reloadPlaylists();
|
|
if (typeof(playlistManager) != 'undefined') {
|
|
playlistManager.reloadAll();
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
this.deleteUserPlaylist = function(name) {
|
|
openpl = null;
|
|
var data = {del: encodeURIComponent(name)};
|
|
$.ajax({
|
|
type: "GET",
|
|
url: "utils/getUserPlaylist.php",
|
|
cache: false,
|
|
data: data,
|
|
dataType: "xml"
|
|
})
|
|
.done(self.reloadPlaylists)
|
|
.fail(function(data, status) {
|
|
debug.error("MPD","Failed to delete user playlist",name);
|
|
});
|
|
}
|
|
|
|
this.renamePlaylist = function(name, e, callback) {
|
|
openpl = null;
|
|
oldplname = name;
|
|
debug.log("MPD","Renaming Playlist",name,e);
|
|
var fnarkle = new popup({
|
|
css: {
|
|
width: 400,
|
|
height: 300
|
|
},
|
|
title: language.gettext("label_renameplaylist"),
|
|
atmousepos: true,
|
|
mousevent: e
|
|
});
|
|
var mywin = fnarkle.create();
|
|
var d = $('<div>',{class: 'containerbox'}).appendTo(mywin);
|
|
var e = $('<div>',{class: 'expand'}).appendTo(d);
|
|
var i = $('<input>',{class: 'enter', id: 'newplname', type: 'text', size: '200'}).appendTo(e);
|
|
var b = $('<button>',{class: 'fixed'}).appendTo(d);
|
|
b.html('Rename');
|
|
fnarkle.useAsCloseButton(b, callback);
|
|
fnarkle.open();
|
|
}
|
|
|
|
this.doRenamePlaylist = function() {
|
|
self.do_command_list([["rename", decodeURIComponent(oldplname), $("#newplname").val()]],
|
|
function() {
|
|
self.reloadPlaylists();
|
|
layoutProcessor.postAlbumActions();
|
|
if (typeof(playlistManager) != "undefined") {
|
|
playlistManager.reloadAll();
|
|
}
|
|
}
|
|
);
|
|
return true;
|
|
}
|
|
|
|
this.doRenameUserPlaylist = function() {
|
|
var data = {rename: encodeURIComponent(oldplname),
|
|
newname: encodeURIComponent($("#newplname").val())
|
|
};
|
|
$.ajax({
|
|
type: "GET",
|
|
url: "utils/getUserPlaylist.php",
|
|
cache: false,
|
|
data: data,
|
|
dataType: "xml"
|
|
})
|
|
.done(function(data) {
|
|
layoutProcessor.postAlbumActions();
|
|
self.reloadPlaylists();
|
|
})
|
|
.fail(function(data, status) {
|
|
debug.error("MPD","Failed to rename user playlist",name);
|
|
});
|
|
return true;
|
|
}
|
|
|
|
this.deletePlaylistTrack = function(name,songpos,callback) {
|
|
openpl = name;
|
|
if (!callback) {
|
|
callback = self.checkReloadPlaylists;
|
|
}
|
|
self.do_command_list([['playlistdelete',decodeURIComponent(name),songpos]], callback);
|
|
}
|
|
|
|
this.checkReloadPlaylists = function() {
|
|
if (openpl !== null) {
|
|
var string = browsePlaylist(encodeURIComponent(openpl), 'pholder_'+hex_md5(openpl));
|
|
$('#pholder_'+hex_md5(openpl)).load(string);
|
|
}
|
|
if (typeof(playlistManager) != 'undefined') {
|
|
playlistManager.checkToUpdateTheThing(encodeURIComponent(openpl));
|
|
}
|
|
openpl = null;
|
|
}
|
|
|
|
this.clearPlaylist = function(callback) {
|
|
// Mopidy does not like removing tracks while they're playing
|
|
self.do_command_list([['stop'], ['clear']], callback);
|
|
}
|
|
|
|
this.savePlaylist = function() {
|
|
var name = $("#playlistname").val();
|
|
debug.log("GENERAL","Save Playlist",name);
|
|
if (name == '') {
|
|
return false;
|
|
} else if (name.indexOf("/") >= 0 || name.indexOf("\\") >= 0) {
|
|
infobar.error(language.gettext("error_playlistname"));
|
|
} else {
|
|
self.do_command_list([["save", name]], function() {
|
|
self.reloadPlaylists();
|
|
if (typeof(playlistManager) != "undefined") {
|
|
playlistManager.reloadAll();
|
|
}
|
|
infobar.notify(language.gettext("label_savedpl", [name]));
|
|
$("#plsaver").slideToggle('fast');
|
|
self.checkProgress();
|
|
});
|
|
}
|
|
}
|
|
|
|
this.getPlaylist = function(reqid) {
|
|
debug.log("PLAYER","Getting playlist using mpd connection");
|
|
$.ajax({
|
|
type: "GET",
|
|
url: "getplaylist.php",
|
|
cache: false,
|
|
dataType: "json"
|
|
})
|
|
.done(function(data) {
|
|
playlist.newXSPF(reqid, data);
|
|
})
|
|
.fail(playlist.updateFailure);
|
|
}
|
|
|
|
this.play = function() {
|
|
self.do_command_list([['play']]);
|
|
}
|
|
|
|
this.pause = function() {
|
|
self.do_command_list([['pause']]);
|
|
}
|
|
|
|
this.stop = function() {
|
|
playlist.checkPodcastProgress();
|
|
self.do_command_list([["stop"]], self.onStop);
|
|
}
|
|
|
|
this.next = function() {
|
|
playlist.checkPodcastProgress();
|
|
self.do_command_list([["next"]]);
|
|
}
|
|
|
|
this.previous = function() {
|
|
playlist.checkPodcastProgress();
|
|
self.do_command_list([["previous"]]);
|
|
}
|
|
|
|
this.seek = function(seekto) {
|
|
debug.log("PLAYER","Seeking To",seekto);
|
|
self.do_command_list([["seek", player.status.song, parseInt(seekto.toString())]]);
|
|
}
|
|
|
|
this.playId = function(id) {
|
|
playlist.checkPodcastProgress();
|
|
self.do_command_list([["playid",id]]);
|
|
}
|
|
|
|
this.playByPosition = function(pos) {
|
|
playlist.checkPodcastProgress();
|
|
self.do_command_list([["play",pos.toString()]]);
|
|
}
|
|
|
|
this.volume = function(volume, callback) {
|
|
self.do_command_list([["setvol",parseInt(volume.toString())]], callback);
|
|
return true;
|
|
}
|
|
|
|
this.removeId = function(ids) {
|
|
var cmdlist = [];
|
|
$.each(ids, function(i,v) {
|
|
cmdlist.push(["deleteid", v]);
|
|
});
|
|
self.do_command_list(cmdlist);
|
|
}
|
|
|
|
this.toggleRandom = function() {
|
|
var new_value = (player.status.random == 0) ? 1 : 0;
|
|
self.do_command_list([["random",new_value]], function() {
|
|
playlist.doUpcomingCrap();
|
|
self.checkProgress();
|
|
});
|
|
}
|
|
|
|
this.toggleCrossfade = function() {
|
|
var new_value = (player.status.xfade === undefined || player.status.xfade === null ||
|
|
player.status.xfade == 0) ? prefs.crossfade_duration : 0;
|
|
self.do_command_list([["crossfade",new_value]]);
|
|
}
|
|
|
|
this.setCrossfade = function(v) {
|
|
self.do_command_list([["crossfade",v]]);
|
|
}
|
|
|
|
this.toggleRepeat = function() {
|
|
var new_value = (player.status.repeat == 0) ? 1 : 0;
|
|
self.do_command_list([["repeat",new_value]]);
|
|
}
|
|
|
|
this.toggleConsume = function() {
|
|
var new_value = (player.status.consume == 0) ? 1 : 0;
|
|
self.do_command_list([["consume",new_value]]);
|
|
}
|
|
|
|
this.checkConsume = function(state) {
|
|
debug.log("PLAYER","Checking Consume",state);
|
|
self.do_command_list([["consume",state]]);
|
|
}
|
|
|
|
this.takeBackControl = function(v) {
|
|
self.do_command_list([["repeat",0],["random", 0],["consume", 1]]);
|
|
}
|
|
|
|
this.addTracks = function(tracks, playpos, at_pos) {
|
|
var abitofahack = true;
|
|
layoutProcessor.notifyAddTracks();
|
|
debug.log("MPD","Adding Tracks",tracks,playpos,at_pos);
|
|
var cmdlist = [];
|
|
$.each(tracks, function(i,v) {
|
|
switch (v.type) {
|
|
case "uri":
|
|
if (prefs.cdplayermode && at_pos === null && !playlist.radioManager.isRunning()) {
|
|
cmdlist.push(['addtoend', v.name]);
|
|
} else {
|
|
cmdlist.push(['add',v.name]);
|
|
}
|
|
break;
|
|
case "playlist":
|
|
case "cue":
|
|
cmdlist.push(['load',v.name]);
|
|
break;
|
|
case "item":
|
|
cmdlist.push(['additem',v.name]);
|
|
break;
|
|
case "artist":
|
|
cmdlist.push(['addartist',v.name]);
|
|
break;
|
|
case "stream":
|
|
cmdlist.push(['loadstreamplaylist',v.url,v.image,v.station]);
|
|
break;
|
|
case "playlisttoend":
|
|
cmdlist.push(['playlisttoend',v.playlist,v.frompos]);
|
|
break;
|
|
case "resumepodcast":
|
|
cmdlist.push(['resume', v.uri, v.resumefrom, v.pos]);
|
|
playpos = null;
|
|
abitofahack = false;
|
|
break;
|
|
case 'remoteplaylist':
|
|
cmdlist.push(['addremoteplaylist', v.name]);
|
|
break;
|
|
}
|
|
});
|
|
// Note : playpos will only be set if at_pos isn't, because at_pos is only set when dragging to the playlist
|
|
if (prefs.cdplayermode && at_pos === null && !playlist.radioManager.isRunning()) {
|
|
cmdlist.unshift(["clear"]);
|
|
cmdlist.unshift(["stop"]);
|
|
if (abitofahack) {
|
|
// Don't add the play command if we're doing a resume,
|
|
// because postcommand.php will add it and this will override it
|
|
cmdlist.push(['play']);
|
|
}
|
|
} else if (playpos !== null) {
|
|
cmdlist.push(['play', playpos.toString()]);
|
|
}
|
|
if (at_pos === 0 || at_pos) {
|
|
cmdlist.push(['moveallto', at_pos]);
|
|
}
|
|
self.do_command_list(cmdlist);
|
|
}
|
|
|
|
this.move = function(first, num, moveto) {
|
|
var itemstomove = first.toString();
|
|
if (num > 1) {
|
|
itemstomove = itemstomove + ":" + (parseInt(first)+parseInt(num));
|
|
}
|
|
if (itemstomove == moveto) {
|
|
// This can happen if you drag the final track from one album to a position below the
|
|
// next album's header but before its first track. This doesn't change its position in
|
|
// the playlist but the item in the display will have moved and we need to move it back.
|
|
playlist.repopulate();
|
|
} else {
|
|
debug.log("PLAYER", "Move command is move&arg="+itemstomove+"&arg2="+moveto);
|
|
self.do_command_list([["move",itemstomove,moveto]]);
|
|
}
|
|
}
|
|
|
|
this.stopafter = function() {
|
|
var cmds = [];
|
|
if (player.status.repeat == 1) {
|
|
cmds.push(["repeat", 0]);
|
|
}
|
|
cmds.push(["single", 1]);
|
|
self.do_command_list(cmds);
|
|
}
|
|
|
|
this.cancelSingle = function() {
|
|
self.do_command_list([["single",0]]);
|
|
}
|
|
|
|
this.doOutput = function(id) {
|
|
state = $('#outputbutton_'+id).is(':checked');
|
|
if (state) {
|
|
self.do_command_list([["disableoutput",id]]);
|
|
} else {
|
|
self.do_command_list([["enableoutput",id]]);
|
|
}
|
|
}
|
|
|
|
this.doMute = function() {
|
|
if (prefs.player_backend == "mopidy") {
|
|
if ($("#mutebutton").hasClass('icon-output-mute')) {
|
|
$("#mutebutton").removeClass('icon-output-mute').addClass('icon-output');
|
|
self.do_command_list([["disableoutput", 0]]);
|
|
} else {
|
|
$("#mutebutton").removeClass('icon-output').addClass('icon-output-mute');
|
|
self.do_command_list([["enableoutput", 0]]);
|
|
}
|
|
} else {
|
|
if ($("#mutebutton").hasClass('icon-output-mute')) {
|
|
$("#mutebutton").removeClass('icon-output-mute').addClass('icon-output');
|
|
self.do_command_list([["enableoutput", 0]]);
|
|
} else {
|
|
$("#mutebutton").removeClass('icon-output').addClass('icon-output-mute');
|
|
self.do_command_list([["disableoutput", 0]]);
|
|
}
|
|
}
|
|
}
|
|
|
|
this.search = function(command) {
|
|
if (player.updatingcollection) {
|
|
infobar.notify(language.gettext('error_nosearchnow'));
|
|
return false;
|
|
}
|
|
var terms = {};
|
|
var termcount = 0;
|
|
lastsearchcmd = command;
|
|
$("#collectionsearcher").find('.searchterm').each( function() {
|
|
var key = $(this).attr('name');
|
|
var value = $(this).val();
|
|
if (value != "") {
|
|
debug.trace("PLAYER","Searching for",key, value);
|
|
terms[key] = value.split(',');
|
|
termcount++;
|
|
}
|
|
});
|
|
if ($('[name="searchrating"]').val() != "") {
|
|
terms['rating'] = $('[name="searchrating"]').val();x
|
|
termcount++;
|
|
}
|
|
var domains = new Array();
|
|
if (prefs.search_limit_limitsearch && $('#mopidysearchdomains').length > 0) {
|
|
// The second term above is just in case we're swapping between MPD and Mopidy
|
|
// - it prevents an illegal invocation in JQuery if limitsearch is true for MPD
|
|
domains = $("#mopidysearchdomains").makeDomainChooser("getSelection");
|
|
}
|
|
if (termcount > 0) {
|
|
$("#searchresultholder").empty();
|
|
doSomethingUseful('searchresultholder', language.gettext("label_searching"));
|
|
var st = {
|
|
command: command,
|
|
resultstype: prefs.displayresultsas,
|
|
domains: domains,
|
|
dump: collectionHelper.collectionKey('b')
|
|
};
|
|
debug.log("PLAYER","Doing Search:",terms,st);
|
|
if ((termcount == 1 && (terms.tag || terms.rating)) ||
|
|
(termcount == 2 && (terms.tag && terms.rating)) ||
|
|
(prefs.player_backend == 'mopidy' && prefs.searchcollectiononly) ||
|
|
((terms.tag || terms.rating) && !(terms.genre || terms.composer || terms.performer || terms.any))) {
|
|
// Use the sql search engine if we're looking only for things it supports
|
|
debug.log("PLAYER","Searching using database search engine");
|
|
st.terms = terms;
|
|
} else {
|
|
st.mpdsearch = terms;
|
|
}
|
|
$.ajax({
|
|
type: "POST",
|
|
url: "albums.php",
|
|
data: st
|
|
})
|
|
.done(function(data) {
|
|
$("#searchresultholder").html(data);
|
|
collectionHelper.scootTheAlbums($("#searchresultholder"));
|
|
layoutProcessor.postAlbumActions();
|
|
data = null;
|
|
});
|
|
}
|
|
}
|
|
|
|
this.reSearch = function() {
|
|
player.controller.search(lastsearchcmd);
|
|
}
|
|
|
|
this.rawsearch = function(terms, sources, exact, callback, checkdb) {
|
|
if (player.updatingcollection) {
|
|
infobar.notify(language.gettext('error_nosearchnow'));
|
|
callback([]);
|
|
}
|
|
$.ajax({
|
|
type: "POST",
|
|
url: "albums.php",
|
|
dataType: 'json',
|
|
data: {
|
|
rawterms: terms,
|
|
domains: sources,
|
|
command: exact ? "find" : "search",
|
|
checkdb: checkdb
|
|
}
|
|
})
|
|
.done(function(data) {
|
|
callback(data);
|
|
data = null;
|
|
})
|
|
.fail(function() {
|
|
callback([]);
|
|
});
|
|
}
|
|
|
|
this.postLoadActions = function() {
|
|
self.checkProgress();
|
|
if (thenowplayinghack) {
|
|
// The Now PLaying Hack is so that when we switch the option for
|
|
// 'display composer/performer in nowplaying', we can first reload the
|
|
// playlist (to get the new artist metadata keys from the backend)
|
|
// and then FORCE nowplaying to accept a new track with the same backendid
|
|
// as the previous - this forces the nowplaying info to update
|
|
thenowplayinghack = false;
|
|
nowplaying.newTrack(playlist.getCurrentTrack(), true);
|
|
}
|
|
}
|
|
|
|
this.doTheNowPlayingHack = function() {
|
|
debug.log("MPD","Doing the nowplaying hack thing");
|
|
thenowplayinghack = true;
|
|
playlist.repopulate();
|
|
}
|
|
|
|
function clearProgressTimer() {
|
|
clearTimeout(progresstimer);
|
|
}
|
|
|
|
this.checkProgress = function() {
|
|
clearProgressTimer();
|
|
// Track changes are detected based on the playlist id. This prevents us from repopulating
|
|
// the browser every time the playlist gets repopulated.
|
|
if (player.status.songid !== previoussongid) {
|
|
debug.mark("MPD","Track has changed");
|
|
playlist.trackHasChanged(player.status.songid);
|
|
previoussongid = player.status.songid;
|
|
safetytimer = 500;
|
|
}
|
|
|
|
var progress = infobar.progress();
|
|
playlist.setCurrent({progress: progress});
|
|
var duration = playlist.getCurrent('Time') || 0;
|
|
infobar.setProgress(progress,duration);
|
|
|
|
if (player.status.state == "play") {
|
|
if (duration > 0 && progress >= duration) {
|
|
setTheClock(self.checkchange, safetytimer);
|
|
if (safetytimer < 5000) { safetytimer += 500 }
|
|
} else {
|
|
AlanPartridge++;
|
|
if (AlanPartridge < 5) {
|
|
setTheClock( self.checkProgress, 1000);
|
|
} else {
|
|
AlanPartridge = 0;
|
|
setTheClock( self.checkchange, 1000);
|
|
}
|
|
}
|
|
} else {
|
|
setTheClock(self.checkchange, 10000);
|
|
}
|
|
}
|
|
|
|
this.checkchange = function() {
|
|
clearProgressTimer();
|
|
// Update the status to see if the track has changed
|
|
if (playlist.getCurrent('type') == "stream") {
|
|
self.do_command_list([], self.checkStream);
|
|
} else {
|
|
self.do_command_list([], null);
|
|
}
|
|
}
|
|
|
|
this.checkStream = function() {
|
|
updateStreamInfo();
|
|
self.checkProgress();
|
|
}
|
|
|
|
this.onStop = function() {
|
|
infobar.setProgress(0,-1,-1);
|
|
self.checkProgress();
|
|
}
|
|
|
|
this.replayGain = function(event) {
|
|
var x = $(event.target).attr("id").replace('replaygain_','');
|
|
debug.log("MPD","Setting Replay Gain to",x);
|
|
self.do_command_list([["replay_gain_mode",x]]);
|
|
}
|
|
|
|
this.addTracksToPlaylist = function(playlist,tracks,moveto,playlistlength,callback) {
|
|
debug.log("PLAYER","Adding tracks to playlist",playlist,"then moving to",moveto,"playlist length is",playlistlength);
|
|
var cmds = new Array();
|
|
for (var i in tracks) {
|
|
if (tracks[i].uri) {
|
|
cmds.push(['playlistadd',decodeURIComponent(playlist),tracks[i].uri,
|
|
moveto,playlistlength]);
|
|
} else if (tracks[i].dir) {
|
|
cmds.push(['playlistadddir',decodeURIComponent(playlist),tracks[i].dir,
|
|
moveto,playlistlength]);
|
|
}
|
|
}
|
|
self.do_command_list(cmds,callback);
|
|
}
|
|
|
|
this.movePlaylistTracks = function(playlist,from,to,callback) {
|
|
var cmds = new Array();
|
|
cmds.push(['playlistmove',decodeURIComponent(playlist),from,to]);
|
|
self.do_command_list(cmds,callback);
|
|
}
|
|
|
|
}
|