Search code examples
reactjsreact-nativereact-native-video

When a video had stopped, other video stopped simultaneously in react native video


I have developed react-native cli, react-native-video (Currently, tried to expo-video).

In a screen, there are one flatList, it has a renderItem(column2). In a renderItem renders image or video thumbnail. Like shopping app UI AMAZON.

The problem is videos. It will stops automatically by user's swipe down to phone's view. Simultaneously, below stopped video, other video player will stops. This video is in exactly middle of user's phone view!

How can i solve this?

  1. FlatList,

const [videoPlayback, setVideoPlayback] = useState(false);
 const viewabilityConfig = {
    itemVisiblePercentThreshold: 80,
  };

  const _onViewableItemsChanged = useCallback((props) => {
    const changed = props.changed;
    changed.forEach((item) => {
      if (item.item.vimeoId) {
        if (item.isViewable) {
          setVideoPlayback((prev) => true);
        } else {
          setVideoPlayback((prev) => false);
        }
      }
    });
  }, []);
...
      <FlatList
        ref={ref}
        numColumns={2}
        data={posts}
        keyExtractor={(item: any) => `${item.postId}`}
        viewabilityConfig={viewabilityConfig}
        onViewableItemsChanged={_onViewableItemsChanged}
        renderItem={({ item, index }) => (
          <PostContainer item={item} videoPlayback={videoPlayback} navigation={navigation} index={index} />
        )}

  1. PostContainer
const PostContainer = ({ item, videoPlayback }) => {
  const videoPlayer = useRef(null);

  useFocusEffect(
    React.useCallback(() => {
      videoPlayer?.current?.seek(0);

      if (videoPlayer && !videoPlayback) {
        videoPlayer?.current?.seek(0);
      }
    }, [fadeAnim, videoPlayback]),
  );

  return (
    <View>

      { // This place that image component rendered}

      {item.vimeoId && (
        <StyledVideo
          ref={videoPlayer}
          paused={!videoPlayback}
          repeat={true}
          resizeMode={"cover"}
          volume={0}
          source={{
            uri: item.vimeoThumbnail,
          }}
        />
      )}
    </View>
  );
};


Solution

  • I solved my problem. There are no fault in my logic. the important thing is 'What videos are current playing?'

    1. FlatList
      const _onViewableItemsChanged = useCallback(
        (props) => {
          const changed = props.changed;
          changed.forEach((item) => {
            if (item.item.vimeoId) {
              const tempId = item.item.vimeoId;
    
              if (item.isViewable) {
                if (readVideosVar.list.indexOf(tempId) === -1) {
                  dispatch(postSlice.actions.addId(tempId));
                }
              } else {
                dispatch(postSlice.actions.deleteId(tempId));
              }
            }
          });
        },
        [dispatch],
      );
    
    1. redux
        addId: (state, action) => {
          if (state.list.indexOf(action.payload) !== -1) {
            return;
          } else {
            let tempA = [];
            tempA.push(action.payload);
            state.list = state.list.concat(tempA);
          }
        },
        deleteId: (state, action) => {
          if (state.list.indexOf(action.payload) === -1) {
            return;
          } else {
            let stand = state.list;
            let findIdx = stand.indexOf(action.payload);
            let leftA = stand.slice(0, findIdx);
            let rightA = stand.slice(findIdx + 1);
            state.list = leftA.concat(rightA);
          }
        },
    

    Compared to the existing code, I had added 'redux-toolkit'. In dispatch logic, "onViewalbeItems" had tracked chagend viewable items by real-time.

    And then, I also added,

    export const viewabilityConfig = {
      minimumViewTime: 1000,
      viewAreaCoveragePercentThreshold: 0,
    };
    
    

    This is just sugar.

    I solved it like this !