Skip to content

Instantly share code, notes, and snippets.

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 dcpesses/801d038f600a04a668c5a9432f4504bd to your computer and use it in GitHub Desktop.
Save dcpesses/801d038f600a04a668c5a9432f4504bd to your computer and use it in GitHub Desktop.
A bash script to batch convert video files for chromecast compatibility
#! /bin/bash
# Batch Convert Script by StevenTrux
#
# Modified by Danny Pesses to handle filenames with spaces and display color highlighting
#
# The Purpose of this Script is to batch convert any video file to mp4 or mkv format for chromecast compatibility
# this script only convert necessary tracks if the video is already
# in H.264 format it won't convert it saving your time!
# Put all video files need to be converted in a folder!
# Variable used:
# outmode should be mp4 or mkv
# sourcedir is the directory where to be converted videos are
# indir is the directory where converted video will be created
# usage:
#########################
# cast.sh mp4 /home/user/divx /home/user/chromecastvideos
# or
# cast.sh mkv /home/user/divx /home/user/chromecastvideos
#########################
# working mode
outmode=$1
# check output mode
if [[ $outmode ]]; then
if [ $outmode = "mp4" ] || [ $outmode = "mkv" ]
then
echo -e "\033[1;34mWORKING MODE\033[0m $outmode"
else
echo -e "\033[1;31m$outmode is NOT a Correct target format. You need to set an output format! like cast.sh mp4 xxxx or cast.sh mkv xxxx\033[0m"
exit
fi
else
echo -e "\033[1;31mWorking mode is missing. You should set a correct target format like mp4 or mkv\033[0m"
exit
fi
# Source dir
sourcedir="$2"
if [[ $sourcedir ]]; then
echo -e "Using \033[1;34m$sourcedir\033[0m as Input Folder"
else
echo -e "\033[1;31mError: Check if you have set an input folder\033[0m"
exit
fi
# Target dir
indir="$3"
if [[ $indir ]]; then
if mkdir -p "$indir/castable"
then
echo -e "Using \033[1;34m$indir/castable\033[0m as Output Folder"
else
echo -e "\033[1;31mError: Check if you have the rights to write in $indir\033[0m"
exit
fi
else
echo -e "\033[1;31mError: Check if you have set an output folder\033[0m"
exit
fi
# set format
if [ $outmode=mp4 ]
then
outformat=mp4
else
outformat=matroska
fi
# Check FFMPEG Installation
if ffmpeg -formats > /dev/null 2>&1
then
ffversion=`ffmpeg -version 2> /dev/null | grep ffmpeg | sed -n 's/ffmpeg\s//p'`
echo -e "Your ffmpeg verson is \033[1;34m$ffversion\033[0m"
else
echo -e "\033[1;31mERROR: You need ffmpeg installed with x264 and libfdk_aac encoder\033[0m"
exit
fi
if ffmpeg -formats 2> /dev/null | grep "E mp4" > /dev/null
then
echo -e "Check mp4 container format ... \033[1;32mOK\033[0m"
else
echo -e "Check mp4 container format ... \033[1;31mNOK\033[0m"
exit
fi
if ffmpeg -formats 2> /dev/null | grep "E matroska" > /dev/null
then
echo -e "Check mkv container format ... \033[1;32mOK\033[0m"
else
echo -e "Check mkv container format ... \033[1;31mNOK\033[0m"
exit
fi
if ffmpeg -codecs 2> /dev/null | grep "libfdk_aac" > /dev/null
then
echo -e "Check AAC Audio Encoder ... \033[1;32mOK\033[0m"
else
echo -e "Check AAC Audio Encoder ... \033[1;31mNOK\033[0m"
exit
fi
if ffmpeg -codecs 2> /dev/null | grep "libx264" > /dev/null
then
echo -e "Check x264 the free H.264 Video Encoder ... \033[1;32mOK\033[0m"
else
echo -e "Check x264 the free H.264 Video Encoder ... \033[1;31mNOK\033[0m"
exit
fi
echo -e "\033[1;32mYour FFMpeg is OK; Entering File Processing\033[0m"
echo -e "\033[1;34m-------------------------------------------\033[0m"
################################################################
cd "$sourcedir"
# for filelist in `ls`
find . -print0 | while read -d $'\0' filelist
do
if [ ! -f "$filelist" ] #check if it's not a file
then
echo -e "\033[1;31mERROR File \"$filelist\" is NOT A FILE, skipping\033[0m"
continue
fi
if ffmpeg -i "$filelist" 2>&1 | grep 'Invalid data found' #check if it's video file
then
echo -e "\033[1;31mERROR File \"$filelist\" is NOT A VIDEO FILE can be converted!\033[0m"
continue
fi
if ffmpeg -i "$filelist" 2>&1 | grep Video: | grep h264 #check video codec
then
vcodec=copy
else
vcodec=libx264
fi
if ffmpeg -i "$filelist" 2>&1 | grep Video: | grep "High 10" #10 bit H.264 can't be played by Hardware.
then
vcodec=libx264
fi
if [ ffmpeg -i "$filelist" 2>&1 | grep Audio: | grep aac ] || [ ffmpeg -i "$filelist" 2>&1 | grep Audio: | grep mp3 ] #check audio codec
then
acodec=copy
else
acodec=libfdk_aac
fi
echo -e "\033[1;32mConverting \"$filelist\"\033[0m"
echo -e "Video codec: \033[1;34m$vcodec\033[0m Audio codec: \033[1;34m$acodec\033[0m Container: \033[1;34m$outformat\033[0m"
# using ffmpeg for real converting
echo -e "ffmpeg -i \"$filelist\" -y -f $outformat -acodec $acodec -ab 192k -ac 2 -absf aac_adtstoasc -async 1 -filter:v 'crop=ih/9*16:ih' -vcodec $vcodec -vsync 0 -profile:v main -level 3.1 -qmax 22 -qmin 20 -x264opts no-cabac:ref=2 -threads 0 \"$indir/castable/$filelist.$outmode\" < /dev/null"
ffmpeg -i "$filelist" -y -f $outformat -acodec $acodec -ab 192k -ac 2 -absf aac_adtstoasc -async 1 -filter:v 'crop=ih/9*16:ih' -vcodec $vcodec -vsync 0 -profile:v main -level 3.1 -qmax 22 -qmin 20 -x264opts no-cabac:ref=2 -threads 0 "$indir/castable/$filelist.$outmode" < /dev/null
done
echo ALL Processed!
###################
echo -e "\033[1;32mDONE, your video files are chromecast ready\033[0m"
exit
@AndriusWild
Copy link

Hello,
Could you explain the command line 121 please?
I thought find prints results by default so why would you need -print0
Also I tried to google on while read -d $'\0' argument but was not able to find what is that for

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment