关于ffmpeg基础知识入门

关于ffmpeg

关于ffmpeg,我们首先需要知道它是什么,ffmpeg官网对ffmpeg进行了定义:

image.png

一个针对音视频的录制/转换/串流传输的跨平台解决方案。

image.png

当然,在about页面介绍得更加详细,可以说ffmpeg是针对音视频领域的全能操作框架。在现如今的互联网世界中,关于音视频的操作处理,或直接或间接都会依赖到这个框架(当然也有其他音视频框架)。

怎样使用ffmpeg

ffmpeg有两种使用方法:

  • 自定义开发使用
  • 命令行使用

因为ffmpeg的音视频处理能力都封装在对应的库文件中,因此我们再可以在自己的代码工程中嵌入对应的库文件,然后就可以调用它的基础能力,通过各种组合实现我们想要的功能,这就是自定义开发使用。

而且ffmpeg自身也会把这些功能库统一封装并套壳,打包成一个可执行文件,可以接受各种输入命令,比如在windows上就是ffmpeg.exe文件,我们可以下载这个可执行文件,然后再命令行窗口执行对应的命令行代码。

命令行

我们以windows平台为例,在官网下载最新的可执行文件,不出意外,你会下载到三个可执行文件,分别是:

  • ffmpeg,用于音视频进行修改(录制,采集,裁剪,转换等)处理的能力
  • ffprobe,用于分析音视频文件的相关信息
  • ffplay,发播放音视频

把文件所在路径添加到系统路径即可在命令行窗口进行调用。

比如查看媒体文件的一些信息

ffprobe -show_streams sample.mp4 // 显示sample.mp4内部的流的信息

比如视频文件的格式转换

// mp4转换为avi
ffmpeg -i sample.mp4 -c copy output.avi

命令行的参数和组合形式非常多,具体可以参考官网 Command Line Tools Documentation

也可以先看看阮一峰 FFmpeg 视频处理入门教程,我认为他的教程都非常详细且易懂

自定义开发

自定义开发则是撇开了ffmpeg的壳,只获取其内部功能实现的库文件,把库文件集成到我们工程中,通过调用ffmpeg提供的API来实现我们自己的功能,这个会涉及到了c/cpp开发。

关于自定义开发更多细节就不举例了,这不是本文的重点,而且后面会专门在ffmpeg的基础上进行功能开发。

小结

相对而言命令行的方式更简单一些,因为命令行相当于已经提前封装了一些功能实现的逻辑代码,自定义开发的使用复杂的多,因为自定义开发则需要自己实现逻辑。但是自定义开发比较灵活,而且更适合精细化的,自定义程度较高的那些需求,而且更容易让我们理解音视频处理的一些过程。

其实这两种使用方式没有本质区别,命令行在library之上增加了中间层,把一些功能实现凝结为几个命令参数以达到简化开发的目的。而自定义则直接拿开中间层,直接接触library。

image.png

ffmpeg的功能模块

image.png
  • libavcodec 提供音视频的编解码能力

  • libavformat 提供处理各种音视频容器格式的能力,比如封装,解封装

  • libavutil 提供一些实用的功能函数

  • libavfilter 提供音视频流的滤镜效果

  • libavdevice 提供操作输入和输出设备的能力。例如,从摄像头获取视频数据以及将视频数据输出到屏幕

  • libswresample 实现音频混合和重采样能力

  • libswscale 实现视频帧的颜色转换和缩放能力

如果使用命令行模式,一般会把上述的库全部打包起来,而如果是自定义开发则是按需使用,比如如果不涉及设备操作可以不要libavdevice,不需要滤镜功能可以不要libavfilter...

这些支持库都是跨平台的,既可以是动态库也可以是静态库,

ffmpeg的一些基础概念

time_scale

time_scale 可以称作时间刻度,具体的含义是把一秒钟分为多少个刻度

time_scale = 10 // 表示把一秒钟分为10份,10个刻度,每个刻度代表1/10秒

time_scale = 1000 // 表示把一秒钟分为1000份,1000个刻度,每个刻度代表1/1000秒

time_base

time_base是ffmpeg中一个非常重要的概念,一般称作时间基,或者可以说是ffmpeg中的时间基础单位。

