版权声明:本人原创,码字辛苦,整理代码更是辛苦,转发请说明原处https://blog.csdn.net/qq_37815596谢谢! https://blog.csdn.net/qq_37815596/article/details/89521062
- 安装react-native-video
npm install react-native-video --save
- IOS环境下-手动链接:
1.在Xcode中打开项目,在Libraries上单击右键,然后选择"Add Files to..."
2.在本地目录下,找到对应的项目文件-------node_modules-------react-native-video-------ios-------RCTVideo.xcodeproj
3.打开工程的Build Phases,点击"+"
- 直接运行下面命令来链接react-native-video库
react-native link react-native-video
- Android环境下:直接运行下面命令来链接react-native-video库。
react-native link react-native-video
demo:
react-native link react-native-orientation
react-native link react-native-video
粘贴部分重要代码,完整代码见链接:
该部分实现功能:
1.实现播放、暂停视频;
2.视频全屏、小屏播放视频
3.实现视频进度条
4.切换视频
使用说明:
下载代码之后:npm install,然后npm start,然后再链接即可查看效果。下载代码地址:https://download.csdn.net/download/qq_37815596/11151258
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';
import Icon from 'react-native-vector-icons/FontAwesome';
const screenWidth = Dimensions.get('window').width;
const videoUrl=["http://124.129.157.208:8810/SD/2017qingdao/xiaoxueEnglish/grade3/b/1.mp4","http://124.129.157.208:8810/SD/zhishidian/grade_8_1/wuli_shu/01.mp4"]
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 = {
currentVideo: 0,
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, // 是否从头开始播放
};
}
/// -------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() {
if (this.state.currentVideo != videoUrl.length-1)
{
this.setState({currentVideo: this.state.currentVideo + 1}); //<-- use setState instead of assignment to update
}
else
{
this.setState({currentVideo: 0}); //<-- use setState instead of assignment to update
}
}
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: videoUrl[this.state.currentVideo]}}
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() }}>
<Icon name="play-circle" size={58} color="black" />
</TouchableWithoutFeedback>
}
</View>
</TouchableWithoutFeedback>
{
this.state.showVideoControl ?
<View style={[styles.control, {width: this.state.videoWidth}]}>
<TouchableOpacity activeOpacity={0.3} onPress={() => { this.onControlPlayPress() }}>
{this.state.isPlaying ?
<Icon name="pause-circle-o" size={26} color="white" style={styles.playControl} /> :
<Icon name="play-circle-o" size={26} color="white" style={styles.playControl} />
}
</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() }}>
{this.state.isFullScreen ? <Icon name="compress" size={16} color="white" style={styles.shrinkControl} /> :
<Icon name="expand" size={16} color="white" style={styles.shrinkControl}/> }
</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()}}/>
</View>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#f0f0f0'
},
playControl: {
marginLeft: 15,
},
shrinkControl: {
marginRight: 15,
transform: [{ rotate: '90deg'}]
},
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
},
});
- 属性介绍:
Props
Prop | Type | Required | Default | Description |
---|---|---|---|---|
url | string, number | Yes | A URL string (or number for local) is required.(本地或者网络地址) | |
autoPlay | bool | No | false | Autoplays the video as soon as it's loaded(加载完成后自动播放) |
loop | bool | No | false | Allows the video to continuously loop(循环播放) |
title | string | No | '' | Adds a title of your video at the top of the player(顶部视频标题) |
placeholder | string | No | undefined | Adds an image placeholder while it's loading and stopped at the beginning(加载时一个图像占位符,可以添加loading图) |
logo | string | No | undefined | Adds an image logo at the top left corner of the video(左上角添加一个小logo图) |
theme | string | No | 'white' | Adds an optional theme colour to the players controls(播放器主题,改变控件颜色) |
style | number, object | No | {} | Apply styles directly to the Video player (ignored in fullscreen mode)(样式,全屏下失效) |
resizeMode | string | No | 'contain' | Fills the whole screen at aspect ratio. contain, cover etc(视频填充效果) |
rotateToFullScreen | bool | No | false | Tapping the fullscreen button will rotate the screen. Also rotating the screen will automatically switch to fullscreen mode(旋转屏幕会自动全屏) |
fullScreenOnly | bool | No | false | This will play only in fullscreen mode(全屏下播放) |
inlineOnly | bool | No | false | This hides the fullscreen button and only plays the video in inline mode(会隐藏全屏按钮,默认false) |
playInBackground | bool | No | false | Audio continues to play when app enters background.(后台下会一直播放) |
playWhenInactive | bool | No | false | [iOS] Video continues to play when control or notification center are shown.(ios下拉状态栏会继续播放,默认关闭) |
rate | number | No | 1 | Adjusts the speed of the video. 0 = stopped, 1.0 = normal(视频播放速度) |
volume | number | No | 1 | Adjusts the volume of the video. 0 = mute, 1.0 = full volume(音量调整) |
onMorePress | function | No | undefined | Adds an action button at the top right of the player. Use this callback function for your own use. e.g share link(右上角可以添加一个功能,比如做分享之类的操作) |
onFullScreen | function | No | Returns the fullscreen status whenever it toggles. Useful for situations like react navigation.(这个没太理解,抱歉) | |
onTimedMetadata | function | No | undefined | Callback when the stream receives metadata(貌似是做直播流) |
scrollBounce | bool | No | false | Enables the bounce effect for the ScrollView(没发现什么作用) |
lockPortraitOnFsExit | bool | No | false | Keep Portrait mode locked after Exiting from Fullscreen mode(没发现什么作用) |
lockRatio | number | No | undefined | Force a specific ratio to the Video player. e.g. lockRatio={16 / 9}(强制视频按照这个比例) |
onLoad | function | No | (data) => {} | Returns data once video is loaded(加载视频后返回数据) |
onProgress | function | No | (progress) => {} | Returns progress data(进度函数) |
onEnd | function | No | () => {} | Invoked when video finishes playing(播放完成时调用) |
onError | function | No | (error) => {} | Returns an error message argument(返回错误消息参数) |
error | boolean, object | No | true | Pass in an object to Alert. Seehttps://facebook.github.io/react-native/docs/alert.html |