zoukankan      html  css  js  c++  java
  • RN 使用react-native-video 播放视频(包含进度条、全屏)

    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={{ 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={{ 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:{
             340,
            height: 240
        },
        playBtn:{
             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'
        }
      });



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



    这是全屏播放时

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

  • 相关阅读:
    websocketpp相关
    大地水准面、大地基准面
    ubuntu18.04 和 qt 5.13.1 安装
    高斯——克吕格投影反算
    高斯——克吕格投影正算
    缓和曲线10麦克康奈尔
    vsCode 需安装的扩展
    显示windows电脑上已连接过的wifi密码
    linux Java项目CPU内存占用高故障排查
    tcpdump常用参数说明及常见操作
  • 原文地址:https://www.cnblogs.com/tengyuxin/p/12030742.html
Copyright © 2011-2022 走看看