前段时间公司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="data:images/video.jpg" style="width: 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); width: 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应该是个不错的选择。

H5 video踩坑实录的更多相关文章

  1. 后端路由项目由 gulp 改为 webpack 的踩坑实录

    前言 公司有个后端路由的项目是用 gulp 作为前端自动化构建工具,最近学习了一下 webpack,深感其强大,一狠心将其改成了 webpack 构建,以下是踩坑实录. gulp 先来说说原来的架构. ...

  2. JAVA实用案例之文件导出(JasperReport踩坑实录)

    写在最前面 想想来新公司也快五个月了,恍惚一瞬间. 翻了翻博客,因为太忙,也有将近五个多月没认真总结过了. 正好趁着今天老婆出门团建的机会,记录下最近这段时间遇到的大坑-JasperReport. 六 ...

  3. ffmpeg 踩坑实录 添加实时水印(二)

    一.背景介绍 最近领导要求做一个视频录制的相关项目.其中,需要对视频文件进行添加 实时时间水印.于是,我想到了使用之前的ffmpeg来做. 二.ffmpeg实际操作 首先把需要添加水印的视频文件,上传 ...

  4. JasperReport报表导出踩坑实录

    写在最前面 翻了翻博客,因为太忙,已经好久没认真总结过了. 正好趁着今天老婆出门团建的机会,记录下最近这段时间遇到的大坑-JasperReport. 六月份的时候写过一篇利用poi文件导入导出的小De ...

  5. HashMap踩坑实录——谁动了我的奶酪

    说到HashMap,hashCode 和 equals ,想必绝大多数人都不会陌生,然而你真的了解这它们的机制么?本文将通过一个简单的Demo还原我自己前不久在 HashMap 上导致的线上问题,看看 ...

  6. (最新)VS2015安装以及卸载过程——踩坑实录

    前言 Visual Studio (简称VS)是微软公司旗下最重要的软件集成开发工具产品.是目前最流行的 Windows 平台应用程序开发环境,也是无数人学习编程的入门软件之一.Visual Stud ...

  7. ffmpeg 踩坑实录 安装与视频切片(一)

    这段时间一直在做一个关于视频处理的项目.其中有一块需要切片相关功能.于是采用了ffmpeg来完成相关需求. 第一,ffmpeg的安装. 首先下载官方包,我这里用的是ffmpeg-release-64b ...

  8. windows安装rabbitmq踩坑实录

    最近学习springcloud消息总线需要用到rabbitmq,然后安装的时候踩了一些坑,记录如下: 首先安装rabbitmq之前需要先安装erlang,因为rabbitmq服务端使用erlang写的 ...

  9. Ubuntu14.04安装PowerDNS踩坑实录

    公司要使用PowerDNS,作为内网域名解析的工具.让我和另一组的同事学一下如何配置及调优.所以先找了两台服务器试着安装一下.这一装就是一个礼拜,经历了大大小小的坑,记下来以后可能需要参考.安装过程如 ...

随机推荐

  1. [LeetCode] 由 “打印机任务队列" 所想

    一.这是个基础问题 Ref: Python之队列模拟算法(打印机问题)[首先研究这个问题作为开始] 任务队列 定义一个任务队列,来管理任务,而无需关心队列的”任务类型". # 自定义队列类 ...

  2. [C++]类的设计(2)——拷贝控制(析构和三五法则)

    1.析构函数:释放对象使用的资源,并销毁对象的非static数据成员:析构函数不接受参数,因此不能被重载.对于一个给定类,有且只有一个析构函数.   2.析构函数的组成:一个函数体+一个析构部分(im ...

  3. 转:ext的xtype值

    基本组件: xtype Class 描述 button Ext.Button 按钮 splitbutton Ext.SplitButton 带下拉菜单的按钮 cycle Ext.CycleButton ...

  4. win10下安装FFmpeg步骤

    1.官方下载地址:https://ffmpeg.zeranoe.com/builds/ # 下载方式一,太慢 # 下载方式二,推荐 2.解压到D:\Program Files (x86),这个看个人喜 ...

  5. flexible.js分析--JavaScript

    //立即执行函数 (function flexible(window, document) { // 获取的html 的根元素 var docEl = document.documentElement ...

  6. Django中的表关系实现及操作

    表关系的实现   预备知识 ORM的正向操作和反向操作: 1.正向操作:一个模型中定义了一个外键,通过该模型对该外键操作的操作叫做正向操作. 2.反向操作:被外键所关联的模型,通过该模型对外键所在模型 ...

  7. Lab_0操作系统实验准备(全)

    一.实验介绍 实验目的: 知识储备: 二.相关下载 1.下载镜像文件 这个镜像文件是vdi类型的,只能用visualbox下载 链接:https://pan.baidu.com/s/1L7WX6ju4 ...

  8. CSS隐藏元素 display、visibility、opacity的区别

    关于使指定元素无法在视野内看到,有3个方法 display: none; opacity: 0; visibility: hidden; 1.display: none; 该方法会改变页面布局. 元素 ...

  9. 【DP合集】合并 union

    给出一个 1 ∼ N 的序列 A ( A 1 , A 2 , ..., A N ) .你每次可以将两个相邻的元素合并,合并后的元素权值即为 这两个元素的权值之和.求将 A 变为一个非降序列,最少需要多 ...

  10. 【NOIP2016】蚯蚓

    Description 本题中,我们将用符号 ⌊c⌋表示对 cc 向下取整,例如:⌊3.0⌋=⌊3.1⌋=⌊3.9⌋=3. 蛐蛐国最近蚯蚓成灾了!隔壁跳蚤国的跳蚤也拿蚯蚓们没办法,蛐蛐国王只好去请神刀 ...