react-native-video 中的 OnBuffer 道具不起作用
Posted
技术标签:
【中文标题】react-native-video 中的 OnBuffer 道具不起作用【英文标题】:OnBuffer props in react-native-video is not working 【发布时间】:2020-05-29 07:43:40 【问题描述】:我正在使用 react-native-video 播放来自 url 的视频。如果视频正在缓冲,我正在使用 onBuffer 道具显示加载程序。但就我而言,onBuffer 不起作用。如果视频大小很大,那么在网络速度慢或网络不稳定的情况下,视频播放需要时间,所以如果视频没有播放但处于缓冲模式,我想显示加载器。
【问题讨论】:
【参考方案1】:我遇到了同样的问题,我可以按照以下建议在 android 中解决这个问题:https://github.com/react-native-community/react-native-video/issues/1920#issuecomment-604545238
据我了解,默认情况下,android 使用没有这些功能的 android 播放器。但是 ExoPlayer 有很多功能,比如缓冲、自适应比特率等。所以,我们必须明确指定使用 ExoPlayer。 重要的部分是启用 multiDex。
这是修复建议的内容,并且效果很好:
如果您对如何启用 exoplayer 感兴趣,请按照以下步骤操作:
使用以下内容创建 react-native.config.js:
module.exports =
dependencies:
'react-native-video':
platforms:
android:
sourceDir: '../node_modules/react-native-video/android-exoplayer',
,
,
,
,
;
现在在https://developer.android.com/studio/build/multidex之后启用multidex
使用 gradlew clean 清理并重新构建以使其工作
【讨论】:
【参考方案2】:你可以使用 react-native-video 的 onLoad
和 onEnd
属性来展示加载器。
举例
<Video
poster=/*uri*/
posterResizeMode="cover"
source=/*source*/
onLoad=()=>/* set loader to true*/
onEnd=()=>/* set loader to false*/
/>
【讨论】:
我想处理缓冲。 onLoad 和 onEnd 在视频开始和视频结束时起作用。【参考方案3】:我在我的应用程序中对缓冲状态执行了所有这些操作,您可以像这样简单地检查缓冲区的状态并显示加载器。您必须使用onLoadStart, onBuffer and onLoadEnd
的组合,下面是一个示例,说明如何在缓冲时构建自定义加载器和显示。
如果您不想使用我的加载器或此动画内容,请删除该内容并渲染您自己的加载器。
class VideoPlayer extends React.Component
constructor (props)
super(props)
this.state =
paused: false,
buffering: true,
animated: new Animated.Value(0),
progress: 0,
duration: 0
handleMainButtonTouch = () =>
if (this.state.progress >= 1)
this.player.seek(0)
this.setState(state =>
return
paused: !state.paused
)
;
handleProgressPress = e =>
const position = e.nativeEvent.locationX
const progress = (position / 250) * this.state.duration
const isPlaying = !this.state.paused
this.player.seek(progress)
;
handleProgress = progress =>
this.setState(
progress: progress.currentTime / this.state.duration
)
;
onBuffer = (isBuffering) =>
this.setState( buffering: isBuffering )
if (isBuffering)
this.triggerBufferAnimation()
if (this.loopingAnimation && isBuffering)
this.loopingAnimation.stopAnimation()
onLoadStart = () =>
this.triggerBufferAnimation()
handleLoad = (duration) =>
this.setState(
duration: duration
)
;
triggerBufferAnimation = () =>
this.loopingAnimation && this.loopingAnimation.stopAnimation()
this.loopingAnimation = Animated.loop(
Animated.timing(this.state.animated,
toValue: 1,
duration: 1500
)
).start()
;
render ()
console.log('video player ', this.props)
const isShowingDetails, hideDetails, showDetails, thumbnailUrl, url = this.props
const buffering = this.state
const BufferInterpolation = this.state.animated.interpolate(
inputRange: [0, 1],
outputRange: ['0deg', '600deg']
)
const rotateStyles = transform: [
rotate: BufferInterpolation
]
return (
<React.Fragment>
<Video
ref=ref =>
this.player = ref;
source= uri: url
controls
paused=this.state.paused
// poster=thumbnailUrl
onBuffer=this.onBuffer
onLoadStart=this.onLoadStart
onLoad=this.handleLoad
key=url
onProgress=this.handleProgress
style=styles.backgroundVideo
useTextureView=false
onVideoEnd=() => alert('Video ended')
bufferConfig=
minBufferMs: 15000,
maxBufferMs: 50000,
bufferForPlaybackMs: 2500,
bufferForPlaybackAfterRebufferMs: 5000
/>
<View
color=Colors.appColor
style=styles.videoCover
>
buffering && <Animated.View style=rotateStyles>
<FontAwesome5 name='circle-notch' size=50 color='rgba(255, 255, 255, 0.6)' />
</Animated.View>
</View>
</React.Fragment>
)
export default VideoPlayer
const styles = StyleSheet.create(
backgroundVideo:
height: undefined,
width: '100%',
backgroundColor: 'black',
aspectRatio: 16 / 9,
zIndex: 100
// 2: 0
,
videoCover:
justifyContent: 'center',
alignItems: 'center',
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
backgroundColor: 'transparent',
zIndex: 10
,
controls:
backgroundColor: 'rgba(0, 0, 0, 0.5)',
height: 20,
left: 0,
bottom: 5,
right: 0,
position: 'absolute',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-around',
paddingHorizontal: 10,
zIndex: 10
,
duration:
color: '#FFF',
marginLeft: 15
)
【讨论】:
@AmitTiwary Buffer is not working function is not called in the buffering state 是什么意思? 这个问题,你能在世博会上做点心吗?或者可以与此问题共享最小回购【参考方案4】:同样的事情发生在我身上。 解决方案是使用 exoPlayer 而不是 mediaPlayer。 当我们安装 react-native-video 包时,默认情况下它会安装 mediaPlayer,这在仅使用本地媒体文件的情况下会更好。 但是当我们需要处理在线视频时,我们需要 exoPlayer。
exoPlayer如何申请?
这在 react-native-video 文档中有很好的定义: https://github.com/react-native-video/react-native-video
【讨论】:
欢迎。谢谢你的建议。以下是一些您可能不知道的 SO 发布指南。 SO不将仅链接响应视为答案。照原样,这是帖子评论部分有用内容的完美示例。对于大多数问题,答案必须包含解决 OP 问题所需的确切代码,最好是解释重要的部分。链接很好,如果您还将链接页面中的重要信息嵌入到您的帖子中。否则,如果页面变得不可用,或者它的内容发生变化,你的帖子就会变得毫无用处,并且质量会受到影响。请参阅 ***.com/help以上是关于react-native-video 中的 OnBuffer 道具不起作用的主要内容,如果未能解决你的问题,请参考以下文章
当我单击 react-native-video 播放器中的硬件后退按钮时如何锁定 LandScape 模式?
react-native-video:无法读取 null 的属性“常量”