[html](video)微信浏览器中video播放视频的兼容

1.需求

朋友的一个公众号线上商城需要使用视频播放功能

  • 后台 上传视频+视频封面
  • 前台 视频列表使用后台上传封面展示(播放视频完成后也只显示封面图)
  • 前台 视频点击后全屏播放(自定义的样式,而为微信提供的默认视频播放)
  • 为减轻服务器压力,使用七牛云存储上传

2. 当时的思路整理

一开始想的很简单,①后台上传-> ②七牛云存储-> ③视频链接存储数据库-> ④前台显示

3. 产生问题

①②③很快解决了
但是④前台使用 在微信中 html5

  • 苹果 video标签加载好,poster 封面正常显示,点击播放为苹果自带的视频播放逻辑,但退出播放后,封面图消失。
  • 安卓 video标签加载时,poster封面一闪而过,然后将视频中的第一帧作为封面显示了(视频尺寸横竖宽高都不一样),然后视频播放为x5内核浏览器默认的视频播放逻辑,播放完后有令人讨厌的广告。

4.解决问题

上述得知 poster封面一闪而过 的问题的原因了,poster写得很清楚,播放了poster就失效了!

  • poster失效的解决思路
    页面加载后,将上传的封面图显示,外加一个三角播放图,视频隐藏
    用户点击此区域,执行视频的显示、播放,封面图的隐藏
    用户退出视频播放,执行视频的隐藏、暂停,封面图的显示
    大概代码如下

① 页面加载

// html文件
// js文件

②用户点击(关键代码)

//js文件
function switchPlay(obj){
var videoObj = $(obj).find(".video1")
var locate_poster = $(obj).find(".video-preview")
//如果是播放状态的视频,则切换视频为暂停并隐藏,显示封面
  if(videoObj.attr("data-box-flag")=="true" || videoObj.attr("data-box-flag")==true){
    videoObj.get(0).pause();
    videoObj.hide()
    locate_poster.show();
  }
  else{
    videoObj.show()
    locate_poster.hide();
    videoObj.get(0).play()
  }
}
  • 微信X5内核浏览器的官方文档关于H5同层播放器的说明

x5-video-player-type 启用H5同层播放器

通过video属性“x5-video-player-type”声明启用同层H5播放器

同层页面内播放是标准的视频播放形态,在video标签中添加属性来控制网页内部同层播放,可以在视频上方显示html元素。

示例: https://tencentx5.github.io/x5/video_page_samelayer.htm

详情可以参考: https://docs.qq.com/doc/DTUxGdWZic0RLR29B

