一个第三方的视频播放组件:
react-native-video:此组件的需要对原生的android和iOS进行一些操作才可以使用。具体参照GitHub:https://github.com/react-native-community/react-native-video
export default class Detail extends Component { constructor(props){ super(props); this.state = { rowData:this.props.rowData, //从上以页面传递过来的数据 videoLoaded:false, //标记是否加载完 goProgress:false, //标记是否在播放状态(即是否还在progress过程),暂停也是在progress状态 isVideoOk:true, //标记视频是否正常 //下面的状态都是组件Video自带的,必须有 rate: 1, volume: 1, // 声音的放大倍数,0 代表没有声音,就是静音muted, 1 代表正常音量 normal,更大的数字表示放大的倍数 muted: false, // true代表静音,默认为false. resizeMode: 'contain',// 视频的自适应伸缩铺放行为 paused: false, // true代表暂停,默认为false duration: 0.0, //视频的总时间长度 currentTime: 0.0, //当前播放的进度 } } //开始加载的回调函数 _onLoadStart = () => { console.log('_onLoadStart') } //加载完毕后的回调函数 _onLoad = (data) => { console.log('_onload 视频总长度'+data.duration) this.setState({ duration: data.duration }); }; //正在播放时候的回调函数 _onProgress = (data) => { if(!this.state.videoLoaded) { this.setState({ videoLoaded: true }) } if(!this.state.goProgress) { this.setState({ goProgress: true }) } console.log('_onProgress 数据对象'+JSON.stringify(data)) this.setState({ currentTime: data.currentTime }); console.log('_onProgress 当前时间'+data.currentTime) }; //播放完毕后的回调函数 _onEnd = () => { this.setState({ paused: true, currentTime:this.state.duration, //否则当视频播放完毕后进度条还有一小块没有顶满 goProgress:false }) }; //发生错误的回调函数 _onError = (error)=> { console.log('错误'+JSON.stringify(error)) this.setState({ isVideoOk:false }) } //重新从头开始播放 _rePlay = ()=>{ this.refs.VideoPlayer.seek(0); //this.refs.VideoPlayer通过ref找到子组件Video this.setState({ paused:false }) } //暂停 _pause = () =>{ if(!this.state.paused) { this.setState({ paused: true }) } } //暂停后恢复播放 _resume = ()=> { if(this.state.paused) { this.setState({ paused: false }) } } //获取当前播放进度占总长度的比例 getCurrentTimePercentage() { if (this.state.currentTime > 0) { return parseFloat(this.state.currentTime) / parseFloat(this.state.duration); } return 0; }; render() { const flexCompleted = this.getCurrentTimePercentage() * 100; const flexRemaining = (1 - this.getCurrentTimePercentage()) * 100; let rowData = this.state.rowData; return ( <View style={styles.container}> {/*头部标题和返回按钮*/} <DetailTatil backToList={this._backtoList}/> <View style={styles.videoBox}> <Video ref="VideoPlayer" //Video组件的标记 source={{uri:'http://183.2.204.11/youku/6977DD384574D72B8E93562A1/0300080100595CA431F631003E8803E1CFEC05-52A3-9C7E-F6FE-08902263E9C6.mp4?sid=050354086381818185773_00&sign=d8259ba16df7653fa59ad648cee7ddd0&ctype=50'}} style={styles.fullScreen} rate={this.state.rate} // 控制暂停/播放,0 代表暂停paused, 1代表正常 paused={this.state.paused} // true代表暂停,默认为false volume={this.state.volume} // 声音的放大倍数,0 代表没有声音,就是静音muted, 1 代表正常音量 normal,更大的数字表示放大的倍数 muted={this.state.muted} // true代表静音,默认为false. resizeMode={this.state.resizeMode} // 视频的自适应伸缩铺放行为 repeat={false} //重复播放 playInBackground={false} // 当app转到后台运行的时候,播放是否暂停 onLoadStart={this._onLoadStart} // 当视频开始加载时的回调函数,会传一个参数 onLoad={this._onLoad} // 当视频加载完毕时的回调函数 onProgress={this._onProgress} // 进度控制,每250ms调用一次,以获取视频播放的进度 onEnd={this._onEnd} onError={this._onError} /> {/*在视频加载完之前加一个加载的loading圆圈,就是把ActivityIndicator组件叠加到video组件上面,需要绝对定位*/} {!this.state.videoLoaded ? <ActivityIndicator color={'red'} size={'large'} style={styles.loading} /> : null} {/*中间的播放按钮重新播放 先判断,在根据判断的结果添加组件*/} {this.state.videoLoaded && !this.state.goProgress ? //判断已经加载完并且已经不再progress过程 <Icon name='ios-play' //播放视频的图标 size={45} style={styles.play} onPress={this._rePlay} /> : null} {/*视频播放的时候点击视频上任何一个地方都会暂停,暂停后点击播放按钮继续播放*/} {this.state.videoLoaded && this.state.goProgress ? <TouchableOpacity onPress={this._pause} style={styles.pauseArea} > {this.state.paused ? <Icon name='ios-play' //播放视频的图标 size={45} style={styles.play} onPress={this._resume} /> : null} </TouchableOpacity> : null} {/*当视频出错的时候在video上显示内容*/} {!this.state.isVideoOk ? <Text style={styles.failText}>视频出错</Text> : null} {/*视频的进度条,也可以用width来设置*/} <View style={styles.progress}> {/*flex属性是flex-grow, flex-shrink 和 flex-basis的简写*/} <View style={[styles.innerProgressCompleted, { flex: flexCompleted }]} /> <View style={[styles.innerProgressRemaining, { flex: flexRemaining }]} /> {/*这两个view就是进度条*/} </View> </View> </View> ); } //返回上一个页面,从哪个页面跳进来返回哪一个页面 _backtoList = ()=>{ let {navigator} = this.props; if(navigator){ navigator.pop(); //pop()跳转回去并且卸载掉当前场景 } } }