zoukankan      html  css  js  c++  java
  • react-native 封装 VedioPlayer 组件

    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 (
          <View style={styles.videoBox}>
            <Video
              style={styles.video}
              ref="videoPlayer"
              source={{uri: this.props.uri}}
              // 声音放大的倍数: 0 is muted, 1 is double.
              volume={5}
              // 是否暂停 true or false.
              paused={this.state.paused}
              // 0 是 暂停, 1 是 正常.
              rate={this.state.rate}
              // 是否静音 true or false.
              muted={this.state.muted}
              // 充满整个播放区域 或 自适应
              resizeMode={this.state.resizeMode}
              // 是否重复播放 true or false.
              repeat={this.state.repeat}
              // 当视频开始加载时
              onLoadStart={this._onLoadStart.bind(this)}
              // 当视频在不断的加载时
              onLoad={this._onLoad.bind(this)}
              // 当视频播放时,每250ms调用一次,便于知悉当前播放位置(时间)
              onProgress={this._onProgress.bind(this)}
              // 当视频播放结束时调用
              onEnd={this._onEnd.bind(this)}
              // 当视频出错时调用
              onError={this._onError.bind(this)}
            />
            {/* 视频出错 */}
            {
              !this.state.videoOk && <Text style={styles.failText}>视频出错了!很抱歉</Text>
            }
    
            {/* 没有加载 */}
            {
              !this.state.videoLoaded && <ActivityIndicator style={styles.loading} color="#ee735c"/>
            }
    
            {/* 播放结束 */}
            {
              this.state.videoLoaded && !this.state.playing
                ?
                <Icon
                  style={styles.playIcon}
                  onPress={this._rePlay.bind(this)}
                  name='ios-play'
                  size={48}
                />
                : null
            }
    
            {/* 视频正在播放,控制是否暂停 */}
            {
              this.state.videoLoaded && this.state.playing
                  ?
                  <TouchableOpacity
                    style={styles.pauseBtn}
                    onPress={this._pause.bind(this)}
                  >
                    {
                      this.state.paused
                        ?
                        <Icon
                          style={styles.resumeIcon}
                          size={48}
                          onPress={this._resume.bind(this)}
                          name="ios-play"
                        />
                        :
                        <Text></Text>
                    }
                  </TouchableOpacity>
                  : null
            }
            {/*进度条*/}
            <View style={styles.progressBox}>
              <View style={[styles.progressBar, { width * this.state.videoProgress}]}></View>
            </View>
          </View>
        )
      }
    
      // 当视频开始加载时
      _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,
        height: width * 0.56,
        backgroundColor: '#000'
      },
      // 视频播放器
      video: {
         width,
        height: width * 0.56,
        backgroundColor: '#000'
      },
      // 加载动画(菊花图)
      loading: {
        position: 'absolute',
        left: 0,
        top: 80,
         width,
        alignSelf: 'center', // 字体居中对齐
        backgroundColor: 'transparent'
      },
      // 视频出错时,文本样式
      failText: {
        position: 'absolute',
        left: 0,
        top: 90,
         width,
        textAlign: 'center',
        color: '#fff',
        backgroundColor: 'transparent'
      },
      // 进度条样式
      progressBox: {
         width,
        height: 2,
        backgroundColor: '#ccc'
      },
    
      progressBar: {
         1,
        height: 2,
        backgroundColor: '#ff6600'
      },
      // 播放按钮样式
      playIcon: {
        position: 'absolute',
        top: 90,
        left: width / 2 - 30,
         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,
        height: width * 0.56
      },
      // 继续
      resumeIcon: {
        position: 'absolute',
        top: 80,
        left: width / 2 - 30,
         60,
        height: 60,
        paddingTop: 8,
        paddingLeft: 22,
        backgroundColor: 'transparent',
        borderColor: '#fff',
        borderWidth: 1,
        borderRadius: 30,
        color: '#ed7b66'
      }
    });

    2.调用组件

    {/*视频播放器*/}
    <VideoPlayer uri={data.video} />

    3.效果图

  • 相关阅读:
    Vim 配置 winmanager
    删除字符串中重复字符
    检查字符串中是否存在重复字符
    字符串逆序输出
    shell 循环使用
    Windows下JNI执行步骤
    JNI中使用cl命令生成DLL文件
    javaZIP压缩文件
    java Mail发送邮件
    关于在同一个DIV下的Hover效果问题
  • 原文地址:https://www.cnblogs.com/crazycode2/p/9427898.html
Copyright © 2011-2022 走看看