依此可以解决 “\color{#FF3030}{安卓 video标签加载时,poster封面一闪而过,然后将视频中的第一帧作为封面显示了(视频尺寸横竖宽高都不一样),然后视频播放为x5内核浏览器默认的视频播放逻辑,播放完后有令人讨厌的广告}” 问题


//html 文件
 
  • Safari浏览器关于 HTML5 Audio 和 Video 的指南 关于全屏进入和退出事件的触发
    image.png

    这边写得很清楚,ios中当视频进入或退出全屏模式,webkitbeginfullscreen 和 webkitendfullscreen 分别触发
    因此解决 “\color{#FF3030}{苹果 video标签加载好,poster 封面正常显示,点击播放为苹果自带的视频播放逻辑,但退出播放后,封面图消失。}” ,就有了方法
// js文件
//当点击播放时,绑定全屏事件,退出全屏时 隐藏视频和显示自定义封面图
if(isiOS){
        var video = videoObj.get(0);
        video.addEventListener('webkitbeginfullscreen', function() {
            _exitfullscreen = false;
        });
        video.addEventListener("webkitendfullscreen", function(){
            locate_poster.show(); //自设定的封面图显示
            videoObj.hide() // 视频隐藏
            loadingdiv.hide(); 
        });
}

完后后的效果

  • 安卓


    Screenrecorder-2019-12-26-10-24-09-791.gif
  • 苹果


    1577327921194.gif

B站做出的效果(太完美了)

轻视频引流 福利哦!!

1577328387769.gif

[B站在微信打开效果非常好] (https://m.bilibili.com/index.html)

1577328461815.gif

最后-完整的文件

-html文件

-css文件

.img-box-hengv{
    width: 100%;
    /* height: 80px; */
    display: flex;
    overflow-x: auto;
    flex-direction: row;
    flex-wrap: nowrap;
    justify-content: flex-start;
}
.img-box-hengv img{
    width: 33%;
}
.pro-box-hengv{
    box-sizing: border-box;
    position: relative;
    width: calc(33%);
    float: left;
    position: relative;
    box-shadow: 0 0px 0px rgba(0, 0, 0, 0.5);
    /*padding: 5px 20px 5px;*/
    text-align: center;
}
.pro-box-hengv img{
    width:100%;
    border-radius: 5px;
    padding: 2px;
}
.preview-videos {
    width: 99%;
    float: left;
    padding: 2px;
    border-radius: 5px;
    background: #ccc;
}
.video1{
    display:none;
}
.pro-box-video{
    cursor:pointer;
}
.playdiv{
    position:absolute;top: 40%;margin-top: -25px;margin-left: -25px;left: 50%;
}
.playimg{
    width:50px!important;
    height:50px!important;
}
.pro-box-focus{
    position: fixed;
    width: 100%;
    z-index: 9999;
    background-color: black;
    height: auto;
    top: 0;
}
.pro-box-focus video{
    position: absolute;
    top: 50%;
    left: 50%;
    padding:0!important;
}
.pro-box-focus .playdiv{
    top:50%!important;
    position:fixed!important;
}
.video-close-btn{
    position: absolute;
    width: 36px;
    height: 36px;
    background: rgba(0,0,0,0.5) url(/weixinpl/mshop/images/icon-closew.png) no-repeat center;
    right: 50px;
    top: 10px;
    background-size: 50%, 25%, 25%;
    border-radius: 5px;
}
.loadingdiv{
    position: absolute;
    top: 40%;
    margin-top: -8px;
    margin-left: -8px;
    left: 50%;
    width: 16px!important;
    height: 16px;
    background: url(/weixinpl/common/qiniu-sdk/images/ui-anim_basic_16x16.gif) no-repeat scroll 0 0 transparent;
    float: left;
    z-index: 9999;
    display:none;
}
.video-preview{
    border-radius: 5px;
    padding: 2px;
}
  • js文件
/**
 * 手機播放視頻時,切換全屏系列動作,兼容蘋果和安卓
 * @param obj 點擊 包裹視頻整個dom
 */

var u = navigator.userAgent;
var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; //android终端
var isiOS = u.indexOf('iPhone') > -1  ; //ios终端
var _exitfullscreen = true; //全屏标识,在此暂未用到,但是需要预留

/**
 * 手機端視頻兼容播放js
 * @autor raulin 20191220
 * 説明:微信端以及安卓/手機 存在很多不兼容的情況,簡單的做了一些適配
 * 需配合 對應的 html代碼 和 css 使用
 */
function switchPlay(obj){
    var videoObj = $(obj).find(".video1") //视频
    var playDiv = $(obj).find(".playdiv") // 播放按钮
    var loadingdiv = $(obj).find(".loadingdiv") // 加载图
    var poster = $(obj).find(".qiniu-poster") //七牛拿过来的第一张封面图,用于全屏时的 垂直居中
    var locate_poster = $(obj).find(".video-preview") // 自定义封面图(为了美观)
    var videohFlag = parseInt(videoObj.css("height")) //未播放前的视频高度
    var pw = parseInt(poster.css("width")) //七牛封面图的宽度
    var ph = parseInt(poster.css("height")) //七牛封面图的高度
    var dataBoxFlag = videoObj.attr("data-box-flag") //判断是否已经进入全屏状态(安卓适用)

    if(dataBoxFlag=="true" || dataBoxFlag==true){
        console.log("正在蒙版中,所以不处理播放逻辑,处理缩小逻辑")
        //暂停视频
        videoObj.get(0).pause();
        //去除模拟全屏状态
        $(obj).removeClass("pro-box-focus");
        $(".video-close-btn").remove(); //全屏的关闭按钮去除
        $(obj).css("height","auto");
        //视频尺寸位置还原
        videoObj.css({"margin-left":"","margin-top":""})
        videohFlag = videoObj.attr("data-videoh-flag")
        videoObj.css("height",videohFlag+"px")
        //显示封面图+播放按钮图,隐藏视频
        locate_poster.show();
        videoObj.hide()
        playDiv.show()
        loadingdiv.hide();
        //标注全屏状态为false
        videoObj.attr("data-box-flag","false")
        return;
    }
    loadingdiv.show();
    if(isiOS){
        var video = videoObj.get(0);
        video.addEventListener('webkitbeginfullscreen', function() {
            _exitfullscreen = false;
        });
        video.addEventListener("webkitendfullscreen", function(){
            locate_poster.show();
            videoObj.hide()
            loadingdiv.hide();
        });
        video.addEventListener('pause', function(e) {
            pauseTimestamp = new Date().getTime();
            console.log('触发了 暂停', pauseTimestamp);
        });
        videoObj.show()
        locate_poster.hide();
        videoObj.get(0).play()

    }else{
        locate_poster.hide();
        videoObj.show()
        videoObj.get(0).play()
        $(obj).addClass("pro-box-focus");
        $(obj).css("height",document.documentElement.clientHeight+"px");
        videoObj.css("height","auto")
        k = 0;
        if(pw>0){
            console.log(pw+"-"+ph)
            k = parseFloat(ph/pw);
        }
        if(k>0){
            w = document.body.clientWidth
            mt = -1*(w*k)/2

        }else{
            mt = -1*(parseInt(videoObj.css("height"))/2)
        }
        ml = -1*(document.body.clientWidth/2)

        videoObj.css({"margin-left":ml+"px","margin-top":mt+"px"})

        playDiv.hide()

        videoObj.attr("data-videoh-flag",videohFlag)
        videoObj.attr("data-box-flag","true")
        videoObj.attr("data-play-flag","true")
        videoObj.parent().append("
") loadingdiv.hide(); } } /** * 全屏狀態下 ,播放 停止 與退出 * @param obj 視頻dom / 播放按鈕dom * @param flag 0 obj為視頻dom 1 obj為播放按鈕dom */ function switchplaycheck(obj,flag=0){ var videoObj = $(obj) var playDiv = $(obj).siblings(".playdiv") if(flag==1){ videoObj = $(obj).siblings(".video1") playDiv = $(obj) } boxFlag = videoObj.attr("data-box-flag") if(boxFlag=="false"|| boxFlag==false){ switchPlay(videoObj.parent().parent().get(0)) return; } console.log("点到video啦") playFlag = videoObj.attr("data-play-flag") if(playFlag == "true"){ videoObj.get(0).pause(); videoObj.attr("data-play-flag","false") playDiv.show() }else{ videoObj.get(0).play(); videoObj.attr("data-play-flag","true") playDiv.hide() } }

end

你可能感兴趣的:([html](video)微信浏览器中video播放视频的兼容)