将原生多视频与Swiper组件播放暂停问题进行反应

问题描述 投票:0回答:1

我在swiper中有多个视频逐个显示视频,但是所有的视频都是同时加载和播放的,音频搞砸了,我希望一次播放当前的视频。

import * as React from 'react';
import { Text, View, StyleSheet,Image, Dimensions } from 'react-native';
import { Constants } from 'expo';
import { Video } from 'expo';
import Swiper from './Swiper';
import InViewPort from './InViewport';
const screenWidth = Dimensions.get('window').width ;
const screenHeight = Dimensions.get('window').height;

export default class App extends React.Component {
  constructor(props) {
    super(props);
    // Your source data
    this.state = {
      images: {},
      muted : false,
      paused: true,
    };
    this.player = Array();
    this.onChangeImage = this.onChangeImage.bind(this);
  }

   videoError(err){
     console.warn(err);
   }

   pauseVideo = () => {
     var curr = this.state.currentIndex;
     console.warn(curr);
     if(this.player[curr]) {
       this.setState({paused: true });
     }
   }

   playVideo = () => {
     var curr = this.state.currentIndex;
     console.warn(curr);
     if(this.player[curr]) {
     this.setState({paused: false});
     }
   }

   handlePlaying = (isVisible) => {
     isVisible ? this.playVideo() : this.pauseVideo();
   }


  onChangeImage (index) {
     this.setState({ currentIndex: index});
   }


  render() {
   let items = Array.apply(null, Array(15)).map((v, i) => {
      return {
        id: i,
        caption: i + 1,
        source: { uri: 'http://placehold.it/200x200?text=' + (i + 1) },
        dimension: '{ width: 150, height: 150 }',
      };
    });
      return(
        <View style={styles.DefaultView}>
          <Swiper
          showsPagination={false}
          onIndexChanged={this.onChangeImage}
          index={0}
          >
           {items.map((item, key) => {
             if(key==1 || key ==5){
               return (
                 <InViewPort onChange={this.handlePlaying} key={key}>
                  <Video onError={this.videoError}
                   muted={this.state.muted}
                   paused={this.state.paused}
                   source={{uri: 'http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4' }}
                   style={styles.backgroundVideo}
                   ref={(ref) => {
                      this.player[key] = ref;
                    }}
                    controls={true}
                   />
                  </InViewPort>
               )
             }else{
               return(
                 <Image
                   resizeMode='contain'
                   style={{width:screenWidth, height: screenHeight}}
                   source={item.source}
                   key={key}
               />
              )
             }
           })}
         </Swiper>
         </View>
      )
  }
}

const styles = StyleSheet.create({
    scrollView: {
        flex: 1,
        flexDirection: 'row',
    },
    DefaultView: {
        flex: 1,
        backgroundColor: '#000',
        width: screenWidth,
        justifyContent:'center',
        alignItems:'center'
    },
    iconContainer: {
      flexDirection: "row",
      justifyContent: "space-evenly",
      width: 150,
    },
    backgroundVideo: {
      position: 'absolute',
      top: 0,
      left: 0,
      bottom: 0,
      right: 0,
      width: screenWidth,
      height: 300,
      marginTop:'50%',
      position:'absolute',
  },
});

我需要一些想法,我们有一个玩家参考使用,swiper组件有onIndexChanged,当我们转移到下一个视频时会触发,我们如何将玩家的参考链接到onIndexChanged以及当我们刷我们如何制作时它目前的视频只能播放?

根据安德鲁的建议,我已经使用了InPortView组件来确定当前的滑动视图,但我仍然不确定如何为视频元素提供参考,以便在播放功能中使用并暂停关注视频。

使用的组件:

对于视频react-native-video

对于Swiper:react-native-swiper

使用Expo示例更新完整代码:Expo Snack

reactjs react-native
1个回答
1
投票

所以带上你的零食。我设法让它发挥作用。

我将视频移动到它自己的组件中并传递了一些额外的道具,阵列中的indexcurrentIndex显示。

export default class App extends React.Component {
  constructor(props) {
    super(props);
    // Your source data
    this.state = {
      images: {},
      muted : false,
      paused: true,
      currentIndex: 0
    };
  }

  onChangeImage = (index) => {
     console.log('currentIndex ', index)
     this.setState({ currentIndex: index});
   }

  render() {
   let items = Array.apply(null, Array(15)).map((v, i) => {
      return {
        id: i,
        caption: i + 1,
        source: { uri: 'http://placehold.it/200x200?text=' + (i + 1) },
        dimension: '{ width: 150, height: 150 }',
      };
    });
      return(
        <View style={styles.DefaultView}>
          <Swiper
          showsPagination={false}
          onIndexChanged={this.onChangeImage}
          index={0}
          >
           {items.map((item, key) => {
             if(key==1 || key ==5){
               return (
                 <VideoPlayer key={key} index={key} currentIndex={this.state.currentIndex}/>
               )
             }else{
               return(
                 <Image
                   resizeMode='contain'
                   style={{width:screenWidth, height: screenHeight}}
                   source={item.source}
                   key={key}
               />
              )
             }
           })}
          </Swiper>
         </View>
      )
  }
}

视频组件使用react-native-inviewport来帮助处理它是否在视口中。然而它与react-native-swiper不能很好地融合,但它有可能让它发挥作用。

export default class VideoPlayer extends React.Component {

  pauseVideo = () => {
    if(this.video) {
      this.video.pauseAsync();
    }
  }

  playVideo = () => {
    if(this.video) {
      this.video.playAsync();
    }
  }

  handlePlaying = (isVisible) => {
    this.props.index === this.props.currentIndex ?  this.playVideo() : this.pauseVideo();
  }

  render() {
      return (
        <View style={styles.container}>
          <InViewPort onChange={this.handlePlaying}>
            <Video
              ref={ref => {this.video = ref}}
              source={{ uri: 'http://d23dyxeqlo5psv.cloudfront.net/big_buck_bunny.mp4' }}
              rate={1.0}
              volume={1.0}
              isMuted={false}
              resizeMode="cover"
              shouldPlay
              style={{ width: WIDTH, height: 300 }}
            />
          </InViewPort>
        </View>
      )
  }  
}

当我单独使用InViewPort组件时,它似乎认为位置6中的视频位于视口中并将播放它。所以我使用InviewPort的方法是执行检查以比较视频的indexcurrentIndex,如果它们匹配播放视频,否则暂停。我想这可以更新为使用componentDidUpdate来处理道具的变化。但是,当组件安装时,需要执行其他检查,以便它不播放视频。

这是我的小吃,它的工作。 https://snack.expo.io/@andypandy/swiper-video

© www.soinside.com 2019 - 2024. All rights reserved.