RN 使用react-native-video 播放视频(包含进度条、全屏)

2023-03-07,,

21年12月3日,阐述上有问题:应该将问题拆分,不该将代码整一大堆,看着很不舒适

目标需求:
1. 实现视频播放

2. 进度条

3. 进入全屏

目标图是这样的:

需要三个组件

1. 播放视频组件, react-native-video    官网地址 https://www.npmjs.com/package/react-native-video#allowsexternalplayback

2. 进度条,官网上提供的 slider组件我忘记说的什么原因,即将停止支持,我找了react-native-silder  这个个第三方包 官网地址  https://github.com/react-native-community/react-native-slider#onvaluechange现在react-native-silder 的一些生命周期方法都是警告,因为react很多声明周期函数,已经废弃或改名字 ,我目前在尝试   https://github.com/callstack/react-native-slider

3. 全屏播放,react-native-orientation这个包有问题,因为RN 将对 rnpm 换一种支持策略 ,所以选择用 react-native-orientation-locker 官网地址  https://github.com/wonday/react-native-orientation-locker

后面的就直接上代码了

import React from 'react';
import {View,Text,StyleSheet,TouchableWithoutFeedback,TouchableOpacity,Dimensions} from 'react-native';
//导入Video组件
import Video from 'react-native-video';
// 导入 Silder组件
import Slider from '@react-native-community/slider';
// 屏幕方向锁定: 他需要改变 原来Android文件代码,当然适配两端的话,IOS也是需要更改的。
import Orientation from 'react-native-orientation-locker'; let screenWidth = Dimensions.get('window').width;
let screenHeight = Dimensions.get('window').height;
console.log(screenWidth+" "+screenHeight+"带有小数"); export default class App extends React.Component{
constructor(props){
super(props);
this.changePausedState = this.changePausedState.bind(this);
this.customerSliderValue = this.customerSliderValue.bind(this);
this.enterFullScreen = this.enterFullScreen.bind(this);
this._changePauseSliderFullState = this._changePauseSliderFullState.bind(this);
this._onStartShouldSetResponder = this._onStartShouldSetResponder.bind(this);
this.state = {
isPaused: true, //是暂停
duration: 0, //总时长
currentTime: 0, //当前播放时间
sliderValue: 0, //进度条的进度 //用来控制进入全屏的属性
videoWidth: screenWidth,
videoHeight: 226,
isFullScreen: false,
isVisiblePausedSliderFullScreen: false
}
}
changePausedState(){ //控制按钮显示播放,要显示进度条3秒钟,之后关闭显示
this.setState({
isPaused: this.state.isPaused?false:true,
isVisiblePausedSliderFullScreen: true
})
//这个定时调用失去了this指向
let that = this;
setTimeout(function(){
that.setState({
isVisiblePausedSliderFullScreen: false
})
},3000)
}
_changePauseSliderFullState(){ // 单击事件,是否显示 “暂停、进度条、全屏按钮 盒子”
let flag = this.state.isVisiblePausedSliderFullScreen?false:true;
this.setState({
isVisiblePausedSliderFullScreen: flag
})
//这个定时调用失去了this指向
let that = this;
setTimeout(function(){
that.setState({
isVisiblePausedSliderFullScreen: false
})
},3000)
}
//格式化音乐播放的时间为0:00。借助onProgress的定时器调用,更新当前时间
formatMediaTime(time) {
let minute = Math.floor(time / 60);
let second = parseInt(time - minute * 60);
minute = minute >= 10 ? minute : "0" + minute;
second = second >= 10 ? second : "0" + second;
return minute + ":" + second; }
//加载视频调用,主要是拿到 “总时间”,并格式化
customerOnload(e){
let time = e.duration;
this.setState({
duration: time
})
}
// 获得当前的,播放时间数,但这个数是0.104,需要处理
customerOnprogress(e){
let time = e.currentTime; // 获取播放视频的秒数
this.setState({
currentTime: time,
sliderValue: time
})
}
// 移动滑块,改变视频播放进度
customerSliderValue(value){
this.player.seek(value);
}
enterFullScreen(){ //1.改变宽高 2.允许进入全屏模式 3.如何配置屏幕旋转,不需要改变进度条盒子的显示和隐藏
this.setState({
videoWidth: screenHeight,
videoHeight: screenWidth,
isFullScreen: true
})
// 直接设置方向
Orientation.lockToLandscape();
}
_onStartShouldSetResponder(e){
console.log(e);
}
componentDidMount() {
var initial = Orientation.getInitialOrientation();
if (initial === 'PORTRAIT') {
console.log('是竖屏');
} else {
console.log('如果是横屏,就将其旋转过来');
Orientation.lockToPortrait();
}
}
render(){
// 播放按钮组件:是否显示
let playButtonComponent = (
<TouchableWithoutFeedback
onPress={this.changePausedState}
>
<View style={styles.playBtn}>
</View>
</TouchableWithoutFeedback>
);
let pausedBtn = this.state.isPaused?playButtonComponent:null;
// 暂停按钮、进度条、全屏按钮 是否显示
let pausedSliderFullComponent = (
<View style={{position:"absolute",bottom:0}}>
<View style={{flexDirection:'row',alignItems:'center'}}>
{/* 进度条按钮 */}
<View style={styles.sliderBox}>
<Text>{this.formatMediaTime(this.state.currentTime)}</Text>
<Slider
style={{width: 200, height: 40}}
value={this.state.sliderValue}
maximumValue={this.state.duration}
thumbTintColor="#000" //开关夹点的yanse
minimumTrackTintColor="red"
maximumTrackTintColor="#ccc"
step={1}
onValueChange={this.customerSliderValue}
/>
<Text>{this.formatMediaTime(this.state.duration)}</Text>
</View>
{/* 全屏按钮 */}
<View>
<TouchableOpacity
onPress={this.enterFullScreen}
>
<Text style={{backgroundColor:'#00ff00',padding:5}}>全屏</Text>
</TouchableOpacity>
</View> </View>
</View>
);
let pausedSliderFull = this.state.isVisiblePausedSliderFullScreen?pausedSliderFullComponent:null;
return (
<View>
<View>
<TouchableWithoutFeedback
onPress={this._changePauseSliderFullState}
onResponderMove={this._onStartShouldSetResponder}
>
<Video source={require('../jifen.mp4')}
ref={(ref) => {
this.player = ref
}}
style={{width: this.state.videoWidth,height: this.state.videoHeight,backgroundColor:"#FFC1C1"}}
allowsExternalPlayback={false} // 不允许导出 或 其他播放器播放
paused = {this.state.isPaused} // 控制视频是否播放
resizeMode="cover"
onLoad={(e)=>this.customerOnload(e)}
onProgress={(e)=>this.customerOnprogress(e)}
fullscreen={this.state.isFullScreen}
/>
</TouchableWithoutFeedback>
{/* 播放的按钮:点击之后需要消失 */}
{pausedBtn}
{/* 暂停按钮,进度条,全屏按钮 */}
{pausedSliderFull}
</View>
</View>
)
}
}
var styles = StyleSheet.create({
myVideo:{
width: 340,
height: 240
},
playBtn:{
width: 50,
height: 50,
backgroundColor:'red',
borderRadius: 50,
position: "absolute",
top: "50%",
left: "50%",
marginLeft: -25,
marginTop:-25,
zIndex:999
},
sliderBox:{
flex:0,
flexDirection:'row',
alignItems:'center'
}
});

看个效果图吧,这个普通播放时

这是全屏播放时

测试这个花了挺长时间的,有用点个赞吧,哈哈

RN 使用react-native-video 播放视频(包含进度条、全屏)的相关教程结束。

《RN 使用react-native-video 播放视频(包含进度条、全屏).doc》

下载本文的Word格式文档,以方便收藏与打印。