ffmpeg的使用

2020/02/11 影音 共 3912 字,约 12 分钟
Bob.Zhu

查看详情信息

使用ffmpeg简单分析视频源,基本信息包括分辨率、帧率、码率这几个关键数据,参考信息包括文件格式、编码格式、像素格式等。

ffmpeg -i input.mp4

视频基本信息

可以看到分辨率是1080x1928,帧率是30fps,码率是13095kbps,文件就是mp4,编码格式是h264(main),像素格式yuv420p;文件时长00:01:10.1,1分10秒;按这个码率,视频部分尺寸是13095x70=916650kb,这里是bit位,换算大KB是114581.25,换算MB是约111.90MB。 我们简单评估一下对用户网络的要求,如果缓冲是500ms,那么13095x0.5=6547.5kb=818.4375KB=约0.8MB的下载速度,还是比较苛刻的,因为网络运营商给大家报的是kbps是小b,换算一下相当于要求6.4Mb。

基本信息脚本

resolution.sh

#!/bin/bash

# 指定的文件夹路径
dir_path=/Volumes/adolphor/Downloads

#常用的视频分辨率主要包括以下几种:
#- 480p:720x480,标清分辨率,常用于DVD视频和一些网络视频。
#- 720p:1280x720,高清分辨率,常用于高清电视和网络视频。
#- 1080p:1920x1080,全高清分辨率,常用于蓝光视频、高清电视和网络视频。
#- 2K:2048x1080,2K分辨率,常用于电影和一些高端视频制作。
#- 4K:3840x2160,4K分辨率,常用于超高清电视、电影和一些高端视频制作。

printf "%-13s %-12s %-14s <= %s\n" "分辨率" "帧率" "文件大小" "文件名"

# 使用find命令查找所有的视频文件
find "$dir_path" -type f \( -name "*.mp4" -o -name "*.avi" -o -name "*.mkv" \) -exec bash -c '
    file="$1"
    # 使用ffmpeg获取视频信息
    info=$(ffmpeg -i "$file" 2>&1)

    # 使用sed获取分辨率
    resolution=$(echo "$info" | sed -n "s/.*Video:.* \([0-9]*x[0-9]*\).*/\1/p")
    # 使用sed获取帧率
    fps=$(echo "$info" | sed -n "s/.*Video:.* \([0-9\.]* fps\).*/\1/p")
    # 使用du和awk获取文件大小
    size_in_kb=$(du -k "$file" | awk "{print \$1}")
    size_in_mb=$(printf "%.0f" $(echo "$size_in_kb/1024" | bc -l))

    # 打印文件名和分辨率
    # echo "$resolution, $fps, ${size_in_mb}MB<= $file"
    printf "%-10s %-10s %-10s <= %s\n" "$resolution" "$fps" "$size_in_mb MB" "$file"
' bash {} \;

视频压缩

ffmpeg -y -i xx.mp4 -c:a copy -c:v libx264 -profile:v high -r 30 -crf 30 -s 720x1080 -movflags +faststart xx-out.mp4
ffmpeg -y -i xx.mp4 -c:a copy -c:v libx264 -profile:v high -r 30 -crf 30 -vf scale=720x1080 -movflags +faststart xx-out.mp4

简单介绍参数:

  • -y:表示输出文件覆盖
  • -i:表示输入文件
  • -c:a:表示音频部分编码,copy表示直接复制到新文件
  • -c:v:表示视频部分编码,libx264表示使用h264编码
  • -profile:v:h264编码参数,使用更紧凑的压缩算法
  • -r:表示视频帧率,30fps
  • -crf:表示码率应用固定码率比,从0~500,值越大码率越低,一般18~32效果较好
  • -s:视频分辨率裁剪,720x1080表示裁剪成720p
  • -movflags +faststart:将MP4文件的moov原子(元数据)移动到文件的开头,边播放边下载

视频分辨率

-vf scale-s 都是ffmpeg中用于设置视频分辨率的选项,但它们的使用方式和上下文有所不同。 -vf scale是一个视频过滤器(Video Filter)选项,它允许你在一个复杂的过滤器链中使用,可以与其他过滤器一起使用。 例如,你可以在缩放视频后添加其他过滤器,如裁剪或旋转等。 使用-vf scale时,你需要指定宽度和高度,如-vf scale=1920:1080。
-s 选项是一个更简单的设置分辨率的方法,它直接设置输出视频的宽度和高度。例如,-s 1920x1080。 但是,-s选项不能与其他过滤器一起在同一过滤器链中使用。 总的来说,如果你只需要简单地改变视频的分辨率,-s选项可能更简单。 但是,如果你需要执行更复杂的视频处理任务,如缩放后的裁剪或旋转等,那么-vf scale将更有用。

元数据前置

-movflags +faststart是一个ffmpeg的选项,它的作用是将MP4文件的moov原子(元数据)移动到文件的开头。 在默认情况下,当ffmpeg生成MP4文件时,它会将moov原子放在文件的末尾。 moov原子包含了视频文件的关键信息,如时长、编码类型、帧率等。 因此,如果moov原子在文件的末尾,那么在视频文件完全下载之前,播放器无法开始播放视频。
-movflags +faststart选项就是用来解决这个问题的。它会将moov原子移动到文件的开头, 这样播放器在下载了文件的一小部分后就可以开始播放视频,而不需要等待整个文件下载完成。 这对于在线播放视频(如流媒体)非常有用,可以提高用户体验。

demo

# 2.1G
ffmpeg -i test.mp4
Stream #0:0[0x1](und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p(progressive), 1600x900, 1573 kb/s, 14.39 fps, 15 tbr, 15360 tbn (default)
# G
ffmpeg -y -i test.mp4 -c:a copy -c:v libx264 -profile:v high -movflags +faststart output1.mp4

# 24帧率大小
ffmpeg -y -i test.mp4 -c:a copy -c:v libx264 -profile:v high -r 24  -s 1920x1080 -movflags +faststart output.mp4
# 30帧率大小
ffmpeg -y -i test.mp4 -c:a copy -c:v libx264 -profile:v high -r 30  -s 1920x1080 -movflags +faststart output.mp4

生成gif

图片转gif

使用ffmpeg将png转为gif:

# 模糊匹配:增加 -pattern_type glob 参数,匹配非数字开头的图片名称 
# 第一步:生成调色板
ffmpeg -pattern_type glob -i '*.png' -vf palettegen palette.png
# 第二步:在生成动图时使用调色板
ffmpeg  -framerate 1 -pattern_type glob -i '*.png' -i palette.png -lavfi paletteuse out.gif

视频转gif

批量处理

macOS 批量处理

ffmpeg -i /Users/adolphor/Downloads/temp/视频.mov -vf scale=1920:1080 视频scale.mp4
ffmpeg -i /Users/adolphor/Downloads/temp/视频.mov -c:v libx264 -crf 30 -c:a aac -vf scale=1920:1080 视频scale.mp4
find ./ -name '*.mp4' -exec sh -c 'ffmpeg -i "$0" -c:v libx264 -crf 30 -c:a aac -vf scale=1920:1080 "${0%%.mp4}.small.mp4"' {} \;

Windows 批量处理

for %%i in (*.mp4) do ffmpeg -i "%%i" -c:v libx264 -crf 30 -c:a aac -vf scale=1920:1080 "%%i.small.mp4"

参考资料

文档信息

Search

    Table of Contents