ffmpeg学习笔记

📅 2026/6/24 9:14:51
ffmpeg学习笔记
peg是一款处理多媒体的瑞士军刀般的工具视频、音频、字幕都能处理解码、转码、合成、过滤视频压缩、转换视频比例、把视频解码成一张张的图片把图片编码为视频都是这款组件的常用功能这也是我目前了解到的一部分。它是由几个核心库构成的libavutil它是一个包含工具类方法的组件有随机数生成数据结构数学方法核心的多媒体的基础工具等。libavcodec音视频的解码和编码组件。libvformat包含分离视频中的视频流和音频流字幕流或者把不同的格式组合成一个多媒体文件的多媒体格式的组件。libavdevice一个包含从电脑里的音视频软件架构中抓取流或者把其他地方的流推送到这些音视频软件架构中去达到播放视频播放声音功能的组件。libavfilter一个过滤媒体的组件就相当于对解码好的每一帧数据进行再次加工比如对视频的每一帧进行美颜对声音进行调整添加特效的组件。libswscale一个高度优化的图像缩放和像素格式色彩空间转换操作的库。libswresample一个高度优化的音频重采样重矩阵化和样本格式转换操作的库补充说明声道音频设备采集到声音来源的位置和从音频设备播放出去的声音传播到哪个地方的位置。左声道设备模拟人的左耳朵听到的声音。右声道设备模拟人的右耳朵听到的声音。环绕声就是模拟人处在声音中间时听到的声音。采样率每秒对经过设备采集到的声音并经过信号模拟后的数据的采集次数这个信号模拟就跟声道模拟左声道右声道一样的意思。因为每次出现的声音它产生的那段对应的数据是连续的采样就是对这段连续时间发生的数据进行采集离散的样本数据这个离散就是时间点不连续可能在第1微秒出采集后接着跑到第10微秒出采集声音样本。为什么需要离散的采样而不是所有数据都抓取全部的模拟后的声音数据我认为是在模拟时同样一个音调在连续的时间里会产生有许多重复或相近人耳根本区分不了的数据这些数据丢弃不影响采集后人耳听到的声音的区别而且还能通过控制降低采样率减少音频所占用的磁盘空间。采样率越高同一时间声音样本信息就越丰富所以听到的声音和原生一样采样率越低声音失真就越严重但通常一般的采样率听不出区别。重采样就是对声音以新的采样率再次进行采样。重矩阵化不同的声道数是不同的矩阵的维度所以从矩阵就是用不同的声道数重新转换声音。ffmpeg 介绍ffmpeg [global_options] {[input_file_options] -i input_url} {[input_file_options] -i input2_url} ... {[output_file_options] output_url}{[output_file_options] output_url2} ...global_options全局可选命令作用到所有输入输出文件input_file_options 输入可选命令-i 指定输入文件input_url输入文件的路径或者网络urloutput_file_options输出可选命令output_url输出文件的路径或者网络urlffmpeg 可以读取任意数量的输入常规文件、管道、网络流从音视频设备抓取每一个输入用 -i区分比如 -i a.mp3,-i b.rmvb,它可以由任意数量的输出根据不同的路径名称来区分比如 output1.mp3,output2.mp4。因为元数据在解复用时会把数据分离成不同的基础流而又会在复用时又会合并在一起。如果不指定单独的基础流要怎么处理其内部自动会处理好这些对应关系。也可以手动用 -map 0:1可以表示选择第一个输入文件或输出文件的下标为1的基础流。输入的命令行的可选项是针对紧跟在它后面的输入文件对于输出文件也是一样的原则。所有输入文件放在最前面所有输出文件放在所有输入文件的后面。例子ffmpeg -i input.avi output.mp4 //格式自动转换 ffmpeg -i input.avi -b:v 64k -bufsize 64k output.mp4 //转换格式并且把视频比特率变成64kbit/s ffmpeg -i input.avi -r 24 output.mp4//格式转换改变视频帧率为24贞每秒 ffmpeg -r 1 -i input.m2v -r 24 output.mp4 //强制输入视频为1贞每秒仅原始格式的视频数据才有效输出文件为24贞每秒详细介绍ffmpeg在每使用一个 -i指令时会创建一个解复用的实例对象。这个解复用的作用是把一个视频里的视频流、音频流、字幕流把原始同一时间混合在一起的流分离成各自媒体数据的流以及其包含的基础属性数据和一些全局属性原始数据。ffmpeg的工作原理是建立一个转码管道。把从输入文件下载下来的数据块向水流一样在这个管道里流通而解复用就像分离不同大小硬币的设备区分不通过的流。就像下面这个图然后等区分完后会经过混合又形成一个整体的输出文件。Decoders解码器会接收把基础流打包好一块一块的根据流对应的数据格式打包的流然后经过解码器把这些流解码成原始的贞数据对于视频来说是像素数组集合对于音频来说是pcm格式的原始音频贞。对于 Loopback decoders 器解码器就是自身而其他解码器是和解复用的基础流有关系。Filtering过滤通道分为简单过滤-filter和复杂过滤filter_complex 简单过滤是从一个decoder那获取数据经过这个过滤后输出给一个输出的编码器复杂过滤通道是独立的能接收0个或多个不同的流然后内部又不同的过滤器和管道其后跟的输出流也又多个如下图从过滤通道出来的数据接着会被送入编码器编码器及能降低原来的音视频的质量同时也能增加音视频的质量但那样会增大数据量。经过编码器的数据会接着送入复用然后经过混合形成输出文件。Streamcopyffmpeg的管道最简单的是单流管道把一个视频分离成多个基础流并只提取其中一个流在不经过解码过滤或者编码直接copy到输出文件。这叫做single-stream streamcopy上述操作用命令表达ffmpeg -i INPUT.mkv -map 0:1 -c copy OUTPUT.mp4这里-map 0:1,是第0个的下标为1的基础流 -c copy 就是选择复制解码器这个管道的作用时改变基础流的数量因为没有解码再编码的过程所以速度很快。但可能不被一些容器支持肯定不会被过滤器支持因为过滤器需要解码而这个没有解码。应用举例ffmpeg -i INPUT0.mkv -i INPUT1.aac -map 0:0 -map 1:0 -c copy OUTPUT.mp4 //把0.mkv输入文件的第0个基础流和1.aac输入文件的第0个基础流合并到output.mp4Transcoding转码转码时把流解码后再编码它的代价比较大仅在需要过滤通道需要覆盖视频需要音频重采样或者把流输出到无法被原始编码器解码的输出文件里时需要用到它。如果把输入流原样输出或者输出的容器支持解码原始输入的流就不用这个转码ffmpeg 如果 不指定-c那么它会自动的用转码器。应用举例ffmpeg -i INPUT.mkv -map 0:v -map 0:a -c:v libx264 -c:a copy OUTPUT.mp4 //把第0个输入文件的视频流经过libx264转码把第0个输入文件的音频流原样复制最后合并输出的Output.mp4Filtering转码后的数据在编码前可以走过滤通道简单过滤通道他是线性的。复杂过滤通道不是线性的又0个或多个输入可以对应不同数量的输出。Loopback decoders是把经过编码后的数据在重新解码喂给过滤通道在处理。例子ffmpeg -i INPUT \ -map 0:v:0 -c:v libx264 -crf 45 -f null - \使用libx264转码 -threads 3 -dec 0:0 \编码后再解码 -filter_complex [0:v][dec:0]hstack[stack] \开了线程要按顺序输出流 -map [stack] -c:v ffv1 OUTPUT-map详解input file A.avistream 0: video 640x360stream 1: audio 2 channelsinput file B.mp4stream 0: video 1920x1080stream 1: audio 2 channelsstream 2: subtitles (text)stream 3: audio 5.1 channelsstream 4: subtitles (text)input file C.mkvstream 0: video 1280x720stream 1: audio 2 channelsstream 2: subtitles (image)ffmpeg -i A.avi -i B.mp4 out1.mkv out2.wav -map 1:a -c:a copy out3.mov-map 1:a 选第二个输入文件的最大索引的音频流-map 1:a:0选第二个输入文件的索引为0的音频流ffmpeg -i A.avi -i C.mkv -i B.mp4 -filter_complex overlay out1.mp4 out2.srt//overlay会自动选择前面两个输入的视频基础流而忽略B.mp4的视频流输出给out1.mp4然后虽然第二个输入有字幕流但它是图片格式的srt需要文字格式所以这里不选c.mkv的字幕 而是选择了b.mp4里的字幕输出到out2.srtffmpeg -i A.avi -i B.mp4 -i C.mkv -filter_complex [1:v]hues0,split2[outv1][outv2];overlay;aresample \ -map [outv1] -an out1.mp4 \ out2.mkv \ -map [outv2] -map 1:a:0 out3.mkv//[1:v]hues0,split2[outv1][outv2] 把第二个输入文件的视频流变成黑白后分成两个相同的输出outv1outv2-map [outv1] -an out1.mp4 把outv1禁用音频后输出给out1.mp4,out2.mkv里没有-map,是overlay把其余两个输入文件的两个视频流直接给到了out2.mkv-map [outv2] -map 1:a:0 out3.mkv 选择outv2输出流把第二个文件的第一个音频给到out3.mkv输出。主要的命令选项-f fmt (input/output)指定输入输出格式-i url (input)指定输入文件-y (global)默认覆盖输出文件-n (global)如果输出文件已存在则默认不会覆盖输出文件并且立即推出程序。-stream_loop number (input)设置输入流结束后再重复输入的次数0不重复 -1 无线循环重复输入。-recast_media (global)强制把解复用没有识别的媒体类型强制解码常用与被复用再一起的数据流的数据进行解码。-t duration (input/output)只读取 time duiration前的数据读取满了就停止读取-to position (input/output)针对输出文件输出文件超过 time duration 时就停止输出到文件。-fs limit_size (output)输出文件超过多少byte数据后就不再往输出文件输出了。sseof position (input)保留后相对与文件末尾流。position0表示整个文件都忽略。例如position-00:00:10表示保留视频结束前10秒的数据。-isync input_index 输入选项指定一个输入作为同步源。功能自动计算目标输入和参考输入之间起始时间的差值然后用这个差值来调整目标文件的时间戳从而实现同步。要求两个输入的时间戳应来自同一时钟源同步效果才好。注意input_index是 FFmpeg 赋予每个输入文件的索引号从0开始。如果同步源是自己或设置为 -1则不进行调整。用途高级同步功能比手动使用 -itsoffset更自动化但要求也更严格。-metadata[:metadata_specifier] keyvalue 输出选项基于元数据设置一个元数据键值对。功能为输出的媒体文件添加或修改元信息。 input_index 输入选项-timestamp date 输出选项设置容器内的录制时间戳。功能在输出的媒体文件容器中写入一个记录创建时间的元数据date。date​ 必须是日期格式例如 2023-10-27 12:00:00。这不会影响音视频内容只影响文件的元信息。-itsscale scale 输入选项基于流重新调整输入时间戳的缩放比例。功能将所有输入时间戳乘以 scale这个浮点数。用途主要用于处理异常的、非标准的时间基或时间戳。例如某些生成错误的文件可能需要通过此参数来修正播放速度。普通用户很少使用。itsoffset offset 输入选项设置输入时间偏移。功能为整个输入文件的时间戳增加一个 offset偏移量。效果指定一个正的偏移量意味着该输入的所有流音视频等都会被延迟指定的时间。常见用途在合并多个输入源时用于同步音视频。例如如果视频比音频快了2秒可以对视频输入使用 -itsoffset 2来将其延迟2秒使其与音频对齐。