欢迎你们前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~javascript
腾讯视频云终端技术总监,rexchang(常青), 2008 年毕业加入腾讯,一直从事客户端研发相关工做,前后参与过 PC QQ、手机QQ、QQ物联 等产品项目,目前在腾讯视频云团队负责音视频终端解决方案的优化和落地工做,帮助客户在可控的研发成本投入之下,得到业内一流的音视频解决方案,目前咱们的产品线包括:互动直播、点播、短视频、实时视频通话,图像处理,AI 等等。git
小程序音视频是什么?github
2017年腾讯视频云团队跟微信团队联合,将视频云 SDK 跟微信小程序整合在一块儿,并经过 和 两个标签的形式开放内部的功能。经过这两个标签,开发者能够实如今线直播、低延时监控、双人视频通话以及多人视频会议等功能。web
那么WebRTC又是什么?算法
WebRTC(Web Real-Time Communication),是一个支持网页浏览器进行实时语音对话或视频对话的技术,是谷歌收购 GIPS 公司而得到的一项技术,在 Chrome 浏览器上无需安装插件,经过 javascript 就能够编写实时音视频通话程序。json
若是您跟我同样是一个实用主义者,那我就简单从实用主义角度说一下个人结论:小程序搞定了手机,WebRTC拿下了PC。小程序
若是你对技术比较感兴趣,那咱们就能够从多个技术的角度去列举二者的区别,下面是一张详细对比的表格:微信小程序
WebRTC 由谷歌收购 GIPS 得来(这里不得不提一下,我加入腾讯时所在的第一个团队就是 QQ 团队,当时 QQ 的音视频仍是购买的 GIPS 公司的产品,不过因为各类不靠谱,后来就转为自研路线了)。因此其技术被完整的保留而且加入到了 Google 的 Chrome 浏览器内核当中。并且最近苹果也已经开始在 Safari 浏览器中支持 WebRTC 的相关能力。api
WebRTC的底层则是使用RTP和RTCP两种数据协议,其中RTP主要用于音视频数据传输,而RTCP则通常用于控制。
WebRTC在这里则要尴尬的多,一方面Android系统的碎片化自己让WebRTC的具体表现呈现“百花齐放”的景象,同时,iOS 目前的内嵌WebView(也就是在微信等APP里打开的各类内嵌网页)不支持WebRTC也仍是个很麻烦的问题。
相比之下,WebRTC则不是一个团队或者一家公司的问题了,由于它如今已经走标准路线,因此每个新特性都是先肯定标准,而后再推进浏览器厂商(包括苹果)进行跟随。这里面的故事就多了,时间也就更久了。
可是在桌面浏览器这个部分,Chrome目前在PC浏览器市场上留到地位的存在决定了 WebRTC 的优点就很大了,开发者能够在不安装插件的状况下就能够实现本身想要的功能。
相比之下,因为没有 Chrome 的原生支持,因此若是咱们要在 PC 上对接小程序音视频,就须要安装浏览器插件或者经过 wxlite://start 这样的伪协议唤起本地 exe 应用程序(相似在网页上打开 QQ 聊天窗口)。
小程序音视频和WebRTC支架并不是零和博艺,双方都有本身的优点和不足,因此本着“打不过他们,就加入他们”的思路,腾讯视频云团队在2018年春节回来后,就快马加鞭地开始了小程序音视频和WebRTC互通的相关工做。
目前,须要向各位开发者汇报的是,在最新版本的微信中,小程序音视频已经能够跟WebRTC打通,目前在PC 的Chrome浏览器上就能够跟小程序进行实时音视频互通。
// to-do
固然,若是您想知道这个功能是怎么实现的,能够继续看下去:
就像结婚同样,既然你决定要选择另外一我的做为人生下半辈子的伴侣,那你确定会先深刻地了解一下TA这我的,好比性格,脾气,爱好等各个方面。
一样,咱们要想很好的将小程序音视频和WebRTC打通,那也必需要多了解一下WebRTC,这里我就说一下我对 WebRTC 这个“人” 在性格上的一些理解。
首先,她虽然长得不太好看,但颇有内涵。
说WebRTC长得很差看,只是个人一种比喻,个人意思是想说WebRTC的学习成本不低,虽然Google作了不少浅显易懂的PPT来教你怎么 Getting Start,但真要完整的学进去,仍是须要静下心来,慢慢地把她当成本身承认的目标去学下去。可是若是你是第一次恋爱(也就是第一次接触实时音视频),你会发现学习WebRTC的过程,自己就是了解一个实时音视频技术细节的过程。
其次,她很是喜欢迁就别人,各类架构方案她都能支持到。
说WebRTC喜欢迁就比人,也是一种比喻,WebRTC所支持的后台架构很是多(好比 Mixer, Mesh,Router),并且谷歌认为这些后台实现都比较简单,因此既没有开放后台相关的源码,也没有提供统一的后台解决方案。这种开放式的设计思路很是好,但反作用就是实现成本高。在真刀真枪的项目落地时,小规模的公司或者开发者就很容易被这种技术门槛挡在门外。尤为是想要将 WebRTC 真正应用到企业级解决方案中,面对录制和存档的刚性需求,就须要花费大量时间进行定制开发。
了解到 WebRTC 的这些特色后,咱们的互通方案也就比较清晰了:
首先,小程序音视频的特色是接口简单,快速上手,这是小程序的优点;而这一点偏偏是WebRTC的劣势,因此咱们没有必要在小程序端为WebRTC暴露十几个接口类,而是继续采用小程序音视频的 和 标签来解决问题。
其次,WebRTC 的后台没有官方实现,那就意味着这里有很大的发挥空间,腾讯视频云就能够实现一套WebRTC后台并将其同小程序音视频所使用RTMP后台进行打通。简单来讲,腾讯视频云要在小程序音视频和WebRTC之间充当红娘(更确切的说,应该是翻译员)的角色。
可是看过《新闻联播》里国家领导人之间谈话镜头的人都知道,这种翻译是会影响交流速度的。小程序音视频和WebRTC之间互通,中间引入一个翻译员,是否是通信延时也就增长了?
其实不会,由于小程序音视频和WebRTC的视频编码标准在常规应用场景中是一致的,都是H.264标准,这是音频格式不一样而已。这就意味着,翻译员要作的事情不多,两边基本都能挺对对方在说什么,因此延时不会增长太多。
下图所展现的就是腾讯视频云在小程序音视频和WebRTC互通问题上所采起的方案:
(1)首先,微信端的小程序经过腾讯视频云SDK将音视频流推送到腾讯云 RTMP 服务器。
(2)其次,腾讯云 RTMP 服务器的会对音视频数据进行初步的转化处理,而后透传给腾讯视频云的实时音视频后台集群。
(3)再次,实时音视频后台会再次将数据交给一个叫作 WebRTC-Proxy 的模块,就在这里, WebRTC-Proxy 要未来自小程序音视频的音视频数据翻译成 WebRTC 理解的“语言”。
(4)最后,在PC上的Chrome浏览器,就能够经过浏览器内置的WebRTC模块跟 WebRTC-Proxy 通信,进而看到小程序端的视频影像。
(5)上面的四个过程倒过来,就能够实现双向视频通话;而将腾讯视频云做为星型结构的中心节点,多个端(无论是小程序仍是Chrome浏览器)都接入进来,那就能够造成多人音视频解决方案。
仅仅完成了音视频数据在小程序和WebRTC之间的握手还远远不够,由于在一次成功的音视频通话背后,不只仅是把一端的音视频数据传递到另外一端这么简单,还有状态的同步和成员间的状态协同。
好比多人视频通话中,涉及到呼叫和接通的流程,其中一方若是挂断了,其余人要收到挂断的通知。同时,若是有新的参与者加入,那么其余人也要收到相应的通知。WebRTC 中有不少组件,好比 RTCPeerConnection 就在处理上诉林林种种的逻辑。可是 WebRTC 的接口中引入的新名词很是多,对于初学者来讲仍是有必定的入门门槛,为了简化这里的逻辑,咱们引入一个叫作“房间”的概念。
所谓房间(Room),就是把同时参与视频通话的各方圈在一块儿的一个东西。好比双人通话中,通话中的两我的 A 和 B 就能够认为在一个房间中。再好比在多人通话中,通话中的五我的(A B C D E)也能够认为是在一个房间里。
有了房间的概念,那咱们就能够对刚才说的状态协同用两个简单的动做描述一下:若是有一我的加入了视频通话,那么就能够理解为他/她已经进房(EnterRoom)了;若是有一个退出了视频通话,那么就能够理解为他/她已经离开房间(LeaveRoom)了。而房间的门板上始终写着:“目前在房间里有哪几我的”。
有了房间的概念,咱们就能够将小程序的两个简单的 和 标签,同 WebRTC 那一套复杂的 API 进行功能上的对齐,咱们甚至不须要修改咱们在初版中定义的接口,就能够达成这个目标:
(1) 的 url 接口再也不传递 rtmp:// 协议的推流地址,而是传递 room:// 协议的推流地址。room:// 协议的使用方式能够参考咱们的原理版文档 DOC。
(2) 标签在 start 成功以后,就至关于成功进入一个 room,以后,您能够经过 onPushEvent (PUSH_EVT_ROOM_USERLIST = 1020) 事件,收到房间里还有那些人的信息。在视频通话期间,房间内各个成员的进进出出,也都会经过这个事件通知给您的小程序代码。
(3)ROOM_USERLIST 里每一项都是一个二元组(若是是 1v1 的视频通话,ROOM_USERLIST 里只会有一我的): userid 和 playurl。 userid 表明是哪一个用户, playurl 则是这个用户远程画面的播放地址。您要作的只是使用 标签播放这些远程画面的图像和声音而已。
(4)在 WebRTC 这一端,您能够参考咱们的 webrtc API,这套 API 相对于 WebRTC 原生的 API,更适合初学者使用。
若是您但愿一天内就打通 webrtc 和 小程序音视频 的互通,那么我推荐您不要从零开始,由于那会耗费您太多时间去踩坑和 bugfix,推荐您直接使用咱们封装好的 ,这套方案既能够帮助您完成快速接入,又能知足必定的定制需求。
另外,不要忘记在微信=>发现=>小程序=>腾讯云视频云,体验一下腾讯云官方 Demo 中的 WebRTC 互通效果哦。
标签是基于 和 实现的用于 WebRTC 互通的自定义组件。若是您但愿直接使用 和 标签完成对接,或者想要了解 的内部原理,能够参考 DOC。
对接资料 | 说明 | 下载连接 |
---|---|---|
小程序源码 | 包含的组件源码以及demo源码 | DOWNLOAD |
PC端源码 | 基于WebrtcAPI实现的Chrome版WebRTC接入源码(其中 component/WebRTCRoom.js 实现了一个简单的房间管理功能,component/mainwindow.js包含了对 WebRTC API 的使用代码) | webrtc(Chrome).zip |
后台源码 | 实现了一个简单的房间列表功能,同时包含几个所需参数的生成代码 | webrtc_server_list.zip |
属性 | 类型 | 值 | 说明 |
---|---|---|---|
template | String | '1v3' | 必要,标识组件使用的界面模版(用户若是须要自定义界面,请看 界面定制) |
sdkAppID | String | ‘’ | 必要,开通 IM 服务所获取到的 AppID |
userID | String | '' | 必要,用户 ID |
userSig | String | ‘’ | 必要,身份签名,至关于登陆密码的做用 |
roomID | Number | ‘’ | 必要,房间号 |
privateMapKey | String | ‘’ | 必要,房间权限 key,至关于进入指定房间 roomID 的钥匙 |
beauty | Number | 0~5 | 可选,默认 5, 美颜级别 0~5 |
muted | Boolean | true, false | 可选,默认 false,是否静音 |
debug | Boolean | true, false | 可选,默认 false,是否打印推流 debug 信息 |
bindRoomEvent | function | 必要,监听 组件返回的事件 | |
enableIM | Boolean | true, false | 可选,默认false |
bindIMEvent | function | 当IM开启时必要,监听 IM 返回的事件 |
组件包含以下操做接口,您须要先经过 selectComponent 获取 标签的引用,以后就能够进行相应的操做了。
函数名 | 说明 |
---|---|
start() | 启动 |
pause() | 暂停 |
resume() | 恢复 |
stop() | 中止 |
switchCamera() | 切换摄像头 |
var webrtcroom = this.selectComponent("#webrtcroomid")
webrtcroom.pause();
复制代码
标签经过 onRoomEvent 返回内部事件,经过 onIMEvent 返回 IM 消息事件,事件参数格式以下
"detail": {
"tag": "事件tag标识,具备惟一性",
"code": "事件代码",
"detail": "对应事件的详细参数"
}
复制代码
// Page.wxml 文件
<webrtc-room id="webrtcroom"
roomID="{{roomID}}"
userID="{{userID}}"
userSig="{{userSig}}"
sdkAppID="{{sdkAppID}}"
privateMapKey="{{privateMapKey}}"
template="1v3"
beauty="{{beauty}}"
muted="{{muted}}"
debug="{{debug}}"
bindRoomEvent="onRoomEvent"
enableIM="{{enableIM}}"
bindIMEvent="onIMEvent">
</webrtc-room>
// Page.js 文件
Page({
data: {
//...
roomID: '',
userID: '',
userSig: '',
sdkAppID: '',
beauty: 3,
muted: false,
debug: false,
enableIM: false
},
onRoomEvent: function(e){
switch(e.detail.tag){
case 'error': {
//发生错误
var code = e.detail.code;
var detail = e.detail.detail;
break;
}
}
},
onIMEvent: function(e){
switch(e.detail.tag){
case 'big_group_msg_notify':
//收到群组消息
console.debug( e.detail.detail )
break;
case 'login_event':
//登陆事件通知
console.debug( e.detail.detail )
break;
case 'connection_event':
//链接状态事件
console.debug( e.detail.detail )
break;
case 'join_group_event':
//进群事件通知
console.debug( e.detail.detail )
break;
}
},
onLoad: function (options) {
self.setData({
userID: self.data.userID,
userSig: self.data.userSig,
sdkAppID: self.data.sdkAppID,
roomID: self.data.roomID,
privateMapKey: res.data.privateMapKey
}, function() {
var webrtcroomCom = this.selectComponent('#webrtcroom');
if (webrtcroomCom) {
webrtcroomCom.start();
}
})
},
})
复制代码
请确认已经参照 Demo部署 开通了相关服务和并正确的完成了配置。
并不是微信小程序原生提供的标签,而是一个自定义组件,因此您须要额外的代码来支持这个标签。点击 小程序源码 下载源码包,您能够在 wxlite
文件夹下获取到所需文件。
按照以下表格获取关键的 key 信息,这是使用腾讯云互通直播服务所必须的几个信息:
KEY | 示例 | 做用 | 获取方案 |
---|---|---|---|
sdkAppID | 1400087915 | 用于计费和业务区分 | step1 中获取 |
userID | xiaoming | 用户名 | 能够由您的服务器指定,或者使用小程序的openid |
userSig | 加密字符串 | 至关于 userid 对应的登陆密码 | 由您的服务器签发(PHP / JAVA) |
roomID | 12345 | 房间号 | 能够由您的服务器指定 |
privateMapKey | 加密字符串 | 进房票据:至关因而进入 roomid 的钥匙 | 由您的服务器签发(PHP / JAVA) |
下载 sign_src.zip 能够得到服务端签发 userSig 和 privateMapKey 的计算代码(生成 userSig 和 privateMapKey 的签名算法是 ECDSA-SHA256)。
self.setData({
userID: userID,
userSig: userSig,
sdkAppID: sdkAppID,
roomID: roomID,
privateMapKey: privateMapKey
}, function() {
var webrtcroomCom = this.selectComponent('#webrtcroomid');
if (webrtcroomCom) {
webrtcroomCom.start();
}
})
复制代码
//第一步:新建 /pages/templates/mytemplate 文件夹,并建立 mytemplate.wxml 和 mytemplate.wxss 文件
//第二步:编写 mytemplate.wxml 和 mytemplate.wxss 文件
//mytemplate.wxml
<template name='mytemplate'>
<view class='videoview'>
<view class="pusher-box">
<live-pusher
id="rtcpusher"
autopush
mode="RTC"
url="{{pushURL}}"
aspect="{{aspect}}"
min-bitrate="{{minBitrate}}"
max-bitrate="{{maxBitrate}}"
audio-quality="high"
beauty="{{beauty}}"
muted="{{muted}}"
waiting-image="https://mc.qcloudimg.com/static/img/ daeed8616ac5df256c0591c22a65c4d3/pause_publish.jpg"
background-mute="{{true}}"
debug="{{debug}}"
bindstatechange="onPush"
binderror="onError">
<cover-image class='character' src="/pages/Resources/mask.png"></cover-image>
<cover-view class='character' style='padding: 0 5px;'>我</cover-view>
</live-pusher>
</view>
<view class="player-box" wx:for="{{members}}" wx:key="userID">
<view class='poster'>
<cover-image class='set'
src="https://miniprogram-1252463788.file.myqcloud.com/roomset_{{index + 2}}.png">
</cover-image>
</view>
<live-player
id="{{item.userID}}"
autoplay
mode="RTC"
wx:if="{{item.accelerateURL}}"
object-fit="fillCrop"
min-cache="0.1"
max-cache="0.3"
src="{{item.accelerateURL}}"
debug="{{debug}}"
background-mute="{{true}}"
bindstatechange="onPlay">
<cover-view class='loading' wx:if="{{item.loading}}">
<cover-image src="/pages/Resources/loading_image0.png"></cover-image>
</cover-view>
<cover-image class='character' src="/pages/Resources/mask.png"></cover-image>
<cover-view class='character' style='padding: 0 5px;'>{{item.userName}}</cover-view>
</live-player>
</view>
</view>
</template>
//mytemplate.wxss
.videoview {
background-repeat:no-repeat;
background-size: cover;
width: 100%;
height: 100%;
}
复制代码
//为 <webrtc-room> 组件中的 webrtcroom.wxml 文件添加自定义模版
<import src='/pages/templates/mytemplate/mytemplate.wxml'/>
<view class='conponent-box'>
<view styles="width:100%;height=100%;" wx:if="{{template=='1v3'}}">
<template is='mytemplate' data="{{pushURL, aspect, minBitrate, maxBitrate, beauty, muted, debug, members}}"/>
</view>
</view>
//为 <webrtc-room> 组件中的 webrtcroom.wxss 文件添加自定义样式
@import "../templates/mytemplate/mytemplate.wxss";
复制代码
了解腾讯云官网的 WebrtcAPI ,能够对接 Chrome 端的 H5 视频通话,由于不是本文档的重点,此处不作赘述。
实时音视频产品开通
想要尝试这些接入,首先要开通腾讯云实时音视频,快来接入吧~
问答
相关阅读
此文已由做者受权腾讯云+社区发布,更多原文请点击
搜索关注公众号「云加社区」,第一时间获取技术干货,关注后回复1024 送你一份技术课程大礼包!
海量技术实践经验,尽在云加社区!