React Hooks高仿B站Web移动端直播

9,730 阅读5分钟

前言

几个月前React Hooks正式发版,在正式发版之前,发布了alpha版本,这时就已经有很多人开始分享React Hooks的使用方式和经验。笔者也是等到了正式发版稳定后才开始学习,这次在原来高仿B站视频弹幕的基础上使用Hooks开发了直播功能

Hooks

Hooks官方介绍说不用写class组件就能使用state和其它class组件的特性,这简直是Functional programming党的福利,我们知道React中一个function就是一个组件,hooks的引入把React变得更加函数化

由于一些原因,才引入了Hooks,比如this关键字不同与其它语言,需要理解this在javascript中是如何工作的。事件处理的时候处理函数必须绑定this关键字或者需要声明成类的属性,这个语法目前还是不稳定的。class组件中componentDidMountcomponentDidUpdate可能都需要编写数据抓取代码,那么就需要写两份相同的代码,某些情况下需要在componentDidMount中设置事件监听,在componentWillUnmount中移除事件监听,相关连的代码被拆分,很容易出现bug

官方没有打算移除class组件,不建议用hooks重写class,而是推荐在新的代码中尝试使用Hooks

想学习Hooks的童鞋可以到移步到官方文档(英文 中文)

class组件的方法和hooks对应如下

  • constructor:函数组件没有,直接在函数体内使用useState初始化
  • getDerivedStateFromProps:在函数组件内使用useState保存props,props变更时做相应的逻辑处理
  • shouldComponentUpdate:使用React.memo
  • render:函数组件本身
  • componentDidMount, componentDidUpdate, componentWillUnmount:useEffecthook包含了三个生命周期方法

在使用useEffect时,第二个参数很重要,传入[],表示在组件mount时候回调,组件update时不回调,类似class组件中的componentDidMount。函数组件中的内部函数使用了propsstate,并且在useEffect回调函数中调用,该函数一定要放到useEffect的回调函数中定义,同时把使用的propsstate传入第二个参数数组中作为依赖。以下两种情况可以在useEffect外部定义函数

  • 函数不依赖props或state
  • 函数是一个纯函数,没有副作用,没有数据请求

class组件的setState方法用来更新state,它的第二个参数是一个回调函数,在组件update后回调,Hooks暂时没有对应的替代方案,知道了组件更新时需要的时间后,可以用setTimeout进行hack

直播

近几年来,直播非常火热,主播用一台电脑或手机不出门就能赚钱,看直播成为了年轻人的一种娱乐方式

做一个直播需要客户端和服务端配合,客户端录制画面,把视频流推给服务器,服务器对视频流进行转码,转成各种格式的视频流,在播放直播的时候,客户端从服务端拉取直播流进行播放。某里,某讯在直播这块都有一整套的解决方案,只要花钱就很容易搭建起一套直播服务

常见的直播协议有RTMP、 HLS 和 FLV

  • RTMP 协议实时性高,常用来要求延时很短的视频流,但出现卡顿的概率高
  • HLS 协议延时相对较大,但观看体验好,手机端天然支持
  • FLV 居于两者之间,是延时和卡顿相对平衡的播放协议,国内用户使用较多

这三种协议网上都有详细的说明

各平台支持情况如下

平台RTMPHLSFLV
Android支持支持支持
IOS支持支持支持
PC支持(需要flash)支持(video+hls.js)支持(video+flv.js)
移动端(Android)不支持android4.0+不支持
移动端(IOS)不支持支持不支持

Android和IOS上这三种都支持

移动端对HLS天然支持,最好的选择

PC web端不支持video需要用flash播放,支持video时可以用FLV或HLS,但video不支持flv格式,使用B站开源的flv.js就可以播放flv格式的直播流,它是通过将flv转成mp4格式,再用Media Source Extensions API喂给video进行播放。hls.js实现了HLS协议的客户端,它同样需要video和Media Source Extensions API的支持,PC端暂不支持hls,如需播放hls流,就要用到hls.js。HLS延时性较大,在PC端播放直播时一般不采用,但是由于体验好,在点播的时候优先采用HLS

还有一种基于HTTP的动态自适应流DASH,它通过一种自适应的比特率流技术,使高质量的流媒体可以通过 HTTP 协议进行传输,在播放时根据网络条件自动选择码率进行播放。类似HSL,DASH将内容分割为一个或多个片段,每个片段包含很短长度的可播放内容,并且有一个媒体描述片段信息(MPD文件),它还支持多种编码格式

本例中使用的是HLS直播流,建议用手机浏览器体验,很多直播网站的移动端在pc浏览器上调试无法播放,这里笔者使用了hls.js,在pc上同样也可以播放HLS流(Chrome 70及以上会有net::ERR_CERT_SYMANTEC_LEGACY错误)

屏幕截图

live live list room room classify

源码

Github

Hooks相关代码在src/views/live目录下

觉得不错给个Star,谢谢啦~