在 Linux 系统中使用 FFmpeg 的一些小招数。可以配合 shell 命令实现批量处理视频音频等。

  1. grep 抓取 ffmpeg 的标准输出。askubuntu
    (不知为何,ffmpeg 在终端输出的信息是标准错误,要重定向到标准输出才能用管道处理)

    $ ffmpeg -i file.mp4 2>&1 | grep Stream
    
  2. 去除视频中的多余音轨。stackexchange
    首先$ ffmpeg -i file.mp4查看文件流信息,可以看到“Stream #0:0”等等。把需要的流复制出来,合并好以后,原来的文件就可以删掉了

    $ ffmpeg -i file.mp4 -map 0:0 -map 0:2 -acodec copy -vcodec copy new.mp4
    
  3. ffmpeg 重新编码文件,修正视频音画不同步的问题,参考这里。其中-itsoffset写在0号文件之前,表明需要推迟的秒数,-map 0:0表示选择0号文件的0号流,-map 1:1类似。-acodec copy -vcodec copy也可缩写成-c:a copy -c:v copy。下面的例子表示把file.mp4的0号流(一般是视频流)推迟10秒输出为output.mp4文件

    $ ffmpeg -itsoffset 10.0 -i file.mp4 -i file.mp4 -map 0:0 -map 1:1 -acodec copy -vcodec copy output.mp4
    
  4. 从某一时间开始截取一段视频,同时转码后再与另一段音频文件合并成新文件。类似实例参考 surperuser
    -ss [HH:MM:SS]代表开始时间,-t表示截取长度(秒为单位,缺省时表示直到结束)。这两项写在-i选项之前,表示单独为某个流定义选取时间;写在后面表示统一选取时间。如果选择时间比较靠后,ffmpeg 会先定位,可能需要先等待一会。
    -c:v libx264表示用libx264编码器进行编码(运行ffmpeg -encoders查看可用的编码器)。

    $ ffmpeg -i video.webm -i audio.m4a -c:v libx264 -c:a copy -ss 21:00 new.mp4
    
  5. 将原始音频文件(没有任何头信息的 "raw bytes") 转换为普通音频文件。详情参考 ffmpeg 官方文档. 另外,VLC 可以用来直接播放这种 raw byte 音频vlc --demux=rawaud raw
    -f定义需要套用的格式,-ar采样频率,-ac频道数目。下面采用对齐的 32 位小端字节序,对 raw type 输入进行采样,采样率 44.1KHz,输出单个频道,输出为 .mp3 文件。

    $ ffmpeg -f s32le -ar 44.1k -ac 1 raw output.mp3
    
  6. 配合 imagemagick 制作鬼畜 GIF,参考 askubuntu。先用 ffmpeg 采样原视频,输出一组关键帧,-r 代表采样率 FPS,然后用 imagemagick 按一定帧率合并成 GIF,-loop 0 代表无限循环,-delay 为每帧间隔时间,换算关系为

    1 = 100 fps
    2 = 50 fps
    4 = 25 fps
    10 = 10 fps ...

    $ ffmpeg -i video.mp4  -r 5 'frames/frame-%03d.jpg'
    $ cd frames
    $ convert -delay 20 -loop 0 *.jpg myimage.gif
    

    小技巧:建议不要使用 100 fps 进行合并,50 fps 已足够鬼畜,超出 60 fps 后某些应用会进行重采样,导致实际 fps 低于 30 fps。如果生成 GIF 过大,可以考虑降低采样率,或者用 gifsicle 等进一步压缩(imagemagick 的图像压缩是屎,越压越大)