Skip to content

Instantly share code, notes, and snippets.

@liveinstantly
Last active March 29, 2023 09:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save liveinstantly/adfdcdeb8ab2a4ecb7fe2b3844ef5cac to your computer and use it in GitHub Desktop.
Save liveinstantly/adfdcdeb8ab2a4ecb7fe2b3844ef5cac to your computer and use it in GitHub Desktop.
FFmpeg scripts: Multiple Bitrate transcoding for adaptive streaming with FFmpeg.
#!/bin/sh
#
# ffmpeg_abr_transcode.sh
# FFmpeg scripts: Multiple Bitrate transcoding for adaptive streaming with FFmpeg.
#
# (c) 2023 LiveInstantly, LLC. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# NOTE:
# - This script is fixed for 30fps input video.
# - 'High' profile video encoding is with 128kbps audio and other profiles are with 64kbps audio.
# - The encode spec file is as follows:
#
# The encode spec file is a text file with multiple lines, and each line must have 3 elements with comma-separated:
# video-width,video-hight,video-bitrate,vieo-profile
# An example of encode spec file (text file):
# 1920,1080,6000,high
# 1920,1080,4700,high
# 1280,720,3400,high
# 960,540,2250,main
# 960,540,1500,main
# 640,360,1000,main
# 640,360,650,main
# 320,180,400,baseline
#
file=$1
basename=$2
specfile=$3
print_usage() {
echo ""
echo "`basename $0`: ffmpeg GOP aligned encoding"
echo "Usage: `basename $0` [filename] [output file basename]"
echo " [filename]: Input video file path and name."
echo " [output file basename] Output base filename."
echo " [encode spec file] Encode Spec filename."
echo ""
exit 1
}
if [ "x$1" = "x" ]; then
echo "Error: No input video file path given."
print_usage
fi
if [ "x$2" = "x" ]; then
echo "Error: No output file basename given."
print_usage
fi
if [ "x$3" = "x" ]; then
echo "Error: No encode spec file given."
print_usage
fi
if [ ! -f "$3" ]; then
echo "Error: a given encode spec file not found."
print_usage
fi
options="ffmpeg -threads 0"
options="${options} -i ${file}"
options="${options} -pix_fmt yuv420p"
options="${options} -r 30"
count=0
while read line
do
width=`echo ${line} | sed 's/^\([^,]*\),\([^,]*\),\([^,]*\),\([^,]*\)$/\1/'`
height=`echo ${line} | sed 's/^\([^,]*\),\([^,]*\),\([^,]*\),\([^,]*\)$/\2/'`
bitrate=`echo ${line} | sed 's/^\([^,]*\),\([^,]*\),\([^,]*\),\([^,]*\)$/\3/'`
profile=`echo ${line} | sed 's/^\([^,]*\),\([^,]*\),\([^,]*\),\([^,]*\)$/\4/'`
bufsize=`expr ${bitrate} \* 2`
bitrate_str=`printf "%04d" ${bitrate}`
# Map for Video Encoding
options="${options} -map 0:v:0 -c:v libx264"
options="${options} -preset medium -tune film"
options="${options} -b:v ${bitrate}k -profile:v ${profile}"
options="${options} -minrate:v ${bitrate}k"
options="${options} -maxrate:v ${bitrate}k"
options="${options} -bufsize:v ${bufsize}k"
options="${options} -vf:v scale=${width}:${height}"
options="${options} -g 60 -x264opts no-scenecut -sc_threshold 0 -vsync 1"
#options="${options} -g 60 -x264opts keyint=60:keyint_min=60:no-scenecut -sc_threshold 0 -vsync 1"
options="${options} -map 0:a:0 -c:a aac"
if [ "x${profile}" = "xhigh" ]; then
options="${options} -b:a 128k -ac:a 2 -ar:a 48000"
else
options="${options} -b:a 64k -ac:a 2 -ar:a 48000"
fi
options="${options} -af:a aresample=async=1:min_hard_comp=0.100000:first_pts=0"
options="${options} ${basename}_${bitrate_str}_${width}x${height}.mp4"
count=`expr ${count} \+ 1`
done < $3
echo ${options}
exec ${options}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment