WebTransport 与 WebCodecs 初探

什么是WebTransport?

WebTransport 是WebRTC体系下的一套浏览器API,提供低延迟,client和server之间双向通信的能力。 核心的能力点包括:

  • WebTransport 提供基于QUIC 和 HTTP3实现的API, 自动获得QUIC和HTTP3本身的特性,比如应用层的拥塞,避免队头阻塞。
  • 双向通信的能力,多个传输通道复用一个连接的能力,能够很好的替代WebSocket。
  • 提供发送/接受不可靠UDP的能力,这个是浏览器一直欠缺的能力,

相关的规范如下:

  • WebTransport overview 这个规范介绍了WebTransport整体的情况,
  • WebTransport over QUIC 这个规范介绍WebTransport over QUIC的实现规范, 目前版本(M89)的WebTransport实现是基于QUIC的。
  • WebTransport over HTTP/3 这个规范介绍WebTransport over HTTP/3的实现规范,目前版本(M89)还没有实现这这部分。 按照官方的说法是,WebTransport 最终会完全基于HTTP/3 实现,并移除基于QUIC的实现,这个还需要进一步关注。

在浏览器中可以通过URL 来实例化一个WebTransport 实例,比如:

const url = quic-transport://example.com:4999/foo/bar';
const transport = new WebTransport(url);

// Once .ready fulfills, the connection can be used.
await transport.ready;

创建双向通信的通道:

const rs = transport.receiveBidrectionalStreams();
const reader = rs.getReader();
while (true) {
  const {done, value} = await reader.read();
  if (done) {
    break;
  }
  // value is a BidirectionalStream
  // value.readable is a ReadableStream
  // value.writable is a WritableStream
}

创建单向通信的通道:

// Send two Uint8Arrays to the server.
const stream = await transport.createSendStream();
const writer = stream.writable.getWriter();
const data1 = new Uint8Array([65, 66, 67]);
const data2 = new Uint8Array([68, 69, 70]);
writer.write(data1);
writer.write(data2);


// Receive data from the server
const rs = transport.receiveStreams();
const reader = rs.getReader();
while (true) {
  const {done, value} = await reader.read();
  if (done) {
    break;
  }
  // todo 
}

创建udp数据通道:

// Send two datagrams to the server.
const ws = transport.sendDatagrams();
const writer = ws.getWriter();
const data1 = new Uint8Array([65, 66, 67]);
const data2 = new Uint8Array([68, 69, 70]);
writer.write(data1);
writer.write(data2);

// Read datagrams from the server.
const rs = transport.receiveDatagrams();
const reader = rs.getReader();
while (true) {
  const {value, done} = await reader.read();
  if (done) {
    break;
  }
  // value is a Uint8Array.
  console.log(value);
}

WebTransport 与 WebSocket 的区别

WebTransport 与 WebSocket最直接的区别就是一个是基于UDP,一个是基于TCP。WebSocket基于TCP,从而也自带TCP协议本身的缺陷,比如队头阻塞。

WebSocket 是基于消息的协议,所以你不需要考虑数据分包,封装的问题。WebTransport 是基于流式的协议,在传递消息的时候需要自己再增加一层数据的封装格式,使用起来会比WebSocket略麻烦。

另外WebTransport 支持不可靠的UDP发送,这个扩宽了新的场景,这个是WebSocket所不能对比的。 相信WebTransport在成熟之后会抢占WebSocket的一部分使用场景。

什么是WebCodecs?

WebCodecs 的目的是在浏览器中提供高效的音视频编解码的API。

在目前的WebAPI中, 已经有MediaRecorder 和 MSE 两套编解码相关的API, 但他们都有很多限制。

MediaRecorder: MediaRecorder 允许将含有视频和音频的mediatrack 进行编码,但对于一些关键参数无法进行控制,比如对码率的的精确控制,关键帧的精确编码控制。除了对实时的音视频编码外不支持对其他的形式数据编码,MediaRecorder 输出数据前会有一段缓冲,对于低延迟的场景不合适,对于需要使用自有容器格式的场景也不合适。

MSE: MSE可以实时解码媒体数据,但对于音视频的输入输出有比较大的限制,对于解码速度,唯一能控制解码速度是通过playbackRate。并且解码的数据流必须使用特定的容器格式。 另外MSE的解码实时性并不好,可能会引入几百ms的buffer。

WebTransport 与 WebCodecs 配合能带来哪些变化?

1, web端直播

可以改善目前Web端基于http-flv/hls直播的体验,WebTransport 替代HTTP , WebCodecs替代MSE, 相信Web端直播的延迟和卡顿数据会大大改善。

2,云游戏

目前web端的云游戏方案 大都使用WebRTC, WebRTC为通话场景设计,本身的jitterbuffer,音视频同步,渲染延迟设计会引入额外的延迟,且Web端并没有暴露出来可以控制延迟的API, 使用WebTransport + WebCodecs 可以做到更可控的极致低延迟,相信未来在云游戏的场景WebTransport+WebCodecs的方案会成为主流。

3, 远程桌面

远程桌面的场景与云游戏很像, 同上。

4,基于Web端的视频内容制作

OBS是直播推流与视频录制常用的工具,随着我们有了WebCodecs的直接编码能力,配合WebTransport 的浏览器推流的能力,一个Web版本的OBS所需要的能力也越来越完备,我们拭目以待一个WebOBS工具出现。

5,更具定制化能力的RTC组合

WebRTC作为浏览器的一个标准, 在浏览器中我们无法控制WebRTC的内部工作机制, 对于有能力处理好音视频前后处理的团队来说,加上WebTransport提供的传输能力,以及WebCodecs的编解码能力,完全可以在web端定制自己的RTC协议栈。 比如zoom就在使用WebTransport+WebCodecs来构建他们的Web端的视频会议产品(infoq.com/news/2020/08/)。

最后,我们已经在最新的Chrome Canary 开发版本中体验测试 WebTransport + WebCodecs, 后端quic的各种实现也已经具备和WebTransport互通能力, 我们放出一个后端使用quic-go,带有完整采集,编码,推流,服务端中转,拉流,解码,渲染的demo, 具体的代码在这里 github.com/notedit/webc

最后 我组建了一个WebRTC技术交流的群,基本涵盖了行业内做RTC相关的公司的研发伙伴,对于想做技术交流的伙伴可以加我微信,备注“名字@公司名字 ” 我拉你进群,仅限技术产品交流。

 

WebTransport 与 WebCodecs 初探
标签: