问题
前端在收到设计师的视频素材时直接使用?通常,设计师提供的视频都是高清的,我们可能只在界面上一个小地方使用,没必要1080*1920或4K。有时让设计师导出小一点,但依旧会很大。
分析
其实视频的大小无非跟3个因素有关:帧率/分辨率/码率。帧率就是每秒刷新的画面数量;分辨率不用说了,就是画面尺寸;码率是画面质量。
解决
用ffmpeg这个工具可以对视频的这三个参数进行调整,然后输出新的视频,以达到压缩视频的目的。这个方法比一般图形化的工具压缩好的地方是可以精细控制妥协哪一个参数。
比如,你这个视频素材在界面上只是很小的一块区域,没有全屏,就可以把分辨率减小;如果你的视频是一个PPT播放,那对刷新率要求不高,可以把正常的24fps减小到15fps以下。个人测试15fps是人眼可接受的动态画面最小刷新率了,再小的话动态画面会感觉不流畅。
使用一个简单的命令就可以做到。
ffmpeg -i in.mp4 -b:v 1M -r 15 -vf scale=1920:-1 out.mp4
-i in.mp4表示输入视频。-b:v 1M表示把视频的画面码率限制在1M以内。-b:a 128k表示限制音频码率,不过一般音频本来就不太占空间,可以省一点,意义不大。-r 15表示把帧率调整为15fps。-vf scale=1366:-1表示调整分辨率,横向改为1366,纵向等比缩放。out.mp4表示输出视频。
遇到一次压缩多个视频,上面的命令一次一次敲有点累。写了一个shell脚本给大家用:
#!/bin/bash
output_dir="compressed"
for file in $(find ./ -name "*.mp4" -or -name "*.webm"); do
width_height=$(ffprobe.exe -v error -select_streams v:0 -show_entries stream=width,height -of csv=p=0 ${file})
splitIndex=$(expr index ${width_height} ,)
width=${width_height:0:$(expr ${splitIndex} - 1)}
height=${width_height:${splitIndex}:$(expr ${#width_height} - ${splitIndex})}
mkdir -p ./${output_dir}/${file%/*}
if [ ${width} -gt 1920 -o ${height} -gt 1920 ]; then
if [ ${width} -gt ${height} ]; then
ffmpeg -i ${file} -b:v 1M -r 15 -vf scale=1920:-1 ./${output_dir}/${file}
else
ffmpeg -i ${file} -b:v 1M -r 15 -vf scale=-1:1920 ./${output_dir}/${file}
fi
else
ffmpeg -i ${file} -b:v 1M -r 15 ./${output_dir}/${file}
fi
done
其他逻辑不重要,只是找文件、查看文件宽高、创建输出文件夹等等操作。重要的就两行
中间的参数大家根据自己的需求改一下就好了。
Tip: Windows 用户执行不了这个shell,得装一个bash环境,推荐git bash,一般程序员电脑上本来就有这个东西。