#!/bin/bash
# Name: podit
# Summary: iPod H264 640x480 video transcoder script
# Version: 1.1.4
# Date: 2009.10.12
# License: GPLv3+
# URL: http://slated.org/howto_transcode_h264_for_ipod_with_ffmpeg
# © Homer, 2007 - 2009
#
# Requires: ffmpeg
# Requires: gpac
# Requires: perl-DateManip
# These requirements are a guide only. As a minimum you'll
# need ffmpeg and MP4Box (from gpac). You could even get away
# without using MP4Box, although I doubt you will have iTunes
# compatible files (they'll still work with the iPod though).
# Any components you don't want to use (MP4Box, Perl-DateManip)
# will need to be edited/commented out of this script first.
###########################################################
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation, either version 3 of the License, or #
# (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
###########################################################
###########################################################
# Credits... #
# Forums: Doom9, Videohelp, and Ubuntu. #
# Mailing lists: MPlayer and ffmpeg. #
# Blogs: Everywhere. #
# #
# Special thanks to jdong on Ubuntu forums. #
# #
# Note 1: This script is *very* CPU intensive (slow), #
# and will probably melt your PC, but then again #
# it *does* produce incredibly high quality video #
# so IMHO it's worth it. YMMV. #
# #
# Note 2: Now uses MP4Box to "fix" the files for iTunes. #
# #
# Note 3: I've changed podit to work on a *copy* of the #
# original file, rather than directly on the #
# source, primarily because I was transcoding #
# over a network, and it just made more sense to #
# work on local copies. #
# #
###########################################################
################################
### User definable variables ###
###########################################################
# These are the only 4 prefs I would recommend you alter. #
###########################################################
# #
# framerate: e.g. (10, 15, 23.976, 25, 29.97, 30 = MAX) #
# A value of 0 will make the output file the same frame #
# -rate as the input file. #
# #
# framelimit: transcode only the first [n] frames. #
# (Good for testing.) A value of 0 disables this limit. #
# #
# resolution: 320x240 / 640x480 (4:3 aspect) #
# 320x176 / 640x352 (16:9 aspect) #
# Other resolutions are possible (untested). #
# #
# passes: 1 or 2 pass encoding. ffmpeg does not support #
# >2 passes, not that >2 passes is very useful anyway. #
# #
# NOTE: THIS SCRIPT CURRENTLY DOES *NO* ERROR CHECKING, #
# SO PLEASE USE SENSIBLE VALUES. #
# #
###########################################################
framerate=24
#최대 인코딩 시간
framelimit=300000
resolution="480x320"
passes=1
croptop_val=0
cropbottom_val=0
cropleft_val=0
cropright_val=0
video_bitrate="700k"
audio_bitrate="128k"
aspect_ratio="4:3"
while [ "$1" ]; do
########################
### Static variables ###
########################
infile="$1"
tmpdir="${HOME}/tmp"
############################
### transcoding function ###
############################
podenc () {
local passval=$1
if [ $passval -eq 0 ]
then
local passvar=""
else
local passvar="-pass $passval"
fi
if [ $passval -eq 1 ]
then
local audiovar="-an"
local outvar="/dev/null"
else
local audiovar="-acodec libfaac -ab $audio_bitrate -ar 48000 -ac 2"
local outvar="$tmpfile2"
fi
if [ $framelimit -eq 0 ]
then
local framesvar=""
else
local framesvar="-vframes $framelimit"
fi
if [ $framerate -eq 0 ]
then
local ratevar=""
else
local ratevar="-r $framerate"
fi
### You are not expected to understand this. I know *I* don't.
nice -n 19 ffmpeg -y $ratevar -i "$tmpfile1" $ratevar $framesvar \
-cropleft $cropleft_val -cropright $cropright_val \
-croptop $croptop_val -cropbottom $cropbottom_val \
-v 1 -vcodec libx264 -b $video_bitrate -bt 175k -refs 2 \
-deblockalpha 0 -deblockbeta 0 -flags +loop+slice \
-partitions +parti4x4+partp8x8+partb8x8 \
-me_method 8 -me_range 21 -subq 7 -cmp +chroma \
-bf 0 -level 13 -g 300 -keyint_min 30 -aspect $aspect_ratio \
-sc_threshold 40 -rc_eq 'blurCplx^(1-qComp)' -qcomp 0.7 \
-qmax 35 -qdiff 4 -i_qfactor 0.71428572 -b_qfactor 0.76923078 \
-maxrate 768k -bufsize 3000k -s $resolution -f mp4 \
$audiovar $passvar "$outvar"
exit_status=$?
}
########################################
###### Calculate transcoding time ######
########################################
transtime () {
local newdate=$1
local olddate=$2
local difftime=$(echo "${olddate} ${newdate}" | \
awk '{print "perl -MDate::Manip -e '\''$delta = DateCalc(""\""$1"\""",""\""$2"\""",\\$err,1); print $delta;'\''"}' | \
sh | sed -e s/^.//)
local diffyears=$(echo $difftime | cut -d':' -f1)
local diffmonths=$(echo $difftime | cut -d':' -f2)
local diffweeks=$(echo $difftime | cut -d':' -f3)
local diffdays=$(echo $difftime | cut -d':' -f4)
local diffhours=$(echo $difftime | cut -d':' -f5)
local diffminutes=$(echo $difftime | cut -d':' -f6)
local diffseconds=$(echo $difftime | cut -d':' -f7)
echo -ne "\033[1;31mTranscoding time: "
if [ "$diffyears" -ne 0 ]
then
echo -n "$diffyears Years, "
fi
if [ "$diffmonths" -ne 0 ]
then
echo -n "$diffmonths Months, "
fi
if [ "$diffweeks" -ne 0 ]
then
echo -n "$diffweeks Weeks, "
fi
if [ "$diffdays" -ne 0 ]
then
echo -n "$diffdays Days, "
fi
if [ "$diffhours" -ne 0 ]
then
echo -n "$diffhours Hours, "
fi
if [ "$diffminutes" -ne 0 ]
then
echo -n "$diffminutes Minutes, "
fi
echo -e "$diffseconds seconds.\033[0m"
}
##############################
###### Reverse a string ######
##############################
reverseit () {
local instring=$1
instring_length=$(echo -n "$instring" | wc -c)
reverse_string=
while [ $instring_length -gt 0 ]
do
reverse_string=${reverse_string}$(echo $instring | cut -c $instring_length)
let instring_length=instring_length-1
done
echo "$reverse_string"
}
##################################
###### Strip file extension ######
##################################
stripext () {
local instring=$1
#local revnoext_string=$(reverseit "$instring" | sed 's/^.*\.//')
#avi 확장자 제거
local revnoext_string=$(reverseit "$instring" | sed 's/.[aA][vV][iI]//g')
reverseit "$revnoext_string"
}
##################
###### Main ######
##################
outdir=$(find "$infile" -printf "%h")
base_name=$(basename "$infile")
barename=$(stripext "$base_name")
outfile="${outdir}/${barename}.podit.mp4"
tmpfile1="${tmpdir}/${base_name}"
tmpfile2="${tmpdir}/${barename}.podit.mp4"
tmpfile3="${tmpdir}/${barename}.podit.m4v"
clear
mkdir -p "$tmpdir"
if [ -e "$outfile" ]
then
echo -n "\"${outfile}\" already exists. Overwrite? (y/n): "
read answer
if [ "$answer" != "y" ]
then
echo "Transcoding aborted on user request."
exit 1
else
echo
fi
fi
count=1
while [ $count -lt 11 ]
do
let countdown=11-$count
let count=count+1
echo -n "Transcode will proceed in $countdown seconds."
sleep 1
echo -ne "\b \b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"
done
echo -ne " \b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"
rm -f "$tmpfile1" "$tmpfile2" "$tmpfile3" "$outfile"
echo "Copying \"${base_name}\" to \"${tmpdir}\""
rsync -v --progress "$infile" "$tmpfile1"
starttime=$(date +%Y%m%d%H:%M:%S)
echo
if [ "$passes" -eq 1 ]
then
podenc 0
else
podenc 1
podenc 2
fi
if [ "$exit_status" -ne 0 ]
then
echo "Something went wrong with ffmpeg."
echo "Please check the output and try again."
exit 1
fi
endtime=$(date +%Y%m%d%H:%M:%S)
echo
transtime $starttime $endtime
echo
echo "Removing temporary copy of source file."
rm -f "$tmpfile1"
echo
echo "Fixing transcoded file for iPod with MP4Box."
echo
MP4Box -ipod -add "$tmpfile2" "$tmpfile3"
if [ "$?" -ne 0 ]
then
echo "Something went wrong with MP4Box."
echo "Please check the output and try again."
exit 1
fi
echo
echo "Removing MP4Box's temporary source file."
rm -f "$tmpfile2"
echo
echo "Moving finished video to $outdir"
mv "$tmpfile3" "$outfile"
echo
echo -e "\033[1;31mJob \"${barename}\" completed successfully.\033[0m"
shift
done
exit 0