批量 FFmpeg 编码 - 基于比特率的可变 CRF

批量 FFmpeg 编码 - 基于比特率的可变 CRF

我在运行 Ubuntu 的 VM 实例中使用 ffmpeg 将从各种流媒体网站下载的一些视频编码为 HEVC。目前,我使用 bash 脚本将目录中的所有这些文件转换。这些视频的总体比特率在 300 kb/s 到 1500 kb/s 之间变化。在我的测试中,对所有这些视频使用相同的 CRF,如果视频比特率高,则会产生更大的输出文件,如果比特率低,则会产生低质量视频。目前,我手动检查比特率并将相似比特率的文件移动到目录中,并每次相应地更改 CRF。这是我用来检索比特率的命令:

find . -name "*.mp4" -print0 | xargs -0 -i{} sh -c " echo -n '{} ' && ffmpeg -i '{}' 2>&1 | sed -n -e 's/^.*bitrate: //p' "

这是 bash 脚本。

#!/bin/bash -e
for i in ~/ffmpeg/*.mp4;    
do    
ffmpeg -i "$i" -c:v libx265 -crf 26 -c:a libopus -b:a 48k -vbr on -compression_level 10 -frame_duration 60 -application audio "${i%.*}.mkv"    
mv "${i%.*}.mkv" ~/ffmpeg/hevc    
rm -f -- "$i"    
done

如何在此 bash 脚本中根据比特率范围动态更改 CRF?例如,如果总体比特率高于 950 = crf 26,如果总体比特率在 750 到 949 之间 = crf 24,如果总体比特率在 500 到 749 之间 = crf 22,如果总体比特率低于 499 = crf 18。

答案1

这里是您的想法合并成一个脚本:

#!/bin/bash

# Script name: /usr/local/bin/ffscript.sh
# Usage:       go into the source directory and execute `ffscript.sh`  
                                                                                      
for file in *.mp4
do
        # Use command substitution `$()` in order to get the bit rate of the mp4 file as variable
        BIT_RATE=$(ffmpeg -i "$file" 2>&1 | sed -n -e 's/^.*bitrate: //p' | sed -r 's#([0-9]+)\skb/s#\1#')
        echo; echo "$BIT_RATE"

        SRC_FILE="$file"
        NEW_FILE="${file%.*}.mkv"

        if   (( BIT_RATE > 950 )); then CFR='26'
        elif (( BIT_RATE > 750 )); then CFR='24'
        elif (( BIT_RATE > 500 )); then CFR='22'
        else CFR='18'; fi

        echo "$CFR";

        # Remove the leading echo below in order to do the actions
        echo ffmpeg -i "$SRC_FILE" -c:v libx265 -crf "$CFR" -c:a libopus -b:a 48k -vbr on -compression_level 10 -frame_duration 60 -application audio "$NEW_FILE"
        echo mv "$NEW_FILE" ~/ffmpeg/hevc/
        echo rm -f -- "$SRC_FILE"
done

相关内容