Jot*_*nan 0 reactjs react-native
我在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',
},
});
Run Code Online (Sandbox Code Playgroud)
我需要对此有所了解,我们有一个要使用的播放器引用,还有 swiper 组件具有onIndexChanged,当我们移动到下一个视频时会触发它,我们如何将播放器的引用链接到onIndexChanged以及何时滑动我们如何制作它当前视频只能播放?
根据安德鲁的建议,我也使用了 InPortView 组件来确定滑动的当前视图,但我仍然不确定如何参考要在播放和暂停相关视频的功能中使用的视频元素。
使用的组件:
对于 Swiper :react-native-swiper
使用 Expo 示例更新完整代码:Expo Snack
所以带上你的零食。我设法让它工作。
我将 Video 移到它自己的组件中,并向它传递了一些额外的 props,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>
)
}
}
Run Code Online (Sandbox Code Playgroud)
视频组件用于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>
)
}
}
Run Code Online (Sandbox Code Playgroud)
当我InViewPort单独使用该组件时,它似乎认为位置 6 的视频在视口中并且会播放它。因此,我使用的InviewPort是执行检查以将index视频与currentIndex是否匹配播放视频进行比较,否则将暂停。我想这可以更新以用于componentDidUpdate处理道具的变化。但是,当组件安装时需要执行额外的检查,以便它不播放视频。
这是我的小吃,它起作用了。https://snack.expo.io/@andypandy/swiper-video
| 归档时间: |
|
| 查看次数: |
5009 次 |
| 最近记录: |