webrtc是一个比较成熟的实时音视频处理开源项目,一上来老大就扔给我一本webrtc native实践,虽然狠下心“翻”完了一遍,但是还是云里雾里的,在经过几个月的摸索之后,我大概知道原因了,归根到底,是基础不在一个层次,理解不了的,所以我决定,尝试写一个接近我这种零基础入门实时音视频的记录系列,希望能帮到一些同学

基础概念的理解

实时音视频是一个很长的流程,从采集-编码-传输-接收-解码-渲染,每一个步骤都是很大的模块,所以我们一个一个来,我们先从采集相关的设计开始,我们先看一些概念,否则直接看代码会有点懵

stream(流):包含音频轨和视频轨的编码流

track(轨道):音频轨或者视频轨

音视频同异点-我的理解

先说几个点

  • 音频和视频还是很多地方不一样的

    • 音频采集了,自己不不要同时听到自己,一般只需要传输给对方;一般只有一个采集的地方;即使有多个采集的地方,对方希望听到是合流之后的一个声音;
    • 视频采集了,一般需要同时在己方和对方都渲染显示出来;可能要多个采集源;一般希望每个视频源独立展示(甚至是不同的设备展示)
  • 音频和视频有很多地方是一致的
    • 是同级的概念;整体的处理流程几乎一致
  • 音频和视频输入和输出的过程不一样

整体感觉是视频的逻辑要比音频复杂一些,所以下面我主要也是围绕视频展开,音频也会顺便说下

视频代码设计

其实这个地方很难真正从零开始,我这里也是从中间某个点开始说(对着代码说自己的理解);结合上面的同异点,我们来看下webrtc里面的代码设计

source和sink

这是我觉得第一个坑的设计,但你理解了之后,觉得这样设计也没有问题

联系实际场景,摄像头采集到图像之后,保存视频,成为视频源,编码和本地渲染需要消费图像做处理,类似于生产和消费的概念

对于消费者,也就是sink来说,如果我想要增加一个消费者,我继承sink接口,塞到保存视频源的实例里面去,让实例不断给我塞数据给我消费即可(onFrame),所以sink的接口定义比较好理解;

source的接口定义里面只有对sink的操作,这是我觉得一开始不好理解的地方,source并没有存储视频图像(为什么叫source呢?);我现在的理解是,相对于sink,这样的接口就可以理解为source(摄像头采集图像之后,调用source的某个接口,这这个接口里面,对图像数据进行分发给sink,对于sink来说,这个实例就可以理解为source);

videoBroadcaster

broadcaster做的就是我们上面那段话想做的事情

source的接口太简单了,下面是videoSourceBase的函数定义,还增加了一个sinks的成员来保存所有的sink成员;

而broadcaster同时继承了sink和source,这就是我们想做的事情:初始化一个broadcaster实例,增加一个消费者sink的时候,把sink通过broadcaster的source接口存入sinks即可;当采集到图像的时候,把图像按照既定的逻辑调用所有sink的接口即可;

webrtc里面同时是sink又是source的实例还有很多,例如

这是第一个实际概念到代码设计的实践,可以看到,简单的物理概念想真正用代码设计构架起来,还是需要很多抽象设计和构架思考的

source、track、stream

上面说完了整体一个大概念的图像采集之后,采集分发的小流程,这些图像数据source要变成track最后要形成 stream,我们看下这里的设计,在这些之前,有些更细节的概念也要考虑到,例如音视频发生了变化需要通知观察者

所以首先定义了观察者接口和通知者接口,都是很纯粹的接口定义

而通知者的继承关系则很长,通知接口有三个继承者MediaSourceInterface,MediaStreamTrackInterface,MediaStreamInterface,基本source、track、stream都是通知者

MediaSourceInterface

定义了媒体源的基本状态,媒体大类有两个,音频和视频,所以有两个继承者VideoTrackSourceInterface,AudioSourceInterface,上面也说到过,音视频细节上有些差异,从这里的接口设计可以看到一些

AudioSourceInterface

AudioSourceInterface的接口,例如音量这些,都是音频独有的

VideoTrackSourceInterface

因为之前已经定义了VideoSourceInterface,所以这里直接到了videoTrackSource的定义

从audio和video两个继承来看,这里的分化挺明显的

MediaStreamTrackInterface

track的定义和继承如下,定义了trackState和必要接口;同时可以看到有音视频track两个子接口

videoTrack

audioTrack和VideoTrack有一个不一样的地方是,audioTrack只是组合了audioSource,videoTrack还继承了videoSource,我理解这是因为视频的来源和分发比音频复杂,因为所有的音频可能最后会汇聚成一个,是多个视频源可能需要分发和处理到不同的地方;

MediaStreamInterface