现实世界所使用的时间基础单位一般是是秒,因为秒对于普通人而言已经足够精确了,使用毫秒或者微秒毫无必要,但是在ffmpeg中不是以秒为基础单位,而是把秒分为若干份,以一份作为ffmpeg中的时间基础单位。

time_base = 1/24   //表示把1s分为24份,以1/24作为ffmpeg的时间的基础单位。

time_base = 1/1000   //表示把1s分为1000份,以1/1000作为ffmpeg的时间的基础单位。

ffmpeg中大量的时间表示(AVStram,AVPacket,AVFrame中的PTS,DTS),都是以time_base作为基础单位的,而不是现实时间。

PTS/DTS/pts_time

  • DTS(Decoding Time Stamp,解码时间戳)

    • 指示解码器应该在什么时间点开始解码该帧(解码顺序)
  • PTS(Presentation Time Stamp,显示时间戳)

    • 指示帧应该在什么时间点被呈现给用户。PTS 是在解码后确定的时间戳,用于视频帧或音频帧的渲染或播放顺序。
  • pts_time

    • 当前媒体帧的显示时间,单位为秒

DTS,PTS一般都是以time_base为单位的。

关于pts,pts_time,time_base之间的计算方式

time_base = 1/75; 
 Frame        pts           pts_time
   0          0          0 x 1/75 = 0.00  (表示该帧在第0秒显示)
   1          3          3 x 1/75 = 0.04  (表示该帧在第0.04秒显示)
   2          6          6 x 1/75 = 0.08  (表示该帧在第0.08秒显示)
   3          9          9 x 1/75 = 0.12  (表示该帧在第0.12秒显示)

AVStream

在ffmpeg中,读取或者写入视频文件时,内部会构建一个数据结构AVFormatContext,这个结构中包含了视频的相关信息,其中一个信息就是AVStram数组,每一个AVStream都包含了一种数据,比如音频和视频分别代表一个AVStram结构,我们可以从中获取比如时长,帧数,编解码器信息,time_base等

image.png

一旦我们获取了AVStream,我们就可以读取该Stream所代表的数据。

AVPacket

在ffmpeg中,在视频文件读取到基本信息之后,就可以读取正式数据内容用于解码,而这个用于解码的数据格式就是AVPacket.

AVPakcet内部包括待一段解码的数据data,size,pts,dts,time_base,stream_id(表示packet读取自哪个AVStream)等。

image.png

AVFrame

AVFrame则是解码后的原始数据,表示一个可以被使用帧,注意这并不一定是视频帧,也可能是音频帧,因为视频和音频都使用AVFrame的数据结构。

AVFrame内包含可播放数据,宽,高(视频),帧类型(视频),采样数(音频),音频格式,PTS等

一般如果是视频,AVFrame表示得是YUV或者RGB图片;如果是音频,则AVFrame表示得是PCM数据。

image.png

此时的得到的数据可以直接被播放。

音视频同步

在获得了可用的音频或者视频帧之后,也并不是直接发送到对应的设备进行播放即可,一般需要我们进行音视频同步控制,因为会出现音频和视频因为各种差异导致获得可用帧的速度差别很大,比如视频很快播放完,但是音频才播了一点点。因此我们需要通过PTS和time_base来控制每一帧的播放速度。

至于同步方法,一般是需要建立一个时间坐标系作为参考,然后计算每一帧的显示时间戳是否对应了正确的时间,否则就等待。

逻辑流程与数据格式转换

根据上面的对一些数据类型的简单介绍,我们已经可以得到一个音频文件播放过程的逻辑流程了

image.png

同样的,把可播放的原始数据保存成文件则是这个过程的逆过程,大同小异。

总结

本文主要对ffmpeg使用方法,核心模块,ffmpeg中的一些基本概念做了介绍,后面将会站在自定义开发的角度上,分析ffmpeg的数据结构的详情,和一个视频被播放的完整过程实现,最终会讲讲在Android平台的使用方式。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,188评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,464评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,562评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,893评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,917评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,708评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,430评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,342评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,801评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,976评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,115评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,804评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,458评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,008评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,135评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,365评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,055评论 2 355

推荐阅读更多精彩内容