h5直播开发之旅总结

前言

  关于直播,有不少相关技术文章,这里很少说。 做为前端,咱们比较关心咱们所须要的。html

 

直播的大体流程:前端

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

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

 

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

  直播还有一个比较重要的功能,那就是评论,这里咱们须要websocket来实现,其实不仅是消息,还有须要经过websocket进行一些状态通知。浏览器

  由于这里是移动端的项目,因此不支持PC端。若是要兼容PC的话,须要用flash来播放直播流。服务器

 

直播开发之旅

  ① 状态控制:

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

  针对每一个状态咱们确定会有不一样的显示,这三种状态能够是三个页面,相互切换,或者一个页面,控制页面相关隐藏和显示。 但是咱们怎么知道,当前主播已经切换成某种状态了呢? 经过轮询吗? 固然不是,轮询确定是能够实现的。 不过咱们用websocket,由于咱们已经提早准备了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直播开发里,比较核心的地方。 开发过程当中有不少地方,感受受到了充满“恶意”限制,须要用一些比较特别的方法去处理或者妥协。 这一点对于下游的咱们也是迫不得已,过程当中,仍是颇有乐趣的,虽然最终效果并非很好,但从指缝中,争取到的结果,很难得。

 

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

相关文章
相关标签/搜索