Search code examples
reactjsreact-nativeexpoexpo-av

Expo AV Video Component — Loop Part of Video


Can I loop the last X seconds of a Video using Expo AV's Video component? For example, say I have a 15s video. I want it to play out fully, but then loop starting at 5s.

I supposed I could achieve the same effect by splitting the video into two videos and then looping the second video only. However, I tried this and had a lag between playing the first and second videos. Let me know if you have ideas!


Solution

  • To achieve this, you will use only one Video component and override the default looping by giving your Video component a callback function to create an artificial loop by using playFromPositionAsync.

    1. Create a reference to the video that will play

      let video : Video | null; //add type if using typescript
      
    2. Create the video component and give a playback function .

      <Video 
      ref={(r) => {video = r}} //set the video reference  
      source={{uri: uri}}
      isLooping={false} 
      useNativeControls={false} //to not use native play pause... buttons
      shouldPlay //if you want your video to play automatically the first time
      progressUpdateIntervalMillis={100} //the playback update function below will fire every 100ms
      onPlaybackStatusUpdate={_onPlaybackStatusUpdate} />
      
    3. Define the playback function

       const _onPlaybackStatusUpdate = (status: AVPlaybackStatus)=>{
        if (status.isLoaded){ //video is loaded without error
          if (status.didJustFinish){ //fired only once when video ends
            video?.playFromPositionAsync(10000, { toleranceMillisBefore: 0, toleranceMillisAfter: 0 }); //start at 10sec with 0 tolerance (starts exactly at 10sec)
           }
         }
       }
      

    What happens here is your playing your video from 10 sec whenever the end of the video is reached. Note that didJustFinish only fires once but you should get frequent updates to check if the playback has in fact ended, hence progressUpdateIntervalMillis. Without this, the finish event will be false in the beginning of the video and the loop won't start.