React native react本机视频中的OnBuffer道具不起作用

React native react本机视频中的OnBuffer道具不起作用,react-native,react-native-video,React Native,React Native Video,我正在使用react原生视频从url播放视频。我使用onBuffer道具来显示加载程序是否正在缓冲视频。但就我而言,onBuffer不起作用。如果视频大小较大,则在网络速度较慢或不稳定的情况下,播放网络视频需要时间,因此我想显示loader,如果视频未播放,但处于缓冲模式 您可以使用react原生视频的onLoad和onEnd道具来显示加载程序 比如说 <Video poster={/*uri*/} posterResizeMode="cover" source={

我正在使用react原生视频从url播放视频。我使用onBuffer道具来显示加载程序是否正在缓冲视频。但就我而言,onBuffer不起作用。如果视频大小较大,则在网络速度较慢或不稳定的情况下,播放网络视频需要时间,因此我想显示loader,如果视频未播放,但处于缓冲模式

您可以使用react原生视频的
onLoad
onEnd
道具来显示加载程序

比如说

<Video
    poster={/*uri*/}
    posterResizeMode="cover"
    source={/*source*/}
    onLoad={()=>/* set loader to true*/}
    onEnd={()=>/* set loader to false*/}
  />
/*将加载程序设置为true*/}
onEnd={()=>/*将加载程序设置为false*/}
/>

我在我的应用程序中做的所有事情都是关于缓冲状态的。你可以简单地检查缓冲区的状态,然后像这样显示加载程序。您必须结合使用
onLoadStart、onBuffer和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
  }
})
class视频播放器扩展了React.Component{
建造师(道具){
超级(道具)
此.state={
暂停:错,
缓冲:对,
已设置动画:新的已设置动画。值(0),
进展:0,
持续时间:0
}
}
handleMainButtonTouch=()=>{
如果(this.state.progress>=1){
此.player.seek(0)
}
this.setState(state=>{
返回{
暂停:!state.paused
}
})
};
handleProgressPress=e=>{
const position=e.nativeEvent.locationX
施工进度=(位置/250)*this.state.duration
常量显示=!this.state.paused
此.player.seek(进度)
};
handleProgress=进度=>{
这是我的国家({
进度: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})=>{
这是我的国家({
持续时间:持续时间
})
};
triggerBufferAnimation=()=>{
this.loopingAnimation&&this.loopingAnimation.stopAnimation()
this.loopingAnimation=Animated.loop(
动画。计时(this.state.Animated{
toValue:1,
持续时间:1500
})
).start()
};
渲染(){
console.log('video player',this.props)
const{isShowingDetails、hideDetails、showDetails、thumbnailUrl、url}=this.props
const{buffering}=this.state
常量缓冲插值=this.state.animated.interpolate({
输入范围:[0,1],
输出范围:['0deg','600deg']
})
const rotateStyles={transform:[{
旋转:缓冲插值
}]
}
返回(
{
this.player=ref;
}}
source={{uri:url}
控制
暂停={this.state.paused}
//海报={thumbnailUrl}
onBuffer={this.onBuffer}
onLoadStart={this.onLoadStart}
onLoad={this.handleLoad}
键={url}
onProgress={this.handleProgress}
style={style.backgroundVideo}
useTextureView={false}
onVideoEnd={()=>alert('Video end')}
缓冲配置={{
MINMS:15000,
maxBufferMs:50000,
回放缓冲区:2500,
回绝后播放的缓冲区:5000
}}
/>
{
缓冲&&
}
)
}
}
导出默认视频播放器
const styles=StyleSheet.create({
背景视频:{
高度:未定义,
宽度:“100%”,
背景颜色:“黑色”,
专题:16/9,
zIndex:100
// 2: 0
},
视频封面:{
为内容辩护:“中心”,
对齐项目:“居中”,
位置:'绝对',
排名:0,
左:0,,
右:0,,
底部:0,
背景色:“透明”,
zIndex:10
},
控制:{
背景颜色:“rgba(0,0,0,0.5)”,
身高:20,
左:0,,
底部:5,
右:0,,
位置:'绝对',
flexDirection:'行',
对齐项目:“居中”,
为内容辩护:“周围的空间”,
水平方向:10,
zIndex:10
},
持续时间:{
颜色:“#FFF”,
边缘左侧:15
}
})

我也有同样的问题,我可以通过以下建议在android中解决这个问题:

据我所知,默认情况下,android使用的android播放器没有这些功能。但是ExoPlayer有很多特性,比如缓冲、自适应比特率等。。因此,我们必须明确指定使用ExoPlayer。 重要的部分是启用多索引

这就是修复建议,它工作得很好:

如果您了解如何启用exoplayer,请按照以下步骤操作:

使用以下内容创建react-native.config.js:

module.exports = {
  dependencies: {
    'react-native-video': {
      platforms: {
        android: {
          sourceDir: '../node_modules/react-native-video/android-exoplayer',
        },
      },
    },
  },
};
现在按照下面的步骤启用多索引

使用gradlew清理并重建使其工作

同样的情况也发生在我身上。 解决方案是使用exoPlayer而不是mediaPlayer。 当我们安装react native video软件包时,默认情况下它会安装mediaPlayer,这在仅处理本地媒体文件的情况下会更好。 但当我们需要处理在线视频时,我们就需要exoPlayer

如何应用exoPlayer

这在react原生视频文档中有很好的定义:

我想处理缓冲。onLoad和onEnd在视频开始和视频结束时工作。@AmitTiwary缓冲区不工作是什么意思在缓冲状态下没有调用函数?你能用这个问题在世博会上做点小吃吗?或者可以与本次发行共享最低回购协议简单的解决方案谢谢欢迎。谢谢你的建议。以下是一些你可能不知道的SO发布指南。SO不认为仅链接回复为答案。事实上,这是一个完美的例子