├── .nojekyll ├── 数据协同 └── README.md ├── 直播架构 ├── 直播框架 │ └── SRS │ │ └── README.md ├── 系统架构 │ └── README.md ├── README.md ├── 延时优化 │ └── README.md └── 直播简史.md ├── .DS_Store ├── .gitattributes ├── XMPP ├── README.md └── 协议规范.md ├── 10~从零实现 IM 系统 └── IM │ ├── 基于 Java 的 IM 系统.md │ └── README.md ├── WebRTC ├── WebTransport │ └── 99~参考资料 │ │ └── 2023~Replacing WebRTC.md ├── RTCPeerConnection.md ├── README.md └── 连接过程简析.md ├── 音视频编解码 ├── 封装格式 │ ├── MP4.md │ ├── MPEG-TS.md │ └── README.md ├── README.md └── 编解码 │ ├── AAC 音频编码.md │ ├── README.md │ └── H.264.md ├── Feed ├── README.md ├── 分页问题.md └── Feed 流方案.md ├── 流媒体协议 ├── HTTP-FLV.md ├── README.md ├── HLS.md ├── RTMP.md └── RTSP.md ├── README.md ├── .gitignore ├── _sidebar.md ├── index.html └── LICENSE /.nojekyll: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /数据协同/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /直播架构/直播框架/SRS/README.md: -------------------------------------------------------------------------------- 1 | # SRS 2 | -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wx-chevalier/IM-RTC-Notes/master/.DS_Store -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.xmind filter=lfs diff=lfs merge=lfs -text 2 | *.pdf filter=lfs diff=lfs merge=lfs -text 3 | -------------------------------------------------------------------------------- /XMPP/README.md: -------------------------------------------------------------------------------- 1 | # XMPP 2 | 3 | XMPP 是一组基于 XML 的技术。用于实时应用程序。最初。XMPP 作为一个框架开发。目标是支持企业环境内的即时消息传递和联机状态应用程序。 4 | -------------------------------------------------------------------------------- /10~从零实现 IM 系统/IM/基于 Java 的 IM 系统.md: -------------------------------------------------------------------------------- 1 | # 基于 Java 的 IM 系统 2 | 3 | # Links 4 | 5 | - https://zhuanlan.zhihu.com/p/85758575 6 | -------------------------------------------------------------------------------- /WebRTC/WebTransport/99~参考资料/2023~Replacing WebRTC.md: -------------------------------------------------------------------------------- 1 | > [原文地址](https://quic.video/blog/replacing-webrtc/) 2 | 3 | # Replacing WebRTC 4 | -------------------------------------------------------------------------------- /WebRTC/RTCPeerConnection.md: -------------------------------------------------------------------------------- 1 | # RTCPeerConnection 2 | 3 | 本部分我们将研究如何使用 WebRTC 及其 RTCPeerConnection 接口创建和管理对等连接。 4 | 5 | ![RTCPeerConnection](https://s1.ax1x.com/2020/06/06/tyaPSI.md.png) 6 | -------------------------------------------------------------------------------- /音视频编解码/封装格式/MP4.md: -------------------------------------------------------------------------------- 1 | # MP4 2 | 3 | 在互联网常见的格式中,跨平台最好的应该就属 MP4 文件了。因为 MP4 文件既可以在 PC 平台的 Flashplayer 中播放,又可以在移动平台的 Android、iOS 等平台中进行播放,而且使用系统默认的播放器即可以播放。 4 | 5 | # Links 6 | 7 | - https://www.cnblogs.com/renhui/p/10341555.html,包含其他多种文件封装格式,https://www.cnblogs.com/renhui/category/1393420.html 8 | -------------------------------------------------------------------------------- /直播架构/系统架构/README.md: -------------------------------------------------------------------------------- 1 | # 直播 2 | 3 | ![直播应用整体架构](https://s3.ax1x.com/2020/11/13/D9wORP.jpg) 4 | 5 | ![直播 CDN 技术架构](https://s3.ax1x.com/2020/11/13/D9wxsS.png) 6 | 7 | ![直播 APP 流程](https://s3.ax1x.com/2020/11/13/D90CIs.png) 8 | 9 | ![直播 APP 架构](https://s3.ax1x.com/2020/11/13/D90VMT.md.png) 10 | -------------------------------------------------------------------------------- /Feed/README.md: -------------------------------------------------------------------------------- 1 | # Feed 2 | 3 | Feed 流产品在我们手机 APP 中几乎无处不在,常见的 Feed 流比如微信朋友圈、新浪微博、今日头条等。对 Feed 流的定义,可以简单理解为只要大拇指不停地往下划手机屏幕,就有一条条的信息不断涌现出来。大多数 Feed 流产品都包含两种 Feed 流,一种是基于算法推荐,另一种是基于关注(好友关系)。例如微博和知乎,顶栏的页卡都包含“关注”和“推荐”这两种。两种 Feed 流背后用到的技术差别会比较大。 4 | 5 | 不同于“推荐”页卡那种千人前面算法推荐的方式,通常“关注”页卡所展示的内容先后顺序都有固定的规则,最常见的规则是基于时间线来排序,也就是展示“我关注的人所发的帖子,根据发帖时间从晚到早依次排列”。 6 | 7 | # Links 8 | -------------------------------------------------------------------------------- /流媒体协议/HTTP-FLV.md: -------------------------------------------------------------------------------- 1 | # HTTP-FLV 2 | 3 | RTMP 是直接将流的传输架在 RTMP 协议之上,而 HTTP-FLV 是在 RTMP 和客户端之间套了一层转码的过程,即: 4 | 5 | ![image](https://user-images.githubusercontent.com/5803001/47570314-735b7580-d968-11e8-9b7e-7c42d830afc9.png) 6 | 7 | 每个 FLV 文件是通过 HTTP 的方式获取的,所以,它通过抓包得出的协议头需要使用 chunked 编码: 8 | 9 | ``` 10 | Content-Type:video/x-flv 11 | Expires:Fri, 10 Feb 2017 05:24:03 GMT 12 | Pragma:no-cache 13 | Transfer-Encoding:chunked 14 | ``` 15 | -------------------------------------------------------------------------------- /音视频编解码/README.md: -------------------------------------------------------------------------------- 1 | # 音视频 2 | 3 | 视频封装格式就是我们通常所说的 .mp4,.flv,.ogv,.webm 等,它其实就是一个盒子,用来将实际的视频流以一定的顺序放入,确保播放的有序和完整性。视频压缩格式(视频编码)就是指能够对数字视频进行压缩或者解压缩(视频解码)的程序或者设备。通常这种压缩属于有损数据压缩。 4 | 5 | ![音视频编解码流程概要](https://user-images.githubusercontent.com/5803001/47571461-2cbb4a80-d96b-11e8-855f-19dc0c8f8305.png) 6 | 7 | 视频压缩格式和视频格式具体的区别就是,它是将原始的视频码流变为可用的数字编码。首先,由原始数码设备提供相关的数字信号流,然后经由视频压缩算法,大幅度的减少流的大小,然后交给视频盒子,打上相应的 dts,pts 字段,最终生成可用的视频文件。视频编码也可以指通过过特定的压缩技术,将某个视频格式转换成另一种视频格式。 8 | 9 | ![音视频编解码流程](https://s3.ax1x.com/2020/11/13/D9wQv8.png) 10 | -------------------------------------------------------------------------------- /直播架构/README.md: -------------------------------------------------------------------------------- 1 | # 直播 2 | 3 | 过去十年间,直播的技术和生态都发生了翻天覆地的变化。随着技术的发展与更迭,以及网络基建的完善与优化,直播开始通过互联网和移动互联网逐渐影响到每个人。大量直播平台和场景也随之诞生,并向着实时、端到端、强交互等加强用户体验的方向演进。当技术、用户、平台以及直播生态圈愈渐丰富,中国的直播行业早已不是星星之火,直播的进化,不仅是技术的进化,更是生活方式的进化。 4 | 5 | 音视频直播的基本流程都是`采集 → 编码推流 → 网络分发 → 解码 → 播放`这五大环节,其中又会涉及平台硬件、编解码、网络传输、服务并发、数字信号处理、在线学习等多方面技术。从交互模式上,又可以泛分为单对单模式与会议模式两大类;从实时性要求上,直播又可以分为伪实时、准实时与真实时三个等级: 6 | 7 | - 伪实时:视频消费延迟超过 3 秒,单向观看实时,通用架构是 CDN + RTMP + HLS,譬如很多的直播平台 8 | - 准实时:视频消费延迟 1 ~ 3 秒,能进行双方互动但互动有障碍;可以通过 TCP/UDP + FLV 已经实现了这类技术,譬如 YY 直播等 9 | - 真实时:视频消费延迟 < 1 秒,平均 500 毫秒,譬如 QQ、微信、Skype 和 WebRTC 等 10 | 11 | 在直播领域大概可以分类两种类型的在直播:一种是交互式直播,另外一种是非交互式直播。 12 | 13 | - 非交互式直播(如:阅兵直播、NBA 直播、欧冠直播等)交互性不强,允许延迟 10 秒或者 10 秒以上,特点是源比较少,适合做多路转码(用户可以根据网络条件观看)。 14 | - 交互式直播的典型场景有:秀场直播、游戏直播等。这些直播因为对主播和观众的互动性要求比较高,所以要求延迟在 5s 以内。交互式直播的特点是:源比较多,不适合做多路转码,中间服务器只作为中转角色。 15 | 16 | 视频直播相关的技术方面的流程为:实时视频流的采集 -- > 视频流的编码 -- > 视频流的传输 --> 视频流的解码 --> 视频播放。 17 | 18 | ![直播整体流程梳理](https://s3.ax1x.com/2020/11/15/DFu27V.md.png) 19 | -------------------------------------------------------------------------------- /Feed/分页问题.md: -------------------------------------------------------------------------------- 1 | # 分页问题 2 | 3 | 前文已经叙述了基于时间线的 Feed 流常见设计方案,但实操起来会比理论要麻烦许多。接下来专门讨论一个困难点:Feed 流的分页。不管是读扩散还是写扩散,Feed 流本质上是一个动态列表,列表内容会随着时间不断变化。传统的前端分页参数使用 page_size 和 page_num,分表表示每页几条,以及当前是第几页。对于一个动态列表会有如下问题: 4 | 5 | ![动态列表](https://s3.ax1x.com/2020/11/16/DAfE0e.png) 6 | 7 | 在 T1 时刻读取了第一页,T2 时刻有人新发表了“内容 11”,在 T3 时刻如果来拉取第二页,会导致错位出现,“内容 6”在第一页和第二页都被返回了。事实上,但凡两页之间出现内容的添加或删除,都会导致错位问题。为了解决这一问题,通常 Feed 流的分页入参不会使用 page_size 和 page_num,而是使用 last_id 来记录上一页最后一条内容的 id。前端读取下一页的时候,必须将 last_id 作为入参,后台直接找到 last_id 对应数据,再往后偏移 page_size 条数据,返回给前端,这样就避免了错位问题。如下图: 8 | 9 | ![动态读取](https://s3.ax1x.com/2020/11/16/DAfmtA.png) 10 | 11 | 采用 last_id 的方案有一个重要条件,就是 last_id 本身这条数据不可以被硬删除。设想一下上图中 T1 时刻返回 5 条数据,last_id 为内容 6;T2 时刻内容 6 被发布者删除;那么 T3 时刻再来请求第二页,我们根本找不到 last_id 对应的数据了,也就无法确认分页偏移量。通常碰到删除的场景,我们采用软删除方式,只是在内容上置一个标志位,表示内容已删除。由于已经删除的内容不应该再返回给前端,因此软删除模式下,找到 last_id 并往后偏移 page_size 条,如果其中有被删除的数据会导致获得足够的数据条数给前端。这里一个解决方案是找不够继续再往下找,另一种方案是与前端协商,允许返回条数少于 page_size 条,page_size 只是个建议值。甚至大家约定好了以后,可以不要 page_size 参数。 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 实时通信与直播 2 | 3 | 直播和 RTC(Real Time Communication)技术一直是以两种完全不同的形态发展的。直播通常应用于广播电视、体育赛事直播、游戏直播、秀场直播等场合,而 RTC 视频通话最典型的场景就是视频会议和传统的视频通话。随着近些年直播引入更多的互动方式,直播和 RTC 技术的界限也越来越模糊。 4 | 5 | 从信息传输的角度,直播是单向的信息传输,而 RTC 是双向的信息传输,但这个并不构成本质意义上的区别,因为双向的 RTC 可以拆解成两个单向的信息传输流。带来本质差别的是对延迟的要求,不同的延迟对底层传输协议和分发网络有不一样的挑战。早期的互联网的底层基础设施较差(低带宽、高丢包率、高延迟),通过互联网公网来传输无法满足 RTC 的指标要求,使得传统 RTC 应用都采用专网或专线的方式来实现。而大规模的直播技术则利用成熟的 CDN 基础设施来实现直播的功能(牺牲一定的延迟),比如苹果推出的 HLS 协议,就是把视频流切成一段一段的分片,利用传统的文件 CDN 网络来实现分发。 6 | 7 | 移动设备和 4G 网络的普及让手机直播成为流行的一种方式,各 CDN 厂商为了抓住商机,也纷纷进入直播 CDN 的建设。为了进一步降低延迟,各 CDN 厂商普遍采用以 Adobe 公司的 RTMP 和 FLV 协议为主要传输协议,铺设了新一代的直播 CDN 分发基础设施。这套基础设施在秀场直播、游戏直播、体育赛事直播领域获得了巨大的成功。 8 | 9 | 当直播成为一种主流的应用形态后,各种各样纷繁复杂的变化随之而来。最显著的就是引入了主播与粉丝的互动。不管是文字聊天、礼物打赏、直播答题,无一例外的都是更加强调互动的实时性。主播能在第一时间回应粉丝的动作,让观众获得了参与感,极大的提升了用户黏性。更进一步,当观众可以请求与主播进行“现场连麦“时,更是直接以“面对面”的方式进行交流。现场连麦其实已经进入 RTC 的场合了,只不过在这个场景下,底层技术实现还是以两种不同的架构体系来完成的。 10 | 11 | 再来看纯 RTC 最典型的视频会议场景。视频会议的参与方都能与其他人以“完全实时”的方式进行语音、视频、共享桌面等方式进行沟通、交流与互动。对于近几年来兴起的云视频会议,则还可以把会议房间里的音视频流转推出来进行“直播”,供不在会议房间里的人观看。这个时候,整体的参与者就分成了两个部分,一部分是房间内的成员,他们之间是“完全实时”的,另一部分,就是房间外的普通观众。这就构成了一种新型的“场内”和“场外”模式,场内的人能相互感知,场内的人则无法直接感知场外的人,但所有的一举一动又可以被场外的人观看到。 12 | 13 | 直播可以加入 RTC 连麦互动,同样视频会议可以转推出来进行直播,不管从哪一个场景,都在往另外一个方向进行延伸。从用户的视角,这两者的界限在逐渐模糊。 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore all 2 | * 3 | 4 | # Unignore all with extensions 5 | !*.* 6 | 7 | # Unignore all dirs 8 | !*/ 9 | 10 | .DS_Store 11 | 12 | # Logs 13 | logs 14 | *.log 15 | npm-debug.log* 16 | yarn-debug.log* 17 | yarn-error.log* 18 | 19 | # Runtime data 20 | pids 21 | *.pid 22 | *.seed 23 | *.pid.lock 24 | 25 | # Directory for instrumented libs generated by jscoverage/JSCover 26 | lib-cov 27 | 28 | # Coverage directory used by tools like istanbul 29 | coverage 30 | 31 | # nyc test coverage 32 | .nyc_output 33 | 34 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 35 | .grunt 36 | 37 | # Bower dependency directory (https://bower.io/) 38 | bower_components 39 | 40 | # node-waf configuration 41 | .lock-wscript 42 | 43 | # Compiled binary addons (https://nodejs.org/api/addons.html) 44 | build/Release 45 | 46 | # Dependency directories 47 | node_modules/ 48 | jspm_packages/ 49 | 50 | # TypeScript v1 declaration files 51 | typings/ 52 | 53 | # Optional npm cache directory 54 | .npm 55 | 56 | # Optional eslint cache 57 | .eslintcache 58 | 59 | # Optional REPL history 60 | .node_repl_history 61 | 62 | # Output of 'npm pack' 63 | *.tgz 64 | 65 | # Yarn Integrity file 66 | .yarn-integrity 67 | 68 | # dotenv environment variables file 69 | .env 70 | 71 | # next.js build output 72 | .next 73 | -------------------------------------------------------------------------------- /_sidebar.md: -------------------------------------------------------------------------------- 1 | - 1 10~从零实现 IM 系统 [1] 2 | - [1.1 IM [1]](/10~从零实现%20IM%20系统/IM/README.md) 3 | - [1.1.1 基于 Java 的 IM 系统](/10~从零实现%20IM%20系统/IM/基于%20Java%20的%20IM%20系统.md) 4 | - [2 Feed [2]](/Feed/README.md) 5 | - [2.1 Feed 流方案](/Feed/Feed%20流方案.md) 6 | - [2.2 分页问题](/Feed/分页问题.md) 7 | - [3 WebRTC [3]](/WebRTC/README.md) 8 | - [3.1 RTCPeerConnection](/WebRTC/RTCPeerConnection.md) 9 | - 3.2 WebTransport [1] 10 | - 3.2.1 99~参考资料 [1] 11 | - [3.2.1.1 2023~Replacing WebRTC](/WebRTC/WebTransport/99~参考资料/2023~Replacing%20WebRTC.md) 12 | - [3.3 连接过程简析](/WebRTC/连接过程简析.md) 13 | - [4 XMPP [1]](/XMPP/README.md) 14 | - [4.1 协议规范](/XMPP/协议规范.md) 15 | - [5 数据协同](/数据协同/README.md) 16 | 17 | - [6 流媒体协议 [4]](/流媒体协议/README.md) 18 | - [6.1 HLS](/流媒体协议/HLS.md) 19 | - [6.2 HTTP FLV](/流媒体协议/HTTP-FLV.md) 20 | - [6.3 RTMP](/流媒体协议/RTMP.md) 21 | - [6.4 RTSP](/流媒体协议/RTSP.md) 22 | - [7 直播架构 [4]](/直播架构/README.md) 23 | - [7.1 延时优化](/直播架构/延时优化/README.md) 24 | 25 | - 7.2 直播框架 [1] 26 | - [7.2.1 SRS](/直播架构/直播框架/SRS/README.md) 27 | 28 | - [7.3 直播简史](/直播架构/直播简史.md) 29 | - [7.4 系统架构](/直播架构/系统架构/README.md) 30 | 31 | - [8 音视频编解码 [2]](/音视频编解码/README.md) 32 | - [8.1 封装格式 [2]](/音视频编解码/封装格式/README.md) 33 | - [8.1.1 MP4](/音视频编解码/封装格式/MP4.md) 34 | - [8.1.2 MPEG TS](/音视频编解码/封装格式/MPEG-TS.md) 35 | - [8.2 编解码 [2]](/音视频编解码/编解码/README.md) 36 | - [8.2.1 AAC 音频编码](/音视频编解码/编解码/AAC%20音频编码.md) 37 | - [8.2.2 H.264](/音视频编解码/编解码/H.264.md) -------------------------------------------------------------------------------- /音视频编解码/封装格式/MPEG-TS.md: -------------------------------------------------------------------------------- 1 | # MPEG-TS 2 | 3 | MPEG-TS 一种标准数据容器格式,传输与存储音视频、节目与系统信息协议数据,应用于数字广播系统,譬如 DVB,ATSC 与 IPTV。传输流在 MPEG-2 第 1 部分系统中规定,正式称为 ISO/IEC 标准 13818-1 或 ITU-T 建议书[1]。MPEG2/DVB 是一种多媒体传输、复用技术,在数字电视广播中可提供数百个节目频道。复用的含义是,可以同时传输多层节目。 4 | 5 | 注意,DVB 全称为 Digital Video Broadcasting,包括不同的系统,如卫星数字电视广播系统,有线数字电视广播系统,地面开路数字电视广播系统,交互式数字电视广播系统以及数字电视加扰系统。DVB 系统标准是一种全球数字电视技术的标准。如何定义广播中的比特流语法与句法,以实现在比特流中复用数字音频与视频,欧洲的 DVB 采用数字视频压缩 MPEG-2 标准,该标准是定义比特流的语法与句法的一个 ISO/IEC 标准,即 13818-1 标准。DVB 系统的核心技术是采用 MPEG-2 技术进行视频、音频的编码,使用统一的 MPEG-2 传输流(TS 流)。 6 | 7 | MPEG-2 system(编号 13818-1)是 MPEG-2 标准的其中一部分,该部分描述了多个视频,音频和数据多种基本流(ES)合成传输流(TS)和节目流(PS)的方式。 8 | 9 | # TS 介绍 10 | 11 | 一路 TS 比特流通常由连续的固定字节的 TS 包组成,所包含的内容有: 12 | 13 | - 一路或多路视频流(多个 PES 包组成,每个 PES 包的 PID 是一致的,一个 PES 包可能由若干个 TS 包组成) 14 | - 一路或多路音频流(通常为杜比的音频格式) 15 | - 一路或多路字幕 16 | - PSI 表格信息(Program Specific Information,包括 PAT 与 PMT 表,即节目关联表与节目映射表) 17 | - PES: Packetized Elementary Stream,一路基本码流(如 MEPG2 视频流)会在编码器端被打包成 PES 流,由多个 PES 包组成,打包的过程中主要加入了 PTS/DTS 信息。 18 | 19 | PAT 描述有多少路节目,每路节目的 PMT 表的 PID 是多少,PMT 则描述了本节目有多少流,每一路流的类型与 PID 是多少,举个例子,你找个一个 TS 包,它的 PID 是 0,说明它的负载内容是 PAT 信息,解析 PAT 信息,你发现节目 1 的 PMT 表的 PID 是 0x10,接着,你在比特流中寻找一个 PID 为 0x10 的 TS 包,它的负载内容是节目 1 的 PMT 表信息,解析该 PMT 信息,你可以发现第一路流是 MPEG2 音频流,PID 号 0x21,第二路流是 MPEG2 视频流,PID 号是 0x22,第三路流是 DVB 字幕流,PID 号是 0x23,解析完毕,凡是比特流中 PID 号为 0x22 的 TS 包,所负载的内容为 MPEG2 视频流,把这些包一个一个找出来,把其中的有效码流一部分一部分的拼接起来,然后送给解码器去解码。 20 | 21 | 注意,就一般的视频流而言,只要拼接成一个完整的 PES 包,就可以送出去给解码器,然后再继续拼接下一个 PES 包。 22 | 23 | # Links 24 | 25 | - https://blog.csdn.net/Kayson12345/article/details/81266587 26 | -------------------------------------------------------------------------------- /音视频编解码/编解码/AAC 音频编码.md: -------------------------------------------------------------------------------- 1 | # AAC 音频编码 2 | 3 | AAC 是高级音频编码(Advanced Audio Coding)的缩写,出现于 1997 年,最初是基于 MPEG-2 的音频编码技术,目的是取代 MP3 格式。2000 年,MPEG-4 标准出台,AAC 重新集成了其它技术(PS,SBR),为区别于传统的 MPEG-2 AAC,故含有 SBR 或 PS 特性的 AAC 又称为 MPEG-4 AAC。 4 | 5 | AAC 是新一代的音频有损压缩技术,它通过一些附加的编码技术(比如 PS,SBR 等),衍生出了 LC-AAC,HE-AAC,HE-AACv2 三种主要的编码。其中 LC-AAC 就是比较传统的 AAC,相对而言,主要用于中高码率(>=80Kbps),HE-AAC(相当于 AAC+SBR)主要用于中低码(<=80Kbps),而新近推出的 HE-AACv2(相当于 AAC+SBR+PS)主要用于低码率(<=48Kbps)。事实上大部分编码器设成<=48Kbps 自动启用 PS 技术,而>48Kbps 就不加 PS,就相当于普通的 HE-AAC。 6 | 7 | # AAC 编码规格简述 8 | 9 | AAC 共有 9 种规格,以适应不同的场合的需要: 10 | 11 | - MPEG-2 AAC LC 低复杂度规格(Low Complexity)注:比较简单,没有增益控制,但提高了编码效率,在中等码率的编码效率以及音质方面,都能找到平衡点 12 | - MPEG-2 AAC Main 主规格 13 | - MPEG-2 AAC SSR 可变采样率规格(Scaleable Sample Rate) 14 | - MPEG-4 AAC LC 低复杂度规格(Low Complexity)---现在的手机比较常见的 MP4 文件中的音频部份就包括了该规格音频文件 15 | - MPEG-4 AAC Main 主规格 注:包含了除增益控制之外的全部功能,其音质最好 16 | - MPEG-4 AAC SSR 可变采样率规格(Scaleable Sample Rate) 17 | - MPEG-4 AAC LTP 长时期预测规格(Long Term Predicition) 18 | - MPEG-4 AAC LD 低延迟规格(Low Delay) 19 | - MPEG-4 AAC HE 高效率规格(High Efficiency)---这种规格适合用于低码率编码,有 Nero ACC 编码器支持 20 | 21 | 目前使用最多的是 LC 和 HE(适合低码率)。流行的 Nero AAC 编码程序只支持 LC,HE,HEv2 这三种规格,编码后的 AAC 音频,规格显示都是 LC。HE 其实就是 AAC(LC)+SBR 技术,HEv2 就是 AAC(LC)+SBR+PS 技术; 22 | 23 | - HE:“High Efficiency”(高效性)。HE-AAC v1(又称 AACPlusV1,SBR),用容器的方法实现了 AAC(LC)+SBR 技术。SBR 其实代表的是 Spectral Band Replication(频段复制)。简要叙述一下,音乐的主要频谱集中在低频段,高频段幅度很小,但很重要,决定了音质。如果对整个频段编码,若是为了保护高频就会造成低频段编码过细以致文件巨大;若是保存了低频的主要成分而失去高频成分就会丧失音质。SBR 把频谱切割开来,低频单独编码保存主要成分,高频单独放大编码保存音质,“统筹兼顾”了,在减少文件大小的情况下还保存了音质,完美的化解这一矛盾。 24 | 25 | - HEv2:用容器的方法包含了 HE-AAC v1 和 PS 技术。PS 指“parametric stereo”(参数立体声)。原来的立体声文件文件大小是一个声道的两倍。但是两个声道的声音存在某种相似性,根据香农信息熵编码定理,相关性应该被去掉才能减小文件大小。所以 PS 技术存储了一个声道的全部信息,然后,花很少的字节用参数描述另一个声道和它不同的地方。 26 | 27 | # Links 28 | 29 | - https://www.cnblogs.com/renhui/p/10412630.html 30 | -------------------------------------------------------------------------------- /WebRTC/README.md: -------------------------------------------------------------------------------- 1 | # WebRTC 实战 2 | 3 | 我们都知道浏览器本身不支持相互之间建立信道进行通信,都需要通过服务器进行中转。比如现在有两个客户端—甲、乙,他俩想要进行通信,首先需要甲和服务器、乙和服务器之间建立信道。甲给乙发送消息时,甲先将消息发送到服务器上,服务器对甲的消息进行中转,发送到乙处,反过来也是一样。这样甲与乙之间的一次消息要通过两段信道,通信的效率同时受制于这两段信道的带宽。同时这样的信道并不适合数据流的传输,如何建立浏览器之间的点对点传输,一直困扰着开发者。因此 WebRTC 应运而生。 4 | 5 | WebRTC 旨在允许 JavaScript 应用程序创建包含音频和视频流以及用于任意数据的数据通道的实时连接;创建这些连接以直接链接两个用户的浏览器,而不必要求任何支持 WebRTC 协议的中间服务器。并且 WebRTC 通过实现 MediaStream,通过浏览器调用设备的摄像头、话筒,使得浏览器之间可以传递音频和视频。同时 WebRTC 是一个非常优秀的多媒体框架,且支持跨平台(支持 Android、IOS),能够使得 Android 和 IOS 设备作为终端设备能够像浏览器一样,进行即时通信。 6 | 7 | ## WebRTC vs WebSockets 8 | 9 | WebRTC 与 WebSockets 有一个显著的区别:Websockets 通过 TCP 工作,WebRTC 通过 UDP 工作。事实上,WebRTC 是 SRTP 协议,具有一些附加功能,如 STUN、ICE、DTLS 等和内部 VoIP 功能,如自适应抖动缓冲、AEC、AGC 等。因此,Websocket 是为可靠的通信而设计的,如果您想发送任何必须可靠发送的数据,它是一个不错的选择。当您使用 WebRTC 时,传输的数据流是不可靠的。一些数据包可能会在网络中丢失。如果你发送关键数据,例如金融处理,这是很糟糕的,同样的问题是理想的,当你发送音频或视频流,一些帧可能会丢失,没有任何明显的质量问题。如果你想通过 WebRTC 发送数据通道,你应该有一些前向纠错算法来恢复数据,如果一个数据帧在网络中丢失。 10 | 11 | # WebRTC 架构 12 | 13 | 下面是 WebRTC 的基础架构图: 14 | 15 | ![WebRTC 架构](https://s3.ax1x.com/2020/11/13/D98DD1.png) 16 | 17 | 整体架构分为应用层和核心层。应用层提供实现相关业务逻辑 Api,核心层提供应用层需要的核心 API。其中核心层分为四层: 18 | 19 | - 第一层为 C++ API,其中最主要的是 PeerConnection,这个接口需要重点学习和掌握。 20 | - 第二层为 Session 层,为上下文管理层,应用里的音频和视频及非音视频的数据处理逻辑都可以在这层进行。 21 | - 第三层为引擎和传输层,包括音频引擎和视频引擎,以及音视频的传输,这也是整个架构中最重要的一层。 22 | - 第四层与硬件相关,包括音视频的采集和网络的 IO。 23 | 24 | 注意,WebRTC 的核心层无视频的渲染,所有的渲染都需要应用层自行实现。并且第三层中主要包含以下模块: 25 | 26 | - Voice Engine(音频引擎模块):包含编码能力、音频缓冲 Buff(防网络抖动)、回音消除(实时连麦关键点)。 27 | - Video Engine(视频引擎模块):包含编码能力(如 VP8)、视频缓冲、图像增强。 28 | - Transport(传输模块):传输协议在底层使用 UDP,上层使用的 RTP(为安全起见增加 SRTP),还有 P2P 机制,包括 STUN、TURN 和 ICE。 29 | 30 | 我们知道 WebRTC 要解决的是两个浏览器之间如何进行实时音视频互动的问题。从底层来看,就是要解决两个点之间如何进行高效的网络传输。这就涉及要很多重要的传输协议,请参阅 [《Network-Notes](https://github.com/wx-chevalier/Network-Notes?q=)》。 31 | 32 | # Links 33 | 34 | - https://mp.weixin.qq.com/s/BcvsFP8N-IZ9bxgX_FAECw 35 | -------------------------------------------------------------------------------- /XMPP/协议规范.md: -------------------------------------------------------------------------------- 1 | # XMPP 协议规范 2 | 3 | xmpp 是基于 xml 类型进行消息传递的。所有的消息传递类型都是 xmpp 类型的。 4 | 5 | ![聊天数据流](https://s2.ax1x.com/2019/10/24/KUGlWD.png) 6 | 7 | 流程:客户端 A 给客户端 B 发送一条消息,消息先从客户端 A 传到服务器,服务器通过判断客户端 B 是否在线,如果在线的就直接把消息推送给客户端 B,客户端 B 收到消息以后,则发送后回执,服务器收到回执以后再推给客户端 A。如果客户端 B 不在线,则消息在服务器端保存,服务器发送回回执告诉客户端 A 发送消息成功,等客户端 B 上线以后再把消息推送给客户端 B。 8 | 9 | 问题 1: 当客户端 A 给 B 推送消息时,客户端 B 正好此时进入后台。由于后台心跳检测还没有检测到 B 已经离线,这个时候服务器会把消息推送给客户端 B,并且服务器没有保存这条消息。而此时客户端 B 已经进入后台,无法接收到消息,也就无法发送回执。会造成客户端 A 发送消息失败。 10 | 解决方法:服务器每次收到客户端 A 都会发送的消息,都会由服务器发送回执告诉 A 已经发送成功。客户端首先保存聊天信息,再客户端 B 是否在线。如果在线,则发送消息,接受回执,如果没有收到回执,则当成不在线,保存聊天消息为未发送状态,下次等客户端 B 连线后推送。 11 | 12 | # 消息类型 13 | 14 | ## 发送消息类型 15 | 16 | ```xml 17 | { 18 | "messageId" : "d851f47818db46b58abf4e982327ab36", //messageid 19 | "content" : "你好", //消息内容 20 | "fromUserName" : "张三", //发送人 21 | "isSecret" : 0, //单聊是否是密聊消息 0:正常聊天 1:密聊 22 | "timeLen" : 0, 23 | "isAt" : 0, //群聊是否@人 24 | "timeSend" : 1522034423, //发送时间 25 | "type" : 1 //消息类型 26 | } 27 | ``` 28 | 29 | ## 接收消息类型 30 | 31 | ```xml 32 | { 33 | "messageId" : "cdc6007ca03b401f8c9e4a2ccb75d8d5", 34 | "content" : "天津", 35 | "fromUserName" : "李四", 36 | "isSecret" : 0, 37 | "timeLen" : 0, 38 | "isAt" : 0, 39 | "timeSend" : 1522034878, 40 | "type" : 1 41 | } 42 | ``` 43 | 44 | ## 发送回执消息类型 45 | 46 | ```xml 47 | 48 | ``` 49 | 50 | ## 接收回执消息类型 51 | 52 | ```xml 53 | 54 | ``` 55 | -------------------------------------------------------------------------------- /流媒体协议/README.md: -------------------------------------------------------------------------------- 1 | # 流媒体 2 | 3 | 所谓流媒体是指采用流式传输的方式在 Internet 播放的媒体格式。流媒体又叫流式媒体,它是指商家用一个视频传送服务器把节目当成数据包发出,传送到网络上。用户通过解压设备对这些数据进行解压后,节目就会像发送前那样显示出来。 4 | 5 | 流媒体以流的方式在网络中传输音频、视频和多媒体文件的形式。流媒体文件格式是支持采用流式传输及播放的媒体格式。流式传输方式是将视频和音频等多媒体文件经过特殊的压缩方式分成一个个压缩包,由服务器向用户计算机连续、实时传送。在采用流式传输方式的系统中,用户不必像非流式播放那样等到整个文件。全部下载完毕后才能看到当中的内容,而是只需要经过几秒钟或几十秒的启动延时即可在用户计算机上利用相应的播放器对压缩的视频或音频等流式媒体文件进行播放,剩余的部分将继续进行下载,直至播放完毕。 6 | 7 | 常用的流媒体协议包括了 HLS, RTMP 与 HTTP-FLV 这三种,其对比如下: 8 | 9 | | 协议 | 优势 | 缺陷 | 延迟性 | 10 | | -------- | ---------------------- | ------------------- | -------- | 11 | | HLS | 支持性广 | 延时巨高 | 10s 以上 | 12 | | RTMP | 延时性好,灵活 | 量大的话,负载较高 | 1s 以上 | 13 | | HTTP-FLV | 延时性好,游戏直播常用 | 只能在手机 APP 播放 | 2s 以上 | 14 | 15 | # 视频直播协议 16 | 17 | 直播内容传输的介质是网络,而网络中传播视频或者音频时需要使用对应的协议,目前适合直播场景的常用协议有如下几种。 18 | 19 | - RTMP 协议 (HTML 5 不支持,Flash 支持):RTMP 是一种流媒体协议,是 Adobe 的专利协议。基于 TCP,在国内的使用流行度很高。流行原因:开源软件和开源库的支持稳定完整,最常用的推流和拉流的解决方案基本上能够很稳定的运行。如:开源的 librtmp 推流库,服务端有 nginx-rtmp 插件,拉流有 ijkPlayer 播放库。 20 | 21 | - HTTP-FLV 协议 (HTML 5 不支持,Flash 支持):即使用 HTTP 协议流式的传输媒体内容。相对于 RTMP,HTTP 更简单和广为人知。内容延迟同样可以做到 2~5 秒,打开速度更快,因为 HTTP 本身没有复杂的状态交互。所以从延迟角度来看,HTTP-FLV 要优于 RTMP。 22 | 23 | - HLS 协议 (HTML 支持,Flash 支持):即 Http Live Streaming,是由苹果提出基于 HTTP 的流媒体传输协议。HLS 有一个非常大的优点:HTML5 可以直接打开播放;这个意味着可以把一个直播链接通过微信等转发分享,不需要安装任何独立的 APP,有浏览器即可,所以流行度很高。社交直播 APP,HLS 可以说是刚需 。基于 HLS 的直播流 URL 是一个 m3u8 的文件,里面包含了最近若干个小视频 TS(一种视频封装格式,这里就不扩展介绍)文件。这种播放形式的延时比较高(与 TS 文件的大小有关系),同城网络下能够做到 5~7 秒的延时。 24 | 25 | - RTP/RTCP 协议:即 Real-time Transport Protocol,用于 Internet 上针对多媒体数据流的一种传输层协议。RTCP 传输交互控制的信令,RTP 传输实际的媒体数据。RTP 在视频监控、视频会议、IP 电话上有广泛的应用,因为视频会议、IP 电话的一个重要的使用体验:内容实时性强。 26 | 27 | 对比上述 3 种协议,RTP 和它们有一个重要的区别就是默认是使用 UDP 协议来传输数据,而 RTMP 和 HTTP 是基于 TCP 协议传输。 28 | 29 | 使用场景分析:实时音视频流的场景不需要可靠保障,因此也不需要有重传的机制,实时的看到图像声音,网络抖动时丢了一些内容,画面模糊和花屏,完全不重要。TCP 为了重传会造成延迟与不同步,如某一截内容因为重传,导致 1 秒以后才到,那么整个对话就延迟了 1 秒,随着网络抖动,延迟还会增加成 2 秒、3 秒,如果客户端播放是不加以处理将严重影响直播的体验。如何进行优化,会在后面的文章中进行讲解。 30 | 31 | 总结:在直播协议的选择中,如果选择是 RTMP 或 HTTP-FLV 则意味着有 2~5 秒的内容延迟,但是就打开延迟来说,HTTP-FLV 要优于 RTMP。HLS 则有 5~7 秒的内容延迟。选择 RTP 进行直播则可以做到 1 秒内的直播延迟。但就目前所了解,各大 CDN 厂商没有支持基于 RTP 直播的,所以目前国内主流还是 RTMP 或 HTTP-FLV。 32 | -------------------------------------------------------------------------------- /音视频编解码/封装格式/README.md: -------------------------------------------------------------------------------- 1 | # 视频封装格式 2 | 3 | 常见的视频封装格式(简称:视频格式)包括了 AVI,MPEG,VOB 等,即相当于一种储存视频信息的容器,由相应的公司开发出来的。 4 | 5 | ![常见视频容器格式](https://user-images.githubusercontent.com/5803001/47571490-3e9ced80-d96b-11e8-97ec-f1fd8af219e2.png) 6 | 7 | # AVI 8 | 9 | AVI 格式(后缀为.AVI):它的英文全称为 Audio Video Interleaved,即音频视频交错格式。它于 1992 年被 Microsoft 公司推出。 10 | 11 | 这种视频格式的优点是图像质量好。由于无损 AVI 可以保存 alpha 通道,经常被我们使用。缺点太多,体积过于庞大,而且更加糟糕的是压缩标准不统一,最普遍的现象就是高版本 Windows 媒体播放器播放不了采用早期编码编辑的 AVI 格式视频,而低版本 Windows 媒体播放器又播放不了采用最新编码编辑的 AVI 格式视频,所以我们在进行一些 AVI 格式的视频播放时常会出现由于视频编码问题而造成的视频不能播放或即使能够播放,但存在不能调节播放进度和播放时只有声音没有图像等一些莫名其妙的问题。 12 | 13 | # DV-AVI 14 | 15 | DV-AVI 格式(后缀为.AVI):DV 的英文全称是 Digital Video Format,是由索尼、松下、JVC 等多家厂商联合提出的一种家用数字视频格式。 16 | 17 | 数字摄像机就是使用这种格式记录视频数据的。它可以通过电脑的 IEEE 1394 端口传输视频数据到电脑,也可以将电脑中编辑好的的视频数据回录到数码摄像机中。这种视频格式的文件扩展名也是 avi。电视台采用录像带记录模拟信号,通过 EDIUS 由 IEEE 1394 端口采集卡从录像带中采集出来的视频就是这种格式。 18 | 19 | # MOV 20 | 21 | QuickTime File Format 格式(后缀为.MOV):美国 Apple 公司开发的一种视频格式,默认的播放器是苹果的 QuickTime。 22 | 23 | 具有较高的压缩比率和较完美的视频清晰度等特点,并可以保存 alpha 通道。大家可能注意到了,每次安装 EDIUS,我们都要安装苹果公司推出的 QuickTime。安装其目的就是为了支持 JPG 格式图像和 MOV 视频格式导入。 24 | 25 | # MPEG 26 | 27 | MPEG 格式(文件后缀可以是 .MPG .MPEG .MPE .DAT .VOB .ASF .3GP .MP4 等):它的英文全称为 Moving Picture Experts Group,即运动图像专家组格式,该专家组建于 1988 年,专门负责为 CD 建立视频和音频标准,而成员都是为视频、音频及系统领域的技术专家。 28 | 29 | MPEG 文件格式是运动图像压缩算法的国际标准。MPEG 格式目前有三个压缩标准,分别是 MPEG-1、MPEG-2、和 MPEG-4。MPEG-1、MPEG-2 目前已经使用较少,着重介绍 MPEG-4,其制定于 1998 年,MPEG-4 是为了播放流式媒体的高质量视频而专门设计的,以求使用最少的数据获得最佳的图像质量。目前 MPEG-4 最有吸引力的地方在于它能够保存接近于 DVD 画质的小体积视频文件。你可能一定注意到了,怎么没有 MPEG-3 编码,因为这个项目原本目标是为高分辨率电视(HDTV)设计,随后发现 MPEG-2 已足够 HDTV 应用,故 MPEG-3 的研发便中止。 30 | 31 | # WMV 32 | 33 | WMV 格式(后缀为.WMV .ASF):它的英文全称为 Windows Media Video,也是微软推出的一种采用独立编码方式并且可以直接在网上实时观看视频节目的文件压缩格式。 34 | 35 | WMV 格式的主要优点包括:本地或网络回放,丰富的流间关系以及扩展性等。WMV 格式需要在网站上播放,需要安装 Windows Media Player(简称 WMP),很不方便,现在已经几乎没有网站采用了。 36 | 37 | # Real Video 38 | 39 | Real Video 格式(后缀为.RM .RMVB):Real Networks 公司所制定的音频视频压缩规范称为 Real Media。 40 | 41 | 用户可以使用 RealPlayer 根据不同的网络传输速率制定出不同的压缩比率,从而实现在低速率的网络上进行影像数据实时传送和播放。RMVB 格式:这是一种由 RM 视频格式升级延伸出的新视频格式,当然性能上有很大的提升。RMVB 视频也是有着较明显的优势,一部大小为 700MB 左右的 DVD 影片,如果将其转录成同样品质的 RMVB 格式,其个头最多也就 400MB 左右。大家可能注意到了,以前在网络上下载电影和视频的时候,经常接触到 RMVB 格式,但是随着时代的发展这种格式被越来越多的更优秀的格式替代,著名的人人影视字幕组在 2013 年已经宣布不再压制 RMVB 格式视频。 42 | 43 | # FLV 44 | 45 | Flash Video 格式(后缀为.FLV):由 Adobe Flash 延伸出来的的一种流行网络视频封装格式。随着视频网站的丰富,这个格式已经非常普及。 46 | 47 | # MKV 48 | 49 | Matroska 格式(后缀为.MKV):是一种新的多媒体封装格式,这个封装格式可把多种不同编码的视频及 16 条或以上不同格式的音频和语言不同的字幕封装到一个 Matroska Media 档内。它也是其中一种开放源代码的多媒体封装格式。Matroska 同时还可以提供非常好的交互功能,而且比 MPEG 的方便、强大。 50 | -------------------------------------------------------------------------------- /直播架构/延时优化/README.md: -------------------------------------------------------------------------------- 1 | # 直播延时优化 2 | 3 | # NO BUFFER 4 | 5 | 低延迟:顾名思义,就是让播放端和推流端的时间差越小越好,那么如何做到低延迟呢,一个词概括:no buffer,首先说明一下视频流的流向:推流端--->CDN 服务器--->拉流端 6 | 7 | - 推流端 nobuffer,也就是保证推流端缓存的 buffer 最小。这样基本上保证在推流端出现网络抖动或者突然变差的情况下,能够舍弃已经缓存的 buffer,继续推新生成好的视频帧。这样保证了,在网络端开始传输的时候的视频内容是最新的。 8 | - CDN nobuffer,针对性的调整 CDN 的配置,让 CDN 服务器缓存的 GOP 尽可能的少,这样保证拉流端获取到的是最新的内容。 9 | - 拉流端 nobuffer,既然推流和中转的 CDN 都设置了 nobuffer,那么拉流端设置 nobuffer 的意义,应该不需要做过多的解释了吧。 10 | 11 | # 编码优化 12 | 13 | - 确保 Codec 开启了最低延迟的设置。Codec 一般都会有低延迟优化的开关,对于 H.264 来说其效果尤其明显。很多人可能不知道 H.264 的解码器正常情况下会在显示之前缓存一定的视频帧,对于 QCIF 分辨率大小的视频(176 × 144)一般会缓存 16 帧,对于 720P 的视频则缓存 5 帧。对于第一帧的读取来说,这是一个很大的延迟。如果你的视频不是使用 H.264 来编码压缩的,确保没有使用到 B 帧,它对延迟也会有较大的影响,因为视频中 B 帧的解码依赖于前后的视频帧,会增加延迟。 14 | 15 | - 编码器一般都会有码控造成的延迟,一般也叫做初始化延迟或者视频缓存检验器 VBV 的缓存大小,把它当成编码器和解码器比特流之间的缓存,在不影响视频质量的情况下可以将其设置得尽可能小也可以降低延迟。 16 | 17 | - 如果是仅仅优化首开延迟,可以在视频帧间插入较多的关键帧,这样客户端收到视频流之后可以尽快解码。但如果需要优化传输过程中的累计延迟,尽可能少使用关键帧也就是 I 帧(GOP 变大),在保证同等视频质量的情况下,I 帧越多,码率越大,传输所需的网络带宽越多,也就意味着累计延迟可能越大。这个优化效果可能在秒级延迟的系统中不是很明显,但是在 100 ms 甚至更低延迟的系统中就会非常明显。同时,尽量使用 ACC-LC Codec 来编码音频,HE-ACC 或者 HE-ACC 2 虽然编码效率高,但是编码所需时间更长,而产生更大体积的音频造成的传输延迟对于视频流的传输来说影响更小。 18 | 19 | - 不要使用视频 MJPEG 的视频压缩格式,至少使用不带 B 帧的 MPEG4 视频压缩格式(Simple profile),甚至最好使用 H.264 baseline profile(X264 还有一个-tune zerolatency 的优化开关)。这样一个简单的优化可以降低延迟,因为它能够以更低的码率编码全帧率视频。 20 | 21 | - 如果使用了 FFmpeg,降低-probesize 和 -analyze duration 参数的值,这两个值用于视频帧信息监测和用于监测的时长,这两个值越大对编码延迟的影响越大,在直播场景下对于视频流来说 analyzeduration 参数甚至没有必要设定。 22 | 23 | - 固定码率编码 CBR 可以一定程度上消除网络抖动影响,如果能够使用可变码率编码 VBR 可以节省一些不必要的网络带宽,降低一定的延迟。因此建议尽量使用 VBR 进行编码。 24 | 25 | # 传输协议优化 26 | 27 | - 在服务端节点和节点之间尽量使用 RTMP 而非基于 HTTP 的 HLS 协议进行传输,这样可以降低整体的传输延迟。这个主要针对终端用户使用 HLS 进行播放的情况。 28 | 29 | - 如果终端用户使用 RTMP 来播放,尽量在靠近推流端的收流节点进行转码,这样传输的视频流比原始视频流更小。 30 | 31 | - 如果有必要,可以使用定制的 UDP 协议来替换 TCP 协议,省去弱网环节下的丢包重传可以降低延迟。它的主要缺点在于,基于 UDP 协议进行定制的协议的视频流的传输和分发不够通用,CDN 厂商支持的是标准的传输协议。另一个缺点在于可能出现丢包导致的花屏或者模糊(缺少关键帧的解码参考),这就要求协议定制方在 UDP 基础之上做好丢包控制。 32 | 33 | # 传输网络优化 34 | 35 | - 我们曾经介绍过实时流传输网络,它是一种新型的节点自组织的网状传输网络,既适合国内多运营商网络条件下的传输优化,也适合众多海外直播的需求。 36 | 37 | - 在服务端节点中缓存当前 GOP,配合播放器端优化视频首开时间。 38 | 39 | - 服务端实时记录每个视频流流向每个环节时的秒级帧率和码率,实时监控码率和帧率的波动。 40 | 41 | - 客户端(推流和播放)通过查询服务端准实时获取当前最优节点(5 秒一次),准实时下线当前故障节点和线路。 42 | 43 | # 推流、播放优化 44 | 45 | - 考察发送端系统自带的网络 buffer 大小,系统可能在发送数据之前缓存数据,这个参数的调优也需要找到一个平衡点。 46 | 47 | - 播放端缓存控制对于视频的首开延迟也有较大影响,如果仅优化首开延迟,可以在 0 缓存情况下在数据到达的时候立即解码。但如果在弱网环境下为了消除网络抖动造成的影响,设置一定的缓存也有必要,因此需要在直播的稳定性和首开延迟优化上找到平衡,调整优化缓冲区大小这个值。 48 | 49 | - 播放端动态 buffer 策略,这是上面播放端缓存控制的改进版本。如果只是做 0 缓存和固定大小的缓存之间进行选择找到平衡,最终还是会选择一个固定大小的缓存,这对亿级的移动互联网终端用户来说并不公平,他们不同的网络状况决定了这个固定大小的缓存并不完全合适。因此,我们可以考虑一种动态 buffer 策略,在播放器开启的时候采用非常小甚至 0 缓存的策略,通过对下载首片视频的耗时来决定下一个时间片的缓存大小,同时在播放过程中实时监测当前网络,实时调整播放过程中缓存的大小。这样即可做到极低的首开时间,又可能够尽量消除网络抖动造成的影响。 50 | 51 | - 动态码率播放策略。除了动态调整 buffer 大小的策略之外,也可以利用实时监测的网络信息来动态调整播放过程中的码率,在网络带宽不足的情况下降低码率进行播放,减少延迟。 52 | 53 | 以上,是低延迟优化方面的部分技巧。实际上我们优化低延迟的时候并不是只关注低延迟,而是在保证其它条件不影响用户体验的情况下尽量做到低延迟,因此它的内容涉及到更多广泛的话题。 54 | -------------------------------------------------------------------------------- /Feed/Feed 流方案.md: -------------------------------------------------------------------------------- 1 | # Feed 流方案 2 | 3 | # 读扩散 4 | 5 | 读扩散也称为拉模式,这应该是最符合我们直觉的一种实现方式。如下图: 6 | 7 | ![读扩散方式](https://s3.ax1x.com/2020/11/16/DARUEj.png) 8 | 9 | 每一个内容发布者都有一个自己的发件箱(“我发布的内容”),每当我们发出一个新帖子,都存入自己的发件箱中。当我们的粉丝来阅读时,系统首先需要拿到粉丝关注的所有人,然后遍历所有发布者的发件箱,取出他们所发布的帖子,然后依据发布时间排序,展示给阅读者。这种设计,阅读者读一次 Feed 流,后台会扩散为 N 次读操作(N 等于关注的人数)以及一次聚合操作,因此称为读扩散。每次读 Feed 流相当于去关注者的收件箱主动拉取帖子,因此也得名拉模式。 10 | 11 | 这种模式的好处是底层存储简单,没有空间浪费。坏处是每次读操作会非常重,操作非常多。设想一下如果我关注的人数非常多,遍历一遍我所关注的所有人,并且再聚合一下,这个系统开销会非常大,时延上可能达到无法忍受的地步。因此读扩散主要适用系统中阅读者关注的人没那么多,并且刷 Feed 流并不频繁的场景。拉模式还有一个比较大的缺点就是分页不方便,我们刷微博或朋友圈,肯定是随着大拇指在屏幕不断划动,内容一页一页的从后台拉取。如果不做其他优化,只采用实时聚合的方式,下滑到比较靠后的页码时会非常麻烦。 12 | 13 | # 写扩散 14 | 15 | 据统计,大多数 Feed 流产品的读写比大概在 100:1,也就是说大部分情况都是刷 Feed 流看别人发的朋友圈和微博,只有很少情况是自己亲自发一条朋友圈或微博给别人看。因此,读扩散那种很重的读逻辑并不适合大多数场景。我们宁愿让发帖的过程复杂一些,也不愿影响用户读 Feed 流的体验,因此稍微改造一下前面方案就有了写扩散。写扩散也称为推模式,这种模式会对拉模式的一些缺点做改进。如下图: 16 | 17 | ![写扩散](https://s3.ax1x.com/2020/11/16/DAWIFs.png) 18 | 19 | 系统中每个用户除了有发件箱,也会有自己的收件箱。当发布者发表一篇帖子的时候,除了往自己发件箱记录一下之外,还会遍历发布者的所有粉丝,往这些粉丝的收件箱也投放一份相同内容。这样阅读者来读 Feed 流时,直接从自己的收件箱读取即可。这种设计,每次发表帖子,都会扩散为 M 次写操作(M 等于自己的粉丝数),因此成为写扩散。每篇帖子都会主动推送到所有粉丝的收件箱,因此也得名推模式。 20 | 21 | 这种模式可想而知,发一篇帖子,背后会涉及到很多次的写操作。通常为了发帖人的用户体验,当发布的帖子写到自己发件箱时,就可以返回发布成功。后台另外起一个异步任务,不慌不忙地往粉丝收件箱投递帖子即可。写扩散的好处在于通过数据冗余(一篇帖子会被存储 M 份副本),提升了阅读者的用户体验。通常适当的数据冗余不是什么问题,但是到了微博明星这里,完全行不通。比如目前微博粉丝量 Top2 的谢娜与何炅,两个人微博粉丝过亿。 22 | 23 | 设想一下,如果单纯采用推模式,那每次谢娜何炅发一条微博,微博后台都要地震一次。一篇微博导致后台上亿次写操作,这显然是不可行的。另外由于写扩散是异步操作,写的太慢会导致帖子发出去半天,有些粉丝依然没能看见,这种体验也不太好。通常写扩散适用于好友量不大的情况,据悉微信朋友圈正是写扩散模式。每一名微信用户的好友上限为 5000 人,也就是说你发一条朋友圈最多也就扩散到 5000 次写操作,如果异步任务性能好一些,完全没有问题。 24 | 25 | # 读写混合模式 26 | 27 | 读写混合也可以称作推拉结合。这种方式可以兼具读扩散和写扩散的优点。我们首先来总结一下读扩散和写扩散的优缺点: 28 | 29 | | | 优点 | 缺点 | 适用场景 | 30 | | ------ | ------------------------ | ----------------------------------------------- | --------------------------------------------------------- | 31 | | 读扩散 | 节约存储空间发帖操作简单 | 读帖操作复杂关注人数多时是灾难 | 用户不活跃,很少读帖有大 V 粉丝量多,但每个粉丝关注的人少 | 32 | | 写扩散 | 读帖操作简单 | 发帖操作复杂,浪费存储空间大 V 粉丝量多时是灾难 | 用户非常活跃,经常刷帖无大 V,用户粉丝量都比较少 | 33 | 34 | 仔细比较一下读扩散与写扩散的优缺点,不难发现两者的适用场景是互补的。因此在设计后台存储的时候,我们如果能够区分一下场景,在不同场景下选择最适合的方案,并且动态调整策略,就实现了读写混合模式。如下图: 35 | 36 | ![读写混合模式](https://s3.ax1x.com/2020/11/16/DAWzk9.png) 37 | 38 | 当何炅这种粉丝量超大的人发帖时,将帖子写入何炅的发件箱,另外提取出来何炅粉丝当中比较活跃的那一批(这已经可以筛掉大部分了),将何炅的帖子写入他们的收件箱。当一个粉丝量很小的路人甲发帖时,采用写扩散方式,遍历他的所有粉丝并将帖子写入粉丝收件箱。 39 | 40 | 对于那些活跃用户登录刷 Feed 流时,他直接从自己的收件箱读取帖子即可,保证了活跃用户的体验。当一个非活跃的用户突然登录刷 Feed 流时,我们一方面需要读他的收件箱,另一方面需要遍历他所关注的大 V 用户的发件箱提取帖子,并且做一下聚合展示。在展示完后,系统还需要有个任务来判断是否有必要将该用户升级为活跃用户。因为有读扩散的场景存在,因此即使是混合模式,每个阅读者所能关注的人数也要设置上限,例如新浪微博限制每个账号最多可以关注 2000 人。如果不设上限,设想一下有一位用户把微博所有账号全部关注了,那他打开关注列表会读取到微博全站所有帖子,一旦出现读扩散,系统必然崩溃;即使是写扩散,他的收件箱也无法容纳这么多的微博。 41 | 42 | 读写混合模式下,系统需要做两个判断。一个是哪些用户属于大 V,我们可以将粉丝量作为一个判断指标。另一个是哪些用户属于活跃粉丝,这个判断标准可以是最近一次登录时间等。这两处判断标准就需要在系统发展过程中动态地识别和调整,没有固定公式了。可以看出读写结合模式综合了两种模式的优点,属于最佳方案。然而他的缺点是系统机制非常复杂,给程序员带来无数烦恼。通常在项目初期,只有一两个开发人员,用户规模也很小的时候,一步到位地采用这种混合模式还是要慎重,容易出 bug。当项目规模逐渐发展到新浪微博的水平,有一个大团队专门来做 Feed 流时,读写混合模式才是必须的。 43 | -------------------------------------------------------------------------------- /音视频编解码/编解码/README.md: -------------------------------------------------------------------------------- 1 | # 视频编解码 2 | 3 | 视频实际上就是一帧一帧的图片,拼接起来进行播放;标准的图像格式使用 RGB 三字节描述像素颜色值,会占用较大的存储空间与带宽。视频编解码器会根据前后图像的变化做运动检测,通过各种压缩把变化的结果发送到对方。 4 | 5 | 实时视频编码器需要考虑两个因素:编码计算量和码率带宽,实时视频会运行在移动端上,需要保证实时性就需要编码足够快,码率尽量小。基于这个原因现阶段一般认为 H.264 是最佳的实时视频编码器,而且各个移动平台也支持它的硬编码技术;譬如 1080P 进行过 H.264 编码后带宽也就在 200KB/S ~ 300KB/S 左右。 6 | 7 | # 编码基础 8 | 9 | 总的来说,常用的编码方式分为三种: 10 | 11 | - 变换编码:消除图像的帧内冗余。涉及到图像学里面的两个概念:空域和频域。空域就是我们物理的图片,频域就是将物理图片根据其颜色值等映射为数字大小。而变换编码的目的是利用频域实现去相关和能量集中。常用的正交变换有离散傅里叶变换,离散余弦变换等等。 12 | - 运动估计和运动补偿:消除帧间冗余。视频压缩还存在时间上的关联性。例如,针对一些视频变化,背景图不变而只是图片中部分物体的移动,针对这种方式,可以只对相邻视频帧中变化的部分进行编码。 13 | - 熵编码:提高压缩效率,熵编码主要是针对码节长度优化实现的。原理是针对信源中出现概率大的符号赋予短码,对于概率小的符号赋予长码,然后总的来说实现平均码长的最小值。编码方式(可变字长编码)有:霍夫曼编码、算术编码、游程编码等。 14 | 15 | I,B,P 实际上是从运动补偿中引出来的,这里为了后面的方便先介绍一下。 16 | 17 | - I 帧(I-frame): 学名叫做: `Intra-coded picture`。也可以叫做独立帧。该帧是编码器随机挑选的参考图像,换句话说,一个 I 帧本身就是一个静态图像。它是作为 B,P 帧的参考点。对于它的压缩,只能使用`熵` 和 `变化编码` 这两种方式进行帧内压缩。所以,它的运动学补偿基本没有。 18 | - P 帧(P‑frame): 又叫做 `Predicted picture`--前向预测帧。即,他会根据前面一张图像,来进行图片间的动态压缩,它的压缩率和 I 帧比起来要高一些。 19 | - B 帧(B‑frame): 又叫做 `Bi-predictive picture`-- 双向预测。它比 P 帧来说,还多了后一张图像的预测,所以它的压缩率更高。 20 | 21 | ![I B P 帧示意](https://s3.ax1x.com/2020/11/13/D9asQU.png) 22 | 23 | 考虑到不同帧传输的无序性,我们还需要引入 PTS 与 DTS 来进行控制,使用 DTS 来解码,PTS 来进行播放。 24 | 25 | - PTS(presentation time stamps): 显示时间戳,显示器从接受到解码到显示的时间。 26 | - DTS(decoder timestamps): 解码时间戳。也表示该 sample 在整个流中的顺序 27 | 28 | # H.26X 29 | 30 | H.26X 系列由 ITU 国际电传视讯联盟主导包括,H.261、H.262、H.263、H.264、H.265 等: 31 | 32 | - H.261:主要在老的视频会议和视频电话产品中使用。 33 | - H.263:主要用在视频会议、视频电话和网络视频上。 34 | - H.264:H.264/MPEG-4 第十部分,或称 AVC(Advanced Video Coding,高级视频编码),是一种视频压缩标准,一种被广泛使用的高精度视频的录制、压缩和发布格式。 35 | - H.265:高效率视频编码(High Efficiency Video Coding,简称 HEVC)是一种视频压缩标准,H.264/MPEG-4 AVC 的继任者。HEVC 被认为不仅提升图像质量,同时也能达到 H.264/MPEG-4 AVC 两倍之压缩率(等同于同样画面质量下比特率减少了 50%),可支持 4K 分辨率甚至到超高画质电视,最高分辨率可达到 8192×4320(8K 分辨率),这是目前发展的趋势。直至 2013 年,Potplayer 添加了对于 H.265 视频的解码,尚未有大众化编码软件出现。 36 | 37 | H.264 是由 ITU 和 MPEG 两个组织共同提出的标准,整个编码器包括帧内预测编码、帧间预测编码、运动估计、熵编码等过程,支持分层编码技术(SVC)。单帧 720P 分辨率一般 PC 上的平均编码延迟 10 毫秒左右,码率范围 1200 ~ 2400kpbs,同等视频质量压缩率是 MPEG4 的 2 倍,H.264 也提供 VBR、ABR、CBR、CQ 等多种编码模式,各个移动平台兼容性好。 38 | 39 | H.264 为了防止丢包和减小带宽还引入一种双向预测编码的 B 帧,B 帧以前面的 I 或 P 帧和后面的 P 帧为参考帧。H.264 为了防止中间 P 帧丢失视频图像会一直错误它引入分组序列(GOP)编码,也就是隔一段时间发一个全量 I 帧,上一个 I 帧与下一个 I 帧之间为一个分组 GOP。 40 | 41 | ![I B P 帧与 GOP](https://s3.ax1x.com/2020/11/13/D9ageJ.png) 42 | 43 | 在实时视频当中最好不要加入 B 帧,因为 B 帧是双向预测,需要根据后面的视频帧来编码,这会增大编解码延迟。 44 | 45 | # MPGA 系列 46 | 47 | MPEG 系列由 ISO 国际标准组织机构下属的 MPEG 运动图象专家组开发视频编码方面主要有: 48 | 49 | - MPEG-1 第二部分(MPEG-1 第二部分主要使用在 VCD 上,有些在线视频也使用这种格式。该编解码器的质量大致上和原有的 VHS 录像带相当。) 50 | - MPEG-2 第二部分(MPEG-2 第二部分等同于 H.262,使用在 DVD、SVCD 和大多数数字视频广播系统和有线分布系统(cable distribution systems)中。) 51 | - MPEG-4 第二部分(MPEG-4 第二部分标准可以使用在网络传输、广播和媒体存储上。比起 MPEG-2 和第一版的 H.263,它的压缩性能有所提高。) 52 | - MPEG-4 第十部分(MPEG-4 第十部分技术上和 ITU-T H.264 是相同的标准,有时候也被叫做“AVC”)最后这两个编码组织合作,诞生了 H.264/AVC 标准。ITU-T 给这个标准命名为 H.264,而 ISO/IEC 称它为 MPEG-4 高级视频编码(Advanced Video Coding,AVC)。 53 | 54 | # 音频编码器 55 | 56 | 实时音视频除了视频编码器以外还需要音频编码器,音频编码器只需要考虑编码延迟和丢包容忍度,所以一般的 MP3、AAC、OGG 都不太适合作为实时音频编码器。从现在市场上来使用来看,Skype 研发的 Opus 已经成为实时音频主流的编码器。Opus 优点众多,编码计算量小、编码延迟 20ms、窄带编码-silk、宽带编码器 CELT、自带网络自适应编码等。 57 | 58 | 同视频编码类似,将原始的音频流按照一定的标准进行编码,上传,解码,同时在播放器里播放,当然音频也有许多编码标准,例如 PCM 编码,WMA 编码,AAC 编码等等。 59 | -------------------------------------------------------------------------------- /流媒体协议/HLS.md: -------------------------------------------------------------------------------- 1 | # HLS 2 | 3 | HLS 全称是 HTTP Live Streaming,是一个由 Apple 公司提出的基于 HTTP 的媒体流传输协议,用于实时音视频流的传输。目前 HLS 协议被广泛的应用于视频点播和直播领域。 4 | 5 | HLS 通过将整条流切割成一个小的可以通过 HTTP 下载的媒体文件, 然后提供一个配套的媒体列表文件, 提供给客户端, 让客户端顺序地拉取这些媒体文件播放, 来实现看上去是在播放一条流的效果.由于传输层协议只需要标准的 HTTP 协议, HLS 可以方便的透过防火墙或者代理服务器, 而且可以很方便的利用 CDN 进行分发加速, 并且客户端实现起来也很方便。 6 | 7 | ## 优缺点 8 | 9 | HLS 协议的优点如下: 10 | 11 | - 客户端支持简单, 只需要支持 HTTP 请求即可, HTTP 协议无状态, 只需要按顺序下载媒体片段即可。 12 | - 使用 HTTP 协议网络兼容性好, HTTP 数据包也可以方便地通过防火墙或者代理服务器, CDN 支持良好。 13 | - Apple 的全系列产品支持,不需要安装任何插件就可以原生支持播放 HLS, 目前 Android 也加入了对 HLS 的支持。 14 | - 自带多码率自适应机制。 15 | 16 | HLS 协议的缺点如下: 17 | 18 | - 相比 RTMP 这类长连接协议, 延时较高, 难以用到互动直播场景。 19 | - 对于点播服务来说, 由于 TS 切片通常较小, 海量碎片在文件分发, 一致性缓存, 存储等方面都有较大挑战。 20 | 21 | # HLS 协议构成 22 | 23 | HLS 由两部分构成,一个是 .m3u8 文件,一个是 .ts 视频文件。每一个 .m3u8 文件,分别对应若干个 ts 文件,这些 ts 文件才是真正存放视频的数据,m3u8 文件只是存放了一些 ts 文件的配置信息和相关路径,当视频播放时,.m3u8 是动态改变的,video 标签会解析这个文件,并找到对应的 ts 文件来播放,所以一般为了加快速度,.m3u8 放在 web 服务器上,ts 文件放在 CDN 上。 24 | 25 | HLS 协议视频支持 H.264 格式的编码,支持的音频编码方式是 AAC 编码。HLS 的架构分为三部分:Server,CDN,Client 。即服务器、分发组件和客户端。 26 | 27 | ![HLS 架构](https://user-images.githubusercontent.com/5803001/47569752-fbd91680-d966-11e8-8e5d-491fa49ec18e.png) 28 | 29 | - 服务器用于接收媒体输入流,对它们进行编码,封装成适合于分发的格式,然后准备进行分发。 30 | - 分发组件为标准的 Web 服务器。它们用于接收客户端请求,传递处理过的媒体,把资源和客户端联系起来。 31 | - 客户端软件决定请求何种合适的媒体,下载这些资源,然后把它们重新组装成用户可以观看的连续流。 32 | 33 | ## m3u8 34 | 35 | .m3u8 文件,其实就是以 UTF-8 编码的 m3u 文件,这个文件本身不能播放,只是存放了播放信息的文本文件: 36 | 37 | ``` 38 | #EXTM3U m3u文件头 39 | #EXT-X-MEDIA-SEQUENCE 第一个TS分片的序列号 40 | #EXT-X-TARGETDURATION 每个分片TS的最大的时长 41 | #EXT-X-ALLOW-CACHE 是否允许cache 42 | #EXT-X-ENDLIST m3u8文件结束符 43 | #EXTINF 指定每个媒体段(ts)的持续时间(秒),仅对其后面的URI有效 44 | mystream-12.ts 45 | ``` 46 | 47 | HLS 协议的使用也非常便捷,将 m3u8 直接写入到 src 中然后交与浏览器解析,也可以使用 fetch 来手动解析并且获取相关文件: 48 | 49 | ```js 50 | 57 | ``` 58 | 59 | HLS 详细版的内容比上面的简版多了一个 playlist,也可以叫做 master。在 master 中,会根据网络段实现设置好不同的 m3u8 文件,比如,3G/4G/wifi 网速等。比如,一个 master 文件中为: 60 | 61 | ``` 62 | #EXTM3U 63 | #EXT-X-VERSION:6 64 | #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=2855600,CODECS="avc1.4d001f,mp4a.40.2",RESOLUTION=960x540 65 | live/medium.m3u8 66 | #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=5605600,CODECS="avc1.640028,mp4a.40.2",RESOLUTION=1280x720 67 | live/high.m3u8 68 | #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1755600,CODECS="avc1.42001f,mp4a.40.2",RESOLUTION=640x360 69 | live/low.m3u8 70 | #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=545600,CODECS="avc1.42001e,mp4a.40.2",RESOLUTION=416x234 71 | live/cellular.m3u8 72 | ``` 73 | 74 | 以 high.m3u8 文件为例,其内容会包含: 75 | 76 | ``` 77 | #EXTM3U 78 | #EXT-X-VERSION:6 79 | #EXT-X-TARGETDURATION:10 80 | #EXT-X-MEDIA-SEQUENCE:26 81 | #EXTINF:9.901, 82 | http://media.example.com/wifi/segment26.ts 83 | #EXTINF:9.901, 84 | http://media.example.com/wifi/segment27.ts 85 | #EXTINF:9.501, 86 | http://media.example.com/wifi/segment28.ts 87 | ``` 88 | 89 | 该二级 m3u8 文件也可以称为 media 文件,其有三种类型: 90 | 91 | - live playlist: 动态列表。顾名思义,该列表是动态变化的,里面的 ts 文件会实时更新,并且过期的 ts 索引会被删除。默认,情况下都是使用动态列表。 92 | - event playlist: 静态列表。它和动态列表主要区别就是,原来的 ts 文件索引不会被删除,该列表是不断更新,而且文件大小会逐渐增大。它会在文件中,直接添加 #EXT-X-PLAYLIST-TYPE:EVENT 作为标识。 93 | - VOD playlist: 全量列表。它就是将所有的 ts 文件都列在 list 当中。如果,使用该列表,就和播放一整个视频没有啥区别了。它是使用 #EXT-X-ENDLIST 表示文件结尾。 94 | 95 | 显而易见,HLS 的延时包含了 TCP 握手、m3u8 文件下载与解析、ts 文件下载与解析等多个步骤,可以缩短列表的长度和单个 ts 文件的大小来降低延迟,极致来说可以缩减列表长度为 1,并且 ts 的时长为 1s,但是这样会造成请求次数增加,增大服务器压力,当网速慢时回造成更多的缓冲,所以苹果官方推荐的 ts 时长时 10s,所以这样就会大改有 30s 的延迟。 96 | -------------------------------------------------------------------------------- /WebRTC/连接过程简析.md: -------------------------------------------------------------------------------- 1 | # WebRTC 连接过程简析 2 | 3 | ![WebRTC 连接时序图](https://s3.ax1x.com/2020/11/13/D9thJf.png) 4 | 5 | 要连接两个浏览器,Web RTC 需要执行五个步骤来建立 P2P 连接。 6 | 7 | - 信号处理,以去除音频或视频中的环境噪声。 8 | - 编解码器处理,以压缩和解压音频或视频。 9 | - 通过防火墙、(NAT)和中继器建立从一个 Peer 到另一个 Peer 的路由,以创建一个 ICE(交互式链接建立)。 10 | - 用户数据在进行连接传输前都会进行加密。 11 | - 管理带宽,给每个 Peer 的带宽不同 12 | 13 | # 信号传递 14 | 15 | 浏览器中的 P2P 连接由服务器建立,以确保所有 Peer 同意建立会话。Peer 之间共享会话密钥、错误信息、媒体元数据、编解码器、带宽、公共 IP 地址和端口等信息以创建连接。服务器向两个 Peer 发出信号,以确定使用什么媒体格式以及每个 Peer 要向对方发送什么。 16 | 17 | ![与信令服务器通信](https://s3.ax1x.com/2020/11/13/D9tXF0.png) 18 | 19 | # 网络地址转换(NAT)和 ICE 20 | 21 | NATs 将家庭路由器等设备上的私有 IP 地址转换为公网 IP 地址。防火墙和 NATs 通过阻止特定的协议或端口来减慢这一过程。WebRTC 使用的解决方案是 ICE 框架。ICE 通过并行尝试所有连接并选择最有效的路径,在互联网上建立 P2P 连接。有两种类型的连接可选 STUN & TURN 22 | 23 | ## STUN 服务器 24 | 25 | 它首先连接到 STUN(Session Traversal Utilities for NAT)服务器,获得直接连接。STUN 服务器为请求者提供了公网 IP 地址,以便与他人进行通信。其目的是帮助请求者回答 "我的 IP 地址是啥 "这个问题。 26 | 27 | ![STUN 服务器如何工作](https://s3.ax1x.com/2020/11/13/D9NEY6.png) 28 | 29 | 要建立与其他 Peer 的连接,需要终端知道自己的公网 IP 才能与他人共享:当一个 Peer(Calvin)在 NAT/防火墙后面时,它只能识别它的私有 IP 地址,而另一个 Peer(Elana)由于防火墙的安全性,无法连接到本地 IP。这个 Peer 会向 STUN 服务器请求,获取它的公网 IP 地址和一种可用 NAT 类型。另一个 Peer(Elana)可以使用 STUN 服务器给定的公网 IP 地址尝试进行连接。如果成功,数据将通过点对点网络传输,而不需要第三方或其他服务器。为了安全起见,所有 STUN 服务器将被丢弃并等待下一次查询。 30 | 31 | 但是,上述情况有时可能会失败,IP 地址和端口会发生变化。这种情况称为 "对称 NAT",STUN 服务器的公网 IP 地址没有足够的能力在这里建立连接,因为端口也需要转换。有些路由器使用对称 NAT,是为了使终端设备更加安全,或者说避免很多陌生人连到你的设备上。对称 NAT 不仅可以将 IP 地址从私有地址转换成公共地址,还可以转换端口。换句话说,路由器只会接受用户已经有过的连接。因此,另一种确保两个 Peer 之间连接的解决方案是通过 TURN 服务器。 32 | 33 | 作为一种协议,STUN 具有超快、轻量的特点。它可以在很短的时间内将数据直接传送给对方。STUN 有利于加快连接速度,更快地获取结果。当用户使用 LAN 局域网传输数据时,场景类似,比使用 Wi-Fi 传输更快。最重要的是,可以直接在两个 Peer 之间传输数据。 34 | 35 | ## TURN 服务器 36 | 37 | TURN(Traversal Using Relays around NAT)服务器作为中继服务器,以防 P2P 连接中断。当 STUN 服务器用于建立连接时,TURN 服务器在整个连接过程中保持活跃。TURN 服务器在 WebRTC Peer 之间不断中继数据。这就是为什么用 "中继 "一词来定义 TURN。 38 | 39 | ![TURN 服务器工作原理](https://s3.ax1x.com/2020/11/13/D9UEHs.png) 40 | 41 | 这个中继服务器是在 STUN 服务器出现故障时用来中继流量的,同时也具有 STUN 的功能。TURN 服务器是一个内置传输功能的 STUN 服务器。更具体地说,TURN 是用来中继 Peer 之间的音视频/数据流,而不是信令数据。按照上文 STUN 服务器的步骤运行,如果 STUN 失败,终端用户会与 TURN 服务器建立连接,通知所有 Peer 向服务器发送数据,服务器负责向第一个终端用户传输数据。为什么总是先使用 STUN 服务器,主要原因是 TURN 服务器成本太高,如果在线传输高清视频的话,会消耗大量带宽。 42 | 43 | # VP9 视频编解码器 44 | 45 | 为什么很多人开始使用 WebRTC,其中一个主要原因就是因为视频。随着视频直播越来越成为主流,视频质量的要求也越来越高,这就要求数据传输的速度要快,或者数据包的大小要小,才能方便传输速度高。VP9 视频编解码器用于对音频或视频进行压缩和解压。音视频数据压缩后大大减小体积,因此 VP9 可以帮助流媒体视频更快传输。Safari 12.1(通过支持 VP8)可以与其他 Peer 进行在线实时视频。 46 | 47 | ![VP9 与 VP8 对比](https://s3.ax1x.com/2020/11/13/D9UwvD.png) 48 | 49 | VP9 是在 VP8 的基础上改进而来的,是谷歌旗下的由 On2 科技公司创建的视频压缩格式。主要功能是隐藏丢包和清理嘈杂的图像,以及多平台的采集和播放功能。通过 VP9,用户可以使用 WebRTC 传输 720p 视频,而不会出现丢包或延迟。同时,它还可以在同样的带宽下支持 1080p 视频通话,并帮助优化连接和数据使用,避免带宽成本过于高昂。 50 | 51 | # APIs 52 | 53 | 有三个主要的 Javascript API 可以处理音频捕获、视频会议和数据传输。 54 | 55 | ## MediaStream 56 | 57 | 使用用户的摄像头和麦克风来获取和传输音频和视频。使用这个 API 可以让你获得麦克风和网络摄像头等设备的访问权限。当开发人员将 WebRTC 集成到他们的网站中时,他们可以对他们想要的音频和视频流的参数进行设置,比如帧率、视频帧的大小、分辨率等。 58 | 59 | 这个 API 是作为 HTML 5 的一部分提供的,而其他两个 API 是专门为 WebRTC 提供的。 60 | 61 | ## RTCPeerConnection 62 | 63 | 将采集到的音视频流实时发送至另一个 WebRTC Peer。使用该 API,用户可以将 getUserMedia 捕获的音频和视频传输给其他 Peer。 64 | 65 | 该 API 具有连接到远程 Peer,维护和监控连接,并在完成后关闭连接等功能。 66 | 67 | ## RTCDataChannel 68 | 69 | 传输任意数据。每个数据通道都与一个 RTCPeerConnection 相关联。内置安全(DTLS)和拥塞控制。 70 | 71 | # 安全 72 | 73 | 在实时通信的数据传输过程中可能会产生很多安全风险。因此,加密是 WebRTC 的强制性功能,并在所有组件上强制执行。WebRTC 使用两种标准加密协议。确保 2 个 Peer 之间连接安全的步骤: 74 | 75 | - 启动信令过程在两个 Peer 之间交换元数据。 76 | - 执行 ICE 检查,ICE 在双方之间建立通道。 77 | - 进行 DTLS 握手。如果有多媒体传输,SRTP 使用 DTLS 握手步骤中导出的密钥。 78 | - 所有 Peer 都有安全通道。 79 | - Peer 之间交换密钥。 80 | 81 | ## 数据报传输层安全协议(DTLS) 82 | 83 | 一种建立在浏览器中的标准化协议。它用于加密数据流。它基于传输层协议(TLP)。保留了传输语义,DTLS 使用用户数据协议(UDP)。它是安全套接字层(SSL)的扩展;任何 SSL 协议都可以用来保护 WebRTC 数据的安全,允许端到端加密。 84 | 85 | ## 安全实时传输协议(SRTP) 86 | 87 | 用于加密媒体流。它是实时传输协议(RTP)的扩展,RTP 没有任何内置的安全机制。在 RTP 的基础上增加了保护、完整性检查和消息认证。缺点是 虽然它为 RTP 数据包提供了加密,但它并没有对报头进行加密。 88 | -------------------------------------------------------------------------------- /10~从零实现 IM 系统/IM/README.md: -------------------------------------------------------------------------------- 1 | # 网络传输 2 | 3 | 单对单模式主要是怎么通过路由路径优化手段达到两点之间最优,这方面 SKYPE 首先提出基于 P2P 的 Real-time Network 模型。而 单对多模式是一个分发树模型,各个客户端节点需要就近接入离自己最近的服务器,然后在服务器与服务器构建一个实时通信网络。 4 | 5 | ## 基础 6 | 7 | ### 推流 8 | 9 | 所谓推流,就是将我们已经编码好的音视频数据发往视频流服务器中。实时音视频系统都是一个客户端到其他一个或者多个客户端的通信行为,这就意味着需要将客户端编码后的音视频数据传输到其他实时音视频系统都是一个客户端到其他一个或者多个客户端的通信行为,这就意味着需要将客户端编码后的音视频数据传输到其他客户端上,一般做法是先将数据实时上传到服务器上,服务器再进行转发到其他客户端,客户端这个上传音视频数据行为称为推流。 10 | 11 | 我们可以通过 Nginx 的 RTMP 扩展方便地搭建推流服务器: 12 | 13 | ``` 14 | rtmp { 15 | 16 | server { 17 | 18 | listen 1935; #监听的端口 19 | 20 | chunk_size 4000; 21 | 22 | 23 | application hls { #rtmp推流请求路径 24 | live on; 25 | hls on; 26 | hls_path /usr/local/var/www/hls; 27 | hls_fragment 5s; 28 | } 29 | } 30 | } 31 | ``` 32 | 33 | 推流会受到客户端网络的影响,例如:wifi 信号衰减、4G 弱网、拥挤的宽带网络等。为了应对这个问题,实时音视频系统会设计一个基于拥塞控制和 QOS 策略的推流模块。 34 | 35 | ### WebRTC 36 | 37 | WebRTC 是一个开源项目,旨在使得浏览器能为实时通信(RTC)提供简单的 JavaScript 接口。说的简单明了一点就是让浏览器提供 JS 的即时通信接口。这个接口所创立的信道并不是像 WebSocket 一样,打通一个浏览器与 WebSocket 服务器之间的通信,而是通过一系列的信令,建立一个浏览器与浏览器之间(peer-to-peer)的信道,这个信道可以发送任何数据,而不需要经过服务器。并且 WebRTC 通过实现 MediaStream,通过浏览器调用设备的摄像头、话筒,使得浏览器之间可以传递音频和视频。WebRTC 有三个重要的部分:MediaStream、RTCPeerConnection、RTCDataChannel: 38 | 39 | - MediaStream:通过设备的摄像头及话筒获得视频、音频的同步流 40 | 41 | - PeerConnection: 用于构建点对点之间稳定、高效的流传输的组件 42 | 43 | - DataChannel:能够使得浏览器之间(点对点)简历一个高吞吐量、低延时的信道,用于传输任何数据 44 | 45 | ## 实时网络传输优化 46 | 47 | ### TCP 与 UDP 48 | 49 | 在大规模实时多媒体传输网络中,TCP 和 RTMP 都不占优势。TCP 是个拥塞公平传输的协议,它的拥塞控制都是为了保证网络的公平性而不是快速到达,我们知道,TCP 层只有顺序到对应的报文才会提示应用层读数据,如果中间有报文乱序或者丢包都会在 TCP 做等待,所以 TCP 的发送窗口缓冲和重发机制在网络不稳定的情况下会造成延迟不可控,而且传输链路层级越多延迟会越大。 50 | 51 | 在实时传输中使用 UDP 更加合理,UDP 避免了 TCP 繁重的三次握手、四次挥手和各种繁杂的传输特性,只需要在 UDP 上做一层简单的链路 QoS 监测和报文重发机制,实时性会比 TCP 好,这一点从 RTP 和 DDCP 协议可以证明这一点,我们正式参考了这两个协议来设计自己的通信协议。 52 | 53 | UDP 不可避免地存在抖动、乱序、丢包问题,视频必须按照严格是时间戳来播放,否则的就会出现视频动作加快或者放慢的现象,如果我们按照接收到视频数据就立即播放,那么这种加快和放慢的现象会非常频繁和明显。也就是说网络抖动会严重影响视频播放的质量,一般为了解决这个问题会设计一个视频播放缓冲区,通过缓冲接收到的视频帧,再按视频帧内部的时间戳来播放既可。 54 | 55 | UDP 除了小范围的抖动以外,还是出现大范围的乱序现象,就是后发的报文先于先发的报文到达接收方。乱序会造成视频帧顺序错乱,一般解决的这个问题会在视频播放缓冲区里做一个先后排序功能让先发送的报文先进行播放。 56 | 57 | UDP 在传输过程还会出现丢包,丢失的原因有多种,例如:网络出口不足、中间网络路由拥堵、socket 收发缓冲区太小、硬件问题、传输损耗问题等等。在基于 UDP 视频传输过程中,丢包是非常频繁发生的事情,丢包会造成视频解码器丢帧,从而引起视频播放卡顿。这也是大部分视频直播用 TCP 和 RTMP 的原因,因为 TCP 底层有自己的重传机制,可以保证在网络正常的情况下视频在传输过程不丢。基于 UDP 丢包补偿方式一般有以下几种: 58 | 59 | - 报文冗余,报文冗余很好理解,就是一个报文在发送的时候发送 2 次或者多次。这个做的好处是简单而且延迟小,坏处就是需要额外 N 倍(N 取决于发送的次数)的带宽。 60 | 61 | - FEC, Forward Error Correction,即向前纠错算法,常用的算法有纠删码技术(EC),在分布式存储系统中比较常见。最简单的就是 A B 两个报文进行 XOR(与或操作)得到 C,同时把这三个报文发往接收端,如果接收端只收到 AC,通过 A 和 C 的 XOR 操作就可以得到 B 操作。 62 | 63 | - 丢包重传,丢包重传有两种方式,一种是 push 方式,一种是 pull 方式。Push 方式是发送方没有收到接收方的收包确认进行周期性重传,TCP 用的是 push 方式。pull 方式是接收方发现报文丢失后发送一个重传请求给发送方,让发送方重传丢失的报文。丢包重传是按需重传,比较适合视频传输的应用场景,不会增加太对额外的带宽,但一旦丢包会引来至少一个 RTT 的延迟。 64 | 65 | ### 拥塞控制 66 | 67 | 要评估一个网络通信质量的好坏和延迟一个重要的因素就是 Round-Trip Time(网络往返延迟),也就是 RTT。评估两端之间的 RTT 方法很简单,大致如下: 68 | 69 | - 发送端方一个带本地时间戳 T1 的 ping 报文到接收端; 70 | 71 | - 接收端收到 ping 报文,以 ping 中的时间戳 T1 构建一个携带 T1 的 pong 报文发往发送端; 72 | 73 | - 发送端接收到接收端发了的 pong 时,获取本地的时间戳 T2,用 T2 – T1 就是本次评测的 RTT。 74 | 75 | 因为客户端有可能在弱网环境下进行推流,音视频数据如果某一时刻发多了,就会引起网络拥塞或者延迟,如果发少了,可能视频的清晰不好。在实时音视频传输过程会设计一个自动适应本地网络变化的拥塞控制算法,像 QUIC 中的 BBR、webRTC 中 GCC 和通用的 RUDP。思路是通过 UDP 协议反馈的丢包和网络延迟(RTT)来计算当前网络的变化和最大瞬时吞吐量,根据这几个值调整上层的视频编码器的码率、视频分辨率等,从而达到适应当前网络状态的目的。 76 | 77 | ### QoS 策略 78 | 79 | 客户端推流除了需要考虑网络上传能力以外,还需要考虑客户端的计算能力。如果在 5 年前的安卓机上去编码一个分辨率为 640P 的高清视频流,那这个过程必然会产生延迟甚至无法工作。为此需要针对各个终端的计算能力设计一个 QoS 策略,不同计算能力的终端采用不同的视频编码器、分辨率、音频处理算法等,这个 QoS 策略会配合拥塞控制做一个状态不可逆的查找过程,直到找到最合适的 QoS 策略位置 80 | 81 | ## 媒体处理技术 82 | 83 | ### 回声消除 84 | 85 | 在实时音视频系统中,回声消除是一个难点,尽管 webRTC 提供了开源的回声消除模块,但在移动端和一些特殊的场景表现不佳。专业的实时音视频系统会进行回声消除的优化。回声消除的原理描述很简单,就是将扬声器播放的声音波形和麦克风录制的波形进行抵消,达到消除回声的作用。因为回声的回录时间不确定,所以很难确定什么时间点进行对应声音数据的抵消。在专业的回声消除模块里面通常会设计一个逼近函数,通过不断对输出和输入声音波形进行在线学习逼近,确定回声消除的时间差值点。 86 | -------------------------------------------------------------------------------- /音视频编解码/编解码/H.264.md: -------------------------------------------------------------------------------- 1 | # MPEG-4/H.264 AVC 编解码标准 2 | 3 | H.264,通常也被称之为 H.264/AVC(或者 H.264/MPEG-4 AVC 或 MPEG-4/H.264 AVC),H.264 的出现就是为了创建比以前的视频压缩标准更高效的压缩标准,使用更好高效的视频压缩算法来压缩视频的占用空间,提高存储和传输的效率,在获得有效的压缩效果的同时,使得压缩过程引起的失真最小。MPEG-4 AVC 和 H.264 是目前较为主流的编码标准。主要定义了两方面的内容:视频数据压缩形式的编码表示和用重建视频信息的语法来描述编码方法。其目的是为了保证兼容的编码器能够成功的交互工作,同时也允许制造厂商自由的开发具有竞争力的创新产品。制造厂商只需要注意的事情就是能够获得和标准中采用的方法同样的结果。 4 | 5 | 提到 H.264 编解码,我们先简单说一下视频压缩算法。视频压缩算法是通过去除时间、空间的冗余来实现的。在一段时间内,相邻的图像的像素、亮度与色温的差别很小,我们没比要对每一个图像进行完成的编码,而是可以选取这段时间的第一张图(也就是第一帧)作为完整的编码,而后面一段时间的图像只需要记录与第一张图(第一帧)在像素、亮度、色温等方面的差别数据即可。通过去除不同类型的冗余,可以明显的压缩数据,代价就是一部分信息失真。 6 | 7 | # 基础概念 8 | 9 | 在 H.264 定义的结构中,一个视频图像编码后的数据叫做一帧。一帧是由一个或多个片(slice)组成的,一个片是由一个或多个宏块(MB)组成的(宏块是 H264 编码的基本单位),一个宏块是由 16x16 的 yuv 数据组成的。 10 | 11 | > 对于 YUV 的介绍参阅 [《Frontend-Notes](https://github.com/wx-chevalier/Frontend-Notes/search?q=YUV)》 12 | 13 | ## 帧类型 14 | 15 | 在 H.264 的协议中,定义了三类帧,分别是 I 帧、B 帧和 P 帧。其中 I 帧就是之前我们所说的一个完整的图像帧,而 B 帧和 P 帧对应的就是之前说的不对全部图像做编码的帧。B 帧和 P 帧的差别在于,P 帧是参考之前的 I 帧生成的,B 帧是参考前后的图像帧生成的。在视频画面播放过程中,若 I 帧丢失了,则后面的 P 帧也就随着解不出来,就会出现视频画面黑屏的现象;若 P 帧丢失了,则视频画面会出现花屏、马赛克等现象。 16 | 17 | ## GOP(画面组) 18 | 19 | 一个 GOP(Group Of Picture)就是一组连续的画面。GOP 结构一般有两个数字,其中一个是 GOP 的长度(即两个 I 帧之间的 B 帧和 P 帧数),另一个数字为 I 帧和 P 帧之间的间隔距离(即 B 帧数)。在一个 GOP 内 I 帧解码不依赖任何的其它帧,P 帧解码则依赖前面的 I 帧或 P 帧,B 帧解码依赖前面的 I 帧或 P 帧及其后最近的一个 P 帧。 20 | 21 | 注意:在码率不变的前提下,GOP 值越大,P、B 帧的数量会越多,平均每个 I、P、B 帧所占用的字节数就越多,也就更容易获取较好的图像质量;Reference 越大,B 帧的数量越多,同理也更容易获得较好的图像质量。但是通过提高 GOP 值来提高图像质量是有限度的。H264 编码器在遇到场景切换的情况时,会自动强制插入一个 I 帧,此时实际的 GOP 值被缩短了。另一方面,在一个 GOP 中,P、B 帧是由 I 帧预测得到的,当 I 帧的图像质量比较差时,会影响到一个 GOP 中后续 P、B 帧的图像质量,直到下一个 GOP 开始才有可能得以恢复,所以 GOP 值也不宜设置过大。同时,由于 P、B 帧的复杂度大于 I 帧,所以过多的 P、B 帧会影响编码效率,使编码效率降低。另外,过长的 GOP 还会影响 Seek 操作的响应速度,由于 P、B 帧是由前面的 I 或 P 帧预测得到的,所以 Seek 操作需要直接定位,解码某一个 P 或 B 帧时,需要先解码得到本 GOP 内的 I 帧及之前的 N 个预测帧才可以,GOP 值越长,需要解码的预测帧就越多,seek 响应的时间也越长。 22 | 23 | ## IDR 帧 24 | 25 | GOP 中的 I 帧又分为普通 I 帧和 IDR 帧,IDR 帧就是 GOP 的第一个 I 帧,这样区分视为了方便控制编码和解码的流程。IDR 帧一定是 I 帧,但是 I 帧不一定是 IDR 帧。IDR 帧因为附带 SPS、PPS 等信息,解码器在收到 IDR 帧时,需要做的工作就是:把所有的 PPS 和 SPS 参数进行更新。 26 | 27 | 可以看出来 IDR 帧的作用是让解码器立刻刷新相关数据信息,避免出现较大的解码错误问题。引入 IDR 帧机制是为了解码的重同步,当解码器解码到 IDR 帧时,立即将参考帧队列清空,将已解码的数据全部输出或抛弃,重新查找参数集,开始一个新的序列。这样,如果前一个序列出现错误,在这里可以获得重新同步的机会。IDR 帧之后的帧永远不会使用 IDR 帧之前的数据来解码。 28 | 29 | # H.264 压缩方式 30 | 31 | H264 的核心压缩算法是帧内压缩和帧间压缩,帧内压缩是生成 I 帧的算法,帧间压缩是生成 B 帧和 P 帧的算法。帧内(Intraframe)压缩的原理是:当压缩一帧图像时,仅考虑本帧的数据而不考虑相邻帧之间的冗余信息,一般采用有损压缩算法,由于帧内压缩是编码一个完整的图像,所以可以独立的解码、显示。帧内压缩率一般不高。 32 | 33 | 帧间(Interframe)压缩的原理是:相邻几帧的数据有很大的相关性,或者说前后两帧信息变化很小的特点。连续的视频其相邻帧之间具有冗余信息,根据这一特性,压缩相邻帧之间的冗余量就可以进一步提高压缩量,减小压缩比。而帧间压缩也称为时间压缩(Temporalcompression),它通过比较时间轴上不同帧之间的数据进行压缩。帧间压缩是无损的,它通过比较本帧与相邻帧之间的差异,仅记录本帧与其相邻帧的差值,这样可以大大减少数据量。 34 | 35 | H.264 压缩视频数据时的具体方式如下: 36 | 37 | - 分组,也就是将一系列变换不大的图像归为一个组,即一个 GOP; 38 | - 定义帧,将每组的图像帧归分为 I 帧、P 帧和 B 帧三种类型; 39 | - 预测帧,以 I 帧做为基础帧,以 I 帧预测 P 帧,再由 I 帧和 P 帧预测 B 帧; 40 | - 数据传输,最后将 I 帧数据与预测的差值信息进行存储和传输。 41 | 42 | # H.264 分层结构 43 | 44 | H.264 的主要目标是为了有高的视频压缩比和良好的网络亲和性,H264 将系统框架分为两个层面,分别是视频编码层面(VCL)和网络抽象层面(NAL)。 45 | 46 | - VLC 层(Video Coding Layer):包括核心压缩引擎和块,宏块和片的语法级别定义,设计目标是尽可能地独立于网络进行高效的编码; 47 | - NAL 层(Network Abstraction Layer):负责将 VCL 产生的比特字符串适配到各种各样的网络和多元环境中,覆盖了所有片级以上的语法级别。 48 | - NALU(NAL Unit):H.264 原始码流(裸流)是由一个接一个 NALU 组成,结构如下图,一个 NALU = 一组对应于视频编码的 NALU 头部信息 + 一个原始字节序列负荷(RBSP,Raw Byte Sequence Payload)。 49 | 50 | ![NALU 结构](https://s3.ax1x.com/2020/11/14/DCPOQe.md.png) 51 | 52 | 一个原始的 H.264 NALU 单元常由 [StartCode] [NALU Header] [NALU Payload] 三部分组成。 53 | 54 | - Start Code:Start Code 用于标示这是一个 NALU 单元的开始,必须是”00 00 00 01” 或”00 00 01”。 55 | - NAL Header:NAL Header 由三部分组成,forbidden_bit(1bit),nal_reference_bit(2bits)(优先级),nal_unit_type(5bits)(类型)。 56 | - RBSP(Raw Byte Sequence Payload)) 57 | 58 | 下图是 RBSP 的序列的样例及相关类型参数的描述表: 59 | 60 | ![RBSP 参数描述表](https://s3.ax1x.com/2020/11/15/DiinYt.png) 61 | 62 | - SPS 是序列参数集,包含的是针对一连续编码视频序列的参数,如标识符 seq_parameter_set_id、帧数及 POC 的约束、参考帧数目、解码图像尺寸和帧场编码模式选择标识等等。 63 | 64 | - PPS 是图像参数集,对应的是一个序列中某一幅图像或者某几幅图像,其参数如标识符 pic_parameter_set_id、可选的 seq_parameter_set_id、熵编码模式选择标识、片组数目、初始量化参数和去方块滤波系数调整标识等等。 65 | 66 | 参数集是一个独立的数据单位,不依赖于参数集之外的其他句法元素。一个参数集不对应某一个特定的图像或者序列,同一个序列参数集可以被一个或者多个图像参数集引用。同理,一个图像参数集也可以被一个或者多个图像引用。只有在编码器认为需要更新参数集的内容时,才会发出新的参数集。 67 | 68 | # H.264 局限性 69 | 70 | 随着数字视频应用产业链的快速发展,视频应用向以下几个方向发展的趋势愈加明显: 71 | 72 | - 高清晰度(HigherDefinition):数字视频的应用格式从 720P 向 1080P 全面升级,而且现在 4K 的数字视频格式也已经成为常见。 73 | - 高帧率(Higherframe rate):数字视频帧率从 30fps 向 60fps、120fps 甚至 240fps 的应用场景升级; 74 | - 高压缩率(HigherCompression rate):传输带宽和存储空间一直是视频应用中最为关键的资源,因此,在有限的空间和管道中获得最佳的视频体验一直是用户的不懈追求。 75 | 76 | 但是面对视频应用不断向高清晰度、高帧率、高压缩率方向发展的趋势,当前主流的视频压缩标准协议 H.264 的局限性不断凸显。主要体现在: 77 | 78 | - 宏块个数的爆发式增长,会导致用于编码宏块的预测模式、运动矢量、参考帧索引和量化级等宏块级参数信息所占用的码字过多,用于编码残差部分的码字明显减少。 79 | - 由于分辨率的大大增加,单个宏块所表示的图像内容的信息大大减少,这将导致相邻的 4 x 4 或 8 x 8 块变换后的低频系数相似程度也大大提高,导致出现大量的冗余。 80 | - 由于分辨率的大大增加,表示同一个运动的运动矢量的幅值将大大增加,H.264 中采用一个运动矢量预测值,对运动矢量差编码使用的是哥伦布指数编码,该编码方式的特点是数值越小使用的比特数越少。因此,随着运动矢量幅值的大幅增加,H.264 中用来对运动矢量进行预测以及编码的方法压缩率将逐渐降低。 81 | - H.264 的一些关键算法例如采用 CAVLC 和 CABAC 两种基于上下文的熵编码方法、deblock 滤波等都要求串行编码,并行度比较低。针对 GPU/DSP/FPGA/ASIC 等并行化程度非常高的 CPU,H.264 的这种串行化处理越来越成为制约运算性能的瓶颈。 82 | 83 | 于是面向更高清晰度、更高帧率、更高压缩率视频应用的 HEVC(H.265)协议标准应运而生。H.265 在 H.264 标准 2 ~ 4 倍的复杂度基础上,将压缩效率提升一倍以上。 84 | -------------------------------------------------------------------------------- /流媒体协议/RTMP.md: -------------------------------------------------------------------------------- 1 | # RTMP 2 | 3 | RTMP,Real-Time Messaging Protocol 是由 Adobe 推出的音视频流传递协议,该协议从属于应用层,被设计用来在适合的传输协议(如 TCP)上复用和打包多媒体传输流(如音频、视频和互动内容)。RTMP 提供了一套全双工的可靠的多路复用消息服务,类似于 TCP 协议[RFC0793],用来在一对结点之间并行传输带时间戳的音频流,视频流,数据流。通常情况下,不同类型的消息会被分配不同的优先级,当网络传输能力受限时,优先级用来控制消息在网络底层的排队顺序。 4 | 5 | RTMP 协议根据不同的套层,也可以分为: 6 | 7 | - 纯 RTMP: 直接通过 TCP 连接,端口为 1935 8 | - RTMPS: RTMP + TLS/SSL,用于安全性的交流。 9 | - RTMPE: RTMP + encryption。在 RTMP 原始协议上使用,Adobe 自身的加密方法 10 | - RTMPT: RTMP + HTTP。使用 HTTP 的方式来包裹 RTMP 流,这样能直接通过防火墙。不过,延迟性比较大。 11 | - RTMFP: RMPT + UDP。该协议常常用于 P2P 的场景中,针对延时有变态的要求。 12 | 13 | 在 Web 上可以通过 MSE(MediaSource Extensions)来接入 RTMP,基本思路是根据 WebSocket 直接建立长连接进行数据的交流和监听。 14 | 15 | # 协议规范 16 | 17 | RTMP 内部是借由 TCP 长连接协议传输相关数据,所以,它的延时性非常低。并且,该协议灵活性非常好(所以,也很复杂),它可以根据 message stream ID 传输数据,也可以根据 chunk stream ID 传递数据。两者都可以起到流的划分作用。流的内容也主要分为:视频,音频,相关协议包等。 18 | 19 | ![RTMP 协议示范](https://user-images.githubusercontent.com/5803001/47570269-56bf3d80-d968-11e8-8e9c-4fc8a5e1a873.png) 20 | 21 | 当使用一个可靠的传输协议如 TCP[RFC0793] 时,RTMP 块流提供了一种可以在多个流中,基于时间戳的端到端交付所有消息的方法。RTMP 块流不提供任何优先级或类似形式的控制,但可以使用更高级别的协议来提供这样的优先级。例如,一个视频服务器可以根据发送的时间或确认每个消息的时间,来决定为一个网络差的用户丢弃视频信息,以确保音频信息的及时接收。RTMP 块流不仅包含了自己的协议控制信息,同时也提供了一个更高级别的协议机制,用来嵌入用户控制信息。 22 | 23 | ## 消息格式 24 | 25 | 消息格式可以被分割成多个块,用来在更高的协议中支持多路复用。在创建块消息格式时,应该包含以下字段: 26 | 27 | - 时间戳:消息的时间戳。这个字段占用 4 字节。 28 | 29 | - 长度:消息的有效长度。如果消息头不能被忽略,它应该包括长度。这个字段在块头中占用 3 字节。 30 | 31 | - 类型 ID:各种类型的协议控制消息的 ID。这些消息使用 RTMP 块流协议和更高级别的协议来传输信息。所有其他类型的 ID 可以用在高级协议,这对于 RTMP 块流来说,是不透明的。事实上,RTMP 块流中没有要求使用这些值作为类型;所有(无协议的)消息可能是相同的类型,或者应用程序使用这个字段来区分多个连接,而不是类型。这个字段在块头中占用 1 字节。 32 | 33 | - 消息流 ID:消息流 ID 可以是任意值。当同一个块流被复用到不同的消息流中时,可以通过消息流 ID 来区分它们。另外,对于 RTMP 块流而言,这是一个不透明值。该字段占用 4 字节,使用小端序。 34 | 35 | ## 握手 36 | 37 | RTMP 连接从握手开始。它包含三个固定大小的块,不像其他的协议,是由头部大小可变的块组成的。客户端(初始化连接的一端)和服务端发送同样的三个块。为了方便描述,客户端发送的三个块命名为 C0,C1,C2;服务端发送的三个块命名为 S0,S1,S2。 38 | 39 | 客户端通过发送 C0 和 C1 消息来启动握手过程。客户端必须接收到 S1 消息,然后发送 C2 消息。客户端必须接收到 S2 消息,然后发送其他数据。服务端必须接收到 C0 或者 C1 消息,然后发送 S0 和 S1 消息。服务端必须接收到 C1 消息,然后发送 S2 消息。服务端必须接收到 C2 消息,然后发送其他数据。 40 | 41 | ```sh 42 | +-------------+ +-------------+ 43 | | Client | TCP/IP Network | Server | 44 | +-------------+ | +-------------+ 45 | | | | 46 | Uninitialized | Uninitialized 47 | | C0 | | 48 | |------------------->| C0 | 49 | | |-------------------->| 50 | | C1 | | 51 | |------------------->| S0 | 52 | | |<--------------------| 53 | | | S1 | 54 | Version sent |<--------------------| 55 | | S0 | | 56 | |<-------------------| | 57 | | S1 | | 58 | |<-------------------| Version sent 59 | | | C1 | 60 | | |-------------------->| 61 | | C2 | | 62 | |------------------->| S2 | 63 | | |<--------------------| 64 | Ack sent | Ack Sent 65 | | S2 | | 66 | |<-------------------| | 67 | | | C2 | 68 | | |-------------------->| 69 | Handshake Done | Handshake Done 70 | | | | 71 | ``` 72 | 73 | 下面是握手示意图中提到的状态: 74 | 75 | - 未初始化:协议版本号在此阶段发送。客户端和服务器均处于未初始化状态。客户端发送携带协议版本号的 C0 包。如果服务器支持此版本,回复 S0 和 S1 包。如果服务器不支持此版本,使用适当的动作回复。在 RTMP 协议中,此动作是中止连接。 76 | 注: 在”C0 和 S0 格式”章节中提及,如果服务器不支持客户端的版本号,可以选择降到版本 3 或中止。 77 | 78 | - 发送版本:客户端和服务器双方在未初始化状态后,会进入发送版本状态。之后,客户端等待 S1 包,服务器等待 C1 包。待接收到数据包,客户端发送 C2 包,服务器发送 S2 包。然后,双方都进入答复状态。客户端等待 C2 的答复,服务器等待 S2 的答复。 79 | 80 | - 握手完成:客户端和服务器交换消息。 81 | 82 | # RTMP 代理 83 | 84 | 关于 RTMP 代理的协议规范。RTMP 是字节协议,第一个包是 c0,1 个字节,一般是 03 表示是明文的 RTMP。所以如果需要做 RTMP 代理,如果直接转发 RTMP 客户端的消息,是没法传递额外的信息的,譬如 HTTP 代理在 Header 中传递的 X-Real-IP,即客户端的 IP,就没法给 RTMP 的后端了。 85 | 86 | 因此,RTMP 的 Proxy 协议必须使用私有协议,c0 的意义必须改写了,譬如另外一个值表示是代理,后面跟随了一些协议信息,这个协议就是 RTMP Proxy 协议。 87 | 88 | 使用网络字节序,big-endian。在 C0 前插入代理的包,兼容 RTMP 标准协议。 89 | 90 | 标准 RTMP 协议如下: 91 | 92 | ``` 93 | C0, 1B, 03表示明文RTMP。后面是C1C2以及其他消息。 94 | ``` 95 | 96 | RTMP 代理协议如下: 97 | 98 | ``` 99 | F3, 1B,常量0xF3,表示RTMP代理协议。 100 | Size, 2B, 表示代理数据的长度,即Size和C0之间的数据。 101 | X-Real-IP, 4B, 表示客户端的真实IP。 102 | C0, 1B,原始客户端的C0,方便代理直接转发客户端的数据。 103 | ``` 104 | 105 | > 备注:一般 Size 应该不超过 C0C1 长度,即`Size<=1537`。 106 | 107 | 例如,标准 RTMP 客户端的消息: 108 | 109 | ``` 110 | 03 // 客户端的C0包,后面是C1C2,以及其他的消息。 111 | ``` 112 | 113 | 或者,代理客户端发送的消息: 114 | 115 | ``` 116 | F3 // 表示是RTMP代理 117 | 00 04 // 表示Extra有4字节 118 | C0 A8 01 67 // 表示客户端IP,C0.A8.01.67,即192.168.1.103 119 | 03 // 客户端原始的C0数据。从这个数据(包括它本身)开始,就是客户端发送的消息了,譬如C1C2。 120 | ``` 121 | 122 | RTMP 协议,譬如握手的 C0、C1、C2、S0、S1、S2,以及数据部分,都没有变更。 123 | -------------------------------------------------------------------------------- /流媒体协议/RTSP.md: -------------------------------------------------------------------------------- 1 | # RTSP 2 | 3 | RTSP(Real Time Streaming Protocol)是由 Real Network 和 Netscape 共同提出的如何有效地在 IP 网络上传输流媒体数据的应用层协议。RTSP 对流媒体提供了诸如暂停,快进等控制,而它本身并不传输数据,RTSP 的作用相当于流媒体服务器的远程控制。服务器端可以自行选择使用 TCP 或 UDP 来传送串流内容,它的语法和运作跟 HTTP 1.1 类似,但并不特别强调时间同步,所以比较能容忍网络延迟。而且允许同时多个串流需求控制(Multicast),除了可以降低服务器端的网络用量,还可以支持多方视频会议(Video onference)因为与 HTTP1.1 的运作方式相似,所以代理服务器的快取功能 Cache 也同样适用于 RTSP,并因 RTSP 具有重新导向功能,可视实际负载情况来转换提供服务的服务器,以避免过大的负载集中于同一服务器而造成延迟。 4 | 5 | ## RTSP 和 HTTP 的区别和联系 6 | 7 | 联系在于,两者都用纯文本来发送消息,且 rtsp 协议的语法也和 HTTP 类似。Rtsp 一开始这样设计,也是为了能够兼容使用以前写的 HTTP 协议分析代码。 8 | 9 | 区别在于,rtsp 是有状态的,不同的是 RTSP 的命令需要知道现在正处于一个什么状态,也就是说 rtsp 的命令总是按照顺序来发送,某个命令总在另外一个命令之前要发送。Rtsp 不管处于什么状态都不会去断掉连接。,而 http 则不保存状态,协议在发送一个命令以后,连接就会断开,且命令之间是没有依赖性的。rtsp 协议使用 554 端口,http 使用 80 端口。 10 | 11 | ## RTSP 和 SIP 的区别和联系 12 | 13 | SIP(Session Initiation Protocol),是基于 IP 的一个应用层控制协议。由于 SIP 是基于纯文本的信令协议,可以管理不同接入网络上的会话等。会话可以是终端设备之间任何类型的通信,如视频会话、既时信息处理或协作会话。该协议不会定义或限制可使用的业务,传输、服务质量、计费、安全性等问题都由基本核心网络和其它协议处理。 14 | 15 | - 联系:sip 和 rtsp 都是应用层的控制协议,负责一次通信过程的建立和控制和结束,不负责中间的传输部分。他们都是基于纯文本的信令协议,穿墙性能良好。支持 tcp、udp,支持多方通信。他们都需要服务器支持,都支持会话中重定向。sip 和 rtsp 都使用 sdp 协议来传送媒体参数,使用 rtp(rtcp)协议来传输媒体流。 16 | 17 | - 区别:rtsp 是专门为流媒体制定的协议,在多个媒体流的时间同步方面比 sip 强大。rtsp 还提供网络负载均衡的功能,减轻服务器压力和网络带宽要求。sip 一般用来创建一次音频、视频通话(双向),而 rtsp 一般用来做视频点播、视频监控等(单向)。当然,从原理上讲,rtsp 也可以做双向的视频通话。 18 | 19 | ## RTSP 和 RTP(RTCP)的关系 20 | 21 | ![RTSP 网络层次图](https://s2.ax1x.com/2020/02/10/151agH.png) 22 | 23 | rtsp 负责建立和控制会话,rtp 负责多媒体的传输,rtcp 配合 rtp 做控制和流量统计,他们是合作的关系。 24 | 25 | # 消息 26 | 27 | RTSP 的消息有两大类,一是请求消息(request),一是回应消息(response),两种消息的格式不同。 28 | 29 | 请求消息格式: 30 | 31 | ```s 32 | 方法 URI RTSP 版本 CR LF 33 | 消息头 CR LF CR LF 34 | 消息体 CR LF 35 | ``` 36 | 37 | 其中方法包括 OPTIONS、SETUP、PLAY、TEARDOWN 等待,URI 是接收方(服务端)的地址,例如:rtsp://192.168.22.136:5000/v0,每行后面的 CR LF 表示回车换行,需要接收端有相应的解析,最后一个消息头需要有两个 CR LF。 38 | 39 | 回应消息格式: 40 | 41 | ```s 42 | RTSP 版本 状态码 解释 CR LF 43 | 消息头 CR LF CR LF 44 | 消息体 CR LF 45 | ``` 46 | 47 | 其中 RTSP 版本一般都是 RTSP/1.0,状态码是一个数值,200 表示成功,解释是与状态码对应的文本解释。状态码由三位数组成,表示方法执行的结果,定义如下: 48 | 49 | - 1XX:保留,将来使用; 50 | - 2XX:成功,操作被接收、理解、接受(received,understand,accepted); 51 | - 3XX:重定向,要完成操作必须进行进一步操作; 52 | - 4XX:客户端出错,请求有语法错误或无法实现; 53 | - 5XX:服务器出错,服务器无法实现合法的请求。 54 | 55 | # 方法 56 | 57 | rtsp 中定义的方法有:OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, SCALE, GET_PARAMETER,SET_PARAMETER。 58 | 59 | ## OPTION 60 | 61 | 目的是得到服务器提供的可用方法: 62 | 63 | ```sh 64 | OPTIONS rtsp://192.168.20.136:5000/xxx666 RTSP/1.0 65 | CSeq: 1 //每个消息都有序号来标记,第一个包通常是 option 请求消息 66 | User-Agent: VLC media player (LIVE555 Streaming Media v2005.11.10) 67 | 68 | # 服务器的回应信息包括提供的一些方法,例如: 69 | 70 | RTSP/1.0 200 OK 71 | Server: UServer 0.9.7_rc1 72 | Cseq: 1 //每个回应消息的 cseq 数值和请求消息的 cseq 相对应 73 | Public: OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, SCALE, GET_PARAMETER //服务器提供的可用的方法 74 | ``` 75 | 76 | ## DESCRIBE 77 | 78 | C 向 S 发起 DESCRIBE 请求,为了得到会话描述信息(SDP): 79 | 80 | ```sh 81 | DESCRIBE rtsp://192.168.20.136:5000/xxx666 RTSP/1.0 82 | CSeq: 2 83 | token: 84 | Accept: application/sdp 85 | User-Agent: VLC media player (LIVE555 Streaming Media v2005.11.10) 86 | 87 | # 服务器回应一些对此会话的描述信息(sdp): 88 | RTSP/1.0 200 OK 89 | Server: UServer 0.9.7_rc1 90 | Cseq: 2 91 | x-prev-url: rtsp://192.168.20.136:5000 92 | x-next-url: rtsp://192.168.20.136:5000 93 | x-Accept-Retransmit: our-retransmit 94 | x-Accept-Dynamic-Rate: 1 95 | Cache-Control: must-revalidate 96 | Last-Modified: Fri, 10 Nov 2006 12:34:38 GMT 97 | Date: Fri, 10 Nov 2006 12:34:38 GMT 98 | Expires: Fri, 10 Nov 2006 12:34:38 GMT 99 | Content-Base: rtsp://192.168.20.136:5000/xxx666/ 100 | Content-Length: 344 101 | Content-Type: application/sdp 102 | v=0 //以下都是 sdp 信息 103 | o=OnewaveUServerNG 1451516402 1025358037 IN IP4 192.168.20.136 104 | s=/xxx666 105 | u=http:/// 106 | e=admin@ 107 | c=IN IP4 0.0.0.0 108 | t=0 0 109 | a=isma-compliance:1,1.0,1 110 | a=range:npt=0- 111 | m=video 0 RTP/AVP 96 //m 表示媒体描述,下面是对会话中视频通道的媒体描述 112 | a=rtpmap:96 MP4V-ES/90000 113 | a=fmtp:96 profile-level-id=245;config=000001B0F5000001B509000001000000012000C888B0E0E0FA62D089028307 114 | a=control:trackID=0//trackID = 0 表示视频流用的是通道 0 115 | ``` 116 | 117 | ## SETUP 118 | 119 | 客户端提醒服务器建立会话,并确定传输模式: 120 | 121 | ```sh 122 | SETUP rtsp://192.168.20.136:5000/xxx666/trackID=0 RTSP/1.0 123 | CSeq: 3 124 | Transport: RTP/AVP/TCP;unicast;interleaved=0-1 125 | User-Agent: VLC media player (LIVE555 Streaming Media v2005.11.10) 126 | //uri 中带有 trackID = 0,表示对该通道进行设置。Transport 参数设置了传输模式,包的结构。接下来的数据包头部第二个字节位置就是 interleaved,它的值是每个通道都不同的,trackID = 0 的 interleaved 值有两个 0或1,0 表示 rtp 包,1 表示 rtcp 包,接受端根据 interleaved 的值来区别是哪种数据包。 127 | 128 | # 服务器回应信息: 129 | RTSP/1.0 200 OK 130 | Server: UServer 0.9.7_rc1 131 | Cseq: 3 132 | Session: 6310936469860791894 //服务器回应的会话标识符 133 | Cache-Control: no-cache 134 | Transport: RTP/AVP/TCP;unicast;interleaved=0-1;ssrc=6B8B4567 135 | ``` 136 | 137 | ## PLAY 138 | 139 | 客户端发送播放请求: 140 | 141 | ```s 142 | PLAY rtsp://192.168.20.136:5000/xxx666 RTSP/1.0 143 | CSeq: 4 144 | Session: 6310936469860791894 145 | Range: npt=0.000- //设置播放时间的范围 146 | User-Agent: VLC media player (LIVE555 Streaming Media v2005.11.10) 147 | 148 | # 服务器回应信息: 149 | RTSP/1.0 200 OK 150 | Server: UServer 0.9.7_rc1 151 | Cseq: 4 152 | Session: 6310936469860791894 153 | Range: npt=0.000000- 154 | RTP-Info: url=trackID=0;seq=17040;rtptime=1467265309 155 | //seq 和 rtptime 都是 rtp 包中的信息 156 | ``` 157 | 158 | ## TEARDOWN 159 | 160 | 客户端发起关闭请求: 161 | 162 | ```sh 163 | TEARDOWN rtsp://192.168.20.136:5000/xxx666 RTSP/1.0 164 | CSeq: 5 165 | Session: 6310936469860791894 166 | User-Agent: VLC media player (LIVE555 Streaming Media v2005.11.10) 167 | 168 | # 服务器回应: 169 | RTSP/1.0 200 OK 170 | Server: UServer 0.9.7_rc1 171 | Cseq: 5 172 | Session: 6310936469860791894 173 | Connection: Close 174 | ``` 175 | 176 | --- 177 | 178 | 以上方法都是交互过程中最为常用的,其它还有一些重要的方法如 get/set_parameter,pause,redirect 等等 179 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | InfoSecurity-Series 7 | 8 | 9 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 34 | 38 | 40 | 45 | 46 |
47 | 64 | 97 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 143 | 144 | 145 | 146 | 155 | 156 | 157 | -------------------------------------------------------------------------------- /直播架构/直播简史.md: -------------------------------------------------------------------------------- 1 | # 直播简史 2 | 3 | # 直播生态的演变 4 | 5 | ## 2010~2013 6 | 7 | 2010 年之前,直播技术的应用主要还集中在广播电视、广电 IPTV、安防视频监控、视频会议及个人媒体中心等领域,使用的传输协议主要为 MMS、RTSP、DVB-C、DVB-T、DVB-S 等。除了这些领域与协议,偶尔还会有一些场景采用 RTMP 与 HTTP+FLV 的方式做直播服务应用,例如一些广电领域的客户或优酷的重大活动直播等。但是当时 RTMP 与 HTTP+FLV 直播并未像后来这么火热,FMS、Wowza 等流媒体服务器还是当时的主流。 8 | 9 | 2010 年之后,随着 Adobe 开放了 RTMP 协议,CRTMPD、libRTMP、Red5 等支持 RTMP 协议的开源框架如雨后春笋般大量涌出,但是这些流媒体服务器还都需要再做一部分开发才能真正建立起服务端能力。2012 年夏天,Nginx RTMP 的出现打破了这场僵局,它通过大幅降低 RTMP 服务器的建设门槛,将 RTMP 协议的直播发展带入快车道。紧接着,2013 年秋天,Simple RTMP Server(SRS)的出现为 RTMP 服务器的建设带来了革命性的改变。并发展至今已经发布了 4.0 版本,SRS 采用了比较前卫的协程方式(用的 StateThread 做基础库)做任务控制,也可以理解为单进程、单线程的工作方式,不需要考虑信号量和锁操作相关的问题。如果想提升应对更高并发的能力,需要扩展多进程,借助第三方的工具来处理,例如 Docker,再例如自己启动多进程来控制多任务。SRS 原生支持的功能比较全,例如 RTMP 转 HTTP+FLV、转 HLS、转 WebRTC 等常用功能,运维操作方面支持 Reload,项目文档健全等。在互联网娱乐直播领域,由于 RTMP 可以保证从画面采集端至播放器端的整体延迟在 3s 左右,故而该协议被广泛应用。 10 | 11 | 与此同时,支持动态多码率的解决方案 HLS(HTTP Live Streaming)与 DASH(Dynamic Adaptive Streaming over HTTP)目前还在以草案的方式向前迭代,并未发布正式的参考标准,FFmpeg、GStreamer 等工具软件也在跟随着草案的更新进行功能迭代。当时,HLS 主要用于移动端与电视盒,DASH 也开始逐步被一些服务商采用,比如 YouTube、Vimeo、Akamai 等。同期动态多码率的解决方案除了 HLS 与 DASH 外,还有 Adobe 的 HDS(HTTP Dynamic Streaming)。由于 HDS 的参考标准并不像 HLS 和 DASH 那样由 RFC 或者 ITU 两个开放标准定制组织负责,而是 Adobe 自己在维护,所以推动起来并不是很顺畅,应用的客户也并不多。 12 | 13 | ## 2013~2015 14 | 15 | 从 2013 年开始,基于 RTMP 协议且主要呈现方式依赖于 Web 浏览器的直播平台开始逐渐发迹。它成为主流选择的原因有以下几点: 16 | 17 | - Flash Player 能够直接播放基于 RTMP 协议传输的音视频数据; 18 | - Web 浏览器已经默认内置 Flash Player 插件,不需要额外安装插件; 19 | - RTMP 推流、播放有很多开源实现,能够快速搭建起端到端的解决方案。 20 | 21 | 相关技术的成熟导致 PC 端涌现出大量基于 Web 浏览器的视频秀场类直播、游戏类直播,以及部分户外直播。与此同时,移动端直播 App 也开始零零散散地出现。虽然安防监控、视频会议、广播电视与互联网行业也在使用直播技术,但其应用领域、方式、场景差异很大。安防监控方面,用户可以连接家用的监控摄像头,用手机观看家里的实时画面。视频会议厂商在 2013 年还在加紧兼容 WebRTC 框架以提升其通用性。H.323/SIP+RTP 的使用方案也比较普遍,因此当时做 RTC 的服务商与平台并不多。 22 | 23 | 2015 年,一个名为“17”的移动端 App 毫无征兆地成为了当时的爆款,但又迅速被 App Store 下架,自此事件开始,直播领域拉开了“千播大战”的序幕。各色各样的直播 App 被大力推广,底层的技术原理大同小异,推流协议仍然是 RTMP,拉流协议则以 RTMP 或 HTTP+FLV 为主,各家 App 主要差别在于起播时间、视频清晰度以及直播卡顿率。伴随着“千播大战”的开场,PC 端直播平台的用户流量开始逐渐被移动端的直播 App 所蚕食,直播平台的形态也渐渐分化。此时的直播应用主要集中在以下四大领域: 24 | 25 | - 广电单向发布直播流,如 IPTV、电视盒,常用 HLS、DASH、HDS 这类端到端且画面延迟在 10s 左右的直播流媒体协议。 26 | - 安防监控采集直播流,如海康、大华、水滴摄像头等,常用 H.323/SIP+RTP 等延迟在 50ms-500ms 左右的协议。 27 | - 互联网/移动互联网互娱直播流,如秀场直播、游戏电竞直播、户外活动直播、街拍直播等,常用 RTMP、HTTP+FLV 等延迟在 3s 左右的直播协议。 28 | - 视频会议直播流,如 Polycom、Cisco 等,常用 H.323/SIP+RTP 等协议。 29 | 30 | ## 2016~2018 31 | 32 | 随着时间的推进,直播场景也越来越复杂。2016 年,大量互娱直播平台逐渐增加了视频会议功能,也就是常说的“连麦”功能,使用场景也变得更复杂。实际上连麦采用的技术与视频会议几乎相同,但要兼顾互娱直播原有的场景,也就是一个直播间里,用户通过连麦进行实时交流,其他观众依然可以以原方式观看视频,例如歌曲合唱、实时采访、表演节目 PK、互相导入粉丝等,主播间也可以通过这种方式导入粉丝进行创收。当然,创新不仅止步于此,移动直播平台数量激增导致的“千播大战”让 2016 年被称为“直播元年”。 33 | 34 | 2017 年,大量的互娱直播平台又创新性地增加了主播与观众互动的能力,例如冲顶大会、在线答题等功能。另一面,直播创业的热潮开始消退,主要是由于用户流量再次向巨头靠拢,头部直播平台马太效应开始显现。随着流量的增加,巨头也不断进行技术迭代和升级,进一步提升了用户的直播观看体验,从而加深了自己的护城河。 35 | 36 | 2018 年,互联网/移动互联网直播开始逐渐从单纯的秀场、游戏、户外直播演变出直播带货场景。而当年的互联网直播巨头快手发布了实时交互性更强的直播 PK 功能,直播的形态从单纯的观看转为互动,又从互动转为挖掘用户需求。 37 | 38 | 从 2019 年至今,直播电商的市场规模达到了近万亿,在巨大的音视频互联网体量下,直播电商市场规模还能达到 100%以上的增长,说明音视频已经成为互联网行业非常重要的一项基础设施。甚至在快手平台,2019 年至 2020 年举办了很多次大型活动,从 2019 年的阅兵到春晚,在线数据一直在突破。快手春晚转播,最高在线人数创下纪录,达到了 2000 多万人;2020 年董明珠在快手直播卖货,一天卖了 3.1 个亿;周杰伦疫情期间从台湾连线,其跨海峡两岸的直播首秀,直播观看人数约 6800 万。 39 | 40 | # 直播技术的迭代 41 | 42 | 自 2008 年 FLV 正式支持 H.264 开始,H.264 编码逐步被广泛应用,同期 VP6、VC-1、H.263、mpeg4video、mpeg2video 等编码方式同样比较火热,但后续只有 H.264 编码在国内脱颖而出。2013 年,PPLive 和迅雷率先公布采用 H.265(即 HEVC)进行视频压缩,在实现同等清晰度的情况下视频码率比 H.264 更低,引起了直播行业的普遍关注。随后各平台开始相继引入 HEVC 编码的视频直播流,但因为 HEVC 专利池问题的复杂性,又出现了一个比较诡异的情况:只有 Safari 浏览器支持 HEVC 的解码,而 Chrome 等浏览器却不支持,导致时至今日依然有大量直播平台还在使用 H.264 的视频编码。 43 | 44 | 除了 HEVC 在发展,谷歌同期还推出并迭代了 VP8、VP9 视频编码,主要应用于 YouTube 等海外视频平台,在国内并未被大规模采用。被大规模推广的 WebRTC 最初对 H.264 的支持不太友好,因此 VP9 才勉强得到了一定范围的应用。 45 | 46 | 2018 年之后,谷歌联合一众巨头共同组建了开放媒体联盟(Alliance for Open Media),并且推出了 AV1 视频编解码标准,且同样在 WebRTC 中被大范围应用。直到今天,视频编码标准中被最广泛应用的依然是 H.264、HEVC 以及 AV1。下一代视频编解码标准 VVC 已经正式发布,而 AV2 也在紧锣密鼓地制定中,业界很多企业也在用 AI 技术进行视频编解码方面的相关研究。相信在不久的将来,会出现更多优秀的视频编码标准。 47 | 48 | 而音频编码标准也随着时代的发展与应用场景的演变在不断迭代,从十年前单向直播领域的 MP3 发展为现在大范围应用的复杂音乐内容压缩编码标准的 AAC。视频会议直播场景下的音频编码标准则从十年前的 G.711、G.729 发展成更优秀的语音通话音频编码 Opus,以及谷歌刚刚发布的音频编码 Lyra。 49 | 50 | 总而言之,音视频编码标准原本处在大一统的时代。随着时间的推移,编解码人才逐年递增,数字信号处理专家也逐渐成长起来,更多人参与到了音视频标准的制定中。因而音视频编解码标准的发展随之进入了快车道,加上参与的公司与相关的组织也在逐年增加,最终用户和不同业务场景可以选择的音视频编码方案将会更加丰富。 51 | 52 | ## 低延时直播场景(延迟 3s 左右) 53 | 54 | 2010 年前,直播多采用 RTSP 传输协议,用户想要在浏览器中观看视频还要额外安装插件,所以多数用户选择在客户端观看直播。当 Adobe 的 RTMP 传输协议开放后,涌现出很多基于 RTMP 协议的框架,例如 LibRTMP、CRTMPD、Nginx RTMP、Simple RTMP Server(现已改名为 Simple RealTime Server)等,加上 OBS、FFmpeg 等客户端开源套件的出现,于是用户可以在 PC 端 Web 浏览器中直接使用默认安装的 Flash Player 插件来播放 RTMP 协议的直播内容,因而基于 RTMP 的应用开始广泛了起来,直播延迟也缩短至可以满足主播与观众的交流需求的范围。 55 | 56 | 随着用户对直播回看的需求的增加,行业对首屏指标的要求也逐渐提高,平台逐渐将播放协议从 RTMP 协议转变为 HTTP 协议,在建立连接时节省了很多 Handshake 相关操作。直播延迟的影响因素有很多,如果仅仅考虑合适的传输协议,通常只能勉强达到秒开的效果,但速度依然较慢,加之个别地区会出现域名劫持等现象,低延迟直播场景的需求仍然很难被满足。于是在域名解析方面,业界又做了一些优化,主要分为 DNS、HTTPDNS、私有化协议预解析域名三种,可以预先将用户调度至直播所属的服务节点,无需在用户发起请求时再进行域名解析,从而节省了域名解析时间,进一步降低直播延迟。 57 | 58 | 整体来看,国内直播目前还是以 RTMP、HTTP 传输协议为主,为了降低延迟,主要采用 DNS 协议调度,并额外增加了 HTTPDNS 与私有化的协议解析域名进行调度,从而解决运营商的内容和流量劫持问题。之所以 RTMP 和 HTTP 会成为主流选择,主要还是因为传输协议比较通用,CDN 厂商支持比较健全。除 RTMP 与 HTTP 外,还有一些介于封装和传输协议之间较为模糊的标准,如 HLS 和 DASH。 59 | 60 | ## 视频会议场景(延迟 50ms-500ms) 61 | 62 | 在谷歌的 WebRTC 大规模应用之前,很多直播会议采用的是类似 RTSP+RTCP+RTP 或者 H.323/SIP+RTP 的方案,视频采集与播放均需要客户端开发解决,无法直接在 Web 浏览器中使用,因而门槛较高。在 WebRTC 大规模应用后,应用视频会议技术的直播平台逐渐增多,只不过这些平台中大部分并不能称之为直播会议,而是体现为连麦、PK 等互动直播形式。 63 | 64 | 在互动直播出现前,大多数直播以秀场、竞技、体育等场景为主,主播与观众的交流方式主要是留言或者发送弹幕。互动直播出现后,诞生了在线抓娃娃、主播观众连麦交流等全新的互动方式,后来火爆全球的 Clubhouse 也采用了同样的技术。 65 | 66 | ## 视频封装的迭代 67 | 68 | 2010 年之前,直播流传输的通常是音视频的裸流,或者是常用的 MPEG-TS 直播流。在 Adobe 开放 RTMP 后,FLV 随即成为了广泛应用的直播流封装格式,该格式常见于秀场直播、游戏竞技类直播,在移动端直播也比较常见。 69 | 70 | 在支持 HEVC 方面,熊猫 TV 在 2017 年开始发起并联合多家公司共同定制了支持 HEVC 的 FLV 事实标准。目前 Adobe 并未对 FLV 参考标准作出任何更新,所以目前来看熊猫 TV 发起的这个标准在实际应用中不会出现任何问题。但如果 Adobe 突然有一天开始继续维护 FLV 并更新了 HEVC 的支持,就会出现比较大的风险,市面上大多数支持 HEVC 的 FLV 封装内容将无法播放。 71 | 72 | 在 PC 直播平台与移动端直播出现的早期,HLS 与 DASH 是同时存在的。HLS 与 DASH 采用的是 MPEG-TS 与 fragmented MP4 的子封装格式,虽然 HLS 与 DASH 也支持动态多码率切换,但是延迟较高。近期推出的 LLDASH 与 LLHLS 都改善了延迟的状况,但还需要在关键帧处切片,因而高延时问题并没有被很好地解决,反而会带来额外的协议方面的开销。 73 | 74 | 时至今日,FLV 封装格式在国内依然被大范围应用,随着 Flash Player 播放器在浏览器中停止更新,PC 直播平台也开始逐渐转向 HLS 与 DASH。但是 FLV 格式在移动端仍有很大用武之地。 75 | 76 | 两年前,快手自研了一套动态多码率自适应切换清晰度的技术(LAS,Live Adaptive Streaming),并于 2020 年开源。开源前该技术已经在快手大规模平稳运行多年,解决了 HLS 的高延迟问题,同时也解决了 RTMP 和 HTTP+FLV 的直播过程因网络质量变化,而不能自动动态切换清晰度导致的直播卡顿率高等问题。 77 | 78 | 视频封装的迭代还在不断演进,而且愈加丰富。单从 FFmpeg 的 Formats 格式支持来看,十年间发展了不计其数的封装格式。由于环境差异,国内外侧重使用的封装技术略有差别,国内还是以 FLV 为主,其次是 HLS/DASH 及其衍生的封装格式,还有已经形成实际使用标准且有数亿用户的 LAS。随着时间的推移,相信视频封装格式的演变将会越来越倾向于满足特定的业务与场景需求。 79 | 80 | ## 音视频传输质量优化策略的迭代 81 | 82 | 在移动网络处于 2.5G 向 3G 升级的年代,移动端直播主要还是以 HLS、RTSP 传输为主,由于当时的网络基础建设并不太适合高清视频传输,再加上视频采集与编码设备能力较弱,所以直播清晰度普遍较低,且直播链路会出现卡顿等问题。在之后的 4-5 年,也就是 3G 向 4G 升级的时代,直播方主要是以自研 TCP 优化方案或者采用 AppEx 的 TCP 优化方案来保证视频内容的传输质量。 83 | 84 | 2016 年谷歌公布 BBR 网络传输优化算法并提供源代码以后,做 TCP 传输优化的专家越来越多,大量更优的网络传输质量优化算法随之出现。 85 | 86 | 还有很多直播平台在不断尝试基于 UDP 做一些直播传输质量优化。例如基于 KCP 替代 TCP,再比如快手发布的 KTP 传输优化,都可以替代 TCP 传输来提升音视频传输质量。再后来,还有很多平台尝试用 QUIC 替代 TCP 传输的方式来提升音视频传输质量,降低音视频端到端的延迟。 87 | 88 | 对于主播推流端遇到弱网或网络上行质量较差的情况,各家平台也加大投入进行弱网服务质量的保障,例如在直播推流时做动态切换帧率、动态切换码率、降低分辨率等操作,确保主播端推流不会卡顿,但是这种做法又加大了服务端做录制兼容、转码兼容等处理的难度,这些问题都在努力解决中。 89 | 90 | 为了降低直播卡顿率,各直播平台还在不断地优化传输协议,从 AppEx 到 BBR、KCP,再到 QUIC,整个行业投入了大量的精力对网络进行针对性优化,专门处理丢包、拥塞、抖动、慢启动等常见的网络问题,也有越来越多的链路传输优化专家开始着手进行更多的探索与深入的研究。 91 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Creative Commons Legal Code 2 | 3 | CC0 1.0 Universal 4 | 5 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE 6 | LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN 7 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS 8 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES 9 | REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS 10 | PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM 11 | THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED 12 | HEREUNDER. 13 | 14 | Statement of Purpose 15 | 16 | The laws of most jurisdictions throughout the world automatically confer 17 | exclusive Copyright and Related Rights (defined below) upon the creator 18 | and subsequent owner(s) (each and all, an "owner") of an original work of 19 | authorship and/or a database (each, a "Work"). 20 | 21 | Certain owners wish to permanently relinquish those rights to a Work for 22 | the purpose of contributing to a commons of creative, cultural and 23 | scientific works ("Commons") that the public can reliably and without fear 24 | of later claims of infringement build upon, modify, incorporate in other 25 | works, reuse and redistribute as freely as possible in any form whatsoever 26 | and for any purposes, including without limitation commercial purposes. 27 | These owners may contribute to the Commons to promote the ideal of a free 28 | culture and the further production of creative, cultural and scientific 29 | works, or to gain reputation or greater distribution for their Work in 30 | part through the use and efforts of others. 31 | 32 | For these and/or other purposes and motivations, and without any 33 | expectation of additional consideration or compensation, the person 34 | associating CC0 with a Work (the "Affirmer"), to the extent that he or she 35 | is an owner of Copyright and Related Rights in the Work, voluntarily 36 | elects to apply CC0 to the Work and publicly distribute the Work under its 37 | terms, with knowledge of his or her Copyright and Related Rights in the 38 | Work and the meaning and intended legal effect of CC0 on those rights. 39 | 40 | 1. Copyright and Related Rights. A Work made available under CC0 may be 41 | protected by copyright and related or neighboring rights ("Copyright and 42 | Related Rights"). Copyright and Related Rights include, but are not 43 | limited to, the following: 44 | 45 | i. the right to reproduce, adapt, distribute, perform, display, 46 | communicate, and translate a Work; 47 | ii. moral rights retained by the original author(s) and/or performer(s); 48 | iii. publicity and privacy rights pertaining to a person's image or 49 | likeness depicted in a Work; 50 | iv. rights protecting against unfair competition in regards to a Work, 51 | subject to the limitations in paragraph 4(a), below; 52 | v. rights protecting the extraction, dissemination, use and reuse of data 53 | in a Work; 54 | vi. database rights (such as those arising under Directive 96/9/EC of the 55 | European Parliament and of the Council of 11 March 1996 on the legal 56 | protection of databases, and under any national implementation 57 | thereof, including any amended or successor version of such 58 | directive); and 59 | vii. other similar, equivalent or corresponding rights throughout the 60 | world based on applicable law or treaty, and any national 61 | implementations thereof. 62 | 63 | 2. Waiver. To the greatest extent permitted by, but not in contravention 64 | of, applicable law, Affirmer hereby overtly, fully, permanently, 65 | irrevocably and unconditionally waives, abandons, and surrenders all of 66 | Affirmer's Copyright and Related Rights and associated claims and causes 67 | of action, whether now known or unknown (including existing as well as 68 | future claims and causes of action), in the Work (i) in all territories 69 | worldwide, (ii) for the maximum duration provided by applicable law or 70 | treaty (including future time extensions), (iii) in any current or future 71 | medium and for any number of copies, and (iv) for any purpose whatsoever, 72 | including without limitation commercial, advertising or promotional 73 | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each 74 | member of the public at large and to the detriment of Affirmer's heirs and 75 | successors, fully intending that such Waiver shall not be subject to 76 | revocation, rescission, cancellation, termination, or any other legal or 77 | equitable action to disrupt the quiet enjoyment of the Work by the public 78 | as contemplated by Affirmer's express Statement of Purpose. 79 | 80 | 3. Public License Fallback. Should any part of the Waiver for any reason 81 | be judged legally invalid or ineffective under applicable law, then the 82 | Waiver shall be preserved to the maximum extent permitted taking into 83 | account Affirmer's express Statement of Purpose. In addition, to the 84 | extent the Waiver is so judged Affirmer hereby grants to each affected 85 | person a royalty-free, non transferable, non sublicensable, non exclusive, 86 | irrevocable and unconditional license to exercise Affirmer's Copyright and 87 | Related Rights in the Work (i) in all territories worldwide, (ii) for the 88 | maximum duration provided by applicable law or treaty (including future 89 | time extensions), (iii) in any current or future medium and for any number 90 | of copies, and (iv) for any purpose whatsoever, including without 91 | limitation commercial, advertising or promotional purposes (the 92 | "License"). The License shall be deemed effective as of the date CC0 was 93 | applied by Affirmer to the Work. Should any part of the License for any 94 | reason be judged legally invalid or ineffective under applicable law, such 95 | partial invalidity or ineffectiveness shall not invalidate the remainder 96 | of the License, and in such case Affirmer hereby affirms that he or she 97 | will not (i) exercise any of his or her remaining Copyright and Related 98 | Rights in the Work or (ii) assert any associated claims and causes of 99 | action with respect to the Work, in either case contrary to Affirmer's 100 | express Statement of Purpose. 101 | 102 | 4. Limitations and Disclaimers. 103 | 104 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 105 | surrendered, licensed or otherwise affected by this document. 106 | b. Affirmer offers the Work as-is and makes no representations or 107 | warranties of any kind concerning the Work, express, implied, 108 | statutory or otherwise, including without limitation warranties of 109 | title, merchantability, fitness for a particular purpose, non 110 | infringement, or the absence of latent or other defects, accuracy, or 111 | the present or absence of errors, whether or not discoverable, all to 112 | the greatest extent permissible under applicable law. 113 | c. Affirmer disclaims responsibility for clearing rights of other persons 114 | that may apply to the Work or any use thereof, including without 115 | limitation any person's Copyright and Related Rights in the Work. 116 | Further, Affirmer disclaims responsibility for obtaining any necessary 117 | consents, permissions or other rights required for any use of the 118 | Work. 119 | d. Affirmer understands and acknowledges that Creative Commons is not a 120 | party to this document and has no duty or obligation with respect to 121 | this CC0 or use of the Work. 122 | --------------------------------------------------------------------------------