#定义新web直播#
传统的web直播互动基于flash,随着浏览器不再支持flash,这个技术方案也逐步退出了历史舞台,取而代之的是基于HTML5规范中video标签,我们部门的web直播方案也是在这个大的背景下开始了架构升级演进,下文的新web直播是基于网校学研大班直播体系进行的探索。
# “创业版” 的诞生#
背景是产品侧提出讲座业务要重构,要能支持rtmp视频播放、即时聊天、投票和献礼物的低延迟互动等功能,需求简单够用。我们采用了基于RTMP/HTTP-Flv的播放器,基于websocket的即时聊天技术,互动的信令通道复用了聊天消息通道。大概耗时一个月的时间,终于把第一个版本开发出来了,但是由于这样那样的原因,项目无法上线,要夭折了(开始很美好,结局很意外)。充满胸膛的热(郁)情(闷)无处宣泄,你以为就此草草收场吗?那不是我们的脾气。
# “野蛮发展” 阶段#
满腔的热情还没有宣泄完,第二个版本就开始了“破土动工”,但是拦住我们向前发展的有三座大山,第一个是web的AI识别能力,第二个是即时语音/视频通信的RTC能力,第三个是十多个直播课堂的教学互动需要与客户端拉齐。
首先,先解决最难的一个web端的AI能力。通过探索,我们借助hark(npm地址:https://www.npmjs.com/package/hark)插件进行识别音量大小变化来完成声音检测事件,视图层进行相应提示。
this._speechEvents = hark(this._stream)
this._speechEvents.on('speaking', () => {
// createLog('检测到说话')
})
this._speechEvents.on('stopped_speaking', () => {
// createLog('检测到停止说话')
})
this._speechEvents.on('volume_change', (db) => {
// createLog('检测到音量变化')
})
声音的编码使用了lamejs,启动了web worker,声音的编码过程是在worker中完成的。lamejs是用 JavaScript 编写的快速 mp3 编码器。
整体流程:
1、获取麦克风的音频流
2、传给web work进行编码
3、编码完成后给主线程处理转换为Blob数据格式
4、通过websocket传给集团的AI服务进行识别
以上完成了AI语音识别能力,图像识别还没有完成,理论上也能实现。
const audioCtx = this._audioCtx = new AudioCtx()
this._audioStream = audioCtx.createMediaStreamSource(this._stream)
this._audioRecorder = audioCtx.createScriptProcessor(16384, 1, 1)
this._audioRecorder.onaudioprocess = (e) => {
const buffer = e.inputBuffer.getChannelData(0)
this._encodeMp3Worker.postMessage({
type: 'encode',
payload: buffer
})
}
第二,集成语音/视频的即时连麦能力。这块我们直接复用了集团直播中台的RTC SDK,快速孵化了我们的业务。
基于webRTC实现了即时的语音/视频通信能力。
第三,与PC端功能拉齐。这个是一个消耗体力的事情,首先要了解客户端的样子,其次拆分任务,分工开发。这也给项目带来很大的问题,很多人参与,质量把控难度大,这个时候是一个代码量暴增的时期。虽然有CR,依然没有摆脱被重构的命运,这也许就是一个大型项目的宿命。
# “系统性” 升级#
经历完“野蛮”的发展阶段后,项目已经达到了有50多个组件模块,项目出现了一些问题:代码风格差异大,理解成本增加;开发之间矛盾出现,问题频出,开始互相不信任;重复代码多。为了解决团队合作问题,为了解决项目体验与稳定性,为了让项目能继续迭(活)代(着),开启了第一版本的重构。
首先,设计了直播框架,将播放器,聊天,信令通道,日志,消息管理中心,收敛到直播框架中,直播框架以npm包进行版本管理,其次直播框架设计了一些base类,约定了一些类的基本方法,例如互动base,消息处理base,初始化base,业务通过重载,实现了自己的业务功能。
这次的重构产出的web直播框架,后来快速孵化了PHP大会web直播项目,海外PC端直播项目,轻直播半身直播项目、小程序直播等,这次的重构还是蛮成功的。web直播框架目前支持RTMP播放器、RTC播放器、涂鸦、小程序直播,h5-RTC直播等。
你以为这就完事了,并不是的,现阶段直播项目单页面应用,已经发展出了61个模块,30余种互动,其中一些互动也到了不得不重构的时候了。
# “模块化” 重构#
这个版本主要是一个模块的重构,主要是对信令处理模块进行了处理,其次对未来课件、语音答题、语音测评进行了模块的重构,并且升级eslint统一代码风格。
1、对未来课件、语音答题等互动通过开发中间类来实例化不同互动,解决了互动组件的耦合性问题
2、对信令消息处理模块将控制逻辑与业务实现做了拆分
3、统一eslint
互动消息处理模块新的流程图:
# 总结 #
“系统性”升级的重构改动非常大,是一个从1.0升级到2.0的过程,当然在升级的过程中,业务开发也在持续的演进着,对于重构这么大一个项目,如何保障能够按期完成以及线上的稳定性是一个挑战,我们采取了以下策略:
技术上
● 核心模块做单元测试
● 接入公司内部的日志采集分析&预警系统,及时发现问题
● 原有项目保持线上运行,做备选方案,采用灰度白名单放量(未实施)
流程上
● 项目全员宣讲web新直播框架技术方案,做到每一个人清楚项目的规划
● 划分模块,具体模块技术负责人串讲具体技术方案,对模块技术方案过审
● 组织日会,问题当天解决,避免阻塞性问题,组织周会拉齐目标
● 提测之前先组织自测,核心主流程一定不能阻塞,降低测试工作量
● 上线前整理上线的检查清单,上线后安排值班
● 组织项目复盘会议,总结经验教训
特别感谢所有参与web直播开发的小伙伴们。
从我们自测的数据来看(待线上数据的检验),大部分指标与native表现相近。
后续会继续完善直播课堂方案,包括但不限于小程序、H5、flutter方向,欢迎感兴趣的伙伴留言。
致力于互联网教育技术的创新和推广
扫码关注我们
@学而思网校技术团队
往期精彩推荐