TransWikia.com

Batch FFmpeg encoding - Variable CRF based on Bitrate

Ask Ubuntu Asked on December 10, 2021

I use ffmpeg in a VM instance running Ubuntu to encode some videos I downloaded from various streaming sites to HEVC. Currently I use a bash script to convert all these files in a directory. Overall Bitrate of these videos varies between 300 kb/s to 1500 kb/s. In my test using the same CRF for all these videos produced either bigger output file in the case of high bitrate videos or low quality video in the case of low bitrate. Currently I manually check the bitrate and move similar bitrate files to a directory and change CRF accordingly each and everytime. This is the command I use to retrieve the bitrate:

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

This is the bash script.

#!/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

How can I change the CRF dynamically based on a range of bitrates in this bash script? Like, if overall Bit Rate above 950 = crf 26, if Overall Bit Rate between 750 to 949 = crf 24, if Overall Bit Rate between 500 to 749 = crf 22, if overall Bit Rate below 499 = crf 18.

One Answer

Here is - your ideas combined into a single script:

#!/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

Answered by pa4080 on December 10, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP