3、ffmpeg系列学习——FFmpeg的音视频处理

  1. 音视频的采样率、采样位深度和声道数

音频和视频的采样率、采样位深度和声道数是媒体文件中的重要参数,它们会直接影响到音视频的质量和文件大小。下面对它们进行详细解释:

  • 采样率

采样率指音频每秒钟采样的次数,用赫兹(Hz)表示。采样率越高,音频的还原度越高,音质也越好,但同时文件大小也会增加。常见的采样率有44.1kHz、48kHz、96kHz等。

  • 采样位深度

采样位深度指音频采样时每个样本的位数,通常是8位、16位、24位、32位等。采样位深度越高,音频的动态范围越大,能表现更细腻的音频信息,但同时文件大小也会增加。

  • 声道数

声道数指音频的通道数量,常见的有单声道(mono)和立体声(stereo)两种。立体声一般包括左右两个声道,而单声道只有一个声道。通常来说,立体声能够更好地还原音频的空间感,但同时文件大小也会增加。

在处理音视频时,了解这些参数可以帮助我们更好地选择合适的参数进行处理,从而得到更高质量的音视频文件。

  1. 音频处理的常用命令

音频处理是 FFmpeg 的主要功能之一。以下是一些常用的音频处理命令:

  • 转换音频格式

将一个音频文件转换成另一个格式,可以使用下面的命令:

ffmpeg -i input.mp3 output.wav

上面的命令将 input.mp3 文件转换成 output.wav 文件。

  • 剪切音频

可以使用下面的命令剪切音频:

ffmpeg -ss 00:00:10 -i input.mp3 -t 10 output.mp3

上面的命令将 input.mp3 文件从第 10 秒开始剪切,长度为 10 秒,并将结果保存到 output.mp3 文件。

  • 合并音频

可以使用下面的命令合并多个音频文件:

ffmpeg -i "concat:input1.mp3|input2.mp3" -acodec copy output.mp3

上面的命令将 input1.mp3 和 input2.mp3 文件合并成一个 output.mp3 文件。

  • 调整音量

可以使用下面的命令调整音频的音量:

ffmpeg -i input.mp3 -filter:a "volume=2.0" output.mp3

上面的命令将 input.mp3 文件的音量调整为原来的两倍,并将结果保存到 output.mp3 文件。

  • 提取音频

可以使用下面的命令从视频中提取音频:

ffmpeg -i input.mp4 -vn -acodec copy output.mp3

上面的命令从 input.mp4 文件中提取音频,忽略视频,直接将音频保存到 output.mp3 文件。

  1. 视频处理的常用命令

视频处理是 FFmpeg 最常用的功能之一,以下是一些常用的视频处理命令:

  1. 视频转码命令

ffmpeg -i input.mp4 -vcodec copy -acodec copy output.avi

该命令将 input.mp4 转换为 output.avi,同时保留原有的视频和音频编码格式。

  1. 裁剪视频命令

ffmpeg -i input.mp4 -ss 00:00:05 -t 00:00:10 -c:v libx264 -c:a copy output.mp4

该命令将 input.mp4 的第 5 秒开始裁剪,裁剪 10 秒钟,视频编码为 H.264,音频保持原格式,输出为 output.mp4。

  1. 视频合并命令

ffmpeg -i "concat:input1.mp4|input2.mp4|input3.mp4" -c copy output.mp4

该命令将 input1.mp4、input2.mp4 和 input3.mp4 三个视频文件合并为一个文件 output.mp4,视频和音频编码格式保持不变。

  1. 添加水印命令

ffmpeg -i input.mp4 -i watermark.png -filter_complex "overlay=10:10" output.mp4

该命令将输入视频 input.mp4 和水印文件 watermark.png 进行叠加,叠加位置为视频左上角偏移 10 像素的位置,输出为 output.mp4。

  1. 提取视频帧命令

ffmpeg -i input.mp4 -vf "select=eq(n\,0)" -q:v 3 -f image2 output.jpg

该命令将输入视频 input.mp4 的第一帧提取出来,输出为 output.jpg,图像质量为 3。

  1. 音视频混合和分离

