开箱即用的 WebRTC 开发环境

本文为作者投稿,版权归作者所有,未经允许,请勿转载。
作者:Piasy


在刚刚落幕的 WWDC17 上,苹果为我们带来了一个不小的惊喜 —— 其浏览器内核WebKit将正式支持 WebRTC,而未来基于 WebKit 内核的苹果浏览器,比如macOS High Sierra、iOS 11 中的 Safari 浏览器和Safari 技术预览版 32,都将使用到 WebRTC 技术。
—— 苹果终于入伙 WebRTC

适逢我也正在倒腾一些 WebRTC 的东西,万事开头难,搞事情最怕的就是开始的拦路虎,编译环境、demo 工程、Server 如何部署,这三个问题(尤其是最后一个)想必会浇灭很多朋友的热情之火。经过近两周的不懈奋斗,我总算把这几头拦路虎一一解决,今天我就在这里把这一套开箱即用的 WebRTC 开发环境分享给大家。

注意:这里我假设大家具备 Docker 的基本使用能力,如不具备,请自行搜索相关教程。

WebRTC 编译环境

一开始我是用的 webrtc-build-scripts 这个工具,它利用的是 Vagrant,为了和后面的其他工具统一,我就基于它构建了一个 Docker 镜像:piasy/webrtc-build

首先是 pull 镜像:

docker pull piasy/webrtc-build

然后就是运行 Docker 镜像了:

docker run --rm \
  -e ENABLE_SHADOW_SOCKS=false \
  -v <path to place webrtc source>:/webrtc \
  -t -i piasy/webrtc-build

单纯对 webrtc-build-scripts 做一层封装肯定没啥意思,针对国情,我在 Docker 镜像里面加上了使用 Shadowsocks 代理的支持,上面的命令不启用 Shadowsocks 代理,如需启用,则运行下面的命令:

docker run --rm \
  -e ENABLE_SHADOW_SOCKS=true \
  -e SHADOW_SOCKS_SERVER_ADDR=<your shadowsocks server ip> \
  -e SHADOW_SOCKS_SERVER_PORT=<your shadowsocks server port> \
  -e SHADOW_SOCKS_ENC_METHOD=<your shadowsocks encrypt method> \
  -e SHADOW_SOCKS_ENC_PASS=<your shadowsocks encrypt password> \
  -v <path to place webrtc source>:/webrtc \
  -t -i piasy/webrtc-build

不过现在还有两点小瑕疵:

  • proxychains 在 Docker 镜像中还有问题,所以 Shadowsocks 代理暂时不能用; 换用 polipo 之后就 OK 了,感谢 技术小黑屋
  • 目前只能编译 Android 环境,iOS 的我还没搞过;

注意:如果 Shadowsocks 的密码有特殊字符,请用 \ 进行转义,例如 &bDmc! 变为 \&bDmc!。

编译命令

# 下载 WebRTC 代码
get_webrtc

# 编译 WebRTC 代码
build_apprtc

更多编译指令,可以参考 webrtc-build-scriptsWebRTC 项目官网

命令行使用 Shadowsocks 代理

在这里顺便分享一下如何在命令行挂上 Shadowsocks 代理:

sudo apt-get install python-pip
sudo pip install shadowsocks
sudo apt-get install proxychains

wget https://download.libsodium.org/libsodium/releases/LATEST.tar.gz
tar zxf LATEST.tar.gz && cd libsodium*
./configure && make && make install

# 修复关联
echo /usr/local/lib > /etc/ld.so.conf.d/usr_local_lib.conf && ldconfig

/etc/shadowsocks.json 配置内容:

{
"server":"server-ip",
"server_port":8000,
"local_address": "127.0.0.1",
"local_port":1080,
"password":"your-password",
"timeout":600,
"method":"aes-256-cfb"
}

~/.proxychains/proxychains.conf 配置内容:

strict_chain
proxy_dns
remote_dns_subnet 224
tcp_read_time_out 15000
tcp_connect_time_out 8000
localnet 127.0.0.0/255.0.0.0
quiet_mode

[ProxyList]
socks5  127.0.0.1 1080

执行下述命令之后,命令行程序就会使用 Shadowsocks 代理了:

sudo sslocal -c /etc/shadowsocks.json -d start
proxychains bash

Android demo 工程

Android demo 可以利用上面的 WebRTC 源码编译出 APK,但我们如何查阅代码、调试代码呢?最好自然是有一个 Android Studio 工程了,这里为大家送上:AppRTC-Android

