2016年是移动直播爆发年,不到半年的时间内无数移动直播App掀起了全民直播的热潮。然而个人觉得直播的门槛相对较高,从推流端到服务端器到播放端,无不需要专业的技术来支撑,仅仅推流端就有不少需要学习的知识.目前大部分直播采用的都是RTMP协议,我这里写一个简单的Demo,帮助大家更好的理解直播推流的过程,主要包括:音视频采集, 音视频编码, 数据打包, RTMP协议等相关的知识等.项目结构分的很清楚,各个模块也用协议进行了分离,方便大家学习不同的模块.

先阐述下推流的整体流程:

  • 建立tcp连接

  • 建立rtmp连接,以及发送各种控制指令

  • 获取原始视频数据和音频数据

  • 对原始视频数据和音频数据进行压缩编码

  • 对编码后的视频数据和音频数据进行打包

  • 发送打包后的音频和视频数据

项目各个类的作用

  • `SGSimpleSession` 是Api接口层,负责对外提供可直接调用的接口,同时也是一个数据分发中心,获取到的原始音视频数据和编码后的数据都在这里被分发到不同的类进行处理.

  • 视频相关的类

1.SGVideoSource 原始视频数据获取类,底层用的是AVFoundation框架来实现.对外提供原始未经编码的的视频数据,同时提供图像预览功能.如果需要添加美颜,摄像头切换,翻转,闪光灯等操作,也是在这里处理的.

原始视频帧: 原始视频数据其实就是一帧一帧的数据,它们没有经过压缩编码,每一帧包含了图像信息和时间信息,我们通过代码提取出图片.

fps :1s中包含的帧数就是帧速(fps),一般fps的范围是15~30帧,帧速越高画面越流畅,带宽消耗量越大.实际直播中,大部分采用15到20就可以了.

分辨率 : 一帧的图像的大小,iOS原生的有352*288,640*480,1280*720等,一般直播采用640 *480,然后裁剪为640 *360.

码率 : 也叫比特率,数据传输时单位时间传送的数据位数. 可以理解为码率决定一帧图像的显示精细程度.在一定范围内,码率越大,图像越清晰,消耗带宽或者文件体积就越大.超过一定范围后,清晰度不变.一般640 * 480分辨率的,码率512kbps就能够保证清晰度.

2.SGVideoConfig这个视频配置的类,主要包括压缩等级,分辨率,码率等的配置

3.SGH264Encoder这个类是编码器,主要功能是对原始的视频帧进行编码压缩处理,这里采用的是`硬编码`,编码输出格式为H264格式.

编码 : 编码是指将原始的帧数据编码压缩,编码后数据更小,方便在网络上传输.原始数据体积较大,网络传输十分不方便,因此需要将数据压缩,视频压缩算法当前比较主流的是H264,这里我们压缩格式是H264格式.H264有不同的压缩等级,压缩等级不同,压缩比也不同.常见的压缩等级有:`baseline ` , `main` , `high`.

硬编码 : 硬编码是相对软编码而言的,一般软编码是通过cpu来运算,比较消耗cpu性能,耗时大,但是兼容性好,软编码一般采用ffmpeg或者x264.相对而言,硬编码使用gpu来编码,速度效率很高.这里采用的是iOS自带的硬解码,只支持iOS8以后的系统.

压缩后的视频帧 : 压缩后的视频有三种帧类型:I ,B ,P帧,I帧也叫关键帧.经过解码后能够独立展示出一幅图像,P帧是前向预测帧,参考前一帧才能解码显示出一幅完整的图像.B 为双向预测帧,必须参考前一帧和后一帧才能解码出图像.因此,I帧的压缩比最低,大约为0.7,它只能采用帧内压缩,P帧压缩比次之,大概能达到0.5,B帧压缩比则更高,达到了0.3~0.5,B帧和P帧采用的是帧内压缩和帧间压缩技术(也就是运动估计,原理是相邻帧的图像有一部分是一样的,专业术语叫空间冗余).实际上,视频压缩等级不同,帧种类也不同,比如`baseline等级`压缩后的视频只有I帧 和 P帧.`main等级` 和 `high等级` 则三种帧都包含,它们的整体压缩比要比`baseline`要高.但是因为B帧需要参考前一帧和后一帧才能显示,很容易造成卡顿情况,因为万一后面的帧没有获取到,导致前一帧已也不能显示,所以在实际应用中(直播app),一般压缩等级采用`baseline`.