1、音视频混合

音视频混合是指将多个音频或视频文件混合成一个文件,或将音频和视频文件合并成一个视频文件。

合并视频文件

将多个视频文件合并成一个视频文件,可以使用 FFmpeg 中的 concat 协议。下面是一个例子,将三个视频文件 test1.mp4、test2.mp4 和 test3.mp4 合并成一个文件 output.mp4:

ffmpeg -i "concat:test1.mp4|test2.mp4|test3.mp4" -c copy output.mp4

其中,-i 参数指定输入文件,使用 concat 协议,参数为需要合并的文件列表,多个文件之间使用 | 分隔;-c copy 参数指定复制视频和音频流,不进行转码。

合并音频文件

将多个音频文件合并成一个音频文件,可以使用 FFmpeg 中的 concat 协议。下面是一个例子,将三个音频文件 test1.mp3、test2.mp3 和 test3.mp3 合并成一个文件 output.mp3:

ffmpeg -f concat -i <(for f in test1.mp3 test2.mp3 test3.mp3; do echo "file '$PWD/$f'"; done) -c copy output.mp3

其中,-f concat 指定使用 concat 协议,-i 参数指定输入文件,使用子进程的方式生成文件列表,-c copy 参数指定复制音频流,不进行转码。

合并音视频文件

将音频和视频文件合并成一个视频文件,可以使用 FFmpeg 中的 -map 选项。下面是一个例子,将 test.mp4 视频和 test.mp3 音频合并成一个视频文件 output.mp4:

ffmpeg -i test.mp4 -i test.mp3 -map 0:v:0 -map 1:a:0 -c:v copy -c:a copy output.mp4

其中,-i 参数指定输入文件,-map 选项指定需要使用的视频流和音频流,-c:v copy 和 -c:a copy 参数分别指定复制视频流和音频流,不进行转码。

2、音视频分离

音视频分离是指将一个音视频文件分离成音频文件和视频文件,可以分别对其进行处理或编辑。

分离视频文件

将视频文件分离成视频流和音频流,可以使用 FFmpeg 中的 -map 选项。下面是一个例子,将 test.mp4 分离成视频文件 test_video.mp4 和音频文件 test_audio.mp3:

ffmpeg -i test.mp4 -map 0:v:0 -c copy test_video.mp4 -map 0:a:0 -c copy test_audio.mp3

其中,-i 参数指定输入文件,-map 选项指定需要使用的视频流和音频流,-c copy 参数指定复制流,不进行转码。

分离音频文件

分离音频文件是指将音频流从视频文件中分离出来,生成一个单独的音频文件,可以方便地对音频进行编辑和处理。

ffmpeg -i input.mp4 -vn -acodec libmp3lame -q:a 4 output.mp3

其中,

-i input.mp4:指定输入文件名,这里是一个视频文件。

-vn:表示不处理视频流,只处理音频流。

-acodec copy:表示复制音频流,不进行重新编码。

-acodec libmp3lame:表示将音频流重新编码为MP3格式。

-q:a 4:表示指定输出音频的质量,值为0-9,数值越小,质量越好,文件大小越大。

output.aac:指定输出文件名,这里是一个AAC格式的音频文件。

  1. 音视频同步处理

音视频同步处理是指将音频和视频的时间轴进行同步,使其在播放过程中达到良好的效果。在实际应用中,由于采集设备、编码器、网络传输等因素的影响,音频和视频的时间轴往往会存在一定的偏差。因此,需要对音视频进行同步处理,以保证播放效果的质量。

在 FFmpeg 中,可以通过设置音频和视频的时间基(time base)和时间戳(timestamp)来实现音视频同步处理。

时间基是一种时间单位,用于将时间戳转换为实际的时间。在 FFmpeg 中,音频和视频的时间基可以通过音频流和视频流的 time_base 属性获取。时间戳则是指某个样本在整个媒体流中的时间位置,一般表示为 PTS(Presentation Time Stamp)或 DTS(Decode Time Stamp)。在 FFmpeg 中,可以通过 AVPacket 结构体中的 pts 和 dts 字段获取时间戳。

