Fix video autoplay: register MANIFEST_PARSED before loadSource, use loadedmetadata for MP4/native-HLS
The MANIFEST_PARSED listener was registered after loadSource/attachMedia, so cached manifests could fire the event before the listener was set — meaning tryAutoplay never ran. Fix: register the listener first, then call loadSource. Also switch MP4 and native-HLS paths to play on loadedmetadata (not immediately after load()) which is the earliest safe moment to call play(). Belt-and-suspenders canplay fallback now also explicitly mutes before calling play(). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
e74862a24d
commit
07cee7b481
@ -808,28 +808,34 @@ function getShuffledPrevUrl() {
|
|||||||
|
|
||||||
window._ytpHls = null;
|
window._ytpHls = null;
|
||||||
|
|
||||||
function tryAutoplay() {
|
|
||||||
video.muted = true;
|
|
||||||
video.autoplay = true;
|
|
||||||
video.play().catch(function(){});
|
|
||||||
}
|
|
||||||
|
|
||||||
function initSource() {
|
function initSource() {
|
||||||
video.muted = true;
|
video.muted = true;
|
||||||
video.autoplay = true;
|
video.autoplay = true;
|
||||||
if (HLS_URL && window.Hls && Hls.isSupported()) {
|
if (HLS_URL && window.Hls && Hls.isSupported()) {
|
||||||
window._ytpHls = new Hls({ startLevel: -1 });
|
window._ytpHls = new Hls({ startLevel: -1 });
|
||||||
|
// Register MANIFEST_PARSED before loadSource to avoid cache race condition
|
||||||
|
window._ytpHls.once(Hls.Events.MANIFEST_PARSED, function() {
|
||||||
|
video.muted = true;
|
||||||
|
video.play().catch(function(){});
|
||||||
|
});
|
||||||
window._ytpHls.loadSource(HLS_URL);
|
window._ytpHls.loadSource(HLS_URL);
|
||||||
window._ytpHls.attachMedia(video);
|
window._ytpHls.attachMedia(video);
|
||||||
window._ytpHls.once(Hls.Events.MANIFEST_PARSED, tryAutoplay);
|
|
||||||
} else if (HLS_URL && video.canPlayType('application/vnd.apple.mpegurl')) {
|
} else if (HLS_URL && video.canPlayType('application/vnd.apple.mpegurl')) {
|
||||||
|
// Native HLS (Safari) — set src then play on loadedmetadata
|
||||||
video.src = HLS_URL;
|
video.src = HLS_URL;
|
||||||
video.load();
|
video.load();
|
||||||
|
video.addEventListener('loadedmetadata', function() {
|
||||||
|
video.muted = true;
|
||||||
video.play().catch(function(){});
|
video.play().catch(function(){});
|
||||||
|
}, { once: true });
|
||||||
} else {
|
} else {
|
||||||
|
// Plain MP4 — play on loadedmetadata (canplay/MANIFEST_PARSED don't apply)
|
||||||
video.src = MP4_URL;
|
video.src = MP4_URL;
|
||||||
video.load();
|
video.load();
|
||||||
|
video.addEventListener('loadedmetadata', function() {
|
||||||
|
video.muted = true;
|
||||||
video.play().catch(function(){});
|
video.play().catch(function(){});
|
||||||
|
}, { once: true });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -840,22 +846,26 @@ window._ytpLoadSource = function(hlsUrl, mp4Url) {
|
|||||||
video.autoplay = true;
|
video.autoplay = true;
|
||||||
if (hlsUrl && window.Hls && Hls.isSupported()) {
|
if (hlsUrl && window.Hls && Hls.isSupported()) {
|
||||||
window._ytpHls = new Hls({ startLevel: -1 });
|
window._ytpHls = new Hls({ startLevel: -1 });
|
||||||
window._ytpHls.loadSource(hlsUrl);
|
|
||||||
window._ytpHls.attachMedia(video);
|
|
||||||
window._ytpHls.once(Hls.Events.MANIFEST_PARSED, function() {
|
window._ytpHls.once(Hls.Events.MANIFEST_PARSED, function() {
|
||||||
video.muted = false;
|
video.muted = false;
|
||||||
video.play().catch(function(){});
|
video.play().catch(function(){});
|
||||||
});
|
});
|
||||||
|
window._ytpHls.loadSource(hlsUrl);
|
||||||
|
window._ytpHls.attachMedia(video);
|
||||||
} else if (hlsUrl && video.canPlayType('application/vnd.apple.mpegurl')) {
|
} else if (hlsUrl && video.canPlayType('application/vnd.apple.mpegurl')) {
|
||||||
video.src = hlsUrl;
|
video.src = hlsUrl;
|
||||||
video.load();
|
video.load();
|
||||||
|
video.addEventListener('loadedmetadata', function() {
|
||||||
video.muted = false;
|
video.muted = false;
|
||||||
video.play().catch(function(){});
|
video.play().catch(function(){});
|
||||||
|
}, { once: true });
|
||||||
} else {
|
} else {
|
||||||
video.src = mp4Url;
|
video.src = mp4Url;
|
||||||
video.load();
|
video.load();
|
||||||
|
video.addEventListener('loadedmetadata', function() {
|
||||||
video.muted = false;
|
video.muted = false;
|
||||||
video.play().catch(function(){});
|
video.play().catch(function(){});
|
||||||
|
}, { once: true });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1316,15 +1326,17 @@ function init() {
|
|||||||
sessionStorage.removeItem('ytpMiniState');
|
sessionStorage.removeItem('ytpMiniState');
|
||||||
}
|
}
|
||||||
|
|
||||||
// canplay fires for ALL source types (HLS.js, MP4, Safari native HLS)
|
// canplay is a belt-and-suspenders fallback — also mute before play
|
||||||
// once the browser has enough data to start — most reliable autoplay trigger
|
|
||||||
video.addEventListener('canplay', function autoStart() {
|
video.addEventListener('canplay', function autoStart() {
|
||||||
video.removeEventListener('canplay', autoStart);
|
video.removeEventListener('canplay', autoStart);
|
||||||
if (miniSeekTime > 0) {
|
if (miniSeekTime > 0) {
|
||||||
video.currentTime = miniSeekTime;
|
video.currentTime = miniSeekTime;
|
||||||
miniSeekTime = 0;
|
miniSeekTime = 0;
|
||||||
}
|
}
|
||||||
|
if (video.paused) {
|
||||||
|
video.muted = true;
|
||||||
video.play().catch(() => {});
|
video.play().catch(() => {});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Update duration when metadata is ready
|
// Update duration when metadata is ready
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user