h5 video踩坑记录

笔者近来在用h5 的video来开发视频,下面来聊一聊是怎么一步一步填坑的。
一些在开发中的注意点,都在代码里的注释进行描述

基本需求

  • 禁止全屏
  • 是否自动播放
  • 播放器尺寸的设置
  • 播放完毕时回到初始状态

1. 禁止全屏

webkit-playsInline={true} // ios
x5-playsInline ={true}// android
playsInline ={true}//ios10

注意:笔者在这里用的是video-react,所以是playsInline,如果使用原生video的话,是playsinline

2. 是否自动播放

  • 设置自动播放需要设置autoPlay属性
  • 笔者所遇到的需求是,由后端接口控制是否默认播放,所以在这里分为两个步骤
// 步骤1:在video标签里设置autoPlay=false


// 步骤2:根据接口的返回值来设置自动播放
handleVideoPlay = (is_first) => {
    let { item: {video_play}, ref_name } = this.props;
    let ref_name_state = this.state.ref_name;
    let video = this[ref_name_state].video;
    if(video_play){// 自动播放, video_play由后端返回
        if(is_first){
            // 首次播放时加延时,避免了在视频未加载成功时就播放
            this.video_timeout = setTimeout(() => {
                video.play();
            }, 300)
        }
    }
}

3. 播放器尺寸的设置

在这里,采用固定视频的宽度,根据视频的封面尺寸来计算视频的高度的算法。

  • 在使用video-react时,发现设置height时,不能使用rem尺寸,只能用px和%,但是后两种单位不能兼容不同的分辨率。所以在这里采用控制视频外层div的尺寸的方法,而将视频的尺寸都设置为100%
// 有封面尺寸时,根据封面的宽高比计算高度;没有封面尺寸时,根据16:9计算高度
let video_height_cal = cover_width ? ((710 * (cover_height/cover_width)/100)): 3.9938;
return (
 
// 视频外层div的尺寸设置
)
  • 经过以上设置之后,视频外层div、播放器、video、封面的尺寸都保持了一致,但是在实际上,却还是在部分机型上有黑边出现(黑边:播放器的背景色,有黑边说明视频和封面没有完全遮盖播放器)

    • 解决办法:增大封面和视频的尺寸,以使其能完全遮盖播放器
.video-react-poster{
    height: 100.1%; // 增大封面的高度,
    top: -0.1px; // 调整位置
    
    // 额外问题
    // 禁止封面的图片重复展示
    background-repeat: no-repeat; 
    // 尽可能的缩放背景并保持图像的宽高比例
    background-size: contain; 
    // 设置完上一个属性后,发现图片并不是上下居中的,所以设置了背景的起始位置
    background-position: center; 
}

.video-react-has-started{
        .video-react-video{
            height: 100.3%; //增大视频的高度
            width: auto;//视频的宽度自适应
            top: -0.4px; // 调整位置
            left: -0.2px;

            // 额外问题
            // 设置max-width是为了避免在将视频全屏播放时,宽度还是auto导致超出屏幕宽度的现象
            max-width: 110%;
        }
    }

4. 播放完毕时回到初始状态

  • 采用的方法是:播放结束时,重新load当前视频
componentDidMount() {
    this.videoLoadSuccess();
}

videoLoadSuccess = () => {
    let video = document.querySelector('video');
    let { ref_name }  =this.state;

    // 在视频达到可以播放的状态时,监听其状态变化
    video.addEventListener('canplaythrough', (event) => {
           // 由于canplaythrough会触发多次,所以在这里添加了对canplaythrough触发的限制,只有当缓存数组里没有该值时,才去监听
           if(!play_through_cache[ref_name]){
                play_through_cache[ref_name] = 1;
                this[ref_name].subscribeToStateChange(this.handleStateChange);
            }
    })
}

// 根据视频的状态变化,判断其是否播放完成
handleStateChange = (state, preState) = > {
    // 视频播放结束回到初始状态(进度条)
    if(state.ended && !prevState.ended){
        this[this.state.ref_name].video.load();
    }
}

希望大家能持续关注哦,留一些个人信息方便大家找到我哦。
github

你可能感兴趣的:(javascript,前端,视频,兼容性,h5播放器)