webrtc如何进行后台录音

作者:音视频小话
原文:https://mp.weixin.qq.com/s/S9gvexb6QAmcO_UnR6otgw

webrtc的语音通话常使用opus编码,在webrtc的会议中常有语音录音的需求:

  • 会议客户需要语音会议记录,方便会后进行会议记录;
  • troubleshooting需要:在后台接受的语音中进行录音,方便知道当前传输语音的质量;

opus编码的录音存在一些挑战:

  • 支持opus编码的录音流媒体格式较少,如传统的flv就不支持opus格式。
  • 什么格式支持opus的效率比较高(报文头小且占比小,而opus负荷占比高)。

备注(普及给小白):流媒体录音(录像)格式,常指格式支持音频(视频)能长期持续写入的格式,如flv,mpegts,fmp4等。也就是文件可以动态的持续写入。

这里推荐采用ogg封装格式来进行opus编码的录音,本文介绍:

  • ogg格式详解;
  • ogg的mux和demux的开源:推荐一个非常独立,移植性强的C++开源;
  • 扩展:webrtc的录像怎么做(支持H264/H265/Vp8/Vp9/AV1编码);

1. Ogg格式详解

1.1 Ogg的结构

Ogg常用来存储opus编码的报文(当然也可以存储其他格式,这里主要介绍opus编码)。主要结构为:

           +++++++++++++++++++++++++++++++++++++++
           
Ogg Page1: |Ogg Header1|Opus packet1|Opus packet2|
           
           ++++++++++++++++++++++++++++++++++++++++++++++++++++
           
Ogg Page2: |Ogg Header2|Opus packet1|Opus packet2|..|packet 255|
           
           ++++++++++++++++++++++++++++++++++++++++++++++++++++
           
           |....                                              |
           
           ++++++++++++++++++++++++++++++++++++++++++++++++++++

如上,Ogg格式是由多个不同Ogg页面组成(Page), 每个Ogg页面由Ogg Header加上多个系列的Opus编码报文组成。上面的一行是Ogg的一个页面,比如:

  • Ogg Page1: [Ogg Header1: 2个Opus报文]
  • Ogg Page2: [Ogg Header2: 255个Opus报文]
  • ……

这样的序列是连续的,且持续的。

1.2 Ogg Header格式

Ogg Header格式如下:

+++++++++++++++++++++++++++++++++++++++++++++
|             Oggs Tag('OggS')             |
+++++++++++++++++++++++++++++++++++++++++++++
|ver(1byte)|headerflag|      gp             |
+++++++++++++++++++++++++++++++++++++++++++++
|                   gp                      |
+++++++++++++++++++++++++++++++++++++++++++++
|                 gp  |    stream_serial    |
+++++++++++++++++++++++++++++++++++++++++++++
|     stream_serial   |    page_sequence    |
+++++++++++++++++++++++++++++++++++++++++++++
|     page_sequence   |       CRC           |
+++++++++++++++++++++++++++++++++++++++++++++
|         CRC         |size count|   size0  |
+++++++++++++++++++++++++++++++++++++++++++++
|   size1  |   size2  |   size3  |   size4  |
+++++++++++++++++++++++++++++++++++++++++++++
|.......
  • Ogg Tag(4bytes):必须是字符串’OggS’
  • Ver(1byte): 版本号,常规为0
  • headerflag(1byte): Opus Header的类型,有以下几种
#define OGG_NULL_HEADER_TYPE        0x00
#define OGG_CONTINUE_HEADER_TYPE    0x01
#define OGG_FIRST_HEADER_TYPE       0x02
#define OGG_LAST_HEADER_TYPE        0x04
  • gp(8bytes): granule position,定义Opus报文之间的dts结构,在常规的webrtc中,间隔为20ms。
  • stream_serial(4bytes): 流id,唯一表示存储的一份流,一般一路opus,该id唯一。
  • page_sequence(4bytes): OggS的page页序号,依次递增。
  • CRC(4bytes):校验和
  • size count(1byte): packets size数组长度,最大为255,也就是该页的packet的个数。
  • size array(1byte x size count): 一个数组,数组成员1byte,表示一个Opus报文的长度,该数组表示一组Opus报文的长度。

1.3 Opus数据包

一个Ogg Page中,有多个Opus数据包。具体有多少个由上面的size count决定,每个Opus数据包的长度由上面的size array中的对应一项决定。

2. Ogg mux/demux开源实现

在cpp_streamer的开源中,对应Ogg mux/demux的实现(主要针对Opus编码)。代码地址:

https://github.com/runner365/cpp_streamer/tree/v1.1/src/format/ogg

该开源的特点:

  • 代码独立: 没有依赖其他第三方库(如ffmpeg或gstream等):
  • 移植性比较强: C++11编写,无依赖库,移植方便
  • 良好的使用C++例子:1) 解封装: src/tools/ogg_dump.cpp(解析ogg文件);2) 封装: src/tools/mpegts2ogg.cpp(mpegts转写ogg文件,内部音频编码是opus)

3. 扩展讨论–录像的方案

webrtc音视频流的录像需要兼容更多的音视频编码格式:

  • H264
  • H265
  • Vp8/Vp9
  • AV1
  • Opus

因为支持的格式比较多,笔者推荐两种录像格式:

  • fmp4: mp4支持的codec类型非常的全面,以上的webrtc编码音视频格式都支持,fmp4具有流媒体持续写入的特点(解决了普通mp4不能持续写入的问题),因此非常适合做封装容器;
  • Enhance Flv: 传统的Flv仅仅支持H264, AAC等编码格式,但是近期公布的扩展Enhance Flv支持多种codec模式,其中包括Vpx, AV1, Opus。笔者在之前的博文(Enhance rtmp-flv协议开始支持多码流)中,详细描述Enhance flv格式如何支持H265, Vpx, AV1, Opus编码。

后续会分享对应fmp4和Enhance Flv的mux和demux代码,感兴趣的可以先点赞/关注,后续继续分享和讨论。

版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。

(0)

相关推荐

发表回复

登录后才能评论