世界上杀伤力最大的武器不是核弹,而是AK-47,这款由卡拉什尼科夫所设计的突击步枪,全世界一共生产了约一亿支。它具有不俗的杀伤力和极为优秀的可靠性。从不卡壳,不易损坏,不管是沙漠还是雨林,都能稳定地倾泻火力。并且操作非常简单,以至于很多非洲兄弟在射击时会将其举过头顶,因为他们相信这种动动手指就能摧毁对方的武器,完全是“白人的巫术”。
抱着同样的想法,我们跟微信团队一起,致力于在小程序上打造出一款效果出色、稳定可靠并且简单易用的音视频组件。本文接下来的部分,我希望能用简单的文字,让您了解那些界面丰富且体验优异的音视频功能背后的故事。
无论多么复杂的音视频功能,我们都可以将其拆解为两个基本“原子”的组合,一个是音视频上行,一个是音视频下行。
音视频上行,就是把自己的声音和画面传送出去。只有这样,别人才能看到您的影像,听到您的声音:
经过预处理之后的画面和声音相比于原始采集的一般会有较大改善,因为所有的预处理都是以“讨好”人类的视听体验为目的,所以这一看似不起眼的部分会吸引很多公司在其上做不少的技术投入。举个身边的例子,以 LCD 平板电视为例,SONY虽然没有自家的液晶面板(以中国台湾和大陆液晶面板为主),却能在总体效果上一直领先其它公司,其背后的秘密就是在图像处理(基于图像数据库做超分辨率显示)和背光技术(所有动物的眼睛都是对亮度最为敏感)上的不间断的积累和投入。
<live-pusher> 的 RTC 模式即 TXLivePusher::setVideoQuality 中的 REALTIME_VIDEOCHAT。
场景 | mode | min-bitrate | max-bitrate | audio-quality | 说明 |
---|---|---|---|---|---|
标清直播 | SD | 300kbps | 800kbps | high | 窄带场景,比如户外或者网络不稳定的情况下适用 |
高清直播 | HD | 600kbps | 1200kbps | high | 目前主流的APP所采用的参数设定,普通直播场景推荐使用这一档 |
超清直播 | FHD | 600kbps | 1800kbps | high | 对清晰度要求比较苛刻的场景,普通手机观看使用 HD 即可 |
视频客服(用户) | RTC | 200kbps | 500kbps | high | 这是一种声音为主,画面为辅的场景,所以画质不要设置的太高 |
车险定损(车主) | RTC | 200kbps | 1200kbps | high | 由于可能要看车况详情,画质上限会设置的高一些 |
多人会议(主讲) | RTC | 200kbps | 1000kbps | high | 主讲人画质可以适当高一些,参与的质量可以设置的低一些 |
多人会议(参与) | RTC | 150kbps | 300kbps | low | 作为会议参与者,不需要太高的画质和音质,audio-quality 的 low 模式,其音质和延迟感都要会比 high 模式差很多 |
也叫播放(play),即从云端拉取编码后的音视频数据流进行解码和播放:
有人经常问我:“在播放器端怎么改变画面的清晰度?” 这个问题回答起来既简单又复杂。简单回答是说播放器并不能改变画面的清晰度,清晰度在视频编码之后就确定了。复杂的回答则是,通过跟云端的配合,确实可以在播放器上改变清晰度。因为腾讯云的每一条直播流都支持多分辨率实时转码,开启这个功能后,就可以在播放器上根据用户的选择播放不同的 url,进而实现不同清晰度的切换。
<live-player> 的 Live 模式即 TXLivePlayer::startPlay 中的 LIVE_RTMP 或 LIVE_FLV。 <live-player> 的 RTC 模式即 TXLivePlayer::startPlay 中的 PLAY_TYPE_LIVE_RTMP_ACC。
有了简单的“原子”,我们就可以进行初步的化学反应,从简单到复杂地构建出一些“分子”结构,接下来,我们先从一个最简单的应用场景开始 —— 单向音视频。
在线培训是一个非常经典的单向音视频场景,您只需要简单的将负责音视频上行的 <live-pusher> 和负责音视频下行 的 <live-player> 组合在一起即可。
<live-pusher> 能够将讲师的影像和声音推送到云端(一般也可以使用专业的采集设备),腾讯云本身就相当于一个 信号放大器,它负责将一路音视频流扩散到位于全国各地的 CDN 机房,如此一来,观众端的 A B C 都可以在离自己最近的云服务器上,使用 <live-player> 拉取到稳定和流畅的音视频流。
由于原理简单、易于维护且支持几百万同时在线的高并发观看,所以从在线教育到体育赛事,从游戏直播到花椒映客,都是基于这种技术实现的。
在讲师端创建一个 <live-pusher> 标签,并将 mode 设置为 HD,技术参考文档见 DOC。 学员一端的小程序只需要创建一个 <live-player> 标签,并将 mode 设置为 live 即可,技术参考文档见 DOC。
但这种技术有个严重的缺陷,就是单向延时无法控制在 1s 以内,一般都是在 2秒-5秒 左右,甚至更长,那么在一些对时延要求很苛刻的场景下就不再适用了,比如下面这个场景:
在线夹娃娃在今年特别流行,玩家可以远程控制抓钩来抓娃娃,所以需要将单向延时控制在 500ms 以内,而且越低越好。要达到这么低的要求,普通的直播技术就不行了,我们需要新引入两个新的科技点:延时控制 和 UDP加速。
现在我们已经拥有了两个新的科技点,接下来就把它用到我们的小程序中:
玩家创建一个 <live-player> 标签,并将其 mode 设置为 RTC,此时小程序会开启延时控制 和 UDP加速,同时,src 要使用 rtmp:// 协议的播放地址,并且要为播放地址添加防盗链签名。技术参考文档见 DOC。 观众也是要创建一个 <live-player> 标签,并将其 mode 设置为 live,此时 src 指定普通的 flv 协议播放地址就可以了,技术参考文档见 DOC。
有了单向低延时技术,那么双向视频通话自然也就比较简单了,只需要通话的双方 A 和 B 各自拉通一路低延时链路就可以了。
是吗?
虽然思路正确,但实现上不是那么简单的,因为我们还需要引入额外的几个科技点:
现在我们又获得了四个新的科技点,接下来我们把它用到我们的小程序中:
A 创建一个 <live-pusher> 标签,mode 设置为 RTC,并将对应的低延时播放地址 urlA 交给 B。 B 创建一个 <live-player> 标签,mode 设置为 RTC,src 指定为 urlA。 B 创建一个 <live-pusher> 标签,mode 设置为 RTC,并将对应的低延时播放地址 urlB 交给 A。 A 创建一个 <live-player> 标签,mode 设置为 RTC,src 指定为 urlB。此处所需的技术参考文档见 实时音视频。
既然双人视频通话已经搞定了,是不是多人也就照葫芦画瓢就可以了?您看,我们只需要将 A 和 B 之间的 url 置换,变成 A、B、C 甚至更多人之间的 url 置换,不就可以了吗?
是吗?
虽然思路正确,但是真正要将功能做到商用级别,仅依靠简单的 url 交换是非常粗糙的,我们需要继续引入额外的两个科技点:
最好的办法就是把参会人的状态和信息都收拢在服务器端,构造一个 房间 的概念,这样就可以确保参会人都能从服务端获得同样的信息,而不需要各自去维护。
现在我们又获得了两个新的科技点,接下来我们把它用到我们的小程序中:
跟之前几个科技点不同,小程序并没有默认提供房间管理和 IM 系统的微信内实现,因为房间管理跟客户业务耦合太紧密,腾讯云通讯 IM 服务也已经有了小程序端的 javascript 组件。
所以我们提供了一个叫做 RTCRoom 的 javascript 组件用于降低这里的实现复杂度,您可以在我们的 小程序源码 中找到 rtcroom.js。
会议发起者 A 可以用 rtcroom.createRoom 创建一个房间。 参会者 B 和 C 可以用 rtcroom.enterRoom 加入一个房间。 这期间,A B C 都可以通过 onMemberEnter 和 onMemberLeave 了解房间内参会者的进进出出。 如果参会者 B 和 C 想要离开,只需要用 rtcroom.leaveRoom 通知其他人即可。 会议发起者 A 可以随时用 rtcroom.destoryRoom 将当前的房间解散掉。
此处所需的技术参考文档见 RTCROOM。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。