具体的音视频同步处理操作,可以参考以下步骤:

代码层面

  • 获取音频流和视频流的 time_base 属性,将其作为时间基。

AVRational audio_timebase = input_audio_stream->time_base;
AVRational video_timebase = input_video_stream->time_base;
  • 获取音频流和视频流的时钟基准值(时钟基准值指的是第一个样本的时间戳),分别保存为 audio_clock 和 video_clock 变量。

double audio_clock = 0;
double video_clock = 0;
AVPacket packet;
int ret;

// 读取音频流和视频流的样本
while ((ret = av_read_frame(input_format_context, &packet)) == 0) {
    if (packet.stream_index == audio_stream_index) {
        // 处理音频样本
        // ...
        audio_clock = av_q2d(audio_timebase) * frame->pts;
    } else if (packet.stream_index == video_stream_index) {
        // 处理视频样本
        // ...
        video_clock = av_q2d(video_timebase) * frame->pts;
    }

    av_packet_unref(&packet);
}
  • 计算音频和视频的时间差(diff),并根据时间差来调整音频和视频的时间戳。

double diff = video_clock - audio_clock;

if (diff > 0.1) {
    // 视频比音频快,需要将音频的时间戳加上时间差
    // ...
} else if (diff < -0.1) {
    // 音频比视频快,需要将视频的时间戳加上时间差
    // ...
}
  • 将调整后的音频样本和视频样本写入输出文件。

AVFrame *audio_frame;
AVFrame *video_frame;

// 循环处理音频样本和视频样本,并写入输出文件
while (has_more_audio_samples || has_more_video_samples) {
    if (has_more_audio_samples) {
        // 处理音频样本
        // ...
        av_interleaved_write_frame(output_format_context, &

命令行

  1. 根据时间戳对齐音视频

在进行音视频合并时,需要对齐音频和视频的时间戳,保证它们在相同的时间播放。可以通过使用FFmpeg的"-itsoffset"参数来实现对齐。该参数用于指定一个时间偏移量,可以正数或负数。正数表示音频比视频快,负数表示视频比音频快。例如:

ffmpeg -i video.mp4 -itsoffset 0.5 -i audio.mp3 -c:v copy -c:a copy output.mp4

上述命令中,将音频向后偏移0.5秒,使其与视频对齐。

  1. 调整音频速率

有时候,在进行音视频处理时,可能需要改变音频的播放速率。可以使用FFmpeg的"atempo"过滤器来实现调整音频速率。该过滤器接受一个浮点数参数,表示音频的播放速率。例如:

ffmpeg -i input.mp3 -filter:a "atempo=1.5" output.mp3

上述命令将音频播放速率提高到1.5倍。

  1. 调整音频音量

在进行音视频处理时,有时候需要调整音频的音量大小。可以使用FFmpeg的"volume"过滤器来实现调整音量大小。该过滤器接受一个浮点数参数,表示音频的音量大小。例如:

ffmpeg -i input.mp3 -filter:a "volume=2.0" output.mp3

上述命令将音频的音量调整为原来的2倍。

  1. 调整视频速率

类似于调整音频速率,有时候在进行音视频处理时,需要调整视频的播放速率。可以使用FFmpeg的"setpts"过滤器来实现调整视频速率。该过滤器接受一个时间参数,表示视频播放的速率。例如:

ffmpeg -i input.mp4 -filter:v "setpts=0.5*PTS" output.mp4

上述命令将视频的播放速率降低到原来的一半。

  1. 调整视频画面大小

在进行音视频处理时,有时候需要调整视频的画面大小。可以使用FFmpeg的"scale"过滤器来实现调整视频画面大小。该过滤器接受一个字符串参数,表示视频的宽度和高度。例如:

ffmpeg -i input.mp4 -vf scale=640:360 output.mp4

上述命令将视频的画面大小调整为640x360。

猜你喜欢

转载自blog.csdn.net/ayou_llf/article/details/129216950