diff options
Diffstat (limited to 'src/view/com/util/post-embeds/VideoEmbedInner/VideoEmbedInnerWeb.tsx')
-rw-r--r-- | src/view/com/util/post-embeds/VideoEmbedInner/VideoEmbedInnerWeb.tsx | 46 |
1 files changed, 36 insertions, 10 deletions
diff --git a/src/view/com/util/post-embeds/VideoEmbedInner/VideoEmbedInnerWeb.tsx b/src/view/com/util/post-embeds/VideoEmbedInner/VideoEmbedInnerWeb.tsx index fa2b7e3d3..ef989c4a4 100644 --- a/src/view/com/util/post-embeds/VideoEmbedInner/VideoEmbedInnerWeb.tsx +++ b/src/view/com/util/post-embeds/VideoEmbedInner/VideoEmbedInnerWeb.tsx @@ -33,7 +33,6 @@ export function VideoEmbedInnerWeb({ } const hlsRef = useHLS({ - focused, playlist: embed.playlist, setHasSubtitleTrack, setError, @@ -113,14 +112,12 @@ promiseForHls.then(Hls => { }) function useHLS({ - focused, playlist, setHasSubtitleTrack, setError, videoRef, setHlsLoading, }: { - focused: boolean playlist: string setHasSubtitleTrack: (v: boolean) => void setError: (v: Error | null) => void @@ -155,8 +152,8 @@ function useHLS({ if (!hlsRef.current) return const hls = hlsRef.current - if (focused && hls.nextAutoLevel > 0) { - // if the current quality level goes above 0, flush the low quality segments + // if the current quality level goes above 0, flush the low quality segments + if (hls.nextAutoLevel > 0) { const flushed: HlsTypes.Fragment[] = [] for (const lowQualFrag of lowQualityFragments) { @@ -179,6 +176,29 @@ function useHLS({ }, ) + const flushOnLoop = useNonReactiveCallback(() => { + if (!Hls) return + if (!hlsRef.current) return + const hls = hlsRef.current + // the above callback will catch most stale frags, but there's a corner case - + // if there's only one segment in the video, it won't get flushed because it avoids + // flushing the currently active segment. Therefore, we have to catch it when we loop + if ( + hls.nextAutoLevel > 0 && + lowQualityFragments.length === 1 && + lowQualityFragments[0].start === 0 + ) { + const lowQualFrag = lowQualityFragments[0] + + hls.trigger(Hls.Events.BUFFER_FLUSHING, { + startOffset: lowQualFrag.start, + endOffset: lowQualFrag.end, + type: 'video', + }) + setLowQualityFragments([]) + } + }) + useEffect(() => { if (!videoRef.current) return if (!Hls) return @@ -197,16 +217,14 @@ function useHLS({ hls.attachMedia(videoRef.current) hls.loadSource(playlist) - // initial value, later on it's managed by Controls - hls.autoLevelCapping = 0 - // manually loop, so if we've flushed the first buffer it doesn't get confused const abortController = new AbortController() const {signal} = abortController const videoNode = videoRef.current videoNode.addEventListener( 'ended', - function () { + () => { + flushOnLoop() videoNode.currentTime = 0 videoNode.play() }, @@ -248,7 +266,15 @@ function useHLS({ hls.destroy() abortController.abort() } - }, [playlist, setError, setHasSubtitleTrack, videoRef, handleFragChange, Hls]) + }, [ + playlist, + setError, + setHasSubtitleTrack, + videoRef, + handleFragChange, + flushOnLoop, + Hls, + ]) return hlsRef } |