
先说需求,从图中可以看出你的源有2个音频轨,每一轨都有16个channel,你想要输出成啥样的?如果是一轨一个文件,还是16channel,用-map分离轨道,-c copy直接保留16 channel的PCM。
最新的AAC是否支持16channel我不太清楚,但是既然你现在用的ffmpeg里自带的AAC不支持,要么重新手动编译换支持的,要么就只能保留PCM,或者你也可以把channel数量降下来,比如降成立体声,-ac 2
利用FFmepg解析并解码音频流数据,然后将解码后的音频数据送给Audio Queue以实现播放
利用FFmpeg解析音频数据流, 利用FFmpeg解码音频数据为PCM格式 利用Audio Queue Player实现音频数据播放
本例以一个苹果原生相机录制的MOV文件为例, 将该文件使用FFmpeg解析并解码,将解码后的数据放入传输队列中,然后开启audio queue player, 播放器在回调函数中轮循取出队列中的数据实现播放
FFmpeg parse流程
FFmpeg解码流程
为了每次能够重新播放,这里需要标记当前是否为解码的第一帧数据,以重新启动播放器 另一点是使用NSTimer等待音频数据放入队列再开始播放,因为audio queue是驱动播放模式,所以必须等音频数据放入传输队列再开始播放
从Parse模块中可以获取当前文件对应FFmepg的上下文对象 AVFormatContext 因此音频流解码器信息可以直接获取
AVFrame 作为解码后原始的音视频数据的容器AVFrame通常被分配一次然后多次重复(例如,单个AVFrame以保持从解码器接收的帧)。在这种情况下,av_frame_unref()将释放框架所持有的任何引用,并在再次重用之前将其重置为其原始的清理状态。
调用avcodec_send_packet将压缩数据发送给解码器最后利用循环接收avcodec_receive_frame解码后的音视频数据
FFmpeg名称中的mpeg来自视频编码标准MPEG,而前缀FF是Fast Forward的首字母缩写。
目录
默认的编译会生成 4 个可执行文件和 8 个静态库。可执行文件包括用于 转码 、 推流 、Dump媒体文件的 ffmpeg 、用于播放媒体文件的 ffplay 、 用于获取媒体文件信息的 ffprobe ,以及作为简单流媒体服务器的 ffserver 。
8个静态库其实就是FFmpeg的8个模块,具体包括如下内容。
比如AAC编码,常见的有两种封装格式
AAC 的 bit stream filter 常常应用在 编码 的过程中。
与音频的AAC编码格式相对应的是视频中的 H264编码 ,它也有两种封装格式
FFmpeg中也提供了对应的 bit stream filter ,称 H264_mp4toannexb ,可以将MP4封装格式的H264数据包转换为annexb封装格式的H264数据 (其实就是裸的H264的数据)包。
H264 的 bit stream filter 常常应用于视频解码过程中。
ffmpeg 是进行媒体文件转码的命令行工具
ffprobe 是用于查看媒体 文件头信息的工具
ffplay 则是用于播放媒体文件的工具
1首先用ffprobe查看一个音频的文件
2输出格式信息format_name、时间长度duration、文件 大小size、比特率bit_rate、流的数目nb_streams等。
3以JSON格式的形式输出具体每一个流 最详细 的信息
4显示帧信息的命令如下:
5查看包信息的命令如下:
ffplay是以FFmpeg框架为基础,外加渲染音视频 的库libSDL来构建的媒体文件播放器。
业界内开源的 ijkPlayer 其实就是基于 ffplay 进行改造的播放器,当然其做了硬件解码以及很多兼容性的工作。
在 ffplay中音画同步的实现方式其实有三种。分别是
并且在 ffplay 中默认的对齐方式也是以 音频 为基准进行对齐的。
首先要声明的是,播放器接收到的视频帧或者音频帧,内部都会有 时间戳(PTS时钟) 来标识它实际应该在什么时刻进行展示。
实际的对齐策略如下:比较视频当前的播放时间和音频当前的播放时间
关键就在于音视频时间的比较以及延迟的计算,当然在比较的过程中会设 置一个 阈值(Threshold) ,若超过预设的阈值就应该做调整(丢帧渲染 或者重复渲染),这就是整个对齐策略。
ffmpeg 就是强大的媒体文件转换工具。它可以转换任何格式的媒体文件,并且还可以用自己的 AudioFilter 以及 VideoFilter 进行处理和编辑。
接下来介绍一个解码的实例,该实例实现的功能非常单一,就是把一个视频文件解码成单独的音频PCM文件和视频YUV文件。
AVFormatContext是API层直接接触到的结构体,它会进行格式的封 装与解封装。
该结构体包含的就是与实际的 编解码 有关的部分。
331 av_register_all
所以该函数的内部实现会先调用 avcodec_register_all 来注册所有configh里面开放的编解码器,然后会注册所有的 Muxer 和 Demuxer (也就是封装格式),最后注册所有的 Protocol (即协议层的东西)。
332 av_find_codec
这里面其实包含了两部分的内容:一部分是寻找 解码器 ,一部分是寻找 编码器 。
333 avcodec_open2
该函数是打开编解码器(Codec)的函数,无论是编码过程还是解码过程,都会用到该函数。
avformat_open_input
根据所提供的文件路径判断文件的格 式,其实就是通过这一步来决定使用的到底是哪一个 Demuxer 。
avformat_find_stream_info
该方法的作用就是把所有 Stream 的 MetaData 信息填充好。
av_read_frame
使用该方法读取出来的数据是 AVPacket 。
对于 音频流 ,一个 AVPacket 可能包含 多 个 AVFrame ,但是对于 视频流 ,一个 AVPacket 只包含 一 个 AVFrame ,该函数最终只会返回一个 AVPacket 结构体。
avcodec_decode
该方法包含了两部分内容:一部分是 解码视频 ,一部分是 解码音频 , 解码 是会委托给对应的解码器来实施的。
avformat_close_input
该函数负责释放对应的资源。
avformat_alloc_output_context2
该函数内部需要调用方法avformat_alloc_context来分配一个 AVFormatContext 结构体。
avio_open2
编码的阶段了,开发者需要将手动封装好的 AVFrame 结构体,作为 avcodec_encode_video 方法的输入,将其编码成为 AVPacket ,然后调用 av_write_frame 方法输出到媒体文件中。
本文参考 音视频开发进阶指南
项目源码地址 - FFmpegDecoder
ffmpeg是音视频处理的c库, 音视频在网络传输过程中,由于数据量大,所有需要进行压缩
压缩目的为了去除冗余信息,冗余信息分为:
1、空间冗余:图像相邻像素之间有较强的相关性
2、时间冗余:视频序列的相邻图像之间内容相似
3、 编码冗余:不同像素值出现的概率不同
4、 视觉冗余:人的视觉系统对某些细节不敏感
5、知识冗余:规律性的结构可由先验知识和背景知识得到
● 无损压缩(Winzip)
压缩前解压缩后图像完全一致
压缩比低
● 有损压缩(H264)
压缩前解压缩后图像不一致
压缩比高
利用人的视觉系统的特性(人眼能见的动画频率和图像细节有限制)
音视频压缩其实就是对音视频进行编码,
视频编码格式
音频编码格式
封装格式
流媒体协议
YUV ,是一种 颜色 编码 方法。常使用在各个视频处理组件中。 YUV在对照片或视频编码时,考虑到人类的感知能力,允许降低色度的带宽。
YUV是编译true-color颜色空间(colorspace)的种类,Y'UV,YUV, YCbCr , YPbPr 等专有名词都可以称为YUV,彼此有重叠。“Y”表示 明亮度 (Luminance、Luma),“U”和“V”则是[色度]
YUV格式有两大类:(平面格式)planar和(打包格式)packed。
1planar:先存储Y,然后U,然后V
2packed:yuv交叉存储
还有我们常说的YUV420sp与YUV420p。
YUV420sp: 一种two-plane模式,即Y和UV分为两个平面,U、V交错排列。
YUV420p: 先把U存放完后,再存放V。UV是连续的。
YUV420的数据大小为: 亮度(行×列) + V(行×列/4) + U(行×列/4)即:W H 3/2,
普遍的编码器都以接受planar的I420数据(YUV420P)
44的I420数据排列如下:
y1 y2 y3 y4
y5 y6 y7 y8
y9 y10 y11 y12
y13 y14 y15 y16
u1 u2 u3 u4
v1 v2 v3 v4
Android相机的采集的视频是NV21(YUV420sP), 也是YUV的格式 只不过U和V的交叉的。
y1 y2 y3 y4
y5 y6 y7 y8
y9 y10 y11 y12
y13 y14 y15 y16
u1 v1 u2 v2
u3 v3 u4 v4
在采集相机数据时需要把UV数据给转换成上面的 顺序。
I frame :帧内编码帧 ,I 帧通常是每个 GOP(MPEG 所使用的一种视频压缩技术)的第一个帧,经过适度地压缩,做为随机访问的参考点,可以当成图象。I帧可以看成是一个图像经过压缩后的产物。
P frame: 前向预测编码帧,通过充分将低于图像序列中前面已编码帧的时间冗余信息来压缩传输数据量的编码图像,也叫预测帧;
B frame: 双向预测内插编码帧 ,既考虑与源图像序列前面已编码帧,也顾及源图像序列后面已编码帧之间的时间冗余信息来压缩传输数据量的编码图像,也叫双向预测帧;
I frame:自身可以通过视频解压算法解压成一张单独的完整的。
P frame:需要参考其前面的一个I frame 或者B frame来生成一张完整的。
B frame:则要参考其前一个I或者P帧及其后面的一个P帧来生成一张完整的。
PTS:Presentation Time Stamp。PTS主要用于度量解码后的视频帧什么时候被显示出来
DTS:Decode Time Stamp。DTS主要是标识读入内存中的帧数据在什么时候开始送入解码器中进行解码。
在没有B帧存在的情况下DTS的顺序和PTS的顺序应该是一样的。
DTS主要用于视频的解码,在解码阶段使用。PTS主要用于视频的同步和输出在显示的时候使用。
如上图:I frame 的解码不依赖于任何的其它的帧而p frame的解码则依赖于其前面的I frame或者P frameB frame的解码则依赖于其前的最近的一个I frame或者P frame 及其后的最近的一个P frame
libavformat
用于各种音视频封装格式的生成和解析,包括获取解码所需信息以生成解码上下文结构和读取音视频帧等功能;音视频的格式解析协议,为 libavcodec 分析码流提供独立的音频或视频码流源。
libavcodec
用于各种类型声音/图像编解码;该库是音视频编解码核心,实现了市面上可见的绝大部分解码器的功能,libavcodec 库被其他各大解码器 ffdshow,Mplayer 等所包含或应用。
libavfilter
filter(FileIO、FPS、DrawText)音视频滤波器的开发,如水印、倍速播放等。
libavutil
包含一些公共的工具函数的使用库,包括算数运算 字符 *** 作;
libswresample
原始音频格式转码。
libswscale
(原始视频格式转换)用于视频场景比例缩放、色彩映射转换;图像颜色空间或格式转换,如 rgb565,rgb888 等与 yuv420 等之间转换。
音视频解5封装流程:
ffmpeg解码流程:
1、brew安装路径:/usr/local/Cellar/
2、隐藏多余信息
3、查看格式信息
1、从视频里提取视频(只留视频不留声音):-an 表示忽略声音估计是 audio no 之类的缩写。
2、从视频里提取mp3:-vn 表示忽略视频,估计是 video no 之类的缩写。
3、从视频里提取pcm\wav音频:
4、截取:(-ss为开始时间 -t为持续时间)
5、格式转换
6、将视频分解成序列
7、将序列合成视频(没有音频)
8、将视频转成gif动画(未压缩)
9、合成视频和音频
10、截取一张jpg
11、截取指定时间的一张图。
1、播放pcm:
以上就是关于ffmpeg 基本用法全部的内容,包括:ffmpeg 基本用法、ffmpeg 命令大全、ffmpeg 音轨提取等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)