最后继承Notifier的是MediaStreamInterface,可以看到,stream是videoTrack和audioTrack的组合

好了,今天就先写到这里,后面应该会持续更新

p

webrtc源码阅读理解一的更多相关文章

  1. Mask RCNN 源码阅读(update)

    之前看了Google官网的object_dectect 的源码,感觉Google大神写的还不错.最近想玩下Mask RCNN,就看了下源码,这里刚好当做总结和梳理.链接如下: Google官网的obj ...

  2. JDK 1.8 源码阅读和理解

    根据 一篇文章教会你,如何做到招聘要求中的“要有扎实的Java基础” 的指引,决定开始阅读下JDK源码. 本文将作为源码阅读总纲 一.精读部分 java.io java.lang java.util ...

  3. JDK部分源码阅读与理解

    本文为博主原创,允许转载,但请声明原文地址:http://www.coselding.cn/article/2016/05/31/JDK部分源码阅读与理解/ 不喜欢重复造轮子,不喜欢贴各种东西.JDK ...

  4. 1.4、WebRTC源码

    文章导读:本篇文章给读者展示WebRTC的源码目录结构,为读者构建全方位的知识体系,如果你有兴趣下载webrtc的源码来编译运行,本节内容可以作为你了解源码的简要说明书,webrtc源码非常庞大的,讲 ...

  5. 【原】AFNetworking源码阅读(六)

    [原]AFNetworking源码阅读(六) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这一篇的想讲的,一个就是分析一下AFSecurityPolicy文件,看看AF ...

  6. 【原】AFNetworking源码阅读(五)

    [原]AFNetworking源码阅读(五) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇中提及到了Multipart Request的构建方法- [AFHTTP ...

  7. 【原】AFNetworking源码阅读(四)

    [原]AFNetworking源码阅读(四) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇还遗留了很多问题,包括AFURLSessionManagerTaskDe ...

  8. 【原】AFNetworking源码阅读(二)

    [原]AFNetworking源码阅读(二) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇中我们在iOS Example代码中提到了AFHTTPSessionMa ...

  9. 【原】AFNetworking源码阅读(一)

    [原]AFNetworking源码阅读(一) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 AFNetworking版本:3.0.4 由于我平常并没有经常使用AFNetw ...

随机推荐

  1. Docker创建seafile搭建私有云

    docker-compose.yml version: '2.0' services: db: image: mariadb:10.1 container_name: seafile-mysql en ...

  2. MySQL——分表,分库操作

    说明 大数据量并且访问频繁的表,将其分为若干个表.如果不分的话,进行一次查询就会将表锁住,导致不能进行其他操作,故分表.表分割垂直分割应用场景:热数据放一个表里,冷数据放一个表里.冷数据使用MyIsa ...

  3. 【springboot】知识点总结

    [springboot 基础编] 01.SpringBoot>01 - 第一个应用–HelloWorld 02.SpringBoot>02 - 整合 MyBatis 03.SpringBo ...

  4. 小白5分钟创建WPF

    创建WPF应用程序 基于生产这里选择.Net Framework进行开发 添加控件 由于不熟悉 高效点 我们这里直接拖拽控件 如果你有一点前端基础 你可以在控件对应Code 根据属性 对控件进行设置 ...

  5. ProjectEuler 008题

    题目: The four adjacent digits in the 1000-digit number that have the greatest product are 9 9 8 9 = 5 ...

  6. VS code快速创建vue模板

    忘记了.vue文件的格式或者不想手动敲那段模板代码怎么办?VS code快速创建vue模板帮你偷个小懒 第一步:新建模板并保存 打开 VS code,依次点击 file > Preference ...

  7. centos6.10下安装mysql8.0.16root密码修改的坑

    上图截取别人的自己懒得弄,检查自己的linux是否有安装就按上图做就行了 接下来是我的干货 mysql8.0安群策略对密码设置很严格规则:大小写加数字和特殊字符串 使用yum安装mysql 后 my. ...

  8. Kubernetes集群部署笔记

    本作品由Galen Suen采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可.由原作者转载自个人站点. 概述 本文用于整理基于Debian操作系统使用kubeadm工具部署Kub ...

  9. C# - 音乐小闹钟_BetaV1.0

    时间:2017-11-20 作者:byzqy 介绍: 前段时间看到别人利用Timer控件实现了检查电脑本地时间,然后对时间进行比较,最终实现闹钟功能.感觉有点意思,于是自己也做了一个小闹钟! 先看一下 ...

  10. ubuntu开机自启设置 Ubuntu16.04下测试OK

    在~/.config/autostart/目录下,添加xxx.desktop文件,内容如下: [Desktop Entry] Type=Application Name=start apps NoDi ...