import React, {Component} from 'react'; import {View, Dimensions, Image, Text, Slider, TouchableWithoutFeedback, TouchableOpacity, Button, StyleSheet} from 'react-native'; import Video from 'react-native-video';//视频组件 import Orientation from 'react-native-orientation';//判断是否横屏播放组件
const screenWidth = Dimensions.get('window').width;
function formatTime(second) { let h = 0, i = 0, s = parseInt(second); if (s > 60) { i = parseInt(s / 60); s = parseInt(s % 60); } // 补零 let zero = function (v) { return (v >> 0) < 10 ? "0" + v : v; }; return [zero(h), zero(i), zero(s)].join(":"); }
export default class VideoPlayScreen extends Component { static navigationOptions = { headerTitle: '测试视频播放' }; constructor(props) { super(props); this.state = { videoUrl: "http://124.129.157.208:8810/SD/2017qingdao/xiaoxueEnglish/grade3/b/1.mp4", videoCover: "http://124.129.157.208:8889/data/uploads/kecheng/2018/01/18/5a600b2c99836.png@0o_0l_220w.png", videoWidth: screenWidth, videoHeight: screenWidth * 9/16, // 默认16:9的宽高比 showVideoCover: true, // 是否显示视频封面 showVideoControl: false, // 是否显示视频控制组件 isPlaying: false, // 视频是否正在播放 currentTime: 0, // 视频当前播放的时间 duration: 0, // 视频的总时长 isFullScreen: false, // 当前是否全屏显示 playFromBeginning: false, // 是否从头开始播放 }; } render() { return ( <View style={styles.container} onLayout={this._onLayout}> <View style={{ width: this.state.videoWidth, height: this.state.videoHeight, backgroundColor:'#000000' }}> <Video ref={(ref) => this.videoPlayer = ref} source={{uri: this.state.videoUrl}} rate={1.0} volume={1.0} muted={false} paused={!this.state.isPlaying} resizeMode={'contain'} playWhenInactive={false} playInBackground={false} ignoreSilentSwitch={'ignore'} progressUpdateInterval={250.0} onLoadStart={this._onLoadStart} onLoad={this._onLoaded} onProgress={this._onProgressChanged} onEnd={this._onPlayEnd} onError={this._onPlayError} onBuffer={this._onBuffering} style={{width: this.state.videoWidth, height: this.state.videoHeight}} /> { this.state.showVideoCover ? <Image style={{ position:'absolute', top: 0, left: 0, width: this.state.videoWidth, height: this.state.videoHeight }} resizeMode={'cover'} source={{uri: this.state.videoCover}} /> : null } <TouchableWithoutFeedback onPress={() => { this.hideControl() }}> <View style={{ position: 'absolute', top: 0, left: 0, width: this.state.videoWidth, height: this.state.videoHeight, backgroundColor: this.state.isPlaying ? 'transparent' : 'rgba(0, 0, 0, 0.2)', alignItems:'center', justifyContent:'center' }}> { this.state.isPlaying ? null : <TouchableWithoutFeedback onPress={() => { this.onPressPlayButton() }}> <Image style={styles.playButton} source={require('../../assets/image/icon_video_play.png')} /> </TouchableWithoutFeedback> } </View> </TouchableWithoutFeedback> { this.state.showVideoControl ? <View style={[styles.control, {width: this.state.videoWidth}]}> <TouchableOpacity activeOpacity={0.3} onPress={() => { this.onControlPlayPress() }}> <Image style={styles.playControl} source={this.state.isPlaying ? require('../../assets/image/icon_control_pause.png') : require('../../assets/image/icon_control_play.png')} /> </TouchableOpacity> <Text style={styles.time}>{formatTime(this.state.currentTime)}</Text> <Slider style={{flex: 1}} maximumTrackTintColor={'#999999'} minimumTrackTintColor={'#00c06d'} thumbImage={require('../../assets/image/icon_control_slider.png')} value={this.state.currentTime} minimumValue={0} maximumValue={this.state.duration} onValueChange={(currentTime) => { this.onSliderValueChanged(currentTime) }} /> <Text style={styles.time}>{formatTime(this.state.duration)}</Text> <TouchableOpacity activeOpacity={0.3} onPress={() => { this.onControlShrinkPress() }}> <Image style={styles.shrinkControl} source={this.state.isFullScreen ? require('../../assets/image/icon_control_shrink_screen.png') : require('../../assets/image/icon_control_full_screen.png')} /> </TouchableOpacity> </View> : null } </View> <View style={{flex: 1, alignItems:'center', justifyContent:'center'}}> <Button title={'开始播放'} onPress={() => {this.playVideo()}}/> <Button title={'暂停播放'} onPress={() => {this.pauseVideo()}}/> <Button title={'切换视频'} onPress={() => {this.switchVideo("http://124.129.157.208:8810/SD/zhishidian/grade_8_1/wuli_shu/01.mp4", 0)}}/> </View> </View> ) } /// -------Video组件回调事件------- _onLoadStart = () => { console.log('视频开始加载'); }; _onBuffering = () => { console.log('视频缓冲中...') }; _onLoaded = (data) => { console.log('视频加载完成'); this.setState({ duration: data.duration, }); }; _onProgressChanged = (data) => { console.log('视频进度更新'); if (this.state.isPlaying) { this.setState({ currentTime: data.currentTime, }) } }; _onPlayEnd = () => { console.log('视频播放结束'); this.setState({ currentTime: 0, isPlaying: false, playFromBeginning: true }); }; _onPlayError = () => { console.log('视频播放失败'); }; ///-------控件点击事件------- /// 控制播放器工具栏的显示和隐藏 hideControl() { if (this.state.showVideoControl) { this.setState({ showVideoControl: false, }) } else { this.setState( { showVideoControl: true, }, // 5秒后自动隐藏工具栏 () => { setTimeout( () => { this.setState({ showVideoControl: false }) }, 5000 ) } ) } } /// 点击了播放器正中间的播放按钮 onPressPlayButton() { let isPlay = !this.state.isPlaying; this.setState({ isPlaying: isPlay, showVideoCover: false }); if (this.state.playFromBeginning) { this.videoPlayer.seek(0); this.setState({ playFromBeginning: false, }) } } /// 点击了工具栏上的播放按钮 onControlPlayPress() { this.onPressPlayButton(); } /// 点击了工具栏上的全屏按钮 onControlShrinkPress() { if (this.state.isFullScreen) { Orientation.lockToPortrait(); } else { Orientation.lockToLandscape(); } } /// 进度条值改变 onSliderValueChanged(currentTime) { this.videoPlayer.seek(currentTime); if (this.state.isPlaying) { this.setState({ currentTime: currentTime }) } else { this.setState({ currentTime: currentTime, isPlaying: true, showVideoCover: false }) } } /// 屏幕旋转时宽高会发生变化,可以在onLayout的方法中做处理,比监听屏幕旋转更加及时获取宽高变化 _onLayout = (event) => { //获取根View的宽高 let {width, height} = event.nativeEvent.layout; console.log('通过onLayout得到的宽度:' + width); console.log('通过onLayout得到的高度:' + height); // 一般设备横屏下都是宽大于高,这里可以用这个来判断横竖屏 let isLandscape = (width > height); if (isLandscape){ this.setState({ videoWidth: width, videoHeight: height, isFullScreen: true, }) } else { this.setState({ videoWidth: width, videoHeight: width * 9/16, isFullScreen: false, }) } Orientation.unlockAllOrientations(); }; /// -------外部调用事件方法------- ///播放视频,提供给外部调用 playVideo() { this.setState({ isPlaying: true, showVideoCover: false }) } /// 暂停播放,提供给外部调用 pauseVideo() { this.setState({ isPlaying: false, }) } /// 切换视频并可以指定视频开始播放的时间,提供给外部调用 switchVideo(videoURL, seekTime) { this.setState({ videoUrl: videoURL, currentTime: seekTime, isPlaying: true, showVideoCover: false }); this.videoPlayer.seek(seekTime); } }
const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#f0f0f0' }, playButton: { width: 50, height: 50, }, playControl: { width: 24, height: 24, marginLeft: 15, }, shrinkControl: { width: 15, height: 15, marginRight: 15, }, time: { fontSize: 12, color: 'white', marginLeft: 10, marginRight: 10 }, control: { flexDirection: 'row', height: 44, alignItems:'center', backgroundColor: 'rgba(0, 0, 0, 0.8)', position: 'absolute', bottom: 0, left: 0 }, });