这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

概述

最近在负责公司官网的开发,在 H5 播放视频时,遇到很多兼容问题,所以总结下在 H5 播放时,遇到的兼容性问题,并封装一个 Video 的组件,便于在 H5 使用。

测试

先来测试一下在不同的浏览器,video 有什么兼容性的问题,要测试两种情况:

  1. 可以内联播放,视频上方可以正常叠文字
  2. 可以全屏播放,比如点击后,全屏播放

前置配置

HTML 和 Style

下面测试的内容,视频节点是以正常文档流方式渲染:

 <div class="video-wrap">
<video :src="videoUrl" :poster="poster" class="video" ref="refVideo" :playsinline="form.playsinline"
:webkit-playsinline="form.playsinline" :x5-playsinline="form.playsinline" :muted="form.muted" :loop="form.loop"
:autoplay="form.autoplay" :controls="form.controls" :x5-video-player-fullscreen="form.x5VideoPlayerFullscreen"
:x5-video-player-type="form.x5VideoPlayerType" :preload="form.preload" />
<div class="video-title">Test title</div>
</div>
<style lang="scss" scoped>
.video {
object-fit: contain;
width: 100%;
height: 100%;
&-wrap {
height: 350px;
position: relative;
}
&-title {
font-size: 24px;
color: #fff;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: #000;
}
}
</style>

渲染的视频和页面不是同域名的,视频的格式是 .mp4

meta 的配置:

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">

下方设置的 playsinline,统一设置了 playsinline + x5-playsinline + webkit-playsinline

测试环境

然后使用我手上的 ios 和 android 手机测试,以下是测试的环境:

  1. ios(17)
    1. safari
    2. 微信
    3. edge
    4. chrome
    5. firefox
    6. UC
    7. 夸克
    8. 百度APP
  2. android(13)
    1. 微信
    2. edge
    3. firefox
    4. qq 浏览器
    5. 夸克
    6. UC
    7. 小米浏览器
    8. 百度APP

ios 系统:

safari

值/属性 muted playsinline autoplay loop preload controls x5VideoPlayerType x5VideoPlayerFullscreen 结果
  true true false false none true none false 正常内联播放
  true false false false none true none false 正常内联播放
  false false false false none true none false 正常内联播放
  true true true false none true none false 自动播放
  true false true false none true none false 自动播放
  false false true false none true none false 不会自动播放
  false false true false none true none false 全屏,自动播放

微信

值/属性 muted playsinline autoplay loop preload controls x5VideoPlayerType x5VideoPlayerFullscreen 结果
  true true false false none true none false 正常内联播放
  true false false false none true none false 正常内联播放
  false false false false none true none false 正常内联播放
  true true true false none true none false 自动播放
  true false true false none true none false 自动播放
  false false true false none true none false 自动播放
  false false true false none true none false 全屏,自动播放

edge

值/属性 muted playsinline autoplay loop preload controls x5VideoPlayerType x5VideoPlayerFullscreen 结果
  true true false false none true none false 正常内联播放
  true false false false none true none false 正常内联播放
  false false false false none true none false 正常内联播放
  true true true false none true none false 自动播放
  true false true false none true none false 自动播放
  false false true false none true none false 不会自动播放
  false false true false none true none false 全屏,自动播放

chrome

值/属性 muted playsinline autoplay loop preload controls x5VideoPlayerType x5VideoPlayerFullscreen 结果
  true true false false none true none false 正常内联播放
  true false false false none true none false 正常内联播放
  false false false false none true none false 正常内联播放
  true true true false none true none false 自动播放
  true false true false none true none false 自动播放
  false false true false none true none false 不会自动播放
  false false true false none true none false 全屏,自动播放

firefox

值/属性 muted playsinline autoplay loop preload controls x5VideoPlayerType x5VideoPlayerFullscreen 结果
  true true false false none true none false 正常内联播放
  true false false false none true none false 正常内联播放
  false false false false none true none false 正常内联播放
  true true true false none true none false 自动播放
  true false true false none true none false 自动播放
  false false true false none true none false 不会自动播放
  false false true false none true none false 全屏播放

夸克

值/属性 muted playsinline autoplay loop preload controls x5VideoPlayerType x5VideoPlayerFullscreen 结果
  true true false false none true none false 正常内联播放,滚动页面后,视频会置顶
  true false false false none true none false 正常内联播放,滚动页面后,视频会置顶
  false false false false none true none false 正常内联播放,滚动页面后,视频会置顶
  true true true false none true none false 不会自动播放
  true false true false none true none false 不会自动播放
  false false true false none true none false 不会自动播放
  true true true false auto false h5-page false 不会自动播放
  false false true false none true none false 无法全屏播放

UC

值/属性 muted playsinline autoplay loop preload controls x5VideoPlayerType x5VideoPlayerFullscreen 结果
  true true false false none true none false 正常内联播放,滚动页面后,视频会置顶
  true false false false none true none false 正常内联播放,滚动页面后,视频会置顶
  false false false false none true none false 正常内联播放,滚动页面后,视频会置顶
  true true true false none true none false 不会自动播放
  true false true false none true none false 不会自动播放
  false false true false none true none false 不会自动播放
  true true true false auto false h5-page false 不会自动播放
  false false true false none true none false 无法全屏播放
  false false true false none false none false 无法全屏播放

百度 APP

值/属性 muted playsinline autoplay loop preload controls x5VideoPlayerType x5VideoPlayerFullscreen 结果
  true true false false none true none false 正常内联播放
  true false false false none true none false 正常内联播放
  false false false false none true none false 正常内联播放
  true true true false none true none false 自动播放
  true false true false none true none false 自动播放
  false false true false none true none false 自动播放
  false false true false none true none false 可以全屏播放,但关闭全屏后,视频会一直停留在顶端

百度 APP 在上述配置下,还会根据 video 节点的位置有不同的显示效果,如果 video 是在页面顶部的位置,它就会一直置顶播放,如果在页面下发(起码超过页面可视区的一半以上),它就会正常内联播放

总结

内联播放:

  1. ios 系统在 safari, 微信, edge, chrome, firefox 的表现都没问题,但在未静音的情况下无法自动播放视频
  2. 而在夸克、UC 和百度 APP 的播放表现上,就很有问题,严重影响用户的体验,视频会被浏览器劫持播放,置顶在页面顶部,挡住页面内容

全屏播放:

  1. 和内联播放的情况差不多
  2. 夸克和 UC 不知道为啥(都是阿里系的),会触发异常,禁止全屏
  3. ios 全屏播放后,再切换页面,如果切换的页面有视频,这时候会自动全屏播放

android 系统

微信

值/属性 muted playsinline autoplay loop preload controls x5VideoPlayerType x5VideoPlayerFullscreen 结果
  true true false false none true none false 正常内联播放
  true false false false none true none false 正常内联播放
  false false false false none true none false 正常内联播放
  true true true false none true none false 自动播放
  true false true false none true none false 自动播放
  false false true false none true none false 不会自动播放
  true true true false auto true h5-page true 全屏后,不会播放

edge

值/属性 muted playsinline autoplay loop preload controls x5VideoPlayerType x5VideoPlayerFullscreen 结果
  true true false false none true none false 正常内联播放
  true false false false none true none false 正常内联播放
  false false false false none true none false 正常内联播放
  true true true false none true none false 自动播放
  true false true false none true none false 自动播放
  false false true false none true none false 不会自动播放
  true true true false auto true none false 全屏后,会播放

firefox

值/属性 muted playsinline autoplay loop preload controls x5VideoPlayerType x5VideoPlayerFullscreen 结果
  true true false false none true none false 正常内联播放
  true false false false none true none false 正常内联播放
  false false false false none true none false 正常内联播放
  true true true false none true none false 自动播放
  true false true false none true none false 自动播放
  false false true false none true none false 不会自动播放
  true true true false auto true none false 全屏后,会播放

qq 浏览器

值/属性 muted playsinline autoplay loop preload controls x5VideoPlayerType x5VideoPlayerFullscreen 结果
  true true false false none true none false 正常内联播放,滚动页面后,视频会置顶
  true false false false none true none false 正常内联播放,滚动页面后,视频会置顶
  false false false false none true none false 正常内联播放,滚动页面后,视频会置顶
  false false false false none true h5-page false 正常内联播放
  true true true false none true none false 不会自动播放
  true false true false none true none false 不会自动播放
  false false true false none true none false 不会自动播放
  true true true false none true none false 会播放,但没全屏
  true true true false none true none true 需要先播放才能全屏

夸克

值/属性 muted playsinline autoplay loop preload controls x5VideoPlayerType x5VideoPlayerFullscreen 结果
  true true false false none true none false 正常内联播放,滚动页面后也正常,但视频会置顶,挡住视频上方绝对定位的文字内容
  true false false false none true none false 同上
  false false false false none true none false 同上
  false false false false none true h5-page false 同上
  false false false false none false none false 正常内联播放
  true true true false none true none false 自动播放
  true false true false none true none false 不会自动播放
  false false true false none true none false 不会自动播放
  true true true false none true none false 无法全屏播放,异常:fullscreen is disallowed
  false false false false none false none false 全屏播放

UC

值/属性 muted playsinline autoplay loop preload controls x5VideoPlayerType x5VideoPlayerFullscreen 结果
  true true false false none true none false 正常内联播放,但视频会置顶,挡住视频上方绝对定位的文字内容
  true false false false none true none false 同上
  false false false false none true none false 同上
  false false false false none true h5-page false 同上
  true true false false none false none false 正常内联播放
  true true true false none true none false 会自动播放
  true false true false none true none false 会自动播放
  false false true false none true none false 不会自动播放
  true true true false none true none false 无法全屏播放,异常:fullscreen is disallowed
  true true false false none false none false 全屏播放

小米浏览器

值/属性 muted playsinline autoplay loop preload controls x5VideoPlayerType x5VideoPlayerFullscreen 结果
  true true false false none true none false 正常内联播放,但视频会置顶,挡住视频上方绝对定位的文字内容
  true false false false none true none false 同上
  false false false false none true none false 同上
  false false false false none true h5-page false 同上
  false false false false none false none false 正常内联播放
  true true true false none true none false 不会自动播放
  true false true false none true none false 不会自动播放
  false false true false none true none false 不会自动播放
  true true false false none true none false 可以全屏,会自动播放

百度 APP

播放就会置顶在可视区最顶端,无论如何控制 全屏播放,如果 autoplay 没有设置 true,不会自动播放,只会全屏

总结

内联播放:

  1. 在 微信, edge, firefox, qq 的表现都没问题,而 qq, 夸克,uc 和小米浏览器都可以通过一些属性设置,达到正常播放。百度 APP 无法在页面内正常播放。
  2. 安卓基本上都是不能自动播放的 全屏播放:
  3. 大部分都可以全屏并自动播放,但微信不行,百度 app 缩小全屏后,视频会一直置顶

测试总结

国产的浏览器,大部分都有一些小问题,但可以通过一些属性设置来解决。下面我就根据上面的测试结果,对问题进行处理并封装成一个 Vue 组件,尽可能地解决上面的问题。

解决方法

遇到的坑

ios 退出全屏事件无效

android 端可以用 fullscreenchange 事件 但 ios 端要用 webkitendfullscreen 事件,webkitfullscreenchange 在 ios 是不会触发的,但最好也加上,有备无患

ios 很多全屏有关的事件,都是跟 video 节点关联

fullscreen 的 API 是 document 的方法和属性,ios 的 webkitExitFullscreen, webkitEnterFullscreen 等等,是 video 的方法和属性

ios 全屏播放后切换到带视频的页面,会自动全屏播放

如果使用 video.play() 的方式触发,就会出现上述情况,可以通过设置 video 自带的 controls:true ,让用户点击视频然后全屏播放的方式,来解决这问题

android 当你遇到视频被浏览器劫持

可以尝试设置 controls:false,这可以解决很多情况的问题 当然还有 playsinline,腾讯系的 x5- 属性等,这里不再重复

无法全屏播放但可以内联播放

这时候可以使用内联全屏播放的方式解决,意思就是将你的视频在可视区占满播放,并且将 video 相关节点用 aboslutefixed 进行定位

带声音的如何自动播放

不可以,一定要有用户交互

android 自动播放

同上,但可以添加 poster 优化用户体验

android 触发播放后,但有时候会出现异常,无法播放

因为视频还没加载完或其他因素,视频暂时无法播放。这时候可以在触发 video.play() 后,添加一个定时检测,检测 video 是否真的在播放,如果没播放,可以让它重新播放:

const isVideoPlaying = (video: HTMLVideoElement) =>
!!(
video &&
video.currentTime > 0 &&
!video.paused &&
!video.ended &&
video.readyState > 2
); const checkPlay = () => {
setTimeout(() => {
played.value = isVideoPlaying(refVideo.value);
}, 500);
};

总结

针对浏览器出现的问题,特殊处理

  1. 安卓的 qq 浏览器,需要设置 x5- 相关的属性
  2. 安卓的 uc、夸克、小米等浏览器,需要设置 :controls="false"
  3. 安卓无法自动播放的,监听 document 的 touch 事件,触发后,执行 video 的 play 方法
  4. ios 的 uc、夸克无法全屏播放的,则用内联播放代替
  5. ios 的全屏播放,如果在微信和 safari 时,要设置 :controls="true",使用 ios 内置的 controls,不然当页面切换时,会自动播放其他页面的视频
  6. 无法内联播放的,用图片代替(没办法。。。)

其他

这些解决方法没有集成到组件内

在那么多浏览器中,百度 APP 这个是最麻烦的,无法内联播放,但有一些企业官网是可以正常播放的,比如特斯拉、蔚来,希望有大神可以解答下是如何实现的。

在这总结中segmentfault - 手机百度 app 视频层级兼容处理,有提到如何解决百度 APP 视频兼容性问题:

  1. ios 视频的地址是使用相对路径的,且设置在 <source>
    1. 但这个确实可以,但要求有点高,我这边的视频资源都放在 cdn 中,域名是不一样的
  2. android 的解决方法,我试过不行

还有一些方法比如 ffmpeg,或者将视频转换为 canvas 播放,这里我就不提了,网上有大量的总结。

总结各种问题的解决方法

内联播放

  1. ios:
    1. 主要通过 playsinline, x5- 的属性和关掉 controls 来解决,夸克、百度 APP 和 UC 则使用图片代替
  2. android:
    1. 主要通过 playsinline 属性和关掉 controls 来解决,百度 APP 则用图片代替

全屏播放

  1. ios:
    1. 夸克和 UC 浏览器使用内联视频的方式播放,并且占满全屏播放,停止播放时,则隐藏 video 节点。
    2. 百度 APP 在停止播放时,需要隐藏 dom 节点
    3. 微信, safari 等浏览器,需要使用 video 内置的 controls 属性触发全屏
    4. 其他浏览器可以正常播放
  2. android:
    1. 和 ios 类似的处理方法

组件封装

Github 仓库

最后我将相关的功能封装成一个 vue 组件,便于快速使用

Vue@2

# 添加依赖
npm i vue2-h5-compatibility-video

引入:

import Vue from "vue";
import { getVideoComponents } from 'vue2-h5-compatibility-video'
import 'vue2-h5-compatibility-video/lib/style.css' const { InsideVideo, FullscreenVideo } = getVideoComponents();
Vue.component("InsideVideo", InsideVideo);
Vue.component("FullscreenVideo", FullscreenVideo);

使用内联视频:

<inside-video
:src="url"
:height="height"
:poster="poster"
:autoplay="true"
:loop="true"
/>

使用全屏视频:

<fullscreen-video
:src="url"
:height="height"
:poster="poster"
@click="show"
ref="refFullscreenVideo"
/> <script>
const refFullscreenVideo = ref()
const show = () => {
refFullscreenVideo.value?.showFullScreen()
}
</script>

添加全局点击事件:

import { getEmitter } from 'vue2-h5-compatibility-video'
// 当页面触发点击时,调用下面的方法,这样会通知视频组件播放
getEmitter().emit("docTouch")

Vue@3

# 添加依赖
npm i vue3-h5-compatibility-video

引入:

import Vue from "vue";
import { getVideoComponents } from 'vue3-h5-compatibility-video'
import 'vue3-h5-compatibility-video/lib/style.css' const { InsideVideo, FullscreenVideo } = getVideoComponents();
Vue.component("InsideVideo", InsideVideo);
Vue.component("FullscreenVideo", FullscreenVideo);

使用内联视频:

<inside-video
:src="url"
:height="height"
:poster="poster"
:autoplay="true"
:loop="true"
/>

使用全屏视频:

<fullscreen-video
:src="url"
:height="height"
:poster="poster"
@click="show"
ref="refFullscreenVideo"
/> <script>
const refFullscreenVideo = ref()
const show = () => {
refFullscreenVideo.value?.showFullScreen()
}
</script>

添加全局点击事件:

import { getEmitter } from 'vue3-h5-compatibility-video'
// 当页面触发点击时,调用下面的方法,这样会通知视频组件播放
getEmitter().emit("docTouch")

自定义组件默认属性

可以在 getVideoComponents 方法中,传入你自定义规则:

import Vue from "vue";
import { getVideoComponents, getDefaultSchedule, getBrowserInfo } from 'vue2-h5-compatibility-video'
import 'vue2-h5-compatibility-video/lib/style.css' const { fullscreenParams, insideParams } = getDefaultSchedule() // 强制要求 ios 下的浏览器只显示封面图
if (getBrowserInfo().isIos) {
insideParams.showPoster = true
insideParams.hideVideo = true
} const { InsideVideo, FullscreenVideo } = getVideoComponents({ fullscreenParams, insideParams });
Vue.component("InsideVideo", InsideVideo);
Vue.component("FullscreenVideo", FullscreenVideo);

通过这种方式可以修改默认的组件属性

遗留问题

android 用户触摸屏后,有时不会自动播放视频

本文转载于:

https://juejin.cn/post/7319890768512958516

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

记录--H5 视频兼容性处理总结的更多相关文章

  1. H5视频直播扫盲

    H5视频直播扫盲 2016-05-25 • 前端杂项 • 14 条评论 • lvming19901227 视频直播这么火,再不学就out了. 为了紧跟潮流,本文将向大家介绍一下视频直播中的基本流程和主 ...

  2. iOS APP 中H5视频默认全屏播放问题解决

    问题描述:在Android中,视频可以正常在H5页面局部播放,iOS中则自动切换至全屏模式. 查看资料得以解决,20190301记录下来. 解决方法:IOS10及以后,在 video标签页中只包含 w ...

  3. 【腾讯Bugly干货分享】H5 视频直播那些事

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57a42ee6503dfcb22007ede8 Dev Club 是一个交流移动 ...

  4. H5 视频直播相关技术

    一.移动视频直播发展 大家首先来看下面这张图: 可以看到,直播从 PC 到一直发展到移动端,越来越多的直播类 App 上线,同时移动直播进入了前所未有的爆发阶段,但是对于大多数移动直播来说,还是要以 ...

  5. 一看就能学会的H5视频推流方案

    本文由云+社区发表 作者:周超 导语 随着直播平台爆发式增长,直播平台从 PC 端转战移动端,紧跟着直播的潮流,自己学习实现了一套简单的 H5 视频推流的解决方案,下面就给小伙伴们分享一下自己学习过程 ...

  6. H5视频推流方案

    导语 随着直播平台爆发式增长,直播平台从 PC 端转战移动端,紧跟着直播的潮流,自己学习实现了一套简单的 H5 视频推流的解决方案,下面就给小伙伴们分享一下自己学习过程中的经验. 环境部署 1. 配置 ...

  7. H5 键盘兼容性小结

    H5 键盘兼容性小结 在 H5 项目中,我们会经常遇到页面中存在单个甚至多个 input/textarea 输入框与底部固定元素的布局情况.在 input/textarea 输入框获取焦点时,会自动触 ...

  8. 简单的 H5 视频推流解决方案

    导语 随着直播平台爆发式增长,直播平台从 PC 端转战移动端,紧跟着直播的潮流,自己学习实现了一套简单的 H5 视频推流的解决方案,下面就给小伙伴们分享一下自己学习过程中的经验. 环境部署 1. 配置 ...

  9. selenium如何处理H5视频

    selenium处理H5视频主要使用的是javascript,javascript函数有内置的对象叫arguments,arguments包含了调用的参数组,[0]代表取第一个值. currentSr ...

  10. H5视频活动踩坑

    最近做了一些嵌入视频的活动,积累了点视频方面的经验,下面记录下别人和自己踩过的坑以及相应的解决方案.1.碰到问题和解决方案1.1.ios 网页中播放视频默认全屏(点击视频会弹出播放器进行全屏播放).解 ...