这个项目其实就是把相关路径的源码摘出来,并把编译完成的 so 库文件也拿出来,放到了一个 Android Studio 工程中,相关源码路径:

AppRTC-Server

AppRTC 是 WebRTC 的一个 demo 应用,它需要和 Server 配合才能运行。这个 Server 的搭建是最令人头疼的了,不过不用担心,咱这不是有开箱即用的工具嘛:piasy/apprtc-server

pull 镜像:

docker pull piasy/apprtc-server

运行 Docker 镜像:

docker run --rm \
  -p 8080:8080 -p 8089:8089 -p 3478:3478 -p 3033:3033 \
  --expose=59000-65000 \
  -e PUBLIC_IP=<server public IP> \
  -v <path to constants.py>:/apprtc_configs \
  -t -i piasy/apprtc-server

运行之后,在 Android demo 的设置界面中,把 Server 地址设置为 http://<server public IP>:8080,demo 即可成功跨网视频通话。很多人自己部署完服务器之后发现,只能在同一 WiFi 下通话,跨 WiFi 就不行了。大家放心,咱们可没这个问题 :)

AppRTC-Server 部署简介

开箱即用当然好,不过这里我也把构建过程中遇到的一些问题分享出来,希望对大家有所帮助。

AppRTC 需要三个 Server:

  • Room Server: 负责处理加入房间、获取配置等请求;
  • Signal Server: 长连接服务器,用于聊天过程中实时下发信息;
  • TURN/STUN Server: 打洞服务器,用于 NAT 打洞;

Room Server 和 Signal Server 都在 apprtc 这个项目中,部署说明很详细,需要注意的是关于 TURN/STUN Server 的配置问题:

AppRTC Android demo 中,会尝试从房间配置中读取 pc_config 域,以取得 TURN/STUN Server 信息;如果没有获取到,就会向配置中的 ice_server_url 指向的服务器获取 TURN/STUN Server 信息。但 apprtc 的配置说明中,让我们把 TURN/STUN Server 配置写在 TURN_SERVER_OVERRIDE 中,这是不行的,因为客户端的逻辑并不会读取 TURN_SERVER_OVERRIDE 这个域,此外 Android demo 读取 pc_config 的代码中,无法正确把 TURN Server 的用户名解析出来,所以我们不得不自己搭一个 ICE Server,尽管这会多一次网络请求,不过用于测试也没啥问题。最后,这里是示例的 constants.py 地址

因此我们还需要第四个 Server:ICE Server。它用于下发 TURN/STUN Server 配置信息,代码如下(nodejs):

var express = require('express')
var crypto = require('crypto')
var app = express()

var hmac = function (key, content) {
  var method = crypto.createHmac('sha1', key)
  method.setEncoding('base64')
  method.write(content)
  method.end()
  return method.read()
}

app.get('/iceconfig', function (req, resp) {
  var query = req.query
  var key = '4080218913'
  var time_to_live = 600
  var timestamp = Math.floor(Date.now() / 1000) + time_to_live
  var turn_username = timestamp + ':ninefingers'
  var password = hmac(key, turn_username)

  return resp.send({
    iceServers: [
      {
        urls: [
          'turn:ICE_SERVER_ADDR:3478?transport=udp',
          'turn:ICE_SERVER_ADDR:3478?transport=tcp',
          'turn:ICE_SERVER_ADDR:3479?transport=udp',
          'turn:ICE_SERVER_ADDR:3479?transport=tcp'
        ],
        username: turn_username,
        credential: password
      }
    ]
  })
})

app.listen('3033', function () {
  console.log('server started')
})

几点说明:

  • 这里面有两个配置写死了:key = '4080218913',用户名 ninefingers,它们都是在部署 Coturn 时配置的;
  • username/credential 并不是 Coturn 创建用户的 username/password,而是按照上述逻辑计算出来的值,否则 Coturn 会报错 401 Unauthorized;
  • 上面的 ICE Server 部署之后,Android demo 请求时会报 404,最终定位是因为 demo 用 HttpURLConnection 时设置了 connection.setDoOutput(true);,注释掉就好了,详见这个 commit

四个 Server 都部署好之后,就可以开心的开始视频聊天啦!

最后再解释一下 Docker 镜像开放的端口:

  • 8080 用于 Room Server;
  • 8089 用于 Signal Server;
  • 3033 用于 ICE Server;
  • 3478 和 59000-65000 用于 TURN/STUN Server;

WebRTC 简介 WebRTC,名称源自网页实时通信(Web Real-Time Communication)的缩写,是一个支持网页浏览器进行实时语音通话或视频聊天的技术,是谷歌2010年以6820万美元收购Global IP Solutions公司而获得的一项技术。 WebRTC提供了实时音视频的核心技术,包括音视频的采集、编解码、网络传输、显示等功能,并且还支持跨平台:windows,linux,mac,android。 虽然WebRTC的目标是实现跨平台的Web端实时音视频通讯,但因为核心层代码的Native、高品质和内聚性,开发者很容易进行除Web平台外的移殖和应用。很长一段时间内WebRTC是业界能免费得到的唯一高品质实时音视频通讯技术。 为什么需要 WebRTC 开发者教程? 虽然WebRTC技术已经较为成熟,其集成了最佳的音/视频引擎,十分先进的codec,且包含了使用STUN、ICE、TURN、RTP-over-TCP的关键NAT和防火墙穿透等众多门槛并不低的技术。抛开音视频技术本身的复杂性外,要想找到合适的资料、完整的代码和库、配合合适的IDE和辅助工具能正常地实现编译和安装都非常的不容易,而这还只是个开始。没有靠谱的教程,你该怎么开始?那么地坑等在那,难道你打算一个一个趟过去? 本《WebRTC 零基础开发者教程》主要讲了什么 本文中提供下载的《WebRTC 零基础开发者教程》将以一个初学者的角度,从0开始逐步引导你掌握WebRTC开发的方方面面(当然,教程中更多的是操作性的内容,具体到技术原理和实现,显然不是本教程的讨论范畴)。 《WebRTC 零基础开发者教程》目录 1 工具 1.1 depot_tools 1.1.1 目标 1.1.2 Chromium 1.1.3 使用说明在这儿 1.1.4 下载 1.1.5 使用 1.1.6 具体使用例子 1.2 Gyp工具 1.3 Python工具 1.4 本地集成开发环境(IDE ) 1.4.1 Visual studio 1.4.2 Kdevelop 1.4.3 Eclipse 2 Webrtc 2.1 下载、编译 2.1.1 Windows下 2.1.2 ubuntu下编译 2.1.3 编译Android(只能在 linux 下) 3 webrtc开发 3.1 开发P2P视频软件需要处理的问题 3.1.1 用户列的获取、交换、信令的交换 3.1.2 P2P通信 3.1.3 多媒体处理 3.2 webrtc架构 3.2.1 WebRTC架构组件介绍 3.2.2 WebRTC核心模块API介绍 3.2.3 webRTC核心API详解 4 Libjingle详细介绍 4.1 重要组件 4.1.1 信号 4.1.2 线程和消息 4.1.3 名称转换 4.1.4 SSL支持 4.1.5 连接 4.1.6 传输,通道,连接 4.1.7 候选项 4.1.8 数据包 4.2 如何工作 4.2.1 Application模块 4.2.2 XMPP Messaging Component 模块 4.2.3 Session Logic and management commponent 模块 4.2.4 Peer to peer Component 模块 4.2.5 其他 4.3 建立libjingle应用程序 5 代码分析 5.1 音频通道建立过程 5.2 音频接收播放过程 5.3 视频接收播放过程 6 协议 6.1 XMPP协议 6.1.1 原理介绍 6.1.2 XMPP 协议网络架构 6.1.3 XMPP 协议的组成 6.1.4 Xmpp介绍 6.1.5 协议内容 6.2 Stun协议 6.2.1 P2P实现的原理 6.2.2 P2P的常用实现 6.2.3 Stun URI 6.2.4 内容 6.2.5 中文内容 6.2.6 开源服务器 6.2.7 公开的免费STUN服务器 6.3 Turn协议 6.3.1 概念 6.3.2 Turn uri 6.3.3 开源服务器工程 6.3.4 开源库 6.4 交互式连接建立(Interactive Connectivity Establishment) 6.4.1 IETF规格 6.4.2 开源工程 6.5 XEP-0166 Jingle 6.5.1 绪论 6.5.2 需求 6.6 Sctp协议 6.7 Rtp协议 7 附件 7.1 Gyp工具 7.2 Google test程序 7.3 Webrtc库介绍 7.4 webrtc代码相关基础知识 7.5 STUN和TURN技术浅析 7.6 基于ICE的VoIP穿越NAT改进方案 7.7 ubuntu安装使用stuntman 7.8 一个开源的ICE库——libnice介绍 7.9 4种利用TURN穿越对称型NAT方案的设计与实现 7.10 基于ICE方式SIP信令穿透Symmetric_NAT技术研究
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值