about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/view/com/util/post-embeds/VideoEmbedInner/VideoEmbedInnerWeb.tsx46
-rw-r--r--src/view/com/util/post-embeds/VideoEmbedInner/web-controls/VideoControls.tsx3
2 files changed, 36 insertions, 13 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
 }
diff --git a/src/view/com/util/post-embeds/VideoEmbedInner/web-controls/VideoControls.tsx b/src/view/com/util/post-embeds/VideoEmbedInner/web-controls/VideoControls.tsx
index dd0dafc33..acd4d1aae 100644
--- a/src/view/com/util/post-embeds/VideoEmbedInner/web-controls/VideoControls.tsx
+++ b/src/view/com/util/post-embeds/VideoEmbedInner/web-controls/VideoControls.tsx
@@ -138,13 +138,10 @@ export function Controls({
   useEffect(() => {
     if (!hlsRef.current) return
     if (focused) {
-      // auto decide quality based on network conditions
-      hlsRef.current.autoLevelCapping = -1
       // allow 30s of buffering
       hlsRef.current.config.maxMaxBufferLength = 30
     } else {
       // back to what we initially set
-      hlsRef.current.autoLevelCapping = 0
       hlsRef.current.config.maxMaxBufferLength = 10
     }
   }, [hlsRef, focused])