转自http://www.cnblogs.com/1wen/p/5973468.html

前言

  关于直播,有很多相关技术文章,这里不多说。 作为前端,我们比较关心我们所需要的。

直播的大致流程:

  APP端调用摄像头 -》 拍摄视频 -》 实时上传视频 -》 服务器端获取视频并解码 -》 存储成一小段一小段视频 -》 服务器端进行推流 -》 H5或者app端通过一个url拉取视频流进行播放

  实际的直播和用户播放的直播会有10秒左右或者更高的延迟,这一点对于后面开发比较重要,一定要注意这个点。

  H5实现直播主要是和video标签打交道,虽然只需要拿到m3u8格式的url,通过video播放,看起来好像就是播放视频一样,但实际我们需要处理一些不可控的情况,这是非常麻烦的。 比如说,直播方网络不好,直播方关闭了摄像头,这些情况都会导致推流断掉,在文章后面,我们详细说这一块。

  直播还有一个比较重要的功能,那就是评论,这里我们需要websocket来实现,其实不只是消息,还有需要通过websocket进行一些状态通知。

  因为这里是移动端的项目,所以不支持PC端。如果要兼容PC的话,需要用flash来播放直播流。

直播开发之旅

  ① 状态控制:

  目前我们先考虑直播的三种状态: 直播前,直播中,结束。

  针对每个状态我们肯定会有不同的显示,这三种状态可以是三个页面,相互切换,或者一个页面,控制页面相关隐藏和显示。 可是我们怎么知道,当前主播已经切换成某种状态了呢? 通过轮询吗? 当然不是,轮询肯定是可以实现的。 不过我们用websocket,因为我们已经提前准备了websocket,所以我们可以通过服务端的推送websocket广播,当获取到的直播状态和当前状态不同,便进行相应切换。

  但是有时候可能因为暂时的网络原因或者其他原因,websocket的广播消息,我们并没有获取到。 所以可以让websocket间隔性的广播直播状态。

  ② 评论消息监听:

  我们也通过websocket拉取评论消息,这里主要的问题在服务端压力上,有可能用户评论量很大的时候,服务器压力过大,出现断连的情况。 也可能是用户网络断开,造成的断连。 一方面后端通过他们的优化来提高承载力,一方面前端和后端进行配合优化。 我们每次连接websocket服务器的时候,前端会通过接口,拿到当前承载量最小的服务器地址进行连接。 websocket如果断连了的话,是不会获得任何消息的,所以保证功能可以使用,我们还会针对websocket进行心跳检测(检查是否断开连接)。

  ③ 心跳 重连

  因为websocket可能会存在断开连接的情况,而这时候是不会触发任何事件的,所以我们不知道它是否断开了。 那么我们设置一种消息类型,由前端发送给服务端,服务端如果返回了数据,就说明连接正常。 如果连接断开了,我们再次去请求后端接口,拿到当前承载量最小的服务器地址,进行重连。 设置一个间隔时间比如10秒,最后一次获取到服务器的消息后,如果10秒内没再收到消息,就进行一次检查,如果10秒内收到了,便重置这个时间。 之前的博客写过比较详细的心跳检测:初探和实现websocket心跳重连》

  ④ video

  关于video,总结起来我们要解决的那些问题,或者有些不能解决的问题,归根到底是一个问题:兼容。 兼容问题又可以分为两种:标签事件的兼容问题和浏览器表现的兼容问题。

  先说video的事件兼容问题,之前测试过这一块,总之比较稳定和兼容性好点的事件如下图片圈出来的:

  

  对,你没看错,目前对我来说好像就timeupdate比较靠谱,总之确实兼容性很差,这样会导致对video的可控性变得很低。

  接着是浏览器的表现兼容问题,比如: 在微信和QQ的内置浏览器里,播放视频会自动全屏,video标签也是永远浮在页面最上层,你根本控制不了。 浮在最上层不只是X5浏览器,还有些手机只带的浏览器。 视频源出现问题的表现,播放按钮的问题,都有不同。 这些都是脱离我们代码本身,浏览器的设置,所以从代码层面上我们是没法解决的。 之前出现这些问题的时候,当然我也会看下相关直播的公司的页面,看他们是怎么解决的。  比如在微信这个流量大口他们有没有实现看起来实现不了的功能。 实际结果是,这些厂家应该是微信有合作,进行了相关定制的。 而我们本不是专门做直播的,所以没必要投入这种成本。

  定制合作这个只是猜测,还不能百分百肯定,如果有谁知道,感谢告知一声!

  ⑤ 评论展示

  本来我们想实现如下图的样式:

  

  但是由于上面提到的问题,video浮在页面最上层,dom无法浮在video的上层。 那么我们的评论就无法展示在上图的位置,所以无奈只有放到video下方去。 根据我们的业务需求不同,目前只有这样,能勉强接受。

  ⑥ video推流监听

  在文章最开始我们提到,推流会有一些不可控的情况,主播关闭摄像头,推送断流等,客户端断网。 这个时候在H5端的表现就是卡住,肯定会卡住。  一旦卡住之后,就算推流又重新开始了,video依然会卡在那里,不会有任何重新播放的样子。  如果推流重新开始,用户自己点击控制条的暂停,再点击播放,又可以正常播放了。 可我们不可能让用户一直点,因为你也不知道推流什么时候重新开始,或者什么时候不再是断网状态。 通过点击控制条的暂停,再点击播放便可以播放的规律,我们可以自己检查当前的状态,再用JS控制video暂停,再播放。

