admin管理员组

文章数量:1573363

最近做了许多有关音视频方面的工作,接触了一些不常用的命令,整理分享出来。

1.剪辑视频

ffmpeg -ss 1 -to 4 -accurate_seek -i input.mp4 -c:v copy output.mp4

指定从视频中的第1秒开始,到第4秒结束的部分剪辑。

  • ss:指定开始时间。
  • to:指定结束时间。如果换成 t,就是持续时间(1s + 4s)。
  • accurate_seek:时间定位时使用更精确的寻找方式。
  • 时间也可以使用时分秒的格式。例如"00:01:30"表示1分30秒。
  • 注意参数的顺序,不要把-i放在前面,否则会无效。

2.裁切视频

ffmpeg -i input.mp4 -vf "crop=w:h:x:y" output.mp4

裁切视频的指定区域。

  • 注意码率,可以添加-b:v指定。否则默认按200k处理。
  • crop=w:h:x:y:w和h分别表示裁剪后的宽度和高度,x和y表示裁剪的起始位置。比如一个1920x1080的视频,我需要裁切中间1080x1080的区域,那就是crop=1080:1080:420:0

3.去除绿幕并修改颜色

ffmpeg -i input.mp4 -vf "chromakey=#3fff08:0.1:0.04" -c:v qtrle -c:a copy output.mov
  • #3fff08是绿幕的颜色,也就是需要替换为透明的颜色。
  • 0.1是相似度(similarity)参数。这个参数决定了颜色匹配的严格程度。值越小,匹配的颜色范围越窄,也就是说,只有非常接近指定颜色的像素才会被视为透明。值越大,匹配的颜色范围越宽,也就是说,即使颜色和指定颜色有一些差距,也会被视为透明。
  • 0.04是混合度(blend)参数。这个参数决定了边缘像素的处理方式。值越小,边缘像素的处理越严格,可能会导致边缘部分出现锐利的边缘。值越大,边缘像素的处理越宽松,可能会导致边缘部分出现柔和的过渡。
ffmpeg -i output.mov -vf "color=color=#2B2D30:size=1920x1080 [bg]; [bg][0:v] overlay=shortest=1" output2.mp4
  • #2B2D30是需要修改的视频背景色。
  • 1920x1080是视频的分辨率,也就是给视频一个这么大的背景。

详细内容可以参看我的上篇博客:通过ffmpeg实现视频背景色替换

4.视频填充

ffmpeg -i input.mp4 -vf "scale=780:780:force_original_aspect_ratio=decrease,pad=1920:1920:(ow-iw)/2:(oh-ih)/2:color=#F5F5F5,setsar=1"
  • scale=780:780:表示对输入视频进行缩放操作,将视频的宽和高都缩放到780像素。
  • force_original_aspect_ratio=decrease:保持原始宽高比例。如果缩放后的视频超出了指定的尺寸,它会减少宽度或高度以保持宽高比,从而确保视频不会被拉伸。
  • pad=1920:1920:将视频填充到1920x1920的分辨率。
  • (ow-iw)/2:(oh-ih)/2:这些是填充的位置参数,表示填充的位置是在视频宽高的中心位置。ow,oh分别代表输出宽度和高度,iw,ih分别代表输入宽度和高度。你可以根据自己的情况计算。
  • color=#F5F5F5:填充的颜色。
  • setsar=1:它将视频的 SAR 设置为 1:1,有助于确保在不同的播放设备上视频的显示不会出现形变。

5.获取指定帧数图片

ffmpeg -i input.mp4 -vf "select='eq(n, N)'" -vframes 1 output_image.jpg
  • select='eq(n, N)':过滤器表达式,用于选择特定的帧数N。如果我们需要最后一帧,那就是总帧数-1。比如视频500帧,那就是select='eq(n,499)'
  • -vframes 1:指定处理的视频帧数为1帧。
  • 这种方式相较其他指定时间的方式更精准更灵活,可以获取更加准确的图像数据。只是需要预先知道视频的总帧数。

获取视频总帧数可以使用:

ffprobe -v error -select_streams v:0 -show_entries stream=nb_frames -of default=nokey=1:noprint_wrappers=1 input.mp4

6.图片合成视频

ffmpeg -loop 1 -i output_image.jpg -c:v libx264 -t 30 -pix_fmt yuv420p -vf "scale=1920:1080" -r 30 still_video.mp4
  • -loop 1:1表示启用循环。此时会无限循环图片。0的话就是一遍。
  • -c:v:指定视频编解码格式libx264。
  • -t:指定输出视频的时间。这里是30s。
  • -pix_fmt:指定像素格式yuv420p。
  • -vf "scale=1920:1080":将图片缩放到1920x1080像素的大小。如果原始图片的宽高比与1920x1080不同,那么图片将被拉伸以适应这个分辨率。
  • -r:指定帧数。这里是30帧。

7.指定固定码率(CBR)

或者说是静态码率。可以强行提升码率,比如上面图片生成的视频,可能结果就几十k的码率,如果想提高码率就可以使用此方法。

ffmpeg -i input.mp4 -b:v 2M -minrate 2M -maxrate 2M -bufsize 2M -nal-hrd cbr output.mp4
  • -b:v:设置视频的码率为2M。这是输出视频的平均码率。
  • -minrate 2M:设置视频的最小码率为2M。
  • -maxrate 2M:设置视频的最大码率为2M。
  • -bufsize 2M:设置编码器的缓冲区大小为2M。在CBR模式下,缓冲区大小通常设置为一个与码率相同的值,这有助于维持恒定的比特率输出。
  • -nal-hrd cbr:强制CBR模式。

输出码率结果会有一些偏差,但整体来说控制的不错。

8.保持音量 (24.04.07更新)

将单声道音频转换为双声道时(使用 -ac 2方式),会发现音量变小了,这可能是因为在混合过程中,默认的混合设置导致了音量的降低。这通常是为了防止在将多个声道混合到一起时可能出现的削峰(clipping)现象。

当单声道转换为双声道时,ffmpeg可能会将单声道信号分配到左右两个声道,并将每个声道的音量减半,以确保总的音量水平不会超过原始的单声道音量。这样做是为了避免在两个声道合并时可能出现的音量超过最大可接受水平(0 dBFS)的情况。

如果你想在转换为双声道时保持原始的音量水平,你可以使用ffmpeg的音频过滤器来调整音量。

ffmpeg -i input_mono.mp3 -af "pan=stereo|c0=c0|c1=c0" output_stereo.mp3
  • stereo:指定双声道
  • c0=c0:表示左声道(channel 0)接收原始单声道信号。
  • c1=c0:表示右声道(channel 1)也接收相同的单声道信号。

这样,原始的单声道信号就会被复制到两个声道,而不会减少音量。(本条解释来自chatgpt)


后面我也会持续补充,大家可以收藏起来,以备不时之需。

本文标签: 常用命令ffmpeg