随机推荐

  1. MAYSQL 2 DAY

    目录 MySQL day02 1.关于查询结果集的去重? 2.连接查询 2.2.连接查询的分类? 2.4.怎么避免笛卡尔积现象?当然是加条件进行过滤. 2.5.内连接之等值连接:最大特点是:条件是等量 ...

  2. 【JS】一个思路搞定三道Promise并发编程题,手摸手教你实现一个Promise限制器

    壹 ❀ 引 之前在整理手写Promise相关资料时,在文章推荐区碰巧看到了一道手写Promise并发控制调度器的笔试题(大厂可能爱考),结果今天同事又正好问了我一个关于Promise调度处理的场景问题 ...

  3. JS script脚本async和defer的区别

    壹 ❀ 引 我在 google recaptcha 谷歌人机身份验证使用教程 一文中有引用这样一段外部资源代码,如下: <script src="https://www.google. ...

  4. Nand flash基本原理

    Nand flash基本原理       Flash全名叫做Flash Memory,属于非易失性存储设备(Non-volatile Memory Device),与此相对应的是易失性存储设备(Vol ...

  5. Linux进程与线程的基本概念及区别

    前言 假设你正在玩一款在线多人游戏,在游戏中,有多个角色需要进行不同的操作,例如攻击.移动.释放技能等等. 接下来,我们用玩游戏的例子,来解释进程和和线程的概念,以及进程和线程的区别. 进程的基本概念 ...

  6. 轻松玩转makefile | 变量与模式

    前言 本文通过简单的几个示例,以及对同一个Makefile进行几个版本的迭代,帮助快速的理解变量和模式规则的使用. 1.回顾 在上一篇文章中,我们使用Makefile编译fun.c和main.c这两个 ...

  7. Github 使用PAT(Personal Access Token)后的命令行登录

    在Github上启用PAT 命令行下使用git push不能再直接使用用户名密码, 在输入密码的地方需要使用PAT来代替. 具体的创建步骤为 https://docs.github.com/en/gi ...

  8. 【Unity3D】地形Terrain

    1 前言 ​ Terrain 是 Unity3D 提供的用于绘制地形的游戏对象,可以在其上绘制山地.江海.池塘.草树等. ​ 用户可以通过[GameObject → 3D Object → Terra ...

  9. golang在 ubuntu下交叉编译报错 gcc: error: unrecognized command line option ‘-mthreads’; did you mean ‘-pthread’?

    前置说明: 之前一直都是用centos 7做开发机, 因为工作需要用c2 工具sliver编译木马而依赖 mingw64,但是centos安装这个非常麻烦, 就换了ubuntu开发机; 现需要交叉编译 ...

  10. 案例分享:Qt高频fpga采集数据压力位移速度加速度分析系统(通道配置、电压转换、采样频率、通道补偿、定时采集、距离采集,导出exce、自动XY轴、隐藏XY轴、隐藏显示通道,文件回放等等)

    需求   1.0-7通道压力采集,采集频率1~100Khz(1,10,20,30-1000Khz):  2.0-7通道压力,可设置补偿值,测量范围:  3.编码器0,1脉冲采集,计算位移,速度,加速度 ...