1
0
Fork 0
mirror of https://gitlab.com/futo-org/fcast.git synced 2025-06-24 21:25:23 +00:00

Added workaround for playback stalling with subtitles enabled

This commit is contained in:
Michael Hollister 2024-11-21 02:14:00 -06:00
parent b0c511c18f
commit 90657117ee

View file

@ -104,6 +104,37 @@ let lastPlayerUpdateGenerationTime = 0;
let isLive = false; let isLive = false;
let isLivePosition = false; let isLivePosition = false;
// Dashjs workaround for playback stalling when captions are enabled and user scrubs video beyond the loaded buffer...
let playbackSeeking = false;
let lastSeekTimestamp = 0;
let lastSeekTime = 0;
let bufferStalled = false;
function stallRecoveryCheck(dashPlayer, value) {
// Buffer could have loaded by now, but the player still might be in the stalled state
if (playbackSeeking) {
const lastSeekDelta = Math.abs(Date.now() - lastSeekTimestamp)
if (lastSeekDelta < 5000) {
console.warn('Possible player stall, waiting 5 seconds after last seek...');
window.setTimeout(() => { stallRecoveryCheck(dashPlayer, value); }, 5000 - lastSeekDelta);
}
else {
console.warn('Detected player stall, reloading video in attempt to unstall...');
dashPlayer.initialize(videoElement, `data:${value.container};base64,` + window.btoa(value.content), true, lastSeekTime);
playerPrevTime = 0;
lastPlayerUpdateGenerationTime = 0;
isLive = false;
isLivePosition = false;
playbackSeeking = false;
lastSeekTimestamp = 0;
lastSeekTime = 0;
bufferStalled = false;
}
}
}
window.electronAPI.onPlay((_event, value: PlayMessage) => { window.electronAPI.onPlay((_event, value: PlayMessage) => {
console.log("Handle play message renderer", JSON.stringify(value)); console.log("Handle play message renderer", JSON.stringify(value));
@ -115,6 +146,11 @@ window.electronAPI.onPlay((_event, value: PlayMessage) => {
isLive = false; isLive = false;
isLivePosition = false; isLivePosition = false;
playbackSeeking = false;
lastSeekTimestamp = 0;
lastSeekTime = 0;
bufferStalled = false;
if (player) { if (player) {
if (player.getSource() === value.url) { if (player.getSource() === value.url) {
if (value.time) { if (value.time) {
@ -197,6 +233,39 @@ window.electronAPI.onPlay((_event, value: PlayMessage) => {
document.getElementById("subtitle-" + e.cueID)?.remove(); document.getElementById("subtitle-" + e.cueID)?.remove();
}); });
// Dashjs workaround for playback stalling when captions are enabled and user scrubs video beyond the loaded buffer...
dashPlayer.on(dashjs.MediaPlayer.events.BUFFER_LEVEL_STATE_CHANGED, (e: any) => {
if (player.isCaptionsSupported()) {
if (e.state === 'bufferStalled') {
bufferStalled = true;
}
else if (e.state === 'bufferLoaded') {
bufferStalled = false;
}
if (playbackSeeking && bufferStalled) {
window.setTimeout(() => { stallRecoveryCheck(dashPlayer, value); }, 5000);
}
}
});
dashPlayer.on(dashjs.MediaPlayer.events.PLAYBACK_SEEKING, (e: any) => {
if (player.isCaptionsSupported()) {
playbackSeeking = true;
lastSeekTimestamp = Date.now();
lastSeekTime = e.seekTime;
}
});
dashPlayer.on(dashjs.MediaPlayer.events.PLAYBACK_SEEKED, (e: any) => {
if (player.isCaptionsSupported()) {
playbackSeeking = false;
lastSeekTimestamp = 0;
lastSeekTime = 0;
}
});
dashPlayer.updateSettings({ dashPlayer.updateSettings({
// debug: { // debug: {
// logLevel: dashjs.LogLevel.LOG_LEVEL_INFO // logLevel: dashjs.LogLevel.LOG_LEVEL_INFO
@ -421,7 +490,7 @@ function playerCtrlStateUpdate(event: PlayerControlEvent) {
if (player.isCaptionsEnabled()) { if (player.isCaptionsEnabled()) {
videoCaptions.setAttribute("style", "display: block; bottom: 75px;"); videoCaptions.setAttribute("style", "display: block; bottom: 75px;");
} else { } else {
videoCaptions.setAttribute("style", "display: block; bottom: 75px;"); videoCaptions.setAttribute("style", "display: none; bottom: 75px;");
} }
@ -434,7 +503,7 @@ function playerCtrlStateUpdate(event: PlayerControlEvent) {
if (player.isCaptionsEnabled()) { if (player.isCaptionsEnabled()) {
videoCaptions.setAttribute("style", "display: block; bottom: 160px;"); videoCaptions.setAttribute("style", "display: block; bottom: 160px;");
} else { } else {
videoCaptions.setAttribute("style", "display: block; bottom: 160px;"); videoCaptions.setAttribute("style", "display: none; bottom: 160px;");
} }
break; break;