###音视频基础知识ios
####视频播放原理git
咱们先从一个简单的视频播放器的原理开始讲述,下图是一个最简单的视频播放的过程(不包括视频加密等等过程):算法
这是一个视频播放的最基本的原理流程图,从这个图能够很总体得看到视频处理的一些主要步骤,后面咱们会详细介绍一些这里提到的基本概念。编程
######注意:咱们利用FFmpeg进行编程的时候几乎就是基于这个流程图来进行。好比说,编程的时候咱们会拿到解码器,解码读取数据,绘制到屏幕上面的时候可能还须要把YUV数据转换为RGB等等。浏览器
咱们常见的封装视频的格式有:flv(音视频分开)、mp四、avi等等。后面咱们会详细说明。服务器
####为何视频须要通过封装处理呢?微信
由于摄像头采集到的画面、以及麦克风采集到的音频数据是通过压缩的处理,否则视频文件就会很大。数据结构
也就是说:函数
####视频的封装格式介绍工具
封装格式的做用是:视频码流和音频码流按照必定的格式存储在一个文件中。
封装格式分析工具:Elecard Format Analyzer
为何要音视频分开存储呢?由于音视频的编码格式各类各样,同时编码必然会形成混乱。
常见的视频封装格式有:
以两个格式为例子,介绍一下原理:
####视频编解码常见格式介绍
视频的压缩算法不少,所以编码格式就会有不少种,下面介绍一些常见的编解码格式:
#####视频编解码格式:
原理分析:
以H264为例,H264是由大小不固定的NALU构成。(NALU实质是一种数据结构)。H264里面有不少子压缩算法,原理比较复杂,包括了熵编码,环路滤波,帧内检测,帧间检测等知识。H264编码原理比较复杂,所以H264的压缩效率是几百到几千倍。
######咱们须要学会FFmpeg便可,由于这个库封装了H264等格式的处理。
视频解码(摄像机获取)获得的是视频像素数据,保存了屏幕上每一个像素点的像素值。常见的像素数据格式有RGB24, RGB32, YUV420P,YUV422P,YUV444P等。压缩编码中通常使用的是YUV格式的像素数据,最为常见的格式为YUV420P。
YUV视频格式是没有通过压缩的,很大。早期在电视上面用得比较多,好比古老的黑白、彩电。彩电播放早期的黑白视频实质上是只播放了Y(亮度)的数据,由于黑白视频只有Y的数据嘛。
RGB也有不少种,好比RGB24,不一样的RGB编码色彩丰富度不一样。
#####音视频编解码格式:
######在作视频直播的时候:音频经常使用AAC来进行编码,用FAAC库来处理;视频用H264编码。
音频采样数据PCM:保存了音频中每一个采样点的值,音频采样数据体积很大,通常须要进过压缩,咱们日常说的“无损”实质上是没有损失的压缩的意思。
#####相关播放(编辑)工具
有兴趣能够下载玩玩。
###FFmpeg介绍
FFmpeg是开源的C/C++音视频处理的类库,这个库十分优秀,以致于不少大公司都在用。主流的视频播放器几乎都使用了FFmpeg。
####FFmpeg的八个函数库的基本介绍
以下图所示:
###Visual Studio下FFmpeg的项目配置
####前言
咱们通常是在VS中写好代码而后放到Android中的,所以有必要搭建VS的开发环境。
####FFmpeg资源获取
首先咱们须要去FFmpeg的官网去获取源码,由于获取的步骤比较麻烦,固下个笔记记录下来,咱们打开ffmpeg.org/:
点击官网中大大的Download按钮,跳转到下面的界面:
选择对应的系统,这里咱们先介绍Windows版本的,点击下面的Windows Builds,跳转到下面的界面:
咱们推荐使用旧版的FFmpeg库,由于若是使用新版的话,除了问题很难去百度。笔者的电脑是64位的,因而就点击All 64-bit Downloads。而后咱们会跳转到下面这个仓库页面:
其中,咱们须要下载的FFmpeg版本是2.8系列的,咱们推荐使用2.8或者如下的版本。其中,dev是开发版本的库,shared是一些动态连接库,static是一些已经编译好的exe(Windows版本)可执行文件。这三个咱们都须要下载下来。
若是你嫌麻烦的话,我下面直接给出下载地址:
https://ffmpeg.zeranoe.com/builds/win64/dev/2015/ffmpeg-20151105-git-c878082-win64-dev.7z
https://ffmpeg.zeranoe.com/builds/win64/shared/2015/ffmpeg-20151105-git-c878082-win64-shared.7z
https://ffmpeg.zeranoe.com/builds/win64/static/2015/ffmpeg-20151105-git-c878082-win64-static.7z
下面并解压的效果以下:
注意:下面分别用dev、static、shared来表明这三个文件夹。
####在命令行玩一玩static中的可执行文件
咱们打开static文件夹,里面有个bin目录,有三个exe文件。这就是咱们即将要玩的东西:
为了简化操做,咱们不妨把bin目录添加到环境变量path中。
而后咱们准备一个测试用的视频,例如笔者准备了一个test.flv视频文件。
打开命令行,输入:
ffmpeg -i test.flv test.avi
复制代码
而后这就完成了一次简单的视频格式转换。相信细心的你也会发现,FFmpeg的官网上面有这么一幅图:
其实这就是一个最简单的例子。
下面咱们再来搞一个是视频转GIF,在命令行输入下面的语句:
ffmpeg -ss 0 -t 11 -i test.flv -s 1366x768 -b:v 1500k test.gif
复制代码
意思就是把test.flv转换为test.gif文件,其中须要指定转换的时间范围,分辨率大小,比特率。
######码率(比特率),单位时间每一帧画面以及音频的大小,也叫做比特每秒,单位时间内播放连续的媒体例如压缩后的音频或者视频的比特数量。码率越高,音视频越清晰。
######把视频转gif是颇有意义的,例如微信中的小视频,咱们没有点开的时候,其实播放的是一个gif文件(可能使用的是libgif这个NDK库),用户点击打开的时候,才会从服务器下载真正的视频文件。这样作大大下降了服务器的压力。
最后咱们看一个播放器的例子,输入下面的命令,就会打开一个播放器,因此说若是你想研究一个Android平台的播放器,那么须要研究ffplay相关的代码:
ffplay test.flv
复制代码
####FFmpeg的VS项目配置
咱们首先建立一个空项目,而后把dev中的include、lib两个目录拷贝到项目的根路径下的源代码目录中(默认是与项目名同样)。
而后在项目属性中配置附加库目录:
而后配置附加库目录:
而后配置有哪些附加库(附加依赖项),以下面所示:
avcodec.lib
avdevice.lib
avfilter.lib
avformat.lib
avutil.lib
postproc.lib
swresample.lib
swscale.lib
复制代码
最后咱们建立一个测试用的CPP文件:
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
using namespace std;
//因为FFmpeg是C和C++混编的,所以使用extern是为了解决兼容问题
extern "C"{
#include "libavcodec/avcodec.h"
}
void main(){
//输出FFmpeg的配置信息,检查是否配置好
cout << avcodec_configuration() << endl;
system("pause");
}
复制代码
而后你会发现编译不过,由于咱们用的FFmpeg库是64位的,所以须要把咱们的平台改成64位的:
而后编译经过,输出的结果以下:
#####题外话——关于extern关键字的基本解释
extern能够置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其余模块中寻找其定义。此外extern也可用来进行连接指定。也就是说extern有两个做用:
若是以为个人文字对你有所帮助的话,欢迎关注个人公众号:
个人群欢迎你们进来探讨各类技术与非技术的话题,有兴趣的朋友们加我私人微信huannan88,我拉你进群交(♂)流(♀)。