3

i am implementing video gallery app using React-Native FlatList, While making the app i had a problem with video pause and play modes, I want to play the video only when the video is fully visible, i tried with different Technics but they are not working properly , Once check my below code..

export default class HomeScreen extends Component {
  _isMounted = false;
  constructor(Props) {
    super(Props);
    this.state = {
      error: null,
      isLoading: false,

      playing: false,
      currentTime: 10,
      duration: 0,
      isFullScreen: false,
      isLoading: true,
      paused: true,
      playerState: PLAYER_STATES.PLAYING,
      screenType: 'content',

    };

    this.viewabilityConfig = {
      waitForInteraction: true,
      viewAreaCoveragePercentThreshold: 95
    }


  }
  onViewableItemsChanged = ({ viewableItems, changed }) => {
    console.log("Visible items are", viewableItems);
    console.log("Changed in this iteration", changed);
  }




 render() {
    const { duration, paused, overlay } = this.state

    return (
      <View style={styles.container}>        

         <FlatList style={styles.list}
                data={this.state.following_Posts}
                // keyExtractor={(item, index) => index.toString()}
                keyExtractor={(data_Posts, index) => {
                  return data_Posts.id.toString();
                }}
                ItemSeparatorComponent={() => { return (<View style={styles.separator} />) }}

               // viewabilityConfig={{ viewAreaCoveragePercentThreshold: 95 }}
              viewabilityConfig={this.viewabilityConfig}

              onViewableItemsChanged={this.onViewableItemsChanged}
              viewabilityConfig={{
                itemVisiblePercentThreshold: 95
              }}

                refreshing={this.state.isLoading}
                onRefresh={this.getFollowingPosts}
                renderItem={(posts, id) => {
                  const items = posts.item;
                  return (
                    <View style={styles.card}>                    

                      <View style={styles.cardContent}>
                        {items.file_Name.toString().endsWith("mp4") ?
                          <View>
                            <Video
                              onEnd={this.onEnd}
                              onLoad={this.onLoad}
                              onLoadStart={this.onLoadStart}
                              onProgress={this.onProgress}
                              paused={this.state.paused}
                              ref={videoPlayer => (this.videoPlayer = videoPlayer)}
                              onFullScreen={this.state.isFullScreen}
                              resizeMode="cover"
                              volume={10}
                              source={{ uri: "http://192.168.1.3:3200/" + items.file_Name }}
                              style={{ width: '100%', height: '100%', top: 0, left: 0, bottom: 0, right: 0, }}

                            />
                            <MediaControls
                              duration={this.state.duration}
                              isLoading={this.state.isLoading}
                              mainColor="#333"
                              onFullScreen={this.onFullScreen}
                              onPaused={this.onPaused}
                              onReplay={this.onReplay}
                              onSeek={this.onSeek}
                              onSeeking={this.onSeeking}
                              playerState={this.state.playerState}
                              progress={this.state.currentTime}
                              toolbar={this.renderToolbar()}
                            />
                          </View>
                       </View>
      />
   </View>
  )
 }


i am also tried with FlatList viewabilityConfig

              viewabilityConfig={this.viewabilityConfig}

              onViewableItemsChanged={this.onViewableItemsChanged}
              viewabilityConfig={{
                itemVisiblePercentThreshold: 95
              }}

So if any one know the solution lease tell me

Sivasankar chimata
  • 311
  • 1
  • 16
  • 31

1 Answers1

0
I struggled with this a bit and could not find the right answer that fit my scenario. I noticed a library that probably would have worked but was out of date. So I came up with something that really works nicely for my scenario and is quite simple to implement. I found a combination of shouldComponentUpdate and onViewableItemsChanged could easily solve the video play in viewport issue. I have pasted the relevant code below;

class Post extends Component {
    constructor(props) {
        super(props);
        this.video = React.createRef();        
    }
    shouldComponentUpdate(nextProps, nextState) {
       this.props.visibleURIS[0] == this.props.video_url || 
       this.props.visibleURIS[1] == this.props.video_url || 
       this.props.visibleURIS[2] == this.props.video_url
    }
    render() {
     <View>
       var image_video = 'image';
       return (
       {this.videoSection(image_video,uripath+item_url,this.props.visibleURIS)}
     </View>
    }
    videoSection = (image_video, uri, visibleURIS) => {
        if (image_video == 'video') {
            return (
                <View style={styles.containerVideo}>
                    <Video
                        ref={this.state.video}
                        style={styles.video}
                        source={{
                            uri
                        }}
                        useNativeControls
                        resizeMode="contain"
                        isLooping={true}
                        shouldPlay={uri == uripath + visibleURIS[0] || uri == 
                        uripath + visibleURIS[1] || uri == uripath + 
                        visibleURIS[2] ? true : false}
                    />
                </View>
            )
        }
    };   
}
export default class ProfileView extends PureComponent {
    constructor(props) {
        super(props);
        this.state = {
           visibleURIS: '',
        };
    }
ItemComponentSocial = ({ item, index }) => {
        const { username  } = item     
        return (
            <Post  
                index={index} 
                username={username}               
                visibleURIS={this.state.visibleURIS}
            />      
        )
    }
onViewableItemsChanged = ({ viewableItems, changed }) => {
        const viewable = [];
        if (viewableItems[0] && viewableItems[0].item.video_url != '') {
            viewable.push(viewableItems[0].item.video_url);
        }
        if (viewableItems[1] && viewableItems[1].item.video_url != '') {
            viewable.push(viewableItems[1].item.video_url);
        }
        if (viewableItems[2] && viewableItems[2].item.video_url != '') {
            viewable.push(viewableItems[2].item.video_url);
        }
        this.setState({
            visibleURIS: viewable,
        });
    };
render() {       
        return (
                <View >
                    <SafeAreaView style={styles.flashlistDetail}>
                    <FlatList
                        onViewableItemsChanged= {this.onViewableItemsChanged}
                        showsVerticalScrollIndicator={false}
                        contentContainerStyle={{ paddingBottom: 20 }}
                        data={Object.values(this.state.dataDetail)}
                        renderItem={this.ItemComponentSocial}
                        keyExtractor={(item, postid) => postid}
                        onEndReached={() => this.socialhandleEnd()}
                        onEndReachedThreshold={0}
                        initialNumToRender={5}
                        estimatedItemSize={8000}
                        ListEmptyComponent={this.EmptyListMessageSocial}
                        horizontal={false}
                        ItemSeparatorComponent={this.renderSeparator}
                        ListHeaderComponent={this.renderHeader}
                        ListFooterComponent={this.renderFooter}
                        />
                    </SafeAreaView >
                    <StatusBar style="auto" />
                </View>
        );
    }
}
const styles = StyleSheet.create({
    containerVideo: {
        flex: 1,
        justifyContent: 'center',
        //top: 318,
    },
    video: {
        alignSelf: 'center',
        width: windowWidth,
        height: windowHeight * .80,
    },
}