在CSDN上的这一段日子,接触到了不少同行业的人,尤为是使用FFMPEG进行视音频编解码的人,有的已是有多年经验的“大神”,有的是刚开始学习的初学者。在和你们探讨的过程当中,我突然发现了一个问题:在“大神”和初学者之间好像有一个不可逾越的鸿沟。“大神”们水平高超,探讨着深奥的问题;而初学者们还停留在入门阶段。到底是什么缘由形成的这种“两极分化”呢?最后,我发现了问题的关键:FFMPEG难度比较大,却没有一个按部就班,由简单到复杂的教程。如今网上的有关FFMPEG的教程多半难度比较大,不太适合刚接触FFMPEG的人学习;并且不少的例子程序编译通不过,极大地打消了学习的积极性。我本身在刚开始学习FFMPEG的时候也遇到了很大的困难。为了帮助更多的人快速成为“大神”,我想总结一个学习FFMPEG的方法,方便你们按部就班的学习FFMPEG。linux
0. 背景知识编程
本章主要介绍一下FFMPEG都用在了哪里(在这里仅列几个我所知的,其实远比这个多)。说白了就是为了说明:FFMPEG是很是重要的。windows
使用FFMPEG做为内核视频播放器:架构
Mplayer,ffplay,射手播放器,暴风影音,KMPlayer,QQ影音...ide
使用FFMPEG做为内核的Directshow Filter:函数
ffdshow,lav filters...工具
使用FFMPEG做为内核的转码工具:学习
ffmpeg,格式工厂...测试
事实上,FFMPEG的视音频编解码功能确实太强大了,几乎囊括了现存全部的视音频编码标准,所以只要作视音频开发,几乎离不开它。
本章主要介绍一下ffmpeg工程包含的三个exe的使用方法。
ffmpeg的官方网站是:http://ffmpeg.org/
编译好的windows可用版本的下载地址(官网中能够链接到这个网站,和官方网站保持同步): http://ffmpeg.zeranoe.com/builds/
该网站中的FFMPEG分为3个版本:Static,Shared,Dev。
前两个版本能够直接在命令行中使用,他们的区别在于:Static里面只有3个应用程序:ffmpeg.exe,ffplay.exe,ffprobe.exe,每一个exe的体积都很大,相关的Dll已经被编译到exe里面去了。Shared里面除了3个应用程序:ffmpeg.exe,ffplay.exe,ffprobe.exe以外,还有一些Dll,好比说avcodec-54.dll之类的。Shared里面的exe体积很小,他们在运行的时候,到相应的Dll中调用功能。
Dev版本是用于开发的,里面包含了库文件xxx.lib以及头文件xxx.h,这个版本不包含exe文件。
打开系统命令行接面,切换到ffmpeg所在的目录,就可使用这3个应用程序了。
ffmpeg是用于转码的应用程序。
一个简单的转码命令能够这样写:
将input.avi转码成output.ts,并设置视频的码率为640kbps
详细的使用说明(英文):http://ffmpeg.org/ffmpeg.html
ffplay是用于播放的应用程序。
一个简单的播放命令能够这样写:
播放test.avi
详细的使用说明(英文):http://ffmpeg.org/ffplay.html
ffprobe是用于查看文件格式的应用程序。
这个就很少介绍了。
详细的使用说明(英文):http://ffmpeg.org/ffprobe.html
本章开始介绍使用ffmpeg的库进行开发。
从http://ffmpeg.zeranoe.com/builds/网站上
1.下载Dev版本,里面包含了ffmpeg的xxx.h头文件以及xxx.lib库文件。
2.下载Shared版本,里面包含了ffmpeg的dll文件。
3.将这两部分文件拷贝到VC工程下面就能够了
注:可能会出现问题,参见:FFMPEG 库移植到 VC 须要的步骤
若是不想本身手动配置,能够下载已经配置好的工程:最简单的基于FFMPEG+SDL的视频播放器
学习文章《100行代码实现最简单的基于FFMPEG+SDL的视频播放器》中的代码,这是ffmpeg作视频播放器最简单的代码了,是我本身精简出来的,已经不能再简化了,每一行都很重要。
原版是基于SDL1.2的视频播放器,后来更新了基于SDL2.0的最简单的视频播放器:最简单的基于FFMPEG+SDL的视频播放器 ver2 (采用SDL2.0)
上述播放器使用libavformat和libavcodec两个类库完成了视频的解码工做。实际上解码工做只须要libavcodec就能够了。所以更新了一个“纯净”的解码器。该解码器只使用libavcodec完成解码工做: 最简单的基于FFmpeg的解码器-纯净版(不包含libavformat)
ffmpeg的函数介绍:ffmpeg函数介绍
注1:播放视频或音频数据的时候会用到SDL。有关SDL能够参考:SDL介绍
SDL参考文档:SDL GUIDE 中文译本
注2:若是想查看解码后的数据,须要用到 YUV播放器:YUV播放器源代码或YUV Player Deluxe均可以
ffmpeg的结构体之间的关系参考文章:FFMPEG中最关键的结构体之间的关系
结构体中每一个变量的分析,参考文章:
FFMPEG结构体分析:AVFormatContext
学习文章《最简单的基于FFMPEG+SDL的音频播放器》 中的代码,和最简单的视频播放器同样,这是最简单的音频播放器,每一行代码都很重要。
原版是基于SDL1.2的音频播放器,后来更新了一个基于SDL2.0的最简单的音频播放器:最简单的基于FFMPEG+SDL的音频播放器 ver2 (采用SDL2.0)
注:若是想要查看解码后的数据(PCM数据),须要用到Audition。
ffplay流程图如文章《FFplay源代码分析:总体流程图》 所示。ffplay代码比较复杂,可是其核心代码和《100行代码实现最简单的基于FFMPEG+SDL的视频播放器》 是同样的。能够两个工程结合着学习。
ffplay代码简介资料:如何用FFmpeg编写一个简单播放器
ffplay使用说明:ffplay的快捷键以及选项
ffplay已经移植到VC下的工程:ffplay_vc2005(别人作的,质量很不错)
ffplay移植到MFC下的工程,包含了简单的图形界面和一些控制按钮:ffplay播放器移植VC的工程:ffplay for MFC
上述软件的代码简介:ffplay for mfc 代码备忘
ffplay.c函数结构简单分析:ffplay.c函数结构简单分析(画图)
ffmpeg编码我本身研究的不是不少,能够参考文章 :使用FFmpeg类库实现YUV视频序列编码为视频
上面那篇文章是用的类库比较旧,新版类库的的使用能够参考下面几篇文章。
图像的编码能够参考:最简单的基于FFMPEG的图像编码器(YUV编码为JPEG)
音频的编码能够参考:最简单的基于FFMPEG的音频编码器(PCM编码为AAC)
视频的编码能够参考:最简单的基于FFMPEG的视频编码器(YUV编码为H.264)
HEVC(H.265)视频编码能够参考:最简单的基于FFmpeg的视频编码器-更新版(YUV编码为HEVC(H.265))
上述编码器使用libavformat和libavcodec两个类库完成了视频的编码工做。实际上编码工做只须要libavcodec就能够了。所以更新了一个“纯净”的编码器。该编码器只使用libavcodec完成编码工做: 最简单的基于FFmpeg的编码器-纯净版(不包含libavformat)
转码其实是先解码而后编码。
不进行转码,只进行封装格式转换的程序可参考:最简单的基于FFMPEG的封装格式转换器(无编解码)
转码程序可参考:最简单的基于FFMPEG的转码程序
比较复杂的转码程序能够参考ffmpeg.c,它移植到MFC下的工程:ffmpeg转码器移植VC的工程:ffmpeg for MFC
ffmpeg.c函数结构简单分析:ffmpeg.c函数结构简单分析(画图)
通晓了ffmpeg库的使用之后,能够看一下ffmpeg的源代码。注意ffmpeg的源代码只有在linux下才能编译,在windows下可使用MinGW进行编译。推荐使用Eclipse查看ffmpeg的源代码。
有一个很完整的ffmpeg源代码的分析文档:ffdoc
FFmpeg的库函数源代码分析文章:
【架构图】
【通用】
FFmpeg 源代码简单分析:av_register_all()
FFmpeg 源代码简单分析:avcodec_register_all()
FFmpeg 源代码简单分析:内存的分配和释放(av_malloc()、av_free()等)
FFmpeg 源代码简单分析:常见结构体的初始化和销毁(AVFormatContext,AVFrame等)
FFmpeg 源代码简单分析:av_find_decoder()和av_find_encoder()
FFmpeg 源代码简单分析:avcodec_open2()
FFmpeg 源代码简单分析:avcodec_close()
【解码】
图解FFMPEG打开媒体的函数avformat_open_input
FFmpeg 源代码简单分析:avformat_open_input()
FFmpeg 源代码简单分析:avformat_find_stream_info()
FFmpeg 源代码简单分析:av_read_frame()
FFmpeg 源代码简单分析:avcodec_decode_video2()
FFmpeg 源代码简单分析:avformat_close_input()
【编码】
FFmpeg 源代码简单分析:avformat_alloc_output_context2()
FFmpeg 源代码简单分析:avformat_write_header()
FFmpeg 源代码简单分析:avcodec_encode_video()
FFmpeg 源代码简单分析:av_write_frame()
FFmpeg 源代码简单分析:av_write_trailer()
【其它】
FFmpeg源代码简单分析:日志输出系统(av_log()等)
FFmpeg源代码简单分析:结构体成员管理系统-AVClass
FFmpeg源代码简单分析:结构体成员管理系统-AVOption
FFmpeg源代码简单分析:libswscale的sws_getContext()
FFmpeg源代码简单分析:libswscale的sws_scale()
FFmpeg源代码简单分析:libavdevice的avdevice_register_all()
FFmpeg源代码简单分析:libavdevice的gdigrab
【脚本】
【H.264】
AVFilter能够给视音频添加各类滤镜效果。有一个简单的例子,是给视频添加水印:
AVDevice能够读取电脑的多媒体设备的数据,或者输出数据到指定的多媒体设备上。
直接使用ffmpeg.exe命令行工具的文章:FFmpeg获取DirectShow设备数据(摄像头,录屏)
编程方面作了2个有关的例子:
读取摄像头:最简单的基于FFmpeg的AVDevice例子(读取摄像头)
屏幕录制:最简单的基于FFmpeg的AVDevice例子(屏幕录制)
Swscale类库能够转换像素数据的格式,同时能够拉伸图像的大小。
libswscale的使用示例: 最简单的基于FFmpeg的libswscale的示例(YUV转RGB)
此外,这个示例还附带了一个程序,用于生成测试图片: 最简单的基于FFmpeg的libswscale的示例附件:测试图片生成工具
封装格式转换器:最简单的基于FFMPEG的封装格式转换器(无编解码)
视音频分离器简化版(demuxer-simple):最简单的基于FFmpeg的封装格式处理:视音频分离器简化版(demuxer-simple)
视音频分离器(demuxer):最简单的基于FFmpeg的封装格式处理:视音频分离器(demuxer)
视音频复用器(muxer):最简单的基于FFmpeg的封装格式处理:视音频复用器(muxer)
直接使用ffmpeg.exe命令行工具的文章:
编程方面作了一个例子:
基于FFmpeg的推流器:最简单的基于FFmpeg的推流器(以推送RTMP为例)
内存播放器:最简单的基于FFmpeg的内存读写的例子:内存播放器
内存转码器:最简单的基于FFmpeg的内存读写的例子:内存转码器
学习完成ffmpeg,还能够了解一下基于ffmpeg的相关的多媒体开源工程,在这里推荐如下几个:
ffdshow是基于ffmpeg的解码器类库libavcodec的DirectShow Filter。普遍安装在PC上。
有关ffdshow的源代码分析文章(更新中):
ffdshow 源代码分析1 : 总体结构
ffdshow 源代码分析 2: 位图覆盖滤镜(对话框部分Dialog)
LAV Filter是基于ffmpeg的解码器类库libavcodec,以及解封装器类库libavformat的DirectShow Filter。普遍安装在PC上。
有关LAV Filter的源代码分析文章:
LAV Filter 源代码分析 2: LAV Splitter
LAV Filter 源代码分析 3: LAV Video (1)
LAV Filter 源代码分析 4: LAV Video (2)
Mplayer是Linux下使用最普遍的播放器,也有Windows版本的。其中使用了ffmpeg。
有关Mplayer的源代码分析文章:
如今广为使用不少播放器都是构建于Media Player Classic - HC的基础之上的。
有关Media Player Classic - HC的源代码分析文章:
Media Player Classic - HC 源代码分析 1:总体结构
Media Player Classic - HC 源代码分析 2:核心类 (CMainFrame)(1)
Media Player Classic - HC 源代码分析 3:核心类 (CMainFrame)(2)
Media Player Classic - HC 源代码分析 4:核心类 (CMainFrame)(3)
Media Player Classic - HC 源代码分析 5:关于对话框 (CAboutDlg)
Media Player Classic - HC 源代码分析 6:MediaInfo选项卡 (CPPageFileMediaInfo)
Media Player Classic - HC 源代码分析 7:详细信息选项卡(CPPageFileInfoDetails)
XBMC是一个优秀的自由和开源的(GPL)媒体中心软件。
有关XBMC源代码分析文章:
XBMC源代码分析 1:总体结构以及编译方法XBMC源代码分析 4:视频播放器(dvdplayer)-解码器(以ffmpeg为例)
XBMC源代码简析 5:视频播放器(dvdplayer)-解复用器(以ffmpeg为例)