gop : 这个我试着描述一下:因为除了I帧,其它帧都不能独立渲染显示,理论上只需要一个I帧其它全部是非I帧,这样压缩比最高,但是因为`(B帧和P帧)参考其他帧`的原因会有一定的误差,当一段时间后,累计误差会原来越大,导致图像失真.解决办法就是以一小段为一个单元,每个单元第一帧都是I帧;这样,即使前面某一小段出了问题也不会影响后面的一小段,每一个小段我们称作一个关gop.每个gop的第一帧一定是关键帧,因为你的没得参考;通常我们设置gop的大小为1s到3s,因此关键帧与关键帧之间的间隔就是1s的帧数(对应gop为1s)到3s的帧数(对应gop为3s),根据上面的定义,1s的帧数为fps,因此关键帧间隔为1*fps 到 3*fps.秒开的优化点之一就是减小gop大小,因为gop第一帧是关键帧,能独立渲染出来,用户进入直播间的时间是随机的,为确保用户尽快拿到关键帧,尽快渲染出图像;同时gop越小,关键帧数量就越多,带宽消耗量就越大.

4.SGH264Packager 这个类负责对已经编码好的H264帧数据进行打包处理,打包成符合RTMP协议格式的数据,然后才能发送.

  • 音频相关类

SGAudioSource 这个类主要负责录制音频数据,输出原始音频帧,音频的格式为PCM格式.

SGAudioConfig 这个类是音频配置相关的类,主要包括声道数,码率,采样率的配置.

SGAACEncoder 这个类作用是将原始PCM音频数据进行编码压缩,编码结果为AAC格式的音频数据,这里采用的是硬编码.软编码的库有faac.

SGAACPackager 这个了类作用是将编码后的AAC格式数据大波按成符合RTMP协议的数据.

  • RTMP相关类

`SGStreamSession`这个类主要是用来建立tcp连接,底层数据的读取和发送,以及连接状态的回调,整个连接状态贯穿整个项目,十分重要.

`SGRtmpSession`这个类主要与RTMP相关,主要负责与服务器交互,包括RTMP握手,指令的发送,对数据的进一步封装,封装成消息,然后再发送.指令有很多,说点重要的,比如握手完成以后,要重新协商消息大小(默认128字节),但是128字节太小,影响效率,一般都稍微改大点,比如这里设置为16kb,如果太大也不好,会导致带宽浪费.这个类涉及到rtmp相关的比较多,比较难以理解,网上有开源的实现librtmp这个库,可以用这个来替代.

以上就是整个项目的基本结构,整个过程类似工厂流水线,可以自行对各个模块进行替换和研究.demo中注释也不少,方便理解.是不是感觉信息量有点大?可能有些地方说的不严谨,还望大家多多指正哈.

这个项目在去年7月份左右就写完了,后来加了一些乌七八糟的东西,后来项目挂了,转战新项目(还是直播).中间写过几篇入门文章,本来打算写成一个系列文章,无奈太忙了,写的不完整.新年伊始,趁着项目不太忙,赶紧整理了一下,纯码字,如果有任何问题可以直接留言.

附上学习博客:

