基础命令
获得基础信息,输出Metadata
打开媒体文件,获取Meta信息,关闭媒体文件
代码
|
|
- 容器/文件 (Container/File)
- 定义: 特定格式的多媒体文件,如
.mp4
,.flv
,.mov
等。 - 作用: 存储和组织多媒体数据,包括音频、视频、字幕等。
- 常见格式:
- MP4: 广泛用于视频存储和流媒体。
- FLV: 主要用于Flash视频。
- MOV: 苹果公司开发的视频格式。
- 媒体流 (Stream)
- 定义: 一段连续的数据,如一段声音数据、一段视频或者一段字幕数据。
- 特点: 由不同编码器编码。
- 类型:
- 音频流: 存储音频数据。
- 视频流: 存储视频数据。
- 字幕流: 存储字幕数据。
- 数据包 (Packet)
- 定义: 一个媒体流由大量的数据包组成,是压缩后的数据。
- 作用: 传输和存储媒体数据的基本单位。
- 特点: 数据包是压缩后的数据,便于传输和存储。
- 数据帧 (Frame)
- 定义: 一个数据包由一个或多个数据帧组成,是非压缩数据。
- 作用: 原始的、未压缩的媒体数据。
- 类型:
- I帧 (Intra Frame): 独立帧,不依赖其他帧。
- P帧 (Predictive Frame): 依赖前一帧进行预测。
- B帧 (Bidirectional Frame): 依赖前后帧进行预测。
- 编解码器 (Codec)
- 定义: 编解码器是以帧为单位实现压缩数据和原始数据之间相互转换的工具。
- 作用: 用于压缩和解压缩媒体数据。
- 常见编解码器:
- 视频编解码器: H.264, H.265, VP9 等。
- 音频编解码器: AAC, MP3, Vorbis 等。
重要结构体
- AVFormatContext: 管理整个多媒体文件的格式和结构。
- AVStream: 表示媒体文件中的一个单独的媒体流。
- AVCodecContext 与 AVCodec: 管理媒体数据的编码和解码过程。
- AVPacket: 表示压缩后的媒体数据。
- AVFrame: 表示未压缩的原始媒体数据。
解封装-提取aac数据
AAC(Advanced Audio Coding)是一种高级音频编码技术,广泛用于数字音频压缩和传输。它是由MPEG(Moving Picture Experts Group)开发的,旨在提供比MP3更高的音质和更高的压缩效率。AAC通常用于各种音频应用,包括音乐、视频、广播和流媒体服务。
AAC的主要特点:
- 高音质:AAC能够在较低的比特率下提供比MP3更高的音质。
- 多通道支持:AAC支持多通道音频,包括立体声、5.1环绕声和7.1环绕声。
- 低延迟:AAC设计用于低延迟应用,适合实时音频传输。
- 灵活性:AAC支持多种比特率和采样率,适用于不同的应用场景。
|
|
流程
操作步骤 | 函数名 |
---|---|
打开媒体文件 | avformat_open_input |
获取码流信息 | avformat_find_stream_info |
获取音频流 | av_find_best_stream |
初始化 packet | av_packet_alloc |
读取 packet 数据 | av_read_frame |
释放 packet 数据 | av_packet_unref |
关闭媒体文件 | avformat_close_input |
代码
|
|
aac音频格式分析
ADTS(Audio Data Transport Stream)和ADIF(Audio Data Interchange Format)是两种用于音频编码的容器格式,主要用于AAC(Advanced Audio Codec)音频编码。它们的主要区别在于数据流的组织方式和使用场景。
ADTS(Audio Data Transport Stream)
- 定义: ADTS是一种流式传输格式,适用于音频数据的实时传输,如广播、流媒体等。
- 结构: 每个ADTS帧都包含一个头信息,后面跟着音频数据。头信息中包含了帧的长度、采样率、声道数等信息。
- 特点:
- 自包含: 每个ADTS帧都是自包含的,可以独立解码。
- 流式传输: 适合流式传输,因为每个帧都可以独立处理。
- 头部信息: 每个帧的头部信息较大,可能会增加一些开销。
ADIF(Audio Data Interchange Format)
- 定义: ADIF是一种文件格式,适用于音频数据的存储和交换,如音频文件的存储。
- 结构: ADIF文件包含一个唯一的头信息,后面跟着所有的音频数据。头信息中包含了编码参数、采样率、声道数等信息。
- 特点:
- 单一头部: 整个文件只有一个头部信息,减少了冗余。
- 非流式: 不适合流式传输,因为需要整个文件的头信息才能开始解码。
- 存储和交换: 适合存储和交换音频数据,因为头部信息只出现一次,减少了文件大小。
总结
- ADTS: 适用于流式传输,每个帧自包含,适合实时传输。
- ADIF: 适用于文件存储和交换,整个文件只有一个头部信息,适合存储和交换音频数据。
选择哪种格式取决于具体的应用场景:如果需要实时传输音频数据,ADTS是更好的选择;如果需要存储或交换音频文件,ADIF更为合适。
提取H264视频数据
流程
流程和提取aac文件一样
操作步骤 | 函数名 |
---|---|
打开媒体文件 | avformat_open_input |
获取码流信息 | avformat_find_stream_info |
获取音频流 | av_find_best_stream |
初始化 packet | av_packet_alloc |
读取 packet 数据 | av_read_frame |
释放 packet 数据 | av_packet_unref |
关闭媒体文件 | avformat_close_input |
代码
|
|
成功运行,要用avi格式的视频文件
如果想提取mp4格式的文件,需要进行以下步骤
mp4→h264
流程
函数名 | 描述 |
---|---|
av_bsf_get_by_name |
根据名称获取比特流过滤器 |
av_bsf_alloc |
分配比特流过滤器上下文 |
avcodec_parameters_copy |
复制编解码器参数 |
av_bsf_init |
初始化比特流过滤器 |
av_bsf_send_packet |
发送数据包到比特流过滤器 |
av_bsf_receive_packet |
从比特流过滤器接收处理后的数据包 |
av_bsf_free |
释放比特流过滤器上下文及相关资源 |
代码
|
|
转封装-mp4转flv
I帧,P帧,B帧
I帧:帧内编码帧(Intra picture),I帧通常是一个GOP的第一帧,经过轻度地压缩,作为随机访问的参考点,可以当成静态图像,I帧压缩可去掉视频的空间冗余信息。
P帧:前向预测编码帧(predictive frame),通过将图像序列中前面已编码帧的时间冗余信息充分去除来压缩传输数据量的编码图像,也称为预测帧。
B帧:双向预测内插编码帧,既考虑源图像序列前面的已编码帧,又顾及源图像序列后面的已编码帧之间的时间冗余信息,来压缩传输数据量的编码图像,也称为双向预测帧
PTS-显示时间戳
DTS-解码时间戳
流程
步骤 | 对应函数 |
---|---|
打开输入媒体文件 | avformat_open_input |
获取输入流信息 | avformat_find_stream_info |
创建输出流上下文 | avformat_alloc_output_context2 |
创建输出码流的AVStream | avformat_new_stream |
拷贝编码参数 | avcodec_parameters_copy |
写入视频文件头 | avformat_write_header |
读取输入视频流 | av_read_frame |
计算pts/dts/duration | av_rescale_q_rnd /av_rescale_q |
写入视频流数据 | av_interleaved_write_frame |
写入视频文件末尾 | av_write_trailer |
代码
|
|
截取封装文件
时间基与时间戳
时间基:时间刻度,表示每个刻度多少秒(就像一把尺子的刻度)
时间戳:表示占多少个时间刻度,单位不是秒,而是时间刻度(多少多少cm)
时间基和时间戳相乘就是时间
PTS:显示时间戳,在什么时候开始显示这一帧数据,转成时间:PTS * 时间基
DTS:解码时间戳,在什么时候开始解码这一帧数据,转成时间:DTS * 时间基
流程
截取封装文件处理流程和转封装流程几乎一样,只是多了一个跳转指定时间戳的步骤。以下是详细流程:
步骤 | 对应函数 |
---|---|
1. 打开输入媒体文件 | avformat_open_input |
2. 获取输入流信息 | avformat_find_stream_info |
3. 创建输出流上下文 | avformat_alloc_output_context2 |
4. 创建输出码流的AVStream | avformat_new_stream |
5. 拷贝编码参数 | avcodec_parameters_copy |
6. 写入视频文件头 | avformat_write_header |
7. 读取输入视频流 | av_read_frame |
8. 跳转指定时间戳 | av_seek_frame |
9. 计算pts/dts/duration | av_rescale_q_rnd /av_rescale_q |
10. 写入视频流数据 | av_interleaved_write_frame |
11. 写入视频文件末尾 | av_write_trailer |
代码
|
|
视频解码
如何使用ffmpeg接口对视频解码
RGB介绍
三原色:RGB色彩模式是工业界的一种颜色标准,是通过对红(R)、绿(G)、蓝(B)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的,RGB即是代表红、绿、蓝三个通道的颜色,这个标准几乎包括了人类视力所能感知的所有颜色,是目前运用最广的颜色系统之一。
显示器:使用RGB三种颜色的发光体作为基本发光单元
分辨率:手机屏幕分辨率是1280*
720,表示屏幕上有1280*
720个像素点,每个像素点由RGB三种颜色组成
RGB格式
调色版:通过编号映射到颜色的一张二维表,如01索引,表示红色 索引格式: RGB1、RGB4、RGB8 是计算机图形学中常见的颜色编码格式,它们代表了不同的颜色深度和存储方式。以下是对这些格式的解释:
-
RGB1:
- 颜色深度:1位(bit)。
- 颜色数量:2种颜色(通常是黑色和白色)。
- 应用场景:常用于早期的单色显示器或简单的图形界面,如文本模式下的显示。
-
RGB4:
- 颜色深度:4位(bit)。
- 颜色数量:16种颜色。
- 应用场景:常用于早期的彩色显示器或低分辨率图形界面,如早期的计算机游戏或简单的图形应用程序。
-
RGB8:
- 颜色深度:8位(bit)。
- 颜色数量:256种颜色。
- 应用场景:常用于早期的彩色显示器或低分辨率图形界面,如早期的计算机游戏、网页设计中的调色板模式等。
这些格式在现代计算机图形处理中已经较少使用,但在某些特定的应用场景或历史研究中仍然具有参考价值。 像素格式:。。。(后续觉得有必要再补上)
命令
ffmpeg命令将图片转RGB数据
|
|
注意输出信息中会输出图片大小,下面的ffplay
需要用
|
|
ffplay命令播放RGB数据
|
|
其中,width
和 height
是图片的宽度和高度,是必要的信息。
通过解码,会发现照片内存明显变大,因为RGB格式存储了更多的颜色信息,所以我们需要对照片进行编码
YUV介绍
YUV 是一种颜色编码系统,常用于视频和图像处理中。Y
代表亮度(Luminance),U
和 V
代表色度(Chrominance)。YUV 格式有多种变体,如 YUV420、YUV422、YUV444 等。
流程
函数名 | 描述 |
---|---|
av_find_best_stream |
在媒体文件中查找最佳流 |
avcodec_alloc_context3 |
分配一个编解码器上下文 |
avcodec_parameters_to_context |
复制编解码器参数 |
avcodec_find_decoder |
查找并获取视频解码器 |
avcodec_open2 |
打开解码器上下文,并与指定的解码器关联 |
av_read_frame |
读取帧 |
avcodec_send_packet |
发送数据包到解码器 |
avcodec_receive_frame |
从解码器接收帧 |
输入指令
|
|
如果播放的视频乱码,主要是由于width
和linesize
大小不一样
后续的更改视频格式的时候会解决这个问题
代码
|
|
更改视频格式
流程
函数名 | 描述 |
---|---|
av_parse_video_size |
解析视频尺寸字符串(如 “1920x1080”)并返回宽度和高度。 |
sws_getContext |
创建一个 SwsContext ,用于图像缩放和格式转换。 |
av_frame_alloc |
分配一个 AVFrame 结构体,用于存储解码后的视频帧。 |
av_image_get_buffer_size |
计算给定图像格式和尺寸所需的缓冲区大小。 |
av_malloc |
分配内存,用于存储图像数据。 |
av_image_fill_arrays |
将图像数据填充到 AVFrame 的缓冲区中,并设置相关的行大小和数据指针。 |
sws_scale |
使用 SwsContext 对图像进行缩放或格式转换。 |
代码
|
|
解码后的数据存储
解码后的视频数据通常存储在 data[0]
、data[1]
、data[2]
等数组中。具体来说:
data[0]
: 存储了linesize[0] * height
个数据。data[1]
和data[2]
: 存储了其他平面的数据(如YUV格式中的U和V平面)。
内存对齐和 linesize
linesize[0]
: 实际上并不等于图像的宽度width
,而是比宽度大。- 这种差异是由于内存对齐的需求,以及解码器的CPU和其他优化原因导致的。
sws_scale
函数功能
sws_scale
函数是 FFmpeg 中用于图像缩放和格式转换的核心函数。它主要完成以下功能:
-
图像色彩空间转换:
- 将图像从一种色彩空间转换为另一种色彩空间,例如从 RGB 转换为 YUV,或者从 YUV420P 转换为 YUV444P。
-
分辨率缩放:
- 调整图像的分辨率,例如将 1920x1080 的图像缩放到 1280x720。
-
前后图像滤波处理:
- 在进行缩放和色彩空间转换时,应用滤波器以平滑图像,减少锯齿和伪影。
BMP文件格式
概念:BMP文件格式,又称为Bitmap(位图)或是DIB(Device-Independent Device,设备无光位图),是Windows操作系统中的标准图像文件格式。由于它可以不作任何变换地保存图像像素域的数据,因此成为我们取得RAW数据的好来源。
扫描方式:从左到右,从下到上
文件组成:
- 位图文件头(Bitmap File Header):提供文件的格式,大小等信息
- 位图信息头(Bitmap Information):提供图像的尺寸,位平面数,压缩方式,颜色索引等信息。
- 调色板(Color Palette):可选,有些位图需要调色板,有些位图,比如真彩色图(24位的BMP)就不需要调色板。
- 位图数据(Bitmap Data):图像数据区
文件头结构体:
|
|
信息头结构体:
|
|
视频编码(yuv到h264)
流程
函数名 | 描述 |
---|---|
avcodec_find_encoder |
查找编码器 |
avcodec_alloc_context3 |
创建编码器上下文 |
avcodec_open2 |
打开编码器 |
av_frame_alloc |
分配帧内存 |
av_image_get_buffer_size |
获取图像缓冲区大小 |
av_image_fill_arrays |
填充图像数据数组 |
avcodec_send_frame |
发送帧到编码器 |
avcodec_receive_packet |
从编码器接收数据包 |
代码
|
|
音频解码
PCM介绍
PCM(Pulse Code Modulation)是一种用于数字音频的标准编码格式。它通过将模拟音频信号转换为数字信号来表示音频数据。PCM 编码的基本原理是将模拟音频信号在时间上进行采样,并将每个采样点的幅度值量化为离散的数字值。
核心过程:采样->量化->编码
PCM关键要素
- 采样率(Sample Rate):每秒采样的次数,常见的采样率有 44.1 kHz、48 kHz 等。
- 量化格式(Sample Format):每个采样点的位数,常见的量化格式有 16 位、24 位等。
- 声道数(Channels):音频信号的声道数,如单声道、立体声等。
PCM数据格式
-
存储格式
- 双声道:采样数据按LRLR方式存储,即左声道和右声道交替存储,存储的时候与字节序有关。
- 单声道:采样数据按时间顺序存储(有时也会采用LRLR方式,但另一个声道数据为0)。
-
存储格式分为
Packed
和Planner
两种,对于双通道音频,Packed
为两个声道的数据交错存储;Planner
为两个声道的数据分开存储。Packed
:LRLRLRPlanner
:LLLRRR
-
ffmpeg音频解码后的数据存放在AVFrame结构体中:
- Packed格式下,frame.data[0]存放所有声道的数据。
- Planner格式下,frame.data[i]存放第i个声道的数据。
- 左声道data[0]:LLLL…
- 右声道data[1]:RRRR…
-
Planner模式是ffmpeg内部存储模式,实际使用的音频文件都是Packed模式。
PCM计算
- 大小计算:以CD的音质为例:量化格式为16比特(2字节),采样率为44100,声道数为2。
- 比特率为:16 * 44100 * 2 = 1378.125 kbps
- 每秒存储空间:1378.125 * 60/8/1024 = 10.09MB
- ffmpeg提取pcm数据命令:
|
|
- ffplay播放pcm数据命令:
|
|
通过上述指令播放不成功的话,可以尝试转换PCM文件
|
|
流程
函数名 | 描述 |
---|---|
avformat_open_input() |
打开输入文件或流并读取头部信息。 |
avformat_find_stream_info() |
读取一些数据包以获取流信息。 |
av_find_best_stream() |
查找最佳流(音频、视频或字幕)。 |
avcodec_alloc_context3() |
分配解码器上下文。 |
avcodec_parameters_to_context() |
将流参数复制到解码器上下文中。 |
avcodec_find_decoder() |
查找合适的解码器。 |
avcodec_open2() |
打开解码器。 |
av_frame_alloc() |
分配AVFrame结构体。 |
av_samples_get_buffer_size() |
计算音频缓冲区的大小。 |
avcodec_fill_audio_frame() |
填充音频帧的缓冲区。 |
av_read_frame() |
从输入文件或流中读取数据包。 |
avcodec_send_packet() |
将数据包发送到解码器进行解码。 |
avcodec_receive_frame() |
从解码器接收解码后的帧。 |
代码
|
|
运行指令
|
|
音频编码
流程
函数名 | 描述 |
---|---|
av_frame_alloc |
分配一个AVFrame结构体 |
av_frame_get_buffer |
为AVFrame分配缓冲区 |
avcodec_find_encoder_by_name |
根据名称查找编码器 |
avcodec_alloc_context3 |
分配编码器上下文 |
avcodec_open2 |
打开编码器 |
avcodec_send_frame |
发送帧到编码器 |
avcodec_receive_packet |
从编码器接收编码后的数据包 |
运行指令
|
|
代码
|
|
指令
|
|
视频采集
视频采集命令
- 查看设备列表:
|
|
- 查看dshow支持的参数:
|
|
- 查看dshow支持的设备:
|
|
一般是Integrated Camera
,这是本地摄像头
- 采集摄像头画面:
|
|
播放摄像头采集画面:
|
|
流程
函数名 | 描述 |
---|---|
avdevice_register_all |
注册所有可用的设备 |
avformat_alloc_context |
分配格式上下文 |
av_dict_set |
设置字典选项 |
av_find_input_format |
查找输入格式 |
avformat_open_input |
打开输入文件 |
avformat_find_stream_info |
查找流信息 |
av_find_best_stream |
查找最佳流 |
avcodec_alloc_context3 |
分配编解码器上下文 |
avcode_parameters_to_context |
将参数复制到上下文 |
avcodec_find_decoder |
查找解码器 |
avcodec_open2 |
打开编解码器 |
av_read_frame |
读取帧 |
avcode_send_packet |
发送数据包 |
avcodec_receive_frame |
接收帧 |
颜色空间格式转换:
函数名 | 描述 |
---|---|
sws_getContext |
获取缩放上下文 |
av_frame_alloc |
分配帧 |
av_image_get_buffer_size |
获取图像缓冲区大小 |
av_malloc |
分配内存 |
av_image_fill_arrays |
填充图像数组 |
sws_scale |
缩放图像 |
先用ffmpeg指令试一下视频采集格式,后续代码写的时候要用对应采集的格式。
代码
|
|
音频采集
音频采集命令
采集麦克风声音:
|
|
播放麦克风采集:
|
|
流程
函数名 | 描述 |
---|---|
avdevice_register_all |
注册所有可用的设备 |
avformat_alloc_context |
分配格式上下文 |
av_dict_set |
设置字典选项 |
av_find_input_format |
查找输入格式 |
avformat_open_input |
打开输入文件 |
avformat_find_stream_info |
查找流信息 |
av_find_best_stream |
查找最佳流 |
avcodec_alloc_context3 |
分配编解码器上下文 |
avcode_parameters_to_context |
将参数复制到上下文 |
avcodec_find_decoder |
查找解码器 |
avcodec_open2 |
打开编解码器 |
av_read_frame |
读取帧 |
avcode_send_packet |
发送数据包 |
avcodec_receive_frame |
接收帧 |
代码
|
|
采集完后要用指令
|
|
才可以播放,可能是参数的不同