小程序与WebRTC联姻能擦出怎样的火花?

欢迎你们前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~javascript

本文由腾讯视频云终端团队发表于云+社区专栏java

腾讯视频云终端技术总监,rexchang(常青), 2008 年毕业加入腾讯,一直从事客户端研发相关工做,前后参与过 PC QQ、手机QQ、QQ物联 等产品项目,目前在腾讯视频云团队负责音视频终端解决方案的优化和落地工做,帮助客户在可控的研发成本投入之下,得到业内一流的音视频解决方案,目前咱们的产品线包括:互动直播、点播、短视频、实时视频通话,图像处理,AI 等等。git

img
本篇文章的思惟导图

分开作一下介绍

小程序音视频是什么?github

2017年腾讯视频云团队跟微信团队联合,将视频云 SDK 跟微信小程序整合在一块儿,并经过 和 两个标签的形式开放内部的功能。经过这两个标签,开发者能够实如今线直播、低延时监控、双人视频通话以及多人视频会议等功能。web

那么WebRTC又是什么?算法

WebRTC(Web Real-Time Communication),是一个支持网页浏览器进行实时语音对话或视频对话的技术,是谷歌收购 GIPS 公司而得到的一项技术,在 Chrome 浏览器上无需安装插件,经过 javascript 就能够编写实时音视频通话程序。json

二者区别在哪里?

若是您跟我同样是一个实用主义者,那我就简单从实用主义角度说一下个人结论:小程序搞定了手机,WebRTC拿下了PC。小程序

若是你对技术比较感兴趣,那咱们就能够从多个技术的角度去列举二者的区别,下面是一张详细对比的表格:微信小程序

img

  • 实现原理: 小程序音视频是将腾讯视频云的 liteavsdk 嵌入到微信内部实现的,而后经过 和 两个标签将 SDK 内部的音视频能力开放出来。因此小程序的标签起到了开发者 API 的做用,而内部的 SDK 则是真正用来实现音视频功能。

WebRTC 由谷歌收购 GIPS 得来(这里不得不提一下,我加入腾讯时所在的第一个团队就是 QQ 团队,当时 QQ 的音视频仍是购买的 GIPS 公司的产品,不过因为各类不靠谱,后来就转为自研路线了)。因此其技术被完整的保留而且加入到了 Google 的 Chrome 浏览器内核当中。并且最近苹果也已经开始在 Safari 浏览器中支持 WebRTC 的相关能力。api

  • 底层协议 小程序音视频的主要协议是目前在直播领域最为经常使用的 RTMP 推流协议,以及 HTTP-FLV 播放协议,这两种协议都已经有多年的沉淀并且在互联网上的资料也是汗牛充栋。

WebRTC的底层则是使用RTP和RTCP两种数据协议,其中RTP主要用于音视频数据传输,而RTCP则通常用于控制。

  • 移动端碎片化问题 小程序音视频因为是微信统一实现的,并且微信团队每一个版本都尽可能要求功能对齐,不然宁肯不上,因此在碎片化问题上基本不存在。

WebRTC在这里则要尴尬的多,一方面Android系统的碎片化自己让WebRTC的具体表现呈现“百花齐放”的景象,同时,iOS 目前的内嵌WebView(也就是在微信等APP里打开的各类内嵌网页)不支持WebRTC也仍是个很麻烦的问题。

  • 扩展性 小程序音视频跟随微信的版本发布,有什么问题通常是当前代码流修正,而后跟随下一个版本发布,因此通常一个功能点(好比给 pusher 加一个美颜的功能)或者一个问题点(好比不支持手势放大)从确立到最终实现(或解决)仅须要一个月的时间,并且微信APP新版本的覆盖速度也确实挺快。

相比之下,WebRTC则不是一个团队或者一家公司的问题了,由于它如今已经走标准路线,因此每个新特性都是先肯定标准,而后再推进浏览器厂商(包括苹果)进行跟随。这里面的故事就多了,时间也就更久了。

  • 桌面浏览器 相信您已经发现,在前面几个问题的分析上,个人观点都倾向小程序音视频。确实,在目前国内的移动领域里,谷歌和苹果都不能一家说了算,真正说了算的仍是微信

可是在桌面浏览器这个部分,Chrome目前在PC浏览器市场上留到地位的存在决定了 WebRTC 的优点就很大了,开发者能够在不安装插件的状况下就能够实现本身想要的功能。

相比之下,因为没有 Chrome 的原生支持,因此若是咱们要在 PC 上对接小程序音视频,就须要安装浏览器插件或者经过 wxlite://start 这样的伪协议唤起本地 exe 应用程序(相似在网页上打开 QQ 聊天窗口)。

并不是零和博弈

小程序音视频和WebRTC支架并不是零和博艺,双方都有本身的优点和不足,因此本着“打不过他们,就加入他们”的思路,腾讯视频云团队在2018年春节回来后,就快马加鞭地开始了小程序音视频和WebRTC互通的相关工做。

目前,须要向各位开发者汇报的是,在最新版本的微信中,小程序音视频已经能够跟WebRTC打通,目前在PC 的Chrome浏览器上就能够跟小程序进行实时音视频互通。

// to-do

固然,若是您想知道这个功能是怎么实现的,能够继续看下去:

充分了解WebRTC

就像结婚同样,既然你决定要选择另外一我的做为人生下半辈子的伴侣,那你确定会先深刻地了解一下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互通问题上所采起的方案:

img

(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 进行功能上的对齐,咱们甚至不须要修改咱们在初版中定义的接口,就能够达成这个目标:

img

(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 互通效果哦。

img

标签说明

标签是基于 和 实现的用于 WebRTC 互通的自定义组件。若是您但愿直接使用 和 标签完成对接,或者想要了解 的内部原理,能够参考 DOC

版本要求

  • 微信 6.6.6 版本开始支持。

效果演示

  • PC 端 用 Chrome 浏览器打开 体验页面 能够体验桌面版 WebRTC 的效果。
  • 微信端 发现=>小程序=>搜索“腾讯视频云”,点击 WebRTC 功能卡,就能够体验跟桌面版 Chrome 互通的效果了。

img

对接资料

对接资料 说明 下载连接
小程序源码 包含的组件源码以及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部署 开通了相关服务和并正确的完成了配置。

step1: 下载自定义组件源码

并不是微信小程序原生提供的标签,而是一个自定义组件,因此您须要额外的代码来支持这个标签。点击 小程序源码 下载源码包,您能够在 wxlite 文件夹下获取到所需文件。

step2: 在工程中引入组件

  • 在 page 目录下的 json 配置文件内引用组件,这一步是必须的,由于 并不是原生标签。 "usingComponents": { "webrtc-room": "/pages/webrtc-room/webrtc-room" } 在 page 目录下的 wxml 文件中使用标签

step3: 获取 key 信息

按照以下表格获取关键的 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)。

step4: 进入房间

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 组件引入模版
//为 <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";
复制代码

Chrome端对接

了解腾讯云官网的 WebrtcAPI ,能够对接 Chrome 端的 H5 视频通话,由于不是本文档的重点,此处不作赘述。

实时音视频产品开通

想要尝试这些接入,首先要开通腾讯云实时音视频,快来接入吧~

问答

怎样部署小程序?

相关阅读

教你1天搭建本身的“微视”

教你从0到1搭建小程序音视频

教你快速搭建一场发布会直播方案

【每日课程推荐】新加坡南洋理工大学博士,带你深度学习NLP技术

此文已由做者受权腾讯云+社区发布,更多原文请点击

搜索关注公众号「云加社区」,第一时间获取技术干货,关注后回复1024 送你一份技术课程大礼包!

海量技术实践经验,尽在云加社区

相关文章
相关标签/搜索