Tuesday, July 29, 2008

AVI to ISO/DVD

A while back I downloaded Elephants dream, and, having watched it, decided to put it on a DVD. Being a weird bloke that I am, I decided I need to do it via the command line...

I generally have no truck with all that messy part of life having to do with codecs and stuff, so I wanted to do something (more or less) simplistic, where I just put in the name of file and go.

I didn't test this extensively and can't guarantee anything. In fact, I'm not so sure about the ISO generation at the moment and will no doubt spend some more time poking at it...

But, at the moment, here it is.
1  #!/bin/bash
2  #
3  # AVI to ISO/DVD 
4  #
5  # Convert a AVI movie into a burn-ready ISO image, or even burn straight onto 
6  # DVD
7  #
8  # Potential issues:
9  #   This script will overwrite existing files,
10 #   It uses a lot of disk space.
11 # Parameters:
12 #   -a | --ac3-present - assume sound is already ac3 and skip 
13 #               audio conversion (otherwise convert audio too)
14 #   -b | --burn-dvd - output the converted data directly to dvd 
15 #               (default device: /dev/dvdrw); optionally enter 
16 #               device name (no spaces after the short switch)
17 #               (if this is not set simply generate an ISO image)
18 #   -c | --chapter-list - a string describing how the dvd should 
19 #               be divided into chapters (default: "0", 
20 #               example: "0,1:12,2:31,3:45,4:55,6:25,7:09,9:07,9:26")           
21 #   -d | --output-dir - a place to land generated files
22 #               (default: directory of the converted file)
23 #   --skip-encoding - skips encoding, if there is already an mpg file - 
24 #               used in testing.
25 #   --skip-cleanup - skips cleaning up: do not delete generated files - 
26 #               used in testing.
27 #   at least one path to an avi file to convert
28 # Examples:
29 #   (These two examples have different outcomes!)
30 #   avi_to_iso elephants_dream.avi              
31 #   avi_to_iso -a -b/dev/dvdrw -c "0,1:12,2:31,3:45,4:55,6:25,7:09,9:07,9:26"\
32 #               elephants_dream.avi
33 # Requires: 
34 #   mencoder    (http://www.mplayerhq.hu/)
35 #   dvdauthor   (http://dvdauthor.sourceforge.net/)
36 #   genisoimage and/or growisofs
37 # Author:
38 #   Konrad Siek
39 
40 #REGEX: "[0-9]{1,2}(,[0-9]{1,2}(:[0-9]{1,2}(:[0-9]{1,2})?)?)*"
41 
42 # Set default options
43 ac3_sound="false"
44 burn_dvd="false"
45 dvd_device="/dev/dvdrw"
46 chapter_list="0"
47 output_directory=""
48 skip_encoding="false"
49 skip_cleanup="false"
50 
51 # Converts a file into a DVD format
52 # @param $1: path
53 function convert_file {
54     # Strip extension from file
55     name=`basename $1 .avi`
56     basename=`basename $1`
57 
58     # Establish destination for converted file
59     if [ "$output_directory" == "" ]
60     then
61         destination=`dirname $1`
62     else
63         destination=$output_directory
64     fi
65 
66     echo "Convert file:"
67     echo -e "\t$1"
68     echo "into:"
69     echo -e "\t$destination/$name.mpg"
70 
71     # Encode video and, perhaps, audio, into mpeg2
72     # Ugh, crappy indentation...
73     if [ $skip_encoding = 'false' ] 
74     then
75         if [ $ac3_sound = 'true' ]
76         then 
77             mencoder \
78                 -oac copy -ovc lavc -of mpeg \
79                 -mpegopts format=dvd -vf scale=720:576,harddup \
80                 -lavcopts \
81                     vcodec=mpeg2video:\
82 vrc_buf_size=1835:\
83 vrc_maxrate=9800:\
84 vbitrate=5000:\
85 keyint=15:\
86 aspect=16/9 \
87                 -ofps 25 -o $destination/$name.mpg $1
88         else
89             mencoder \
90                 -oac lavc -ovc lavc -of mpeg \
91                 -mpegopts format=dvd -vf scale=720:576,harddup \
92                 -srate 48000 -af lavcresample=48000 \
93                 -lavcopts \
94                 vcodec=mpeg2video:\             
95 vrc_buf_size=1835:\
96 vrc_maxrate=9800:\
97 vbitrate=5000:\
98 keyint=15:\
99 aspect=16/9:\
100acodec=ac3:\
101abitrate=192 \
102                -ofps 25 -o $destination/$name.mpg $1 
103        fi
104
105        # Exit if anything went wrong
106        if [ $? != 0 ]
107        then
108            exit 1
109        fi            
110    fi
111
112    # Create a v. simple configuration XML file for dvdauthor
113    echo -e \
114    `echo "<dvdauthor>\n"
115     echo "\t<vmgm />\n"
116     echo "\t<titleset>\n"
117     echo "\t\t<titles>\n"
118     echo "\t\t\t<pgc>\n"
119     echo "\t\t\t<vob file=\"$destination/$name.mpg\" "
120     echo "chapters=\"$chapter_list\" />\n"
121     echo "\t\t\t</pgc>\n"
122     echo "\t\t</titles>\n"
123     echo "\t</titleset>\n"
124     echo "</dvdauthor>\n"` \
125    > $destination/$name.xml
126
127    # Create dvd structure
128    dvdauthor -o $destination/$name -x $destination/$name.xml
129
130    # Exit if anything went wrong
131    if [ $? != 0 ]
132    then
133        exit 1
134    fi
135    
136    # Create output
137    if [ $burn_dvd == "true" ] 
138    then
139        # Burn DVD
140        growisofs -dvd-compat -Z $dvd_device -dvd-video $destination/$name/
141    else
142        # Generate ISO image
143        genisoimage -dvd-video -o $destination/$name.iso $destination/$name
144    fi
145
146    if [ "$skip_cleanup" == "false" ]
147    then
148        # Clean up
149        rm $name.mpg
150        rm $name.xml
151        rm -r $name/
152    fi
153}
154
155# Main
156# Use getopt to parse command arguments.
157options=`getopt    -o ab::c:d: \
158    --long ac3-present,burn-dvd::,chapter-list:,output-dir:,skip-encoding,skip-cleanup \
159    -n $0 -- "$@"`
160
161# Proceed if everything is OK.
162if [ $? == 0 ] 
163then
164    # Set the parsed command options.
165    eval set -- "$options"
166
167    # Setup selected options
168    while true ; do
169        case "$1" in
170            -a|--ac3-present
171                # Assume AC3 sound in input file
172                ac3_sound="true"
173                shift 
174            ;;
175            -c|--chapter-list
176                # Set a chapter list
177                chapter_list=$2
178                shift 2 
179            ;;
180            -b|--burn-dvd)
181                # Burn DVD after convertion
182                burn_dvd="true"
183
184                # Optionally set DVD device
185                if [ $2 != "" ] 
186                then
187                    dvd_device=$2
188                fi
189                shift 2
190            ;;
191            -d|--output-dir)
192                # Set output directory
193                output_directory=$2
194                shift 2
195            ;;
196            --skip-encoding)
197                # Set skip encoding
198                skip_encoding="true"
199                shift
200            ;;
201            --skip-cleanup)
202                # Set skip cleanup
203                skip_cleanup="true"
204                shift
205            ;;
206            --) 
207                # Stop parsing options, continuie with the arguments
208                shift
209                break
210            ;;
211            *) 
212                # Weird error
213                echo "Something went horribly, horribly wrong in the interior."
214                exit 1 
215            ;;
216            esac
217    done
218
219    # Print settings
220    echo "Option summary:"
221    echo -e "\tac3_sound=$ac3_sound"
222    echo -e "\tburn_dvd=$burn_dvd"
223    echo -e "\tdvd_device=$dvd_device"
224    echo -e "\tchapter_list=$chapter_list"
225    echo -e "\toutput_directory=$output_directory"
226    echo -e "\tskip_encoding=$skip_encoding"
227
228    # Start converting...
229    for arg 
230    do 
231        convert_file $arg
232    done
233else
234    exit 1
235fi


The code is also available at GitHub as bash/avi_to_iso.

No comments: