此文已由作者吴家联授权网易云社区发布。

欢迎访问网易云社区,了解更多网易技术产品运营经验。

去年年中的时候,借着产品改版的机会,将之前的h5播放器好好整理重构了一番。之前的h5播放器较为简陋,有几个大问题:没有适配移动端(最大的不足)、没有提供直播模式、有一些历史遗留的bug没有修复。重构版除了解决了这几个大问题外,还做了很多的优化。加上与flash播放器的结合和近期飞哥主导的教育产品组件标准化,播放器适用性变得更强更通用了。

1. h5播放器的设计思路


重构后应该包含这些功能:支持点播(非加密的MP4)和直播播放(m3u8)、兼容(适配)移动端、根据平台自动选择(使用flash还是h5)。

框架和库上,还是选择主要使用nej框架,nej提供了很丰富的方法。对外暴露的类使用regular实现,因为教育产品前端组件和业务工程大部分是使用regular的,在使用上会很方便。另外在移动端上选用了flexible方案,因为教育产品的web页适配已经统一使用flexible了,手势事件的处理选用了

为了方便扩展和添加组件,使用了观察者模式。观察者模式在视频播放器这样规模的工程中使用非常合适,也是屡试不爽的一种设计模式。我直接参考了flex中类似的实现,使用js写了一遍(当然自己写也很快)。

图如上所示,component基类和componentContainer单例类实现了观察者模式,所有组件都继承自component类,component实例中可以调用方法发送notification对象进行组件之间的通信,notification的调度则在componentContainer中实现了。这些组件分为必须组件和可选组件,必须组件包括:视频对象组件(movieData)、视频播放组件(mainVideo)、api组件等,可选组件则是根据不同产品的业务需求来开发的,可以通过不同组件列表的配置来自定义播放器的具体功能,这个也是在componentContainer实现。Html5VideoMedia则是对HTMLVideoElement的封装,它不作为一个组件,只是提供视频播放的功能,以及定义了相关的事件,使用Html5VideoMedia的除了视频播放组件,还可以是片头广告组件。

适配方面,样式上的适配使用了flexible的方案。有的组件比较复杂,比如控制条,在web端和移动端功能差别很大,样式差别也很大,可以考虑不同平台使用不同组件(图中可以看到control和controlMobile),逻辑上会很清晰,不用写很多的if和else,不过因为这样要依赖更多的组件,js和css文件会更大一些。个人觉得为了提高代码的可维护性,牺牲部分的文件大小也是可取的。

     

2. hls直播的一些特点

直播状态的判断。其实直播功能跟业务的关联是很大的,这里的直播状态也是只业务中的状态,比如:未开始、即将开始、直播中、直播结束等等。我们产品中目前还是使用前端轮询的方式更新直播的状态,有一点要提的是hls流是不会触发end事件的,所以h5直播的状态其实是完全靠轮询来控制的。

如何判断流异常。一般网络问题或者是源问题的处理可以监听video标签和source标签的error事件,两种标签都需要监听。但是error触发时的错误信息有时候并不信息,或者说不同浏览器实现上不一样,之前有碰到过改变currentTime属性来seek,偶尔会触发error事件,但是error中只说了是网络错误,没有任何其他信息,在对比了其他视频后才确定是某个视频转码的问题,确实十分的蛋疼。在直播流播放过程中,偶尔会出现流异常的情况,流异常一般会表现为画面卡死,不一定触发error事件。我参考了之前青果同事的方案:每隔一段时间检查currentTime,如果在播放状态下currentTime在这段时间内未改变,很可能就是流异常了,则主动重新加载。

3.一些目前无法解决的问题

ios上视频相关的问题很多,因为系统的限制太多了。稍微列一下:

1. 同时只能播放一个视频或者音频,只允许一个video或者audio标签。做片头广告功能会麻烦一点。

2. ios版本较低的Safari中播放视频会强制全屏,ios
10中可以使用playsinline。在微信和一些定制的webkit中可以添加webkit-playsinline解决。

3. 在没有人为操作的情况下,无法实现进入页面自动开始播放视频

4. ios中无法使用js控制video音量,只能由物理按键控制。在ios中你可以直接隐藏音量控制功能了。。。

5. 还有截屏的问题,不过产品中没有使用到就暂时没有调研。

android上的问题也很多,主要是因为android版本太多、机型太多,各方面参差不齐。稍微列一下:

1.    部分android系统会直接替换video标签,使用系统播放器播放,常见于国产手机

2.    canPlayType方法检测结果与实际不符,这个问题在开发过程中遇到过,例如在一部华硕手机上检测到不支持m3u8播放,但是实际却可以播放,原本想放开这个限制的,后来发现在云课堂app的webview中强制播放可能会导致app崩溃,所以最后还是加上了检测。。

3.    不支持m3u8播放的android一般是android4.0左右及以下的

网易云免费体验馆,0成本体验20+款云产品!

更多网易技术、产品、运营经验分享请点击

相关文章:
【推荐】 IOS渠道追踪方式
【推荐】 如何解决在线网页挂载本地样式的问题

wap html5播放器和直播开发小结的更多相关文章

  1. 搭建rtmp直播流服务之4:videojs和ckPlayer开源播放器二次开发(播放rtmp、hls直播流及普通视频)

    前面几章讲解了使用 nginx-rtmp搭建直播流媒体服务器; ffmpeg推流到nginx-rtmp服务器; java通过命令行调用ffmpeg实现推流服务; 从数据源获取,到使用ffmpeg推流, ...

  2. 7款超具个性的HTML5播放器

    这篇文章我们要分享一些很有个性的HTML5音乐播放器和视频播放器,它们都具有播放器的大部分功能,并以HTML5和JavaScript实现.这些HTML5播放器有着非常漂亮的外观,很多你都无需自己重新定 ...

  3. HTML5 播放器

    之前一个前端群里 大牛 做了一个自适应的HMLT5播放器 最近根据其思路做了一个相对单一移动端的demo,demo用的图片和歌曲json的数据设计 都是群里大牛做的,在这谢谢~: 同时借鉴的几篇文章: ...

  4. Android VLC播放器二次开发3——音乐播放(歌曲列表+歌词同步滚动)

    今天讲一下对VLC播放器音频播放功能进行二次开发,讲解如何改造音乐播放相关功能.最近一直在忙着优化视频解码部分代码,因为我的视频播放器需要在一台主频比较低的机器上跑(800M主频),所以视频解码能力受 ...

  5. Android VLC播放器二次开发2——CPU类型检查+界面初始化

    上一篇讲了VLC整个程序的模块划分和界面主要使用的技术,今天分析一下VLC程序初始化过程,主要是初始化界面.加载解码库的操作.今天主要分析一下org.videolan.vlc.gui.MainActi ...

  6. HTML5播放器 MediaElement.js 使用方法

    目前已经有很多html5播放器可以使用,使用html5播放器可以轻松的在页面中插入媒体视频,从而使我们的web页面变得更加丰富多彩,所以今 天向大家推荐一款非常优秀的html5播放器MediaElem ...

  7. 记录一个Unity播放器插件的开发

    背景 公司最近在做VR直播平台,VR开发我们用到了Unity,而在Unity中播放视频就需要一款视频插件,我们调研了几个视频插件,记录两个,如下: Unity视频插件调研 网上搜了搜,最流行的有以下两 ...

  8. HTML5播放器实例

    鉴于html5Audio and video的使用,设计了一个自定义风格的播放器,除实现一些基本的默认功能之外,还实现了一些高级功能. 具体功能如下: 实现播放暂停按钮 实现静音按钮 实现音量调节滑动 ...

  9. Android VLC播放器二次开发1——程序结构分析

    最近因为一个新项目需要一个多媒体播放器,所以需要做个视频.音频.图片方面的播放器.也查阅了不少这方面的资料,如果要从头做一个播放器工作量太大了,而且难度也很大.所以最后选择了VLC作为基础,进行二次开 ...

随机推荐

  1. Objective-C 引用计数原理

    http://www.cocoachina.com/ios/20160112/14933.html 引用计数如何存储 有些对象如果支持使用 TaggedPointer,苹果会直接将其指针值作为引用计数 ...

  2. vuejs挂载点,模板与实例的关系

    <body> <div id='root'> <h1>{{msg}}</h1> </div> <script> new Vue( ...

  3. hive对有null值的列进行avg,sum,count等操作时会不会过滤null值

    在hive中,我们经常会遇到对某列进行count.sum.avg等操作计算记录数.求和.求平均值等,但这列经常会出现有null值的情况,那这些操作会不会过滤掉null能呢? 下面我们简单测试下: wi ...

  4. Java中ArrayList的对象引用问题

    前言事件起因是由于同事使用ArrayList的带参构造方法进行ArrayList对象复制,修改新的ArrayList对象中的元素(对象)的成员变量时也会修改原ArrayList中的元素(对象)的成员变 ...

  5. javaweb基础(25)_jsp标签实例一

    一.简单标签(SimpleTag) 由于传统标签使用三个标签接口来完成不同的功能,显得过于繁琐,不利于标签技术的推广, SUN公司为降低标签技术的学习难度,在JSP 2.0中定义了一个更为简单.便于编 ...

  6. 导航条(Navbar)

    1.添加.navbar-fixed-top类可以让导航条固定的页面的顶部,固定的导航条会遮住页面上其它的内容,除非给body元素设置padding,导航条默认高度为50px ,因此可以给body元素设 ...

  7. git与github账号建立SSH连接

    第1步:创建SSH Key.在用户主目录下,(就是在你的工作空间一层)看看有没有.ssh目录,如果有,再看看这个目录下有没有id_rsa和id_rsa.pub这两个文件,如果已经有了,可直接跳到下一步 ...

  8. 当GetWindowText获取不到标题时可以用SendMessage

    GetWindowText所有父窗口标题基本可以获取到, 但是当获取父窗口下的子窗口控件标题文本时有时候就没那么好用了, 这个时候可以通过SendMessage发送消息来获取,也很简单,C/C++代码 ...

  9. 牛客NOIP普及组R1 C括号(dp)

    题意 题目链接 Sol maya普及组的dp都要想很长时间,我真是越来越菜了qwq 设$f[i][j]$表示当前到第$i$个位置,剩下$j$个左括号没被匹配 转移的时候判断一下即可 /* */ #in ...

  10. 卸载Redhat 7自带的yum,安装并使用网易163源

    由于redhat的yum在线更新是收费的,如果没有注册的话不能使用,如果要使用,需将redhat的yum卸载后,安装CentOS yum工具,再配置其他源,以下为详细过程:删除redhat原有的yum ...