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 的 onLoadonEnd 属性来展示加载器。

举例

<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

React-native-video 不显示视频播放器

react-native-video:无法读取 null 的属性“常量”

React-Native-Video onClick() 道具

react-native-video 是不是支持来自 hls url 的直播?