学习地址1:https://pan.baidu.com/s/1YVvTc73LMjCalY-GQV2MAw 提取码:2zoj
学习地址2:https://pan.baidu.com/s/1F-GJx9h0CR61uLLWT6r8oQ 提取码:sebo
一、项目介绍
编写这个推流程序,最开始设计的时候是用视频文件推流,后面陆续增加了监控摄像头推流(其实就是rtsp视频流)、网络电台和视频推流(一般是rtmp或者http开头m3u8结尾的视频流)、本地摄像头推流(本地USB摄像头或者笔记本自带摄像头等)、桌面推流(将当前运行环境的系统桌面抓拍推流)。
按照分类的话其实就是三大类,第一类就是视频文件(包括本地视频文件和网络视频文件,就是带了文件时长的),第二类就是各种实时视频流(包括监控摄像头rtsp,网络电台rtmp,网络实时视频m3u8等),第三类就是本地设备采集(包括本地摄像头采集和本地电脑桌面采集),每一种类别都可以用对应的通用的代码去处理,基本上就是在打开阶段有所区别,后面采集和解码并推流阶段,代码是一模一样的。
二、什么是流媒体
所谓流媒体按照字面意思理解就是像流一样的媒体,看起来像是废话。流媒体现在司空见惯,所以一般人大概不会有疑问。事实上在流媒体还没有出现的时候,基本上通过网络播放电影就不太现实。通过网络播放电影的时候必须先将整个文件下载到电脑上然后才能播放,所以一般都要缓冲很久,这也是为什么最开始迅雷等下载工具流行的原因,其实大多数都是用来下电影了。
流媒体最大的特点即是能够做到边下载边播放,而不需要预先将整个文件全部下载完成之后才能播放,这样极大的改善了用户体验,也提高了实时性,使得网络直播成为可能。
三、开发思路
首先,为什么要用NDK来做,因为自己之前就已经实现过RTMP推流、RTMP播放、RTSP转码等等各种c++实现的流媒体项目,有很成熟的代码模块。既然Android有NDK,可以JNI的方式复用之前的成熟代码,大大拓展和加快项目实现,那为什么不这样去做呢。和其他平台一样,要实现采集摄像头推送直播流,需要实现以下几点
获取Android摄像头数据
对摄像头数据进行h264编码
编码后数据以RTMP协议封装数据并推送
下面分开来讲开发思路:
Android端采集摄像头原始数据,可以在Java层通过Camera2获取数据,也可以用NativeCamera通过NDK来获取,不过后者需要的版本高一些,我考虑了一下,还是决定通过Java层获取数据,然后再交给下层处理。
h264编码,可以通过AndroidMediaCodec进行硬件编码,也可以通过x264进行软件编码,这里因为要复用以前的代码,决定使用软件编码来验证
RTMP协议封装,这部分代码,直接使用之前的C++代码即可,本身就是平台无关的,NDK也是linux环境开发,socket网络通信都是相通的。
四、流媒体系统的组成
一个完整的流媒体系统由这些部分组成,信号采集,编码,传输,解码,输出。
1、信号采集
我们所说的流媒体系统都是要在计算机系统上面进行处理的,而系统中最主要的元素是音频和视频,从物理上面来说音频实际上是一种通过物理震动形成的机械波,音频采集即是将这种物理波转换为电信号进而转换成二进制的音频数据,一般采集得到的原始音频数据是 PCM 数据。
2、编码
什么是编码,为什么要编码。假设我们的网络容量是无限的,传输速度也是无限大的,这当然是不需要编码的。而实际上并不是,我们采集到的原始音视频数据量是很大的,所以我们需要想办法,将采集到的原始的音视频二进制数据量尽量变小,方便在网络上进行传输,同时又需要在还原(解码)的时候尽量接近原始音视频(损失,编码也有分为有损和无损)。我们有时候称编码也叫压缩编码,其实压缩这个概念类似我们平时的压缩文件的原理一样,在最常见的概念中,有帧内压缩和帧间压缩。
3、传输
经过采集,编码我们现在已经获得了音视频数据帧,但是一般观看视频的一定不是在采集编码的现场,否则就不需要传输了,传输的过程就是将编码后的音视频数据通过网络传输到希望观看的观众那里。
4、解码
经过编码压缩的数据必须还原成编码之前的原始数据才能播放显示,这个还原过程就是解码的过程。
5、输出
输出的过程就是播放出来的过程,与采集的时候一样,实际上这是将采集的原始音视频数据经过模数转换转换成物理信号,视频信号通过显示器显示出来,音频信号通过音箱放出来。
五、编译所需软件
编译所需软件 :
-- ant : 将软件编译、测试、部署等步骤联系在一起加以自动化的一个工具;
-- autoconf : 用于包以适应多种Unix类系统的 shell脚本的工具;
-- automake : 产生供make程式使用的Makefile,用来编译程式;
-- cmake : 开源的跨平台自动化建构系统,利用配置文件控制建构过程;
-- gawk : linux下查找替换文本工具;
-- gcc : C 语言编译工具;
-- g++ : C ++ 语言编译工具;
-- libtool : 属于GNU建构系统的GNU程序设计工具,用来产生便携式的库;
-- m4 : 宏处理器.将输入拷贝到输出,同时将宏展开;
-- patch : 制作 patch 文件的必要工具;
-- pkg-config : 提供从源代码中编译软件时查询已安装的库时使用的统一接口的计算机软件;
-- protobuf : 全称 protocol buffer, google 的一种数据交换的格式,它独立于语言,独立于平台;
-- ragel : 有限状态机编译器,它将基于正则表达式的状态机编译成传统语言(C,C++,D,Java,Ruby等)的解析器;
-- subversion : SVN 代码管理工具;
-- unzip : zip 的压缩解压缩工具;
-- git : git 版本管理工具;
有疑问加站长微信联系(非本文作者)