var video = document.getElementById('video');
video.pause();
video.play();

  

  如何检查当前是卡住的状态呢?这里就用到我开始说的比较可靠的timeupdate事件。一旦用户是播放状态,监听timeupdate,通过对比currentTime轮询着来检查当前是否卡住。

var checkTime = null;
var checkLastTime = null;
var check = setInterval(function(){if(checkTime != null){if(video.paused){//如果是暂停状态}if(checkTime == checkLastTime || (checkTime== 0 && checkLastTime==0)){if(!video.paused){//如果是暂停状态,就忽略showTip('主播离开一会儿'); //提示一下用户video.pause();video.src = video.src;//重置src,否则ios不会再次播放video.play();}}}checkLastTime = checkTime;
}, 10000);video.addEventListener('timeupdate', function(e){//每次play()都会触发一次timeupdate,所以需要加个条件判断if(checkTime != checkLastTime) hideShowTip();//隐藏上面 主播 离开的提示checkTime = e.target.currentTime;
});

  

  但是这样仍然会有一些问题,比如当前检测到视频卡住了,JS控制重新播放,而当前还是没有获取到推流的话。 浏览器会先loading获取视频,最后会失败显示下图的信息。 我们的检查会轮询执行,所以下面的情况会一直循环,直到视频正常播放。

      

  这样确实有点影响体验,但是目前无解。

  如果用户不是全屏播放,页面下方会有提示用户等待。

  如果是全屏那么就看不到提示,不过用户这个时候可能会关闭全屏,返回到页面上,这样仍然可以看到提示。

  

结语:

  以上就是我所遇到的h5直播开发里,比较核心的地方。 开发过程中有很多地方,需要用一些比较特别的方法去处理或者妥协, 这一点对于下游的我们也是无可奈何,解决问题的过程中,还是很有乐趣的。

H5之直播开发之旅总结相关推荐

  1. h5直播开发之旅总结

    前言 关于直播,有很多相关技术文章,这里不多说. 作为前端,我们比较关心我们所需要的. 直播的大致流程: APP端调用摄像头 -> 拍摄视频 -> 实时上传视频 -> 服务器端获取视 ...

  2. Android直播开发之旅(3):AAC编码格式分析与MP4文件封装(MediaCodec+MediaMuxer)

    Android直播开发之旅(3):AAC编码格式分析与MP4文件封装(MediaCodec+MediaMuxer) (码字不易,转载请声明出处:http://blog.csdn.net/andrexp ...

  3. Android直播开发之旅(25):使用AES算法加密多媒体文件(+RSA+MD5+Base64)

    文章目录 1. AES算法 1.1 AES加密过程 1.1.1 字节代替(SubBytes) 1.1.2 行移位(ShiftRows) 1.1.3 列混合(MixColumns) 1.1.4 加轮密钥 ...

  4. Android直播开发之旅(17):使用FFmpeg提取MP4中的H264和AAC

    最近在开发中遇到了一个问题,即无法提取到MP4中H264流的关键帧进行处理,且保存到本地的AAC音频也无法正常播放.经过调试分析发现,这是由于解封装MP4得到的H264和AAC是ES流,它们缺失解码时 ...

  5. Android直播开发之旅(13):使用FFmpeg+OpenSL ES播放PCM音频

    文章目录 1. OpenSL ES原理 1.1 OpenSL ES核心API讲解 1.1.1 对象(Object)与接口(Interface) 1.1.2 [OpenSL ES的状态机制](https ...

  6. Android直播开发之旅(7):Android视频直播核心技术(架构)详解

    (转载请声明出处:http://blog.csdn.net/andrexpert/article/details/76919535) 一.直播架构解析 目前主流的直播架构中主要有两种方案,即流媒体转发 ...

  7. Android直播开发之旅(4):MP3编码格式分析与lame库编译封装

    转载请声明出处:http://blog.csdn.net/andrexpert/article/77683776 一.Mp3编码格式分析 MP3,全称MPEG Audio Layer3,是一种高效的计 ...

  8. Android直播开发之旅(9):OkCamera,Android 相机应用开发通用库

    OkCamera,Android 相机应用开发通用库 转载请声明出处:http://blog.csdn.net/andrexpert/article/details/79302576 明天就可以回家过 ...

  9. Android直播开发之旅(15):libjpeg库的编译移植与使用

    1. libjpeg介绍  libJPEG库是一款功能强大的JPEG图像处理开源库,它支持将图像数据压缩编码为JPEG格式和对原有的JPEG图像解压缩,Android系统底层处理图片压缩就是用得lib ...

最新文章

  1. 漫画:禅道程序员的一天
  2. 勇攀监控高峰-EMonitor之根因分析 背景
  3. Python内置函数使用说明
  4. KBQA相关论文分类整理
  5. html5,css3, bootstraps
  6. ofo 深圳 java_[Android进阶]OFO首页实现小窥
  7. 基于Matlab的随机信号分析
  8. 十六进制转字符串 java_JAVA十六进制与字符串的转换方法
  9. OutputFormat类——Hadoop
  10. 75 ----平面二次曲线方程的化简: 移轴变换、转轴变换、伸缩变换
  11. python实现简单的ps色阶调整过程
  12. 火狐中无法打开google的搜索结果的解决方式
  13. [信号基础] 信号频率,采样率,采样点(快拍数)等
  14. 网站首页html静态化,网站首页怎么静态化
  15. 将eclipse配置成可迁移,即直接复制就可以使用
  16. 奔跑吧,程序员:从零开始打造产品、技术和团队
  17. 六自由度机器人(机械臂)运动学建模及运动规划系列——避障路径规划算法补充:粒子群算法(PSO)
  18. SHELL脚本练习(持续更新)
  19. Windows 10 1803 升级到 Windows 10 1903
  20. TensorFlow - 求导

热门文章

  1. 大胆猜测:今年816全民顾家日埋了3个伏笔?
  2. 中国古代十大武功卓著的北伐名将
  3. 教育网IP网段(部分)
  4. FlyAI资讯:收藏!深度学习必读10篇经典算法论文总结!
  5. 张益唐新成果首次公开直播,开场写下ac-bd=(a+b)c-(c+d)b,这回好像能看懂?
  6. oracle判断语句-查询部门的工会
  7. 全屏响应式html5+jquery幻灯片轮播特效,纯CSS3超酷全屏响应式幻灯片特效
  8. Java面向对象小项目 慕课网Java入门第二季答答租车系统
  9. 每日开心一刻——2004年9月份
  10. 蓝桥杯单边机省赛一些总结