zoukankan      html  css  js  c++  java
  • H5 video踩坑实录

          前段时间公司APP做了一个APP论坛会议,嵌入了h5播放器。我以为很简单,没想到,这正是我踩进泥潭的开始。。。

        (想要吸取经验的小伙伴可以慢慢往下看,想要解决方案的直接看最后!)

        一、一开始我以为直接用H5原生video就可以直接实现。

          

    <video src="url" poster="video.png" width="100%" height = "9rem"></video>

          src :视频地址,

          poster:视频封面,

          obj.play() :播放,

          obj.pause():暂停。

          到这里我以为就大功告成了,没想到啊,

          首先没有控制条,其次苹果浏览器默认全屏,而且苹果不能直接播放和加载。后来Google发现苹果不允许直接播放视频,除非用户主动点击(这是什么混蛋逻辑)。

          

        二、改变思路,把图片放在video上层,点击触发video播放。同时添加controls,设置playsinline不全屏播放

          html:

          <div id = "myvideo">
    
            <img src = "video.png">
    
            <video src="url" poster="video.png" width="100%" height = "9rem" controls="controls" ></video>
    
          </div>

          js:

                IMG.addEventListener ('click',function(){
    
             img.style.display='none';
    
             video.style.display = 'block';
    
           });
    
            video.addEventListener ('click',function(){
    
              video[0].play();
    
            })        

            ……

          css就不放出来了,小伙伴们自行前往git上下载。

          运行一下发现原生的控制条也太丑了。

                      

          而且还发现这玩意的全屏在移动端无法全屏,点击全屏没有反应。

        三、痛定思痛决定重写video组件,一方面优化这丑陋的原生ui,另一方面通过js方法看看能不能支持全屏。

          html:  

          

          <div class="myvideo">
            <img src="images/video.jpg" style=" 100%;height:100%;" class="img">
            <video class="video" 
             playsinline="isiPhoneShowPlaysinline" x5-video-player-type="h5-page" webkit-playsinline="isiPhoneShowPlaysinline" x-webkit-airplay="" preload="none" 
             src="https://blz-videos.nosdn.127.net/1/HearthStone/f6cd63b590d416821d3e27e0.mp4" poster="images/video.jpg"></video>
            <div class="play">
              <svg t="1561619557935" class="iconPause" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6167" width="2.2rem" height="2.2rem" >
                <path d="M844.704269 475.730473L222.284513 116.380385a43.342807 43.342807 0 0 0-65.025048 37.548353v718.692951a43.335582 43.335582 0 0 0 65.025048 37.541128l622.412531-359.342864a43.357257 43.357257 0 0 0             0.007225-75.08948z" fill="#ffffff" p-id="6168"></path>
              </svg>
              <svg t="1562137769830" class="iconPlay" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3655" width="2.2rem" height="2.2rem" style="display: none;">
                <path d="M319.618435 145.655358c-30.518061 0-55.258535 24.740474-55.258535 55.258535l0 622.170169c0 30.518061 24.740474 55.258535 55.258535 55.258535s55.258535-24.740474 55.258535-55.258535l0-  622.170169C374.876969 170.395832 350.136495 145.655358 319.618435 145.655358z" p-id="3656" fill="#ffffff"></path><path d="M704.381565 145.655358c-30.518061 0-55.258535 24.740474-55.258535 55.258535l0 622.170169c0 30.518061 24.740474             55.258535 55.258535 55.258535s55.258535-24.740474 55.258535-55.258535l0-622.170169C759.6401 170.395832 734.899626 145.655358 704.381565 145.655358z" p-id="3657" fill="#ffffff"></path>
              </svg>
            </div>
            <div class="playShade">
              <div class="progressFather">
                <div class="realTime">00:00</div>
                <div id="progress">
                  <span class="timeBar"></span>
                </div>
                <div class="endTime">00:00</div>
                <div class="all">
                  <svg t="1561625645528" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1999" width="1.6rem" height="1.6rem">
                  <path d="M576 213.333333c0 12.8 8.533333 21.333333 21.333333 21.333334h162.133334l-202.666667 202.666666c-8.533333 8.533333-8.533333 21.333333 0 29.866667 8.533333 8.533333 21.333333 8.533333 29.866667               0l202.666666-202.666667V426.666667c0 12.8 8.533333 21.333333 21.333334 21.333333s21.333333-8.533333 21.333333-21.333333V213.333333c0-12.8-8.533333-21.333333-21.333333-21.333333H597.333333c-12.8               0-21.333333 8.533333-21.333333 21.333333z m-138.666667 343.466667L234.666667 759.466667V597.333333c0-12.8-8.533333-21.333333-21.333334-21.333333s-21.333333 8.533333-21.333333 21.333333v213.333334c0               12.8 8.533333 21.333333 21.333333 21.333333h213.333334c12.8 0 21.333333-8.533333 21.333333-21.333333s-8.533333-21.333333-21.333333-21.333334h-162.133334l202.666667-202.666666c8.533333-8.533333               8.533333-21.333333 0-29.866667-6.4-8.533333-21.333333-8.533333-29.866667 0z" p-id="2000" fill="#ffffff"></path>
                  </svg>
                </div>
              </div>
            </div>
          </div>

        js:

        

    //初始时间,进度显示
    function strTime() {
    starTime[0].innerHTML = timeFormat(mvideo[0].currentTime);
    endTime[0].innerHTML = timeFormat(mvideo[0].duration);
    var currentTime = mvideo[0].currentTime;
    var duration = mvideo[0].duration;
    var percent = 100 * currentTime / duration;
    timeBar[0].style.width = percent + '%';
    //dropProgress();
    };
    //播放
    function videoPlay() {
    mvideo[0].play();
    iconPlay[0].style.display = 'block';
    iconPause[0].style.display = 'none';
    }
    //暂停
    function videoPause() {
    mvideo[0].pause();
    iconPlay[0].style.display = 'none';
    iconPause[0].style.display = 'block';
    }
    //时长转换
    function timeFormat(seconds) {
    var minite = Math.floor(seconds / 60);
    if (minite < 10) {
    minite = "0" + minite;
    }
    var second = Math.floor(seconds % 60);
    if (second < 10) {
    second = "0" + second;
    }
    return minite + ":" + second;
    }
    //更新进度条
    function updateProgress(x, width) {
    var position = x / width;
    mvideo[0].currentTime = position * mvideo[0].duration;
    timeBar[0].style.width = position * 100 + '%';
    }
    
    //全屏
    function all() {
    // console.log(width, height);
    // ovideo[0].style.transform = 'rotate(90deg) translate(' + (height - width) / 2 + 'px,' + (height - width) / 2 + 'px)';
    // ovideo[0].style.zIndex = 2;
    // ovideo[0].style.heigt = width + 'px';
    // ovideo[0].style.width = height + 'px';
    // ovideo[0].style.marginTop = -2 + 'px';
    // ltitle[0].style.display = 'none';
    // lcontent[0].style.display = 'none';
    requestFullScreen(ovideo[0]);
    };
    //全屏
    function requestFullScreen(element) {
    var el = element;
    if (el.requestFullscreen) {
    el.requestFullscreen()
    } else if (el.mozRequestFullScreen) {
    el.mozRequestFullScreen()
    } else if (el.webkitRequestFullscreen) {
    el.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT)
    } else if (player.video.webkitSupportsFullscreen) {
    player.video.webkitEnterFullscreen()
    } else if (el.msRequestFullscreen) {
    el.msRequestFullscreen()
    } else {
    util.addClass(el, 'xgplayer-fullscreen-active')
    }
    }
    //退出全屏
    function exitFullscreen() {
    var el = document;
    if (document.exitFullscreen) {
    document.exitFullscreen()
    } else if (document.webkitExitFullscreen) {
    document.webkitExitFullscreen()
    } else if (document.mozCancelFullScreen) {
    document.mozCancelFullScreen()
    } else if (document.msExitFullscreen) {
    document.msExitFullscreen()
    } else {
    util.removeClass(el, 'xgplayer-fullscreen-active')
    }
    }
    //取消全屏
    function quitAll() {
    // ovideo[0].style.transform = 'rotate(360deg) translate(' + (height - width) / 2 + 'px,' + (height - width) / 2 + 'px)';
    // ovideo[0].style = 'none';
    // ltitle[0].style = 'none';
    // lcontent[0].style = 'none';
    // alert(123);
    exitFullscreen();
    }

     css请前往git自行下载。

    发现iOS无法全屏,查询发现iOS移动浏览器已经禁用了fullScreen组件。崩溃了要。。。

    四、继续改,lz整个伪全屏出来,

      逻辑就是判断浏览器宽高,点击全屏的时候旋转屏幕,然后赋值宽高,慢慢调整,返回全屏时js动态奖video的style设置为空。

      

    var conW = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
    var conH = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
    // transform: rotate(90deg);  667px; height: 375px;transform-origin:28% 50%;
    //var iosTopHe = 0;//若有其他样式判断,写于此
    
    $("#video").css({
    "transform":"rotate(90deg) translate("+((conH-conW)/2)+"px,"+((conH-conW)/2)+"px)",
    "width":conH+30+"px",
    "height":conW+35+"px",
    //"margin-top":iosTopHe+"px",
    // "border-left":iosTopHe+"px solid #000",
    "transform-origin":"center center",
    "-webkit-transform-origin": "center center",
    "z-index":"11111",
    "margin-top":"2.2rem"
    });
    $("#myvideo").css({
    "width":conH+"px",
    "height":conW+"px",
    "margin-top":"0rem",
    "z-index":"11111"
    });
    $('.psVideo-shade').css({
    "z-index":"1111111",
    "width":conH+"px",
    "height":conW+"px",
    //"marginTop":"12rem"
    });
    $('.psVideo-progress').css({
    "width":conH+"px",
    "height":"0.2rem"
    });
    $('.psVideo-btn').css({
    "margin-left":"12rem",
    //"height":"0.2rem"
    })
    $('.psVideo-play-footer').css({
    "margin-bottom":"-0.2rem",
    //"height":"0.2rem"
    })
    width = conH;
    var lw = $('.psVideo-timeBar').width();
    var progresses = $('.psVideo-progress');
    var pw = $('.psVideo-progress')
    var rlw = lw*pw/width;
    $('.psVideo-timeBar').css('width', rlw+'px');
    qenableProgressDrag();
    //updateProgress(rlw);
    quan = true;

    实现起来一言难尽。还是上效果吧。

    你也看见了,状态栏收不回去。没办法,慢慢找别的思路吧。

    五、我在找资料的时候,突然想起来,我上一版的页面在微信,钉钉上都能正常显示,浏览器上好像也能(safari除外)。

      我翻过头去研究之前那一版代码,半天也没有思路,我突然发现video还有第三方插件

      腾讯:https://cloud.tencent.com/document/product/454/7503

      阿里:https://help.aliyun.com/document_detail/51991.html

      七牛:https://developer.qiniu.com/pili/sdk/4621/web-player-sdk

      头条(西瓜):http://h5player.bytedance.com/api/#%E5%AE%9E%E4%BE%8B%E5%8C%96%E5%AE%8C%E6%88%90

      然并卵,在app上仍然无法正常显示,真的要崩溃了。

    六、转机(重点)

      我在漫无目的的找资料的时候,偶然点进去一个安卓webview解决办法,看的时候发现播放器好像没有这么麻烦。嘿嘿嘿,功夫不怕有心人。

      原来移动端嵌套webview时候可以引进ui控件。

      我又去看了一下移动端的ui控件,原来如此。

      安卓iOS引入webview ui控件(移动端又称内核,简单来说就是一个sdk),它可以劫持webview里的h5组件然后渲染,

      微信,钉钉包括我的华为浏览器用的都是这种办法,微信引入了x5内核,钉钉引得啥内核,我不知道,反正事情发展到这出现了转机,我问我之前的安卓同事,从他口里听见了肯定的回复之后,我终于放松了。

      总的来说,对于混合开发APP来说,其实播放器没有那么复杂,H5写入一个video组件即可,ui控件(sdk)会直接帮你渲染。(安卓,ios)统一样式需要他们去解决了,毕竟有的sdk不太支持iOS(比如X5)。

      对于webApp来说,H5Plus应该是个不错的选择。

  • 相关阅读:
    【故障处理】ORA-12162: TNS:net service name is incorrectly specified (转)
    android studio 编程中用到的快捷键
    java时间格式串
    android Error occurred during initialization of VM Could not reserve enough space for object heap Could not create the Java virtual machine.
    linux安装vmware
    x1c 2017 安装mint18的坑——grub2
    x1c2017 8G版 win linux的取舍纠结记录
    python的try finally (还真不简单)
    kafka+docker+python
    json文件不能有注释
  • 原文地址:https://www.cnblogs.com/shoucigongkai/p/11231378.html
Copyright © 2011-2022 走看看