1.封装组件
src/components/VideoPlayer/index.js
/** * 视频播放器 组件(VideoPlayer) */import React, {Component} from 'react';import { StyleSheet, Text, View, Dimensions, ActivityIndicator, TouchableOpacity,} from 'react-native';// 播放器组件import Video from 'react-native-video';import Icon from 'react-native-vector-icons/Ionicons';let {width} = Dimensions.get("window");export default class VideoPlayer extends Component { constructor(props) { super(props); this.state = { // 视频播放器 rate: 1, // 是否暂停 0:暂停, 1:正常 muted: false, // 是否静音 resizeMode: 'contain', // 充满整个播放区域 cover 或 自适应 contain repeat: false, // 是否重复播放 // video control videoOk: true, // 视频是否出错 videoLoaded: false, // 视频是否加载 playing: false, // 视频是否播放中 paused: false, // 是否暂停 videoProgress: 0.01, // 进度条 // all time videoTotal: 0, // 视频总时间 currentTime: 0, // 当前时间 } } render() { return ({/* 视频出错 */} { !this.state.videoOk && ) } // 当视频开始加载时 _onLoadStart() { // } // 当视频在不断的加载时 _onLoad() { // } // 当视频播放时,每250ms调用一次,便于知悉当前播放位置(时间) _onProgress(data) { if (!this.state.videoLoaded) { this.setState({ videoLoaded: true }) } // 视频中时长 let duration = data.playableDuration; let currentTime = data.currentTime; // toFixed(2) get 小数点后两位 let percent = Number((currentTime / duration).toFixed(2)); let newState = { videoTotal: duration, currentTime: Number(data.currentTime.toFixed(2)), videoProgress: percent }; if (!this.state.videoLoaded) { newState.videoLoaded = true } // 视频暂停播放或播放结束,显示播放按钮 if (!this.state.playing) { newState.playing = true } this.setState(newState); } // 当视频播放结束时调用 _onEnd() { this.setState({ videoProgress: 1, // 进度为1表示播放结束 playing: false }); } // 当视频出错时调用 _onError(e) { this.setState({ videoOk: false }); } // 重新播放 _rePlay() { this.refs.videoPlayer.seek(0) } // 暂停播放 _pause() { if (!this.state.paused) { this.setState({ paused: true }) } } // 继续播放 _resume() { if (this.state.paused) { this.setState({ paused: false }) } }}const styles = StyleSheet.create({ // 视频播放器 容器 videoBox: { width: width, height: width * 0.56, backgroundColor: '#000' }, // 视频播放器 video: { width: width, height: width * 0.56, backgroundColor: '#000' }, // 加载动画(菊花图) loading: { position: 'absolute', left: 0, top: 80, width: width, alignSelf: 'center', // 字体居中对齐 backgroundColor: 'transparent' }, // 视频出错时,文本样式 failText: { position: 'absolute', left: 0, top: 90, width: width, textAlign: 'center', color: '#fff', backgroundColor: 'transparent' }, // 进度条样式 progressBox: { width: width, height: 2, backgroundColor: '#ccc' }, progressBar: { width: 1, height: 2, backgroundColor: '#ff6600' }, // 播放按钮样式 playIcon: { position: 'absolute', top: 90, left: width / 2 - 30, width: 60, height: 60, paddingTop: 8, paddingLeft: 22, backgroundColor: 'transparent', borderColor: '#fff', borderWidth: 1, borderRadius: 30, color: '#ed7b66' }, // 暂停 pauseBtn: { position: 'absolute', left: 0, top: 0, width: width, height: width * 0.56 }, // 继续 resumeIcon: { position: 'absolute', top: 80, left: width / 2 - 30, width: 60, height: 60, paddingTop: 8, paddingLeft: 22, backgroundColor: 'transparent', borderColor: '#fff', borderWidth: 1, borderRadius: 30, color: '#ed7b66' }});视频出错了!很抱歉 } {/* 没有加载 */} { !this.state.videoLoaded &&} {/* 播放结束 */} { this.state.videoLoaded && !this.state.playing ? : null } {/* 视频正在播放,控制是否暂停 */} { this.state.videoLoaded && this.state.playing ? { this.state.paused ? : null } {/*进度条*/}: }
2.调用组件
{/*视频播放器*/}
3.效果图