不用任何第三方,写一个RTMP直播推流器的更多相关文章

  1. Android流媒体开发之路二:NDK开发Android端RTMP直播推流程序

    NDK开发Android端RTMP直播推流程序 经过一番折腾,成功把RTMP直播推流代码,通过NDK交叉编译的方式,移植到了Android下,从而实现了Android端采集摄像头和麦克缝数据,然后进行 ...

  2. day122:MoFang:OSSRS流媒体直播服务器&基于APICloud的acLive直播推流模块实现RTMP直播推流

    目录 1.docker安装OSSRS流媒体直播服务器 2.基于APICloud的acLive直播推流模块实现RTMP直播推流 3.直播流管理 1.docker安装OSSRS流媒体直播服务器 1.OSS ...

  3. 基于GPUImage的多滤镜rtmp直播推流

    之前做过开源videocore的推流改进:1)加入了美颜滤镜; 2) 加入了librtmp替换原来过于简单的rtmpclient: 后来听朋友说,在videocore上面进行opengl修改,加入新的 ...

  4. EasyRTMP+EasyRTSPClient实现的多路(支持断线重连)RTSP转RTMP直播推流工具

    本文转自EasyDarwin开源团队成员Kim的博客:http://blog.csdn.net/jinlong0603/article/details/73441405 介绍 EasyRTMP是Eas ...

  5. 流媒体基础实践之——RTMP直播推流

    一.RTMP推流:用户可将RTMP视频流推送到阿麦提供的打流地址.地址格式类似于: rtmp://livepush.myqcloud.com/live 现在可以支持哪些直播源?和那些直播软件?推流参数 ...

  6. EasyRTMP结合海康HCNetSDK获取海康摄像机H.264实时流并转化成为RTMP直播推流(附源码)

    最近一家深耕于南方电网的科技公司同事找到我们,咨询关于调用海康HCNetSDK取流,并进行互联网转化的方案,经过反复的沟通以及自身在EasyDSS和EasyNVR方面的经验,我们推荐了海康HCNetS ...

  7. 基于虹软人脸识别,实现RTMP直播推流追踪视频中所有人脸信息(C#)

    前言 大家应该都知道几个很常见的例子,比如在张学友的演唱会,在安检通道检票时,通过人像识别系统成功识别捉了好多在逃人员,被称为逃犯克星:人行横道不遵守交通规则闯红灯的路人被人脸识别系统抓拍放在大屏上以 ...

  8. rtmp直播推流(一)--flv格式解析与封装

    flv文件格式分析,可参看RTMP中FLV流到标准h264.aac的转换,该文章写的很清晰. flv封装格式解析,可参看视音频数据处理入门:FLV封装格式解析,文章图文并貌,很直观. flv文件封装, ...

  9. 几款优秀的点播、RTSP/RTMP直播播放器介绍

    1.ijkplayer 项目地址: https://github.com/Bilibili/ijkplayer 介绍:Ijkplayer 是Bilibili发布的基于 FFplay 的轻量级 Andr ...

随机推荐

  1. noip模拟9 达哥随单题

    T1.随 看题第一眼,就瞄到最下面 孙金宁教你学数学  ?????原根?目测神题,果断跳过. 最后打了个快速幂,愉快的收到了达哥送来的10分. 实际上这题暴力不难想,看到一个非常小的mod应该就能想到 ...

  2. 程序员学点xx 之 Redis

    程序员学点xx 之 Redis 概述 其实程序员也要和操作系统打交道, 比如最常见的,部署自己电脑上的开发环境. 当然有时某些牛人, 觉得运维或基础部门的同事不够给力, 亲自上手部署服务器或线上环境, ...

  3. ELK分布式日志+NLog在.NetCore中的应用

    一.ELK简介 ELK是Elasticsearch.Logstash和Kibana首字母的缩写.这三者均是开源软件,这三套开源工具组合起来形成了一套强大的集中式日志管理平台 Elasticsearch ...

  4. Hibernate的多对多关系

    1.表的关系: 分别有三个表:课程表.学生表.分数表.课程和学生的关系是多对多的,因为一个学生对应多个课程,而一个课程被多个学生选修.如果用一对多.多对一的观点来看待课程和学生的关系显然是不对的,因为 ...

  5. 致和我一样迷茫的Java程序员们

    缘起 从事近7年Java开发之后,在2019年这个寒冷的冬天里,我终于迎来了人生中的第一次裁员. 啊,30岁之后的裁员真让人焦虑. 按照以往惯例,在面试心仪的公司之前,需要先面试一些不那么心仪的公司热 ...

  6. centos6官网镜像dvd1和dvd2的解释

  7. 今天做一个项目的时候,要在一个编辑的jsp页面的textarea标签设置value属性,结果发现他没有value属性,但是是编辑页面又必须要回显要修改的内容,所以在参考了w3cschool之后很轻松的解决了这个问题。

    今天做一个项目的时候,要在一个编辑的jsp页面的textarea标签设置value属性,结果发现他没有value属性,但是是编辑页面又必须要回显要修改的内容,所以在参考了w3cschool之后很轻松的 ...

  8. node.js和ionic

    1.安装node.js node -v  检测node文件是否安装成功 node --version  检查node版本号 2.Npm   node package manager 管理工具  管理模 ...

  9. Asp.net Core 系列之--5.认证、授权与自定义权限的实现

    ChuanGoing 2019-11-24 asp.net core系列已经来到了第五篇,通过之前的基础介绍,我们了解了事件订阅/发布的eventbus整个流程,初探dapper ORM实现,并且简单 ...

  10. JS三座大山再学习(二、作用域和闭包)

    原文地址 作用域 JS中有两种作用域:全局作用域|局部作用域 栗子1 console.log(name); //undefined var name = '波妞'; var like = '宗介' c ...