0

I was trying to create an app that loads videos from an ARRAY on loop. I am using UseState to change the URI index after the video ends.
The player works perfectly for around 1-2 hours then it freezes the video and throws onError() which gives player error null and sometimes Player release time out.
I am thinking that it might be happening because of useState because it re-renders the component every time when index changes. Maybe this could be memory leakage or something else I am not sure.

please help me I seriously spent a week to find the solution. I even tried caching the videos using the filesystem. but still, it doesn't stop freezing.


const VideoPlayer = ({ wholeResult }) => {
  const focuspoint = React.useRef(null);
  const [index, setIndex] = React.useState(0);
  const [progress, setProgress] = React.useState(false);

  React.useEffect(() => {
    if (wholeResult !== undefined) {
      setProgress(true);
    }
  }, []);

  const navigation = useNavigation();
  return (
    <View style={styles.container}>
      <TouchableOpacity
        onLongPress={() => {
          navigation.navigate("Home");
        }}
        delayLongPress={3000}
      >
        {progress &&
        wholeResult[index] !== "" &&
        wholeResult[index] !== undefined
          ? <Video
          ref={focuspoint}
          style={styles.video}
          source={{
            uri: wholeResult.length == 1 ? wholeResult[0] : wholeResult[index],
          }}
          useNativeControls={false}
          shouldPlay
          resizeMode="stretch"
          isLooping={wholeResult.length == 1 ? true : false}
          onError={(error) => 
            alert(error)
          }
          onPlaybackStatusUpdate={(status) =>
            status?.didJustFinish == true
              ? setIndex((idx) => (idx == wholeResult.length - 1 ? 0 : idx + 1))
              : null
          }
        />
          : null}
      </TouchableOpacity>
    </View>
  );
};

export default VideoPlayer;

EDIT: I think this is the issue with expo-av only or it might be a bug with it. I tried with imageBackground and it's working is perfectly with the same pattern of code.

1 Answers1

0

Answering my Own Question
So I couldn't find the solution to this problem but I got a trick to play, I used Webview to run Html containing a video looping function. But I have to use some parameters that could run in every device by enabling hardware acceleration. and it works for me.

 <WebView
         style={styles.container}
         originWhitelist={["*"]}
         allowFileAccess={true}
         allowUniversalAccessFromFileURLs={true}
         allowFileAccessFromFileURLs={true}
         javaScriptEnabled={true}
         domStorageEnabled={true}
         allowsFullscreenVideo={true}
         mixedContentMode='always'
         androidLayerType="hardware"
         androidHardwareAccelerationDisabled={false}
         mediaPlaybackRequiresUserAction={false}
        source={{
          html: `<!DOCTYPE html>

      <html lang="en">
        <head>
          <meta charset="UTF-8" />
          <meta http-equiv="X-UA-Compatible" content="IE=edge" />
          <meta name="viewport" content="width=device-width, initial-scale=1.0" />
          <title>Document</title>
          <style>
            body {
              margin: 0;
              padding: 0;
              overflow: hidden;
              box-sizing: border-box;
              background: #000;
            }
            video {
              width: 100vw;
              height: 100vh;
              object-fit: cover;
            }
          </style>
        </head>
        
        <body>
          <video id="myVideo" autoplay muted></video>
          <script>
            var videoSource = new Array();
            videoSource = ${JSON.stringify(vid)};
            
            var videoCount = videoSource.length;
            var elem = document.getElementById("myVideo");
            if (elem.requestFullscreen) {
              elem.requestFullscreen();
            } else if (elem.mozRequestFullScreen) {
              elem.mozRequestFullScreen();
            } else if (elem.webkitRequestFullscreen) {
              elem.webkitRequestFullscreen();
            } else if (elem.msRequestFullscreen) {
              elem.msRequestFullscreen();
            }
            document.getElementById("myVideo").setAttribute("src", videoSource[0]);
      
            function videoPlay(videoNum) {
              document
                .getElementById("myVideo")
                .setAttribute("src", videoSource[videoNum]);
              document.getElementById("myVideo").load();
              document.getElementById("myVideo").play();
            }
            document
              .getElementById("myVideo")
              .addEventListener("ended", myHandler, false);
            var incr = (function () {
              var i = 0;
      
              return function () {
                if (i > videoCount - 1) {
                  i = 0;
                }
                return i++;
              };
            })();
            function myHandler() {
              videoPlay(incr());
            }
          </script>
        </body>
      </html>
      `,
        }}
      />