Work around play queue not going to the next song automatically

This commit works around a race caused by some of our JS code trying to
run play() for the next song while the MEJS player is still cleaning up
the last song.

MEJS issue: https://github.com/mediaelement/mediaelement/issues/2650
master
François-Xavier Thomas 6 years ago
parent 767b39ed5b
commit 5a72322772
  1. 63
      airsonic-main/src/main/webapp/WEB-INF/jsp/playQueue.jsp

@ -52,7 +52,7 @@
} }
}}); }});
<c:if test="${model.player.web}">createPlayer();</c:if> <c:if test="${model.player.web}">createMediaElementPlayer();</c:if>
$("#playlistBody").sortable({ $("#playlistBody").sortable({
stop: function(event, ui) { stop: function(event, ui) {
@ -145,8 +145,21 @@
onNext(repeatEnabled); onNext(repeatEnabled);
} }
function createPlayer() { function createMediaElementPlayer() {
$('#audioPlayer').get(0).addEventListener("ended", onEnded);
var player = $('#audioPlayer').get(0);
// Once playback reaches the end, go to the next song, if any.
player.addEventListener("ended", onEnded);
// FIXME: Remove once https://github.com/mediaelement/mediaelement/issues/2650 is fixed.
//
// Once a media is loaded, we can start playback, but not before.
//
// Trying to start playback after a song has endred but before the
// 'canplay' event for the next song currently causes a race condition
// in the MediaElement.js player (4.2.10).
player.addEventListener("canplay", function() { player.play(); });
} }
function getPlayQueue() { function getPlayQueue() {
@ -532,6 +545,40 @@
} }
} }
function loadMediaElementPlayer(song, position) {
var player = $('#audioPlayer').get(0);
// Is this a new song?
if (player.src != song.streamUrl) {
// Stop the current playing song and change the media source.
player.src = song.streamUrl;
// Inform MEJS that we need to load a new media source. The
// 'canplay' event will be fired once playback is possible.
player.load();
// The 'skip' function takes a 'position' argument. We don't
// usually send it, and in this case it's better to do nothing.
// Otherwise, the 'canplay' event will also be fired after
// setting 'currentTime'.
if (position && position > 0) {
player.currentTime = position;
}
// Are we seeking on an already-playing song?
} else {
// Seeking also starts playing. The 'canplay' event will be
// fired after setting 'currentTime'.
player.currentTime = position || 0;
}
// FIXME: Uncomment once https://github.com/mediaelement/mediaelement/issues/2650 is fixed.
//
// Calling 'player.play()' at this point may work by chance, but it's
// not guaranteed in the current MediaElement.js player (4.2.10). See
// the 'createMediaElementPlayer()' function above.
//
// player.play();
}
function skip(index, position) { function skip(index, position) {
if (index < 0 || index >= songs.length) { if (index < 0 || index >= songs.length) {
return; return;
@ -541,16 +588,12 @@
currentStreamUrl = song.streamUrl; currentStreamUrl = song.streamUrl;
updateCurrentImage(); updateCurrentImage();
// Handle ChromeCast player.
if (CastPlayer.castSession) { if (CastPlayer.castSession) {
CastPlayer.loadCastMedia(song, position); CastPlayer.loadCastMedia(song, position);
// Handle MediaElement (HTML5) player.
} else { } else {
if ($('#audioPlayer').get(0).src != song.streamUrl) { loadMediaElementPlayer(song, position);
$('#audioPlayer').get(0).src = song.streamUrl;
$('#audioPlayer').get(0).load();
console.log(song.streamUrl);
}
$('#audioPlayer').get(0).currentTime = position ? position : 0;
$('#audioPlayer').get(0).play();
} }
updateWindowTitle(song); updateWindowTitle(song);

Loading…
Cancel
Save