我在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组件来确定当前的滑动视图,但我仍然不确定如何为视频元素提供参考,以便在播放功能中使用并暂停关注视频。
使用的组件:
对于Swiper:react-native-swiper
使用Expo示例更新完整代码:Expo Snack
所以带上你的零食。我设法让它发挥作用。
我将视频移动到它自己的组件中并传递了一些额外的道具,阵列中的index
和currentIndex
显示。
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
的方法是执行检查以比较视频的index
和currentIndex
,如果它们匹配播放视频,否则暂停。我想这可以更新为使用componentDidUpdate
来处理道具的变化。但是,当组件安装时,需要执行其他检查,以便它不播放视频。
这是我的小吃,它的工作。 https://snack.expo.io/@andypandy/swiper-video