使用 Swiper 组件播放暂停问题反应原生多视频
Posted
技术标签:
【中文标题】使用 Swiper 组件播放暂停问题反应原生多视频【英文标题】:react native multiple video with Swiper component play pause issue 【发布时间】:2019-02-23 17:00:54 【问题描述】:我在滑动器中有多个视频,可以一个一个地显示视频,但是所有视频都同时加载和播放,并且音频混乱,我希望一次只播放当前视频。
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
,当我们滑动时,我们如何让它当前视频只播放?
根据 Andrew 的建议,我也使用 InPortView 组件来确定滑动的当前视图,但我仍然不确定如何为要在播放和暂停关注视频的功能中使用的视频元素提供参考。
使用的组件:
对于视频react-native-video
刷卡者:react-native-swiper
使用 Expo 示例更新了完整代码:Expo Snack
【问题讨论】:
查看我对这篇帖子的回答 ***.com/a/54844767/5508175 虽然它使用平面列表,但我认为它可以适应您的情况。 但是你只有一个视频,我有多个视频。 快完成了,对于单个视频它工作正常,但是当我们有多个视频时,它会从该视频停止的地方播放相同的视频 我不确定你的意思。 我的意思是我们如何让它与多个视频一起工作? 【参考方案1】:所以带上你的零食。我设法让它工作。
我将视频移出到它自己的组件中,并向它传递了一些额外的道具,数组中的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
【讨论】:
不用担心。我很高兴它对你有用。这不是一个完美的解决方案,但它似乎可以完成这项工作。我看了一下尝试使用componentDidMount
和 componentDidUpdate
而不是使用 InViewPort
组件,但它仍然在索引 0 上播放视频。我相信可以用它们来做,但它会进一步调查。
得到结果后请及时更新,非常有帮助。作为一个新手,我需要知道我们可以采取什么方法来完成这项工作。请
不确定这是否会随着钩子而改变,但是当应用道具 onIndexChanged 时,我会在堆栈上看到最后一个屏幕,并带有丑陋的闪光灯以上是关于使用 Swiper 组件播放暂停问题反应原生多视频的主要内容,如果未能解决你的问题,请参考以下文章
使用 react-native-video (Android) 在加载和视频播放之间反应原生黑屏一秒钟