I have a BASH script I downloaded (that works) to do some video conversions using handbrake-CLI but at the moment it only allows conversion from a single file format at a time avi to mkv only. I would like to be able to have it convert any type of input file (avi,wmv,flv...to mkv ) all at once instead of changing the script each time for each input format. How can I adjust the bash script to allow this?
So how can I get this bash script with the line input_file_type="avi" to work with input_file_type="avi,wmv,flv,mp4"
PS: I tried posting the bash script but the format got all messed up if someone knows how to post a bash script to the forum with correct formatting let me know I'll post it here instead of the link below
[http://pastebin.com/hzyxnsYY][1]
Paste the code here:
#!/bin/sh
###############################################################################
#
# Script to recursively search a directory and batch convert all files of a given
# file type into another file type via HandBrake conversion.
#
# To run in your environment set the variables:
# hbcli - Path to your HandBrakeCLI
#
# source_dir - Starting directory for recursive search
#
# input_file_type - Input file type to search for
#
# output_file_type - Output file type to convert into
#
#
# Change log:
# 2014-01-27: Initial release. Tested on ubuntu 13.10.
#
###############################################################################
hbcli=HandBrakeCLI
source_dir="/media/rt/1tera_ext/1_Video_Stuff/1 Documentary"
#source_dir="/media/rt/1tera_ext/1_Video_Stuff/1 Nova and bbc/Carbon diamonds"
input_file_type="avi"
output_file_type="mkv"
echo "# Using HandBrakeCLI at "$hbcli
echo "# Using source directory " "$source_dir"
echo "# Converting "$input_file_type" to "$output_file_type
# Convert from one file to another
convert() {
# The beginning part, echo "" | , is really important. Without that, HandBrake exits the while loop.
#echo "" | $hbcli -i "$1" -o "$2" --preset="Universal";
echo "" | $hbcli -i "$1" -t 1 --angle 1 -c 1 -o "$2" -f mkv --decomb --loose-anamorphic --modulus 2 -e x264 -q 20 --cfr -a 1,1 -E faac,copy:ac3 -6 dpl2,auto -R Auto,Auto -B 160,0 -D 0,0 --gain 0,0 --audio-fallback ffac3 --x264-profile=high --h264-level="4.1" --verbose=1
#echo "" | $hbcli -i "$1" -t 1 --angle 1 -c 1 -o "$2" -f mkv --decomb -w 640 --loose-anamorphic --modulus 2 -e x264 -q 20 --cfr -a 1,1 -E faac,copy:ac3 -6 dpl2,auto -R Auto,Auto -B 160,0 -D 0,0 --gain 0,0 --audio-fallback ffac3 --x264-profile=high --h264-level="4.1" --verbose=1
}
# Find the files and pipe the results into the read command. The read command properly handles spaces in directories and files names.
find "$source_dir" -name *.$input_file_type | while read in_file
do
echo "Processing…"
echo ">Input "$in_file
# Replace the file type
out_file=$(echo $in_file|sed "s/\(.*\.\)$input_file_type/\1$output_file_type/g")
echo ">Output "$out_file
# Convert the file
convert "$in_file" "$out_file"
if [ $? != 0 ]
then
echo "$in_file had problems" >> handbrake-errors.log
fi
echo ">Finished "$out_file "\n\n"
done
echo "DONE CONVERTING FILES"
Assuming the conversion command is the same for all file types, you can use a single find
like this:
find "$source_dir" -type f -regex ".*\.\(avi\|wmv\|flv\|mp4\)" -print0 | while IFS= read -r -d $'\0' in_file
do
done
Alternatively, create an array of file types that you are interested in and loop over them:
input_file_types=(avi wmv flv mp4)
# loop over the types and convert
for input_file_type in "${input_file_types[@]}"
do
find "$source_dir" -name "*.$input_file_type" -print0 | while IFS= read -r -d $'\0' in_file
do
done
done
In order to correctly handle filenames containing whitespace and newline characters, you should use null delimited output. That's what the -print0
and read -d $'\0'
is for.
You can use OR( -o
) operator in find
lane.
E.g.
find "$source_dir" -name *.avi -o -name *wmv -o -name *.flv -o -name *.mp4 | while read in_file
If run by bash:
#!/usr/bin/bash
input_file_type="avi|wmv|flv|mp4"
find "$source_dir" -type f|egrep "$input_file_type" | while read in_file
do
echo "Processing…"
echo ">Input "$in_file
# Replace the file type
out_file=$(in_file%.*}.${output_file_type} # replace file type with different command.
echo ">Output "$out_file
# Convert the file
convert "$in_file" "$out_file"
if [ $? != 0 ]
then
echo "$in_file had problems" >> handbrake-errors.log
fi
echo ">Finished "$out_file "\n\n"
done
Here's the final code that may help someone else, sorry about the link I didn't know how to paste bash script in here without the format getting all messed up
Link to the final code
#!/bin/bash
###############################################################################
#execute using bash mkvconv.sh
# Script to recursively search a directory and batch convert all files of a given
# file type into another file type via HandBrake conversion.
#
# To run in your environment set the variables:
# hbcli - Path to your HandBrakeCLI
#
# source_dir - Starting directory for recursive search
#
# input_file_types - Input file types to search for
#
# output_file_type - Output file type to convert into
#
#
# Change log:
# 2014-01-27: Initial release. Tested on ubuntu 13.10.
#http://stackoverflow.com/questions/21404059/bash-script-to-select-multiple-file-formats-at-once-for-encode-process/21404530#21404530
###############################################################################
hbcli=HandBrakeCLI
source_dir="/media/rt/1tera_ext/1_Video_Stuff/1 Nova and bbc/Carbon diamonds"
input_file_types=(avi wmv flv mp4 webm mov mpg)
output_file_type="mkv"
echo "# Using HandBrakeCLI at "$hbcli
echo "# Using source directory " "$source_dir"
echo "# Converting "$input_file_types" to "$output_file_type
# Convert from one file to another
convert() {
# The beginning part, echo "" | , is really important. Without that, HandBrake exits the while loop.
#echo "" | $hbcli -i "$1" -o "$2" --preset="Universal"; # dont use with preses things are left out
echo "" | $hbcli -i "$1" -t 1 --angle 1 -c 1 -o "$2" -f mkv --decomb --loose-anamorphic --modulus 2 -e x264 -q 20 --cfr -a 1,1 -E faac,copy:ac3 -6 dpl2,auto -R Auto,Auto -B 160,0 -D 0,0 --gain 0,0 --audio-fallback ffac3 --x264-profile=high --h264-level="4.1" --verbose=1
}
# loop over the types and convert
for input_file_types in "${input_file_types[@]}"
do
# Find the files and pipe the results into the read command. The read command properly handles spaces in directories and files names.
#find "$source_dir" -name *.$input_file_type | while read in_file
find "$source_dir" -name "*.$input_file_types" -print0 | while IFS= read -r -d $'\0' in_file
#In order to correctly handle filenames containing whitespace and newline characters, you should use null delimited output. That's what the -print0 and read -d $'\0' is for.
do
echo "Processing…"
echo ">Input "$in_file
# Replace the file type
out_file=$(echo $in_file|sed "s/\(.*\.\)$input_file_types/\1$output_file_type/g")
echo ">Output "$out_file
# Convert the file
convert "$in_file" "$out_file"
if [ $? != 0 ]
then
echo "$in_file had problems" >> handbrake-errors.log
fi
echo ">Finished "$out_file "\n\n"
done
done
echo "DONE CONVERTING FILES"