LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - General
User Name
Password
Linux - General This Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.

Notices


Reply
  Search this Thread
Old 04-28-2008, 06:06 PM   #1
frieza
Senior Member
 
Registered: Feb 2002
Location: harvard, il
Distribution: Ubuntu 11.4,DD-WRT micro plus ssh,lfs-6.6,Fedora 15,Fedora 16
Posts: 3,233

Rep: Reputation: 406Reputation: 406Reputation: 406Reputation: 406Reputation: 406
mass video conversion shell script


a shell script i wrote to convert a series of sequentially numbered movie files to DVD MPEG using mencoder, ffmpeg and DVDauthor
it even generates the .xml file for the dvd
(note the xml file generated has no menu and creates a dvd that loops indeffinately by returning to title 1 when it finishes with the last title)
it even burns the dvd (so have a blank in the drive before you start)
also it deletes the files as it goes including the original so either make sure to comment out the RM commnads or work on a copy of your files if you dont wanna lose the originals
anyways without furhter ado here it is
Code:
#initialize the variable to increment for the jump statement in the xml file
let y=1
#remove the old xml file
rm -f ../mpgs/naruto.xml
#generate the static part at the begining of the xml file
echo "<dvdauthor dest=\"DVD\">" > ../mpgs/naruto.xml
echo "	<vmgm />" >> ../mpgs/naruto.xml
echo "	<titleset>" >> ../mpgs/naruto.xml
echo "		<titles>" >> ../mpgs/naruto.xml
echo "			<video aspect=\"16:9\" format=\"ntsc\" widescreen=\"nopanscan\" />" >> ../mpgs/naruto.xml
#set the upper bounds for the jump statement to one higher then the number of the last title
a=$1
b=$2
let c=$b-$a
let z=$c+2 
#repeat from the first number until the second in sequence
for ((x=$1;x<=$2;x++))
do
#increment the jump variable
let y=$y+1
#if on the last title set it to jump to title 1 (loop the dvd)
if [ \"$y\" = \"$z\" ]
then 
let y=1
fi
#convert from divx to standard avi then remove the divx
mencoder -ovc lavc -oac lavc *_$x* -o episode$x.avi
rm -f *_$x*
#convert from avi to mpeg2 for dvd then remove the avi
ffmpeg -i episode$x.avi -target dvd ../mpgs/episode$x.mpg
rm -f episode$x.avi
#generate the title part of the xml file
echo "			<pgc>" >> ../mpgs/naruto.xml
echo "			<vob file=\"episode$x.mpg\" chapters=\"0,5:00,10:00,15:00,20:00,25:00\"/>" >> ../mpgs/naruto.xml
echo "				<post> jump title $y; </post>" >> ../mpgs/naruto.xml
echo "			</pgc>" >> ../mpgs/naruto.xml
done
#add the closing tags to the divx
echo "		</titles>" >> ../mpgs/naruto.xml
echo "	</titleset>" >> ../mpgs/naruto.xml
echo "</dvdauthor>" >> ../mpgs/naruto.xml
#switch to the mpgs directory
cd ../mpgs
#generate the raw DVD image from the mpgs
dvdauthor -x naruto.xml
#burn the dvd
growisofs -Z /dev/dvd -dvd-video DVD/
#clean up
rm -rf *.mpg
rm -rf DVD
 
Old 04-30-2008, 05:58 AM   #2
unSpawn
Moderator
 
Registered: May 2001
Posts: 29,415
Blog Entries: 55

Rep: Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600
Thanks for sharing. Some remarks if you don't mind. The script doesn't have a proper ending and a shebang line. The file locations are fixed ("naruto.xml") instead of user supplyable variables (using 'getopt' for instance) and the locations are relative ("../mpgs/"). For the echo parts, maybe use tabs (echo -en "\t\tsomething\n")? Before the next stage a test could be done if the input file exists and before removing files maybe check the exit status and break off in case of error? Also I'm wondering if the mencoder and ffmpeg commandlines need more arguments to get the best possible result? And is it necessary to do a two stage mencoder+ffmpeg? Doesn't recoding twice result in considerable degradation of quality?
 
Old 04-30-2008, 09:27 AM   #3
frieza
Senior Member
 
Registered: Feb 2002
Location: harvard, il
Distribution: Ubuntu 11.4,DD-WRT micro plus ssh,lfs-6.6,Fedora 15,Fedora 16
Posts: 3,233

Original Poster
Rep: Reputation: 406Reputation: 406Reputation: 406Reputation: 406Reputation: 406
well im still a relative noob at coding shell scripts. as for the mencoder/ffmpeg dual encode its because ffmpeg often choked on some of the source files.. if i new ffmpeg better it might not be necessary
as for the rm -rf i have been working on a copy so even if they do get deleted prematurely i just make a new copy but since the space on my main HD is limited i can only process so much at a time before i have to delete it so i built that into the automation
any suggestions as to how to make it better would be apprecaited..
i came up with the script because i have 270 some odd avis i want to convert and burn..
as for the location and xml file name being hard coded.. well thats not THAT hard i suppose to chande to suit ones needs
 
Old 04-30-2008, 02:26 PM   #4
frieza
Senior Member
 
Registered: Feb 2002
Location: harvard, il
Distribution: Ubuntu 11.4,DD-WRT micro plus ssh,lfs-6.6,Fedora 15,Fedora 16
Posts: 3,233

Original Poster
Rep: Reputation: 406Reputation: 406Reputation: 406Reputation: 406Reputation: 406
p.s. what do you mean by shebang line
and what WOULD a proper closing be?
edit: my inspiration came from the way a php script dynamically generates HTML tables.

Last edited by frieza; 04-30-2008 at 02:27 PM.
 
Old 04-30-2008, 02:43 PM   #5
unSpawn
Moderator
 
Registered: May 2001
Posts: 29,415
Blog Entries: 55

Rep: Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600
Well, your scripting isn't bad, didn't see any glaring mistakes. I suppose there are worse things to get inspiration from... The shebang line or hashbang is the first default line of a script:
Code:
#!/path/to/interpreter
. I learnt the single proper exit line goes
Code:
exit 0
because you would make the script break of and exit with another value to show errors. I'll not insult you by posting the BaSH scripting guide links :-]
 
Old 05-01-2008, 09:19 AM   #6
frieza
Senior Member
 
Registered: Feb 2002
Location: harvard, il
Distribution: Ubuntu 11.4,DD-WRT micro plus ssh,lfs-6.6,Fedora 15,Fedora 16
Posts: 3,233

Original Poster
Rep: Reputation: 406Reputation: 406Reputation: 406Reputation: 406Reputation: 406
thx, i knew i was missing something i just had forgotten what
at this stage id consider myself more of a hack then a hacker when it comes to shell scripting :P
as for the hard coded locations in the script, its all temporary anyways so i didnt figure it was much of a problem
although if i knew how i could have had it check for the presence of the folder and created it if it didn't exist, or just perform all the tasks in the same folder as the source files, it just seemed cleaner to have a separate directory to put the DVD mpegs and xml file, that's all, and the name of the xml file was picked because that was what I am working on, the actual name of the xml file is ultimately irrelivant tho it could have jest as easily ben a generic name like.. dvd.xml and it would have worked just as fine

Last edited by frieza; 05-01-2008 at 09:24 AM.
 
Old 05-01-2008, 11:12 AM   #7
unSpawn
Moderator
 
Registered: May 2001
Posts: 29,415
Blog Entries: 55

Rep: Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600
Quote:
Originally Posted by frieza View Post
at this stage id consider myself more of a hack then a hacker when it comes to shell scripting :P
Well, I'm not guru either. Deity knows there's many of these conversion scripts but since you posted your script here's my take on it. Hope it gives you some ideas though YMMV(VM):
Code:
#!/bin/sh
# Name restrictions.
declare -r static_char_restr="1234567890-_.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
# What we're called.
progn="${0}"; progn="${progn//*\//}"; progn=${progn%.sh}
# Check for dependencies.
for application in mencoder ffmpeg dvdauthor growisofs; do
        which "$application" >/dev/null 2>&1 || help a0 "$application"
done

help() { # Show help messages
case "$1" in s0) echo "\"${OPTARG}\" is a switch not a value.";; p0) echo "Need full path.";;
p1) echo "Need existing path.";; p2) echo "Missing "${SOURCEDIR}/mpg" path.";;
n0) echo "Not a valid name.";; n1) echo "Name too small.";; n2) echo "Name too large.";;
a0) echo ""$application" not found.";; c0) echo "Error. Stopped mencoder at "$2".";;
c1) echo "Error. Stopped ffmpeg at "$2".";; d0) echo "Could not cd";;
d1) echo "Error. Stopped at dvdauthor.";; d2) echo "Error. Stopped at growisofs.";;
*)  echo "${progn}: -s sourcedir -n projectname -e trackname -f first -l last";;
esac; exit 1; }

# Getopts: no option.
[ $# -eq 0 ] && help
# Getopts: help variant, unrecognised:
case "$1" in h|-help|--h|--help|help) help;; esac
# process options.
while getopts s:n:f:l:h OPT; do
        case "${OPT}" in
                s)      # Source dir and tests.
                        case "${OPTARG}" in -*) help s0;; esac
                        SOURCEDIR="${OPTARG}"
                        [ "${SOURCEDIR:0:1}" = "/" ] || help p0 # Relative path.
                        [ "${SOURCEDIR:0:1}" = "." ] || help p0 # Path malarky.
                        [ -d "${SOURCEDIR}" ] || help p1  # Unreal path
                        [ -d "${SOURCEDIR}/mpgs" ] || help p2 # Expect the "mpgs" sources in subdir
                        ;;
                n)      # Simple name of subject and tests.
                        case "${OPTARG}" in -*) help s0;; esac
                        TARGET="${OPTARG}"
                        [ -n ${TARGET//[$static_char_restr]/} ] && help n0 # Char restrictions in name.
                        [ ${#TARGET} -le 3 ] && help n1 # Name length.
                        [ ${#TARGET} -ge 32 ] && help n2 # Name length.
                        XML="${SOURCEDIR}/mpgs/${TARGET}.xml"
                        ;;
                f)      FIRST="${OPTARG}"
                        ;;
                l)      LAST="${OPTARG}"
                        ;;
                e)      TRACKNAME="${OPTARG}"
                        ;;
                h|*)
                        help
                        ;;
        esac
done

cd "${SOURCEDIR}" || help
mkdir -P mpgs/DVD || help
#initialize the variable to increment for the jump statement in the xml file
let y=1
#remove the old xml file
[ -f "${XML}" ] && rm -f "${XML}"
#generate the static part at the begining of the xml file
echo -en "<dvdauthor dest=\"DVD\">\n\t<vmgm />\n\t\t<titleset>\n\t\t\t<titles>\n" > "${XML}"
echo -en "\t\t\t\t<video aspect=\"16:9\" format=\"ntsc\" widescreen=\"nopanscan\" />\n" >> "${XML}"
#set the upper bounds for the jump statement to one higher then the number of the last title
a=$FIRST; b=$LAST; let c=$b-$a; let z=$c+2
#repeat from the first number until the second in sequence
for ((x=$1;x<=$2;x++)); do
        #increment the jump variable
        let y=$y+1
        #if on the last title set it to jump to title 1 (loop the dvd)
        if [ $y -eq $z ]; then
                let y=1
        fi
        echo "Start processing ${TRACKNAME}${x}."
        #convert from divx to standard avi then remove the divx
        mencoder -ovc lavc -oac lavc *_$x* -o "${TRACKNAME}${x}.avi"
        case "$?" in
                0) rm -f *_$x*;;
                *) help c0 "${TRACKNAME}${x}.avi";;
        esac
        #convert from avi to mpeg2 for dvd then remove the avi
        ffmpeg -i "${TRACKNAME}${x}.avi" -target dvd "mpgs/${TRACKNAME}${x}.mpg"
        case "$?" in
                0) rm -f "${TRACKNAME}${x}.avi";;
                *) help c1 "mpgs/${TRACKNAME}${x}.mpg";;
        esac
        #generate the title part of the xml file
        echo -en "\t\t\t\t<pgc>\n" >> "${XML}"
        echo -en "\t\t\t\t\t<vob file=\"${TRACKNAME}${x}.mpg\" chapters=\"0,5:00,10:00,15:00,20:00,25:00\"/>\n" >> "${XML}"
        echo -en "\t\t\t\t\t\t<post> jump title $y; </post>\n" >> "${XML}"
        echo -en "\t\t\t\t</pgc>\n" >> "${XML}"
        echo "Done processing ${TRACKNAME}${x}."
done
#add the closing tags to the divx
echo -en "\t\t\t</titles>\n\t\t</titleset>\n</dvdauthor>\n" >> "${XML}"
#switch to the mpgs directory
cd mpgs || help d0
#generate the raw DVD image from the mpgs
dvdauthor -x "${XML}" || help d1
#burn the dvd
growisofs -Z /dev/dvd -dvd-video DVD/ || help d2
#clean up
cd "${SOURCEDIR}" || help
rm -rf mpgs || help
exit 0
 
Old 05-01-2008, 01:50 PM   #8
beadyallen
Member
 
Registered: Mar 2008
Location: UK
Distribution: Fedora, Gentoo
Posts: 209

Rep: Reputation: 36
Maybe I'm missing something, but why are you first converting to standard mpeg4 with mencoder, then changing it again to mpeg2 with ffmpeg. My script (which doesn't do the dvdauthor.xml generation, since I like to use dvdstyler) just uses mencoder to do the mpeg2 conversion. Is there an advantage to doing it in two steps?

Anyway, here's my (very basic) script. I just feed it a list of avi files I want on a single DVD, and it converts to dvd compliant mpeg2. It doesn't generate the xml file for you, but it will max out the dvd bitrate. So it will fit 4, 5, 6 or more episodes onto a disc, changing the bitrate as required. It's two pass, both to improve quality, but mostly to get the bitrate control accurate.
Code:
#!/bin/bash

targetsize=4300
abitrate=192

totallen=0

for cur in $*
do
curlen=`midentify "${cur}" | grep 'ID_LENGTH=' | sed 's/ID_LENGTH\=//'`
totallen=$(( $totallen + ${curlen%.*} ))
done

vidlength=$totallen


audiosize=$(( $abitrate*1000*${vidlength%.*}/1024/1024/8 ))
videosize=$(( $targetsize-$audiosize ))

vidbitrate=$(( $videosize*1024*8/${vidlength} ))


echo "Length = $vidlength            Bitrate = $vidbitrate   :   Length = $vidlength"
echo "Audio Size = $audiosize         Video Size = $videosize "

for cur in $*
do
   mencoder $cur -passlogfile $cur.log -oac copy -ovc lavc \
-of mpeg -mpegopts format=dvd:tsaf -vf \
scale=720:-2,expand=720:576,harddup\
 -lavcopts vcodec=mpeg2video:vrc_buf_size=1835:vrc_maxrate=9000:\
vbitrate=${vidbitrate}:keyint=15:vstrict=1:vpass=1:turbo:\
threads=2 -passlogfile "${cur%.*}".log -ofps 25 -o /dev/null

   mencoder -passlogfile $cur.log -oac lavc -ovc lavc -of mpeg \
-mpegopts format=dvd:tsaf -vf scale=720:-2,expand=720:576,harddup \
-srate 48000 -af resample=48000:0:2 \
-lavcopts vcodec=mpeg2video:vrc_buf_size=1835:vrc_maxrate=7000:\
vbitrate=${vidbitrate}:keyint=15:vstrict=1:acodec=ac3:\
abitrate=${abitrate}:vpass=2:threads=2 \
-passlogfile ${cur%.*}.log -ofps 25 -o "${cur%.*}".mpg $cur

echo Done
rm "${cur%.*}".log
done
 
Old 05-01-2008, 02:27 PM   #9
frieza
Senior Member
 
Registered: Feb 2002
Location: harvard, il
Distribution: Ubuntu 11.4,DD-WRT micro plus ssh,lfs-6.6,Fedora 15,Fedora 16
Posts: 3,233

Original Poster
Rep: Reputation: 406Reputation: 406Reputation: 406Reputation: 406Reputation: 406
Quote:
Originally Posted by beadyallen
Maybe I'm missing something, but why are you first converting to standard mpeg4 with mencoder, then changing it again to mpeg2 with ffmpeg. My script (which doesn't do the dvdauthor.xml generation, since I like to use dvdstyler) just uses mencoder to do the mpeg2 conversion. Is there an advantage to doing it in two steps?
the 2 step conversion has more to do with my lack of experience and knowlege of the proper options of the programs in question (mencoder and ffmpeg) then anything
what i wrote was a quick and dirty solution by necessity from having 256 some odd divx files of approximately the same lenght to convert, thus albeit perhaps not the most efficient, certainly preferable to doing each and every individual file by hand.. then generating the xml file manually THEN mastering the dvd image by manually invoking dvdauthor THEN burning it by manually entering the growisofs command
at least now i can just give it say.. 6 files at a time and fill one dvd, come back put in another dvd and start with the next 6 and so on
in short, a quick and dirty hack to automate and simplify an otherwise monumental undertaking
p.s. those who have provided feedback, thanks, ill have to study them when i have the time so i can do the next something or other better the next time

Last edited by frieza; 05-01-2008 at 02:33 PM.
 
Old 05-01-2008, 03:02 PM   #10
beadyallen
Member
 
Registered: Mar 2008
Location: UK
Distribution: Fedora, Gentoo
Posts: 209

Rep: Reputation: 36
Quote:
in short, a quick and dirty hack to automate and simplify an otherwise monumental undertaking
That's the beauty of hacks . I do like the autogenerated xml config. I've previously used a script with sed to alter an already made up config file, filling in the relevant bits, but it's much nicer to build the whole thing as needed. Gives me some ideas to play with. Thanks.
 
Old 05-01-2008, 06:33 PM   #11
frieza
Senior Member
 
Registered: Feb 2002
Location: harvard, il
Distribution: Ubuntu 11.4,DD-WRT micro plus ssh,lfs-6.6,Fedora 15,Fedora 16
Posts: 3,233

Original Poster
Rep: Reputation: 406Reputation: 406Reputation: 406Reputation: 406Reputation: 406
Quote:
Originally Posted by beadyallen View Post
That's the beauty of hacks . I do like the autogenerated xml config. I've previously used a script with sed to alter an already made up config file, filling in the relevant bits, but it's much nicer to build the whole thing as needed. Gives me some ideas to play with. Thanks.
thats the exact reason i posted the script.. even if it doesn't get used as a whole, just offering a new way to look at a problem is enough
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
How to program shell script to automate mass user account creation? EsAsher Linux - General 2 06-30-2007 08:41 AM
Help needed on Mass user creation using shell script EsAsher Linux - General 3 06-29-2007 11:26 PM
shell script problem, want to use shell script auto update IP~! singying304 Programming 4 11-29-2005 05:32 PM
Get video DVD title string for shell script? cheesekeeper Linux - Hardware 9 05-05-2005 05:53 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - General

All times are GMT -5. The time now is 04:17 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration