Last active
December 28, 2021 21:41
-
-
Save jshbrntt/0764f654ba992b663ee9 to your computer and use it in GitHub Desktop.
Script to convert videos to web compatible formats.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
printf "\e[1;36m\n\ | |
_ _ ____ _ \n\ | |
__ _(_) __| | ___ ___ ___|___ \__ _____| |__ \n\ | |
\ \ / / |/ _\` |/ _ \/ _ \/ __| __) \ \ /\ / / _ \ '_ \ \n\ | |
\ V /| | (_| | __/ (_) \__ \/ __/ \ V V / __/ |_) | \n\ | |
\_/ |_|\__,_|\___|\___/|___/_____| \_/\_/ \___|_.__/ \n\ | |
https://gist.github.com/joshua-barnett/0764f654ba992b663ee9\n\ | |
Usage: \n\ | |
$ ./videos2web.sh input_directory/ output_directory \e[m\\n" | |
if [ -z $1 ] | |
then | |
printf "\e[1;31mMissing input directory argument.\e[m\\n" | |
exit 0 | |
fi | |
if [ -z $2 ] | |
then | |
printf "\e[1;31mMissing output directory argument.\e[m\\n" | |
exit 0 | |
fi | |
input_directory=$1 | |
output_directory=$2 | |
if ! [ -d ${input_directory} ] | |
then | |
printf "\e[1;31mInvalid input directory argument.\e[m\\n" | |
exit 0 | |
fi | |
if ! [ -d ${output_directory} ] | |
then | |
printf "\e[1;31mInvalid output directory argument.\e[m\\n" | |
exit 0 | |
fi | |
loglevel=info | |
codecs=(libx264, libvpx, libtheora) | |
function encodeMP4 { | |
local filepath=$1 | |
local resolution=$2 | |
local output_directory=$3 | |
if ! [ -r ${filepath} ] | |
then | |
printf "\e[1;33mInput file either does not exist or isn't readable.\e[m\\n" | |
return | |
fi | |
if [ -z ${resolution} ] | |
then | |
printf "\e[1;33mNo resolution argument supplied.\e[m\\n" | |
return | |
fi | |
if ! [ -d ${output_directory} ] | |
then | |
mkdir -p ${output_directory} | |
printf "\e[1;33mCreated output directory.\e[m\\n" | |
fi | |
local file=${filepath##*/} | |
local filename=${file%.*} | |
case ${resolution} in | |
'360p') | |
local video_bitrate="500k" | |
local video_buffer_size="1000k" | |
local video_scale="640:360" | |
local audio_bitrate="128k" | |
;; | |
'480p') | |
local video_bitrate="1250k" | |
local video_buffer_size="2500k" | |
local video_scale="854:480" | |
local audio_bitrate="128k" | |
;; | |
'720p') | |
local video_bitrate="2500k" | |
local video_buffer_size="5000k" | |
local video_scale="1280:720" | |
local audio_bitrate="128k" | |
;; | |
*) | |
printf "\e[1;33mInvalid resolution must be 360p, 480p, or 720p.\e[m\\n" | |
return | |
;; | |
esac | |
local output_file="${output_directory}/${filename}_${resolution}.mp4" | |
if [ -a ${output_file} ] | |
then | |
printf "\e[1;33mOutput file already exists, delete '${output_file}' to re-encode.\e[m\\n" | |
return | |
fi | |
printf "\e[1;32mEncoding ${filepath} => ${output_file}:\n[vb: ${video_bitrate}, vbs: ${video_buffer_size}, vs: ${video_scale}, ab: ${audio_bitrate}]\e[m\\n" | |
ffmpeg -y -i "${filepath}" -codec:v libx264 -profile:v high422 -preset slow -b:v "${video_bitrate}" -maxrate "${video_bitrate}" -bufsize "${video_buffer_size}" -vf scale="${video_scale}" -threads 4 -pass 1 -an -f mp4 -f mp4 /dev/null -nostdin && \ | |
ffmpeg -i "${filepath}" -codec:v libx264 -profile:v high422 -preset slow -b:v "${video_bitrate}" -maxrate "${video_bitrate}" -bufsize "${video_buffer_size}" -vf scale="${video_scale}" -threads 4 -pass 2 -codec:a libfdk_aac -b:a "${audio_bitrate}" -movflags +faststart -f mp4 "${output_file}" -nostdin | |
} | |
function encodeOGV { | |
local filepath=$1 | |
local resolution=$2 | |
local output_directory=$3 | |
if ! [ -r ${filepath} ] | |
then | |
printf "\e[1;33mInput file either does not exist or isn't readable.\e[m\\n" | |
return | |
fi | |
if [ -z ${resolution} ] | |
then | |
printf "\e[1;33mNo resolution argument supplied.\e[m\\n" | |
return | |
fi | |
if ! [ -d ${output_directory} ] | |
then | |
mkdir -p ${output_directory} | |
printf "\e[1;33mCreated output directory.\e[m\\n" | |
fi | |
local file=${filepath##*/} | |
local filename=${file%.*} | |
case ${resolution} in | |
'360p') | |
local video_bitrate="500k" | |
local video_buffer_size="1000k" | |
local video_scale="640:360" | |
local audio_bitrate="128k" | |
;; | |
'480p') | |
local video_bitrate="1250k" | |
local video_buffer_size="2500k" | |
local video_scale="854:480" | |
local audio_bitrate="128k" | |
;; | |
'720p') | |
local video_bitrate="2500k" | |
local video_buffer_size="5000k" | |
local video_scale="1280:720" | |
local audio_bitrate="128k" | |
;; | |
*) | |
printf "\e[1;33mInvalid resolution must be 360p, 480p, or 720p.\e[m\\n" | |
return | |
;; | |
esac | |
local output_file="${output_directory}/${filename}_${resolution}.ogv" | |
if [ -a ${output_file} ] | |
then | |
printf "\e[1;33mOutput file already exists, delete '${output_file}' to re-encode.\e[m\\n" | |
return | |
fi | |
printf "\e[1;32mEncoding ${filepath} => ${output_file}:\n[vb: ${video_bitrate}, vbs: ${video_buffer_size}, vs: ${video_scale}, ab: ${audio_bitrate}]\e[m\\n" | |
ffmpeg -y -i "${filepath}" -codec:v libtheora -b:v "${video_bitrate}" -maxrate "${video_bitrate}" -bufsize "${video_buffer_size}" -vf scale="${video_scale}" -threads 4 -an -pass 1 -f ogg /dev/null -nostdin && \ | |
ffmpeg -i "${filepath}" -codec:v libtheora -b:v "${video_bitrate}" -maxrate "${video_bitrate}" -bufsize "${video_buffer_size}" -vf scale="${video_scale}" -threads 4 -codec:a libvorbis -b:a "${audio_bitrate}" -movflags +faststart -pass 2 -f ogg "${output_file}" -nostdin | |
} | |
function encodeWEBM { | |
local filepath=$1 | |
local resolution=$2 | |
local output_directory=$3 | |
if ! [ -r ${filepath} ] | |
then | |
printf "\e[1;33mInput file either does not exist or isn't readable.\e[m\\n" | |
return | |
fi | |
if [ -z ${resolution} ] | |
then | |
printf "\e[1;33mNo resolution argument supplied.\e[m\\n" | |
return | |
fi | |
if ! [ -d ${output_directory} ] | |
then | |
mkdir -p $output_directory | |
printf "\e[1;33mCreated output directory.\e[m\\n" | |
fi | |
local file=${filepath##*/} | |
local filename=${file%.*} | |
case ${resolution} in | |
'360p') | |
local video_bitrate="500k" | |
local video_buffer_size="1000k" | |
local video_scale="640:360" | |
local audio_bitrate="128k" | |
;; | |
'480p') | |
local video_bitrate="1250k" | |
local video_buffer_size="2500k" | |
local video_scale="854:480" | |
local audio_bitrate="128k" | |
;; | |
'720p') | |
local video_bitrate="2500k" | |
local video_buffer_size="5000k" | |
local video_scale="1280:720" | |
local audio_bitrate="128k" | |
;; | |
*) | |
printf "\e[1;33mInvalid resolution must be 360p, 480p, or 720p.\e[m\\n" | |
return | |
;; | |
esac | |
local output_file="${output_directory}/${filename}_${resolution}.webm" | |
if [ -a ${output_file} ] | |
then | |
printf "\e[1;33mOutput file already exists, delete '${output_file}' to re-encode.\e[m\\n" | |
return | |
fi | |
printf "\e[1;32mEncoding ${filepath} => ${output_file}:\n[vb: ${video_bitrate}, vbs: ${video_buffer_size}, vs: ${video_scale}, ab: ${audio_bitrate}]\e[m\\n" | |
ffmpeg -y -i "${filepath}" -codec:v libvpx -quality good -cpu-used 0 -b:v "${video_bitrate}" -qmin 10 -qmax 42 -maxrate "${video_bitrate}" -bufsize "${video_buffer_size}" -threads 4 -vf scale="${video_scale}" -an -pass 1 -f webm /dev/null -nostdin && \ | |
ffmpeg -i "${filepath}" -codec:v libvpx -quality good -cpu-used 0 -b:v "${video_bitrate}" -qmin 10 -qmax 42 -maxrate "${video_bitrate}" -bufsize "${video_buffer_size}" -threads 4 -vf scale="${video_scale}" -codec:a libvorbis -b:a "${audio_bitrate}" -pass 2 -f webm "${output_file}" -nostdin | |
} | |
find ${input_directory}/ -type f \( -name "*.mts" -o -name "*.mov" -o -name "*.mp4" \) | while read filepath; do | |
file=${filepath##*/} | |
filename=${file%.*} | |
# 360p | |
encodeOGV $filepath "360p" "${output_directory}/${filename}" | |
encodeMP4 $filepath "360p" "${output_directory}/${filename}" | |
encodeWEBM $filepath "360p" "${output_directory}/${filename}" | |
# 480p | |
encodeOGV $filepath "480p" "${output_directory}/${filename}" | |
encodeMP4 $filepath "480p" "${output_directory}/${filename}" | |
encodeWEBM $filepath "480p" "${output_directory}/${filename}" | |
# 720p | |
encodeOGV $filepath "720p" "${output_directory}/${filename}" | |
encodeMP4 $filepath "720p" "${output_directory}/${filename}" | |
encodeWEBM $filepath "720p" "${output_directory}/${filename}" | |
done | |
# Removing logs generated from 2 pass encoding. | |
find ${output_directory} -maxdepth 1 -type f -name "*.log*" -delete |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment