日常的音视频剪辑通常只需要最简单的裁剪、转码,不需要做任何特效。这种情况下任何商用视频编辑软件都显得臃肿、低效。一行命令能解决的事情,为什么要在商业软件中加载无数插件、解码、渲染、编码…

ffmpeg号称A complete, cross-platform solution to record, convert and stream audio and video.相当强大。

去除视频中的音轨

1
for f in ./*.mp4; do ffmpeg -i "$f" -c copy -an "${f%.mp4}.silent.mp4"; done

视频变速

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

这个方法将视频中的时间轴x0.25,相当于加速了4倍。(注:音频速度不受影响)

制作gif图

将视频导出gif

1
ffmpeg -t 4.5 -i input.mp4 -vf "fps=15,scale=320:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" -loop 0 output.gif

将图片合成gif

1
ffmpeg -f image2 -framerate 9 -i image_%003d.png -vf output.gif

视频压缩

1
2
3
4
5
6
// 压缩码率(默认压缩比)
for f in ./*.MP4; do ffmpeg -i "$f" "${f%.MP4}_low_bit_rate.mp4"; done
// 压缩分辨率,如将4k视频压缩为1080p
for f in ./*.MP4; do ffmpeg -i "$f" -vf scale=1080:-2 "${f%.MP4}_1080p_preview.mp4"; done
// 也可以压缩图片
ffmpeg -i input.jpg -vf scale=320:-2 output_320.png

crop(裁剪像素尺寸)

1
ffmpeg -i in.mp4 -filter:v "crop=out_w:out_h:x:y" out.mp4

其中

  • out_w is the width of the output rectangle
  • out_h is the height of the output rectangle
  • x and y specify the top left corner of the output rectangle

trim(裁剪起止时间)

无损裁剪,非常快:

1
2
3
4
// 从01:19:27至02:18:51
ffmpeg -i input.mp4 -ss 01:19:27 -to 02:18:51 -c:v copy -c:a copy output.mp4
// 从1min:10sec开始,视频长度为1min5sec
ffmpeg -i input.mp4 -ss 00:01:10 -t 00:01:05 -c:v copy -c:a copy output.mp4

由于视频编码有关键帧的概念,并不是每一帧都保留完整的图像信息,因此精确的无损的按帧裁剪是不可能的。近似的按帧裁剪可以实现:

1
ffmpeg -ss 5.32 -i input.mp4 -c:v libx264 -c:a aac -frames:v 60 out.mp4

其中5.23为帧数除以fps,如视频从133帧开始,原始播放速度为25fps。

如果确实需要精确的按帧裁剪,可以用matlab或者Pr。

在视频下方标记帧数

1
2
3
ffmpeg -i input.MP4 -vf "drawtext=fontfile=Arial.ttf: text=%{n}: x=(w-tw)/2: y=h-(2*lh): fontcolor=white: box=1: boxcolor=0x00000099" -y output.mp4
// or
for f in $(find . -name "*.MP4"); do ffmpeg -i $f -vf "drawtext=fontfile=Arial.ttf: text=%{n}: x=(w-tw)/2: y=h-(2*lh): fontcolor=white: box=1: boxcolor=0x00000099" -y "${f%.MP4}_frame_labeled_preview.mp4"; done

连接视频

很多摄像机会在视频文件将要超过4GB时将文件分割,录制视频到下一个4GB以内的视频文件中。如果拍30分钟的4k视频,很容易就有几十GB的视频文件。通常我会将压缩后的视频文件们合成一个文件。

1
ffmpeg -f concat -safe 0 -i <(for f in ./*.MP4; do echo "file '$PWD/$f'"; done) -c copy output.MP4

视频消抖

环波导师的一个项目:http://public.hronopik.de/vid.stab/features.php?lang=en

1
2
3
// example
./ffmpeg/ffmpeg -i DSCN1274.MP4 -vf vidstabdetect=stepsize=32:shakiness=10:accuracy=10:result=transform_vectors.trf -f null -
./ffmpeg/ffmpeg -i DSCN1274.MP4 -vf vidstabtransform=input="transform_vectors.trf":zoom=1:smoothing=30,unsharp=5:5:0.8:3:3:0.4 -vcodec libx264 -preset slow -tune film -crf 18 -acodec copy "stabilized.mp4"

Stabilize plugin

Extracts relative transformations of subsequent frames (used for stabilization together with the transform filter in a second pass) Generates a file with relative transform information (translation, rotation) about subsequent frames.

Options:

  • ‘result’ path to the file used to write the transforms (def:inputfile.stab)
  • ‘shakiness’ how shaky is the video and how quick is the camera? 1: little (fast) 10: very strong/quick (slow) (def: 4)
  • ‘accuracy’ accuracy of detection process (>=shakiness) 1: low (fast) 15: high (slow) (def: 4)
  • ‘stepsize’ stepsize of search process, region around minimum is scanned with 1 pixel resolution (def: 6)
  • ‘algo’ 0: brute force (translation only); 1: small measurement fields (def)
  • ‘mincontrast’ below this contrast a field is discarded (0-1) (def: 0.3)
  • ‘tripod’ virtual tripod mode (if >0): motion is compared to a reference frame (frame # is the value) (def: 0) <— NEW
  • ‘show’ 0: draw nothing (def); 1,2: show fields and transforms in the resulting frames. Consider the ‘preview’ filter
  • ‘help’ print this help message

Transform plugin

Transforms each frame according to transformations given in an input file (e.g. translation, rotate). Reads a file with transform information for each frame and applies them.

Options

  • ‘input’ path to the file used to read the transforms (def: inputfile.stab)
  • ‘smoothing’ number of frames*2 + 1 used for lowpass filtering used for stabilizing (def: 10)
  • ‘maxshift’ maximal number of pixels to translate image (def: -1 no limit)
  • ‘maxangle’ maximal angle in rad to rotate image (def: -1 no limit)
  • ‘crop’ 0: keep border (def), 1: black background
  • ‘invert’ 1: invert transforms(def: 0)
  • ‘relative’ consider transforms as 0: absolute, 1: relative (def)
  • ‘zoom’ percentage to zoom >0: zoom in, <0 zoom out (def: 0)
  • ‘optzoom’ 0: nothing, 1: determine optimal zoom (def) i.e. no (or only little) border should be visible. Note that the value given at ‘zoom’ is added to the here calculated one
  • ‘interpol’ type of interpolation: 0: no interpolation, 1: linear (horizontal) (def), 2: bi-linear 3: quadratic
  • ‘sharpen’ amount of sharpening: 0: no sharpening (def: 0.8) uses filter unsharp with 5x5 matrix
  • ‘tripod’ virtual tripod mode (=relative=0:smoothing=0) <— NEW
  • ‘help’ print this help message