那在上节课中呢?我向你介绍了add track相关的内容,那今天呢?我们来看看编解码器信息的收集。那在这里呢,我们需要问几个重要的问题,那首先呢,就是我们上节课通过,可以让web rtc知道我们都要传输哪些媒体?是否有音频?是否有视频对吧?那当你添加不同的track的时候呢?
y8 rtc自己就能够识别出来,你添加的是音频track还是视频track?那知道了这些信息之后,我们可以得到一个什么结果呢?
就是我们在进行媒体协商的时候生成的sdp中,会包含多个m行。如果你要传输音频数据,它就会有音频的行,如果你要传输视频数据,就会有视频的行。
那在m行中呢,还包括了很多信息,比如plow tap,有一个plow tap列表,那这些plow tap是从何而来的呢?这是我们第一个问题好,
第二个问题,那每个配置tab都有对应的值,比如幺幺幺代表的是ous,96代表的是vp8。那这些信息又是怎么获取到的?也是我们需要弄清楚的。好,
第三个问题,那在整个传输的过程中,我们所选择的传输协议也是非常关键的,你是选择的TCP还是udp?那在udp之上是直接传到rtp还是s rtp?那这些呢?对于我们数据的传输都非常的关键。
那以上这些问题呢?我们在这节课中就会给你答案。那就像我们人类起源一样,盘古开天辟地,那所有的事物呢,都应该有一个起源,对于webrtc来说,它的起源是哪儿呢?
实际就是peer connection factory,那当我们调用create peer connection factory这个API之后,那整个web rtc就开始运转起来了。其中,与我们今天所要介绍的内容息息相关的,
就在这个API中的四个参数,分别是音频编码工厂,音频解码工厂是。视频编码工厂以及视频解码工厂,那通过这四个API就可以一步一步的将我们上面三个问题一一解答。那这里呢?
我以create building audio encoder factory为例子,向你介绍一下web rtc是如何构造payload type列表的。以及如何组织每一个pillow type所对应的编辑码器的好的,
下面呢,我们就来看看这个API那在这个API中呢,它又调用了另外一个方法,就是create audio encoder factory。对于这个方法来说呢,它是一个模板方法了,对吧?那我们可以看到在这个方法的后边有一对尖括号,
也就是这块和这块。那在这个监控二里边儿呢?它列出了目前外边儿tc所支持的音频的编码器,包括了opus multi China lop US。g七二二il bcg 7幺幺这几个音频编码器
那这个模板方法啊,构造的非常巧妙。那他通过这个列表,利用C加加的可变模板参数,就实现了一个工厂方法,那我们来看一下。这个API的实现了好,那这段代码呢?就是create audio encoder factory的实现,那在这个API的上面啊,
我们可以看到一个template关键字。那通过这个关键字呢,我们可以知道它后边儿定义的就是一个模板,那在这个模板里边儿写了type name点儿点儿点儿ts。说明它是一个可变参数模板,可变参数模板是C加加幺幺中的一个非常重要的特性。那对于一般的同学来说呢,理解和使用可变参数模板是非常困难的,但一旦你掌握了C加加幺幺的这个特性,那你就会写出非常优质的代码来。那其中再把tc的create audio encoder factory就给我们提供了这样一个例子,那我们来看看它是怎么实现的啊?那可变参数对于属于c和C加加的同学来说呢,应该都不陌生,因为我们经常使用,
比如说C语言中的print for它就是一个具有可变参数的函数。对吧,它参数里需要打印的内容是可以变化的,那同样可变参数模板也是这个含义。就是你在这个模板列表中啊,可以传入可变参数的模板,这个参数呢是可多可少的,根据你的需要,你去列出来就了。对于可变参数模板,我们该如何使用呢?那么来看一下create audio encoder factory,它是怎么做的?那在这个函数中呢,它生成了一个新的对象,
在新的对象中,它创建了audio encoder factory t,这个对象对吧?那这个对象呢?它也是一个模板类,同时呢,是可变参数的模板类,因为我们把ts点儿点儿点儿给它传进去了。那这个点点点代表的就是你这里边给我传的模板的个数是多少?那它呢?就把这个列表原封不动的传给了。audio encoder factory t这个类好,那下面呢?我们再来看看audio encoder factory t这个类是如何定义的?那就如这里边左侧所展示的,
对于audio encoder factory t来说,它也是一个可变参数模板类,那它定义呢?与我们上一页PPT中。看到的这个定义呢是一样的,它也是template name点点点ts,也就是说接收一个可变参数的模板列表。那对于这个模板来说呢,在编译的时候就会进行可变参数模板的展开,对吧?那展开之后它就类似于这样的一个格式。那在这个模板列表中呢?将每一个模板一一列出来,包括了audio encoder opus,这些模板把它们都列在template的这个尖框儿里。
那这个时候呢,我们就要考虑一个问题了,那既然我们现在已经知道在这个列表中呢,有这么多的编码器,那我如何能将一个个的编码器获取到呢?对于可变参数模板来说呢,一个通常的办法是通过递归的方式获取,也就是说像下面这样。那将这个模板呢,设置成type na met后边呢,再一个type name点点点ts。那说明什么?说明我们后边这个还是一个可变参数的模板,而第一个呢是一个具体的模板。那它的含义呢,
就是将原来可变参数模板中的第一项获取到之后呢,把余下的可变参数作为一个新的可变参数模板。传给ts。对吧,这样可变参数列表中就少了一项,然后通过递归的方式,每次取一项,每次取一项,最终呢,将可变参数模板列表中的每一项给它取近。那这就是获取每一个编码器类的方法,它的实现呢?就如我们下边这段代码所展示的,在y8 tc中呢,它定义了一个helper,
对于helper来说。它需要提供两个模板,那第一个模板呢,就是可变参数模板列表中的第一项,那后边儿ts呢,就是余下的可变参数。好,那在这里边,它实现了一个方法,叫APP supported encoders这个API,它有一个参数是audio codecs pack类型的victor。也就是说,我们每获取到一个编码器的信息,都将它的内容呢?放到这个victor中,
那最后呢?这个victor就是一个输出的信息。那在这个函数中呢,它会调t类中的append supported encoders这个t就是一个具体类型,那对于第一个编码器来说呢,就是oppos编码器。对吧,会调用opus编码器的append supported encoders,那通过这个方法呢,把opus编码器相关的信息。保存到specs中,那之后呢?它又会调用hyper下边的呃pad supported encoder,也就是又调回这个函数。那当它再调回这个函数的时候,
这时候这个t变成了谁呢?就变成了scs。对吧,就这样一项一项把它们全部取出来,取出来之后呢,就将每一个编码器的信息保存到specs中。这就是通过可变参数模板来实现工厂方法的一个实例。这个实验啊,实现的非常巧妙,它对于我们理解这段代码来说呢,会造成一定难度。但一旦你把它理解透了之后,你就会觉得它非常的有意思OK?那下面呢?我们再来重新将这个过程啊,
温故一下。我们来看一个例子,那首先呢,我们通过create peer connection factory这个API,它里边儿的create buildin audio encoder factory。能够知道web rtc指定了它支持的编解码器都有哪些,那其中呢,包括了audio encoder opus。audio encoders CS audio encoder g七二二等等等,对吧?之后呢,我们又介绍了。C加加的可变参数模板,那么rtc呢?正是利用C加加的可变参数模板来实现了音频编码器的工厂方法。
那并且呢,通过递归的方式,将每一个编码器遍历出来,最后呢,将这个编码器的相关信息保存到一个固定的位置。那就如我们这里所展示的,对吧?那每一次递归调用的时候呢?在这个模板中都包含了一个具体的编码器模板。以及一个可变参数模板OK,那在append supported encoder这个API中呢?它就会调用这个具体的,比如说opens的呃pad supported encoder,这个方法将对应的这个编码器的信息保存下来。之后呢,
再调用helper的append supported encoder这个方法,那它又回到这里再取下一个audio encoders CS编码器。再调用它的append supported encoder,把它的信息保存到specs中,对吧?之后呢,是g七二二,那以此类推,就将每一个编码器的信息保存下来了。这就是web rtc获取编码器信息的一个具体的过程OK,那以上呢,就是我们这节课的内容。那有任何的问题呢,你可以到讨论区或者是QQ群里去给我留言,我在那里呢,
给你做相应解答好,谢谢。