1#!/usr/bin/perl -w 2 3package acidrip; 4require 5.000; 5use strict; 6use POSIX; #needed for floor() 7use AcidRip::interface; 8use AcidRip::signals; 9use AcidRip::messages; 10use Data::Dumper; 11use File::Basename; 12use Gtk2::Helper; 13 14sub gui_check ($) { 15 if (/SKIN/) { 16 my $msg = "You have set gui=yes in your config file. this is not a valid MPlayer option, only there for debugging. Remove it and use gmplayer instead for a gui!"; 17 message($msg); 18 print $msg . "\n"; 19 } 20} 21 22sub set_warning_text ($$) { 23 my $widget = shift; 24 my $warn = shift; 25 $widget->modify_text( 'normal', Gtk2::Gdk::Color->new( $warn * 65535, 0, 0 ) ); 26} 27 28sub hhmmss ($) { 29 my $s = shift; 30 my $m = floor $s / 60; 31 my $mins = $m % 60; 32 my $hour = floor $m / 60; 33 return sprintf( "%d:%02d:%02d", $hour, $mins, $s % 60 ); 34} 35 36sub split_track { 37 if ( defined $::dvd->{'track'} && defined get_track()->{'chapter'}) { 38 $::settings->{'blocks'} = undef; 39 $::settings->{'blocks'} = (); 40 my $start = $::settings->{'selected_chapters_start'} || 1; 41 my $stop = $::settings->{'selected_chapters_end'} || get_track()->{'chapter'}[-1]->{'ix'}; 42 my $total_length = get_selection_length(); 43 44 my $length = 0; 45 my $this_block = 1; 46 my $old_length = $length; 47 $::settings->{'blocks'}[0] = $start - 1; 48 49 foreach my $chapter ( $start .. $stop ) { 50 my $this_chapter = get_chapter($chapter); 51 my $target = $total_length * $this_block / $::settings->{'total_blocks'}; 52 $length += $this_chapter->{'length'}; 53 $::settings->{'blocks'}[$this_block] = $chapter; 54 $this_block++ if $old_length < $target && $length > $target; 55 $old_length = $length; 56 } 57 58 $::settings->{'UI'} && set_warning_text( $::widgets->{'total_blocks_spin'}, ( scalar @{ $::settings->{'blocks'} } ) - 1 < $::settings->{'total_blocks'} ? 1 : 0 ); 59 my $msg = "Blocks: "; 60 for ( 1 .. @{ $::settings->{'blocks'} } - 1 ) { 61 $msg .= " $_=[" . ( $::settings->{'blocks'}[ $_ - 1 ] + 1 ) . "-" . ( $::settings->{'blocks'}[$_] ) . "] "; 62 } 63 message($msg); 64 return @{ $::settings->{'blocks'} }; 65 } 66 elsif ( defined $::dvd->{'track'}) { 67 message("Can't split video files, only DVD's") if $::dvd->{'source'} eq 'file'; 68 message("Can't split track - No chapters on this DVD track") if $::dvd->{'source'} eq "dvd"; 69 } 70 else { 71 message("Can't split track - No DVD loaded!"); 72 } 73} 74 75sub converttoint { 76 my $total = 0; 77 my $i; 78 my $data = shift; 79 for ( $i = 0 ; $i < length($data) ; $i++ ) { 80 my $c = substr( $data, $i, 1 ); 81 my $value = 256**$i * ord($c); 82 $total += $value; 83 } 84 return $total; 85} 86 87sub get_track { 88 my $ix = shift || $::settings->{'selected_track'}; 89 return -1 if ! defined $::dvd->{'track'}; 90 return -1 if ! scalar @{$::dvd->{'track'}}; 91 92 foreach ( @{ $::dvd->{'track'} } ) { 93 return $_ if $ix == $_->{'ix'}; 94 } 95 return -1; 96} 97 98sub get_track_param ($) { 99 my $param = shift; 100 my $track = get_track(); 101 if (ref($track) eq 'HASH' and defined $track->{$param}) { 102 return $track->{$param} 103 } else { 104 return -1 105 } 106} 107 108sub get_audio { 109 my $ix = shift; 110 my $track = get_track( shift || $::settings->{'selected_track'} ); 111 foreach ( @{ $track->{'audio'} } ) { 112 return $_ if $ix == $_->{'ix'}; 113 } 114 return -1; 115} 116 117sub get_chapter { 118 my $ix = shift; 119 my $track = get_track( shift || $::settings->{'selected_track'} ); 120 foreach ( @{ $track->{'chapter'} } ) { 121 return $_ if $ix == $_->{'ix'}; 122 } 123 return -1; 124} 125 126sub get_cell { 127 my $ix = shift; 128 my $track = get_track( shift || $::settings->{'selected_track'} ); 129 foreach ( @{ $track->{'cell'} } ) { 130 return $_ if $ix == $_->{'ix'}; 131 } 132 return -1; 133} 134 135sub message { 136 my ( $data, $tag ) = @_; 137 138 if ( defined $::widgets ) { 139 my $context_id = $::widgets->{'status_bar'}->get_context_id('acidrip'); 140 $::widgets->{'status_bar'}->pop($context_id); 141 $::widgets->{'status_bar'}->push( $context_id, $data ); 142 my $iter = $::widgets->{'mencoder_output_text'}->get_buffer->get_end_iter; 143 if ($tag) { 144 $::widgets->{'mencoder_output_text'}->get_buffer->insert_with_tags_by_name( $iter, "AcidRip message - $data\n", $tag ); 145 } 146 else { 147 $::widgets->{'mencoder_output_text'}->get_buffer->insert( $iter, "AcidRip message - $data\n" ); 148 } 149 } 150 else { 151 print "AcidRip message - $data\n"; 152 } 153} 154 155sub load_settings_to_interface { 156 foreach my $value ( keys %{$::settings} ) { 157 $::widgets->{ $value . "_entry" }->set_text( $::settings->{$value} ) 158 if defined( $::widgets->{ $value . "_entry" } ) 159 and $value ne $::widgets->{ $value . "_entry" }->get_text; 160 $::widgets->{ $value . "_spin" }->set_value( $::settings->{$value} ) 161 if defined( $::widgets->{ $value . "_spin" } ) 162 and $value ne $::widgets->{ $value . "_spin" }->get_value_as_int; 163 $::widgets->{ $value . "_check" }->set_active( $::settings->{$value} ) 164 if defined( $::widgets->{ $value . "_check" } ); 165 $::widgets->{ $value . "_option" }->set_history( $::settings->{$value} ) 166 if ( $::settings->{$value} =~ /^\d+$/ ) 167 and defined( $::widgets->{ $value . "_option" } ); 168 } 169} 170 171sub set_setting ($$) { 172 my ( $name, $data ) = @_; 173 $::settings->{$name} = $data; 174 $::widgets->{ $name . "_entry" }->set_text($data) 175 if defined $::widgets->{ $name . "_entry" } and $data ne $::widgets->{ $name . "_entry" }->get_text; # and $::widgets->{$name . "_entry"}->get('editable'); 176 $::widgets->{ $name . "_spin" }->set_value($data) 177 if defined $::widgets->{ $name . "_spin" } and $data ne $::widgets->{ $name . "_spin" }->get_value; #and $::widgets->{$name . "_spin"}->get('editable'); 178} 179 180sub substitute_filename ($) { 181 my $filename = shift; 182 my $f = substr( $::settings->{'title'}, 0, 1 ); 183 $filename =~ s/%N/$::settings->{'selected_track'}/g; # track Number 184 $filename =~ s/%f/$f/g; # First letter of title 185 $filename =~ s/%T/$::settings->{'title'}/g; # Title 186 $filename =~ s/%L/$::settings->{'length'}/g; # Length 187 $filename =~ s/%b/$::settings->{'video_bitrate'}/g; # bitrate 188 $filename =~ s/%l/$::settings->{'language'}/g; # language 189 $filename =~ s/%w/$::settings->{'scale_width'}/g; # width 190 $filename =~ s/%h/$::settings->{'scale_height'}/g; # height 191 return $filename; 192} 193 194sub get_parameters { 195 split_track() if $::settings->{'total_blocks'} > 1; 196 set_bitrate() if $::settings->{'this_block'} > 0; 197 198 my %menc = (); 199 my $length = get_track()->{'length'}; 200 201 $menc{'video_options'} = $::settings->{'video_options'}; 202 $menc{'video'} = "-ovc $::settings->{'video_codec'}"; 203 204 $menc{'info'} = "-info srcform=\"DVD ripped by acidrip.sf.net\""; 205 $menc{'info'} .= ":name=\"$::settings->{'info_name'}\"" if defined $::settings->{'info_name'} && $::settings->{'info_name'} ne ''; 206 $menc{'info'} .= ":comment=\"$::settings->{'info_comment'}\"" if defined $::settings->{'info_comment'} && $::settings->{'info_comment'} ne ''; 207 $menc{'info'} .= ":artist=\"$::settings->{'info_artist'}\"" if defined $::settings->{'info_artist'} && $::settings->{'info_artist'} ne ''; 208 $menc{'info'} .= ":subject=\"$::settings->{'info_subject'}\"" if defined $::settings->{'info_subject'} && $::settings->{'info_subject'} ne ''; 209 $menc{'info'} .= ":genre=\"$::settings->{'info_genre'}\"" if defined $::settings->{'info_genre'} && $::settings->{'info_genre'} ne ''; 210 $menc{'info'} .= ":copyright=\"$::settings->{'info_copyright'}\"" if defined $::settings->{'info_copyright'} && $::settings->{'info_copyright'} ne ''; 211 212 if ( $::settings->{'video_codec'} eq 'lavc' ) { 213 $menc{'video'} = "-ovc lavc -lavcopts $::settings->{'lavc_options'}:vbitrate=$::settings->{'video_bitrate'}"; 214 $menc{'video'} .= ":vpass=$::settings->{'video_pass'}" if $::settings->{'video_passes'} > 1; 215 } 216 if ( $::settings->{'video_codec'} eq 'divx4' ) { 217 $menc{'video'} = "-ovc divx4 -divx4opts $::settings->{'divx4_options'}:br=$::settings->{'video_bitrate'}"; 218 $menc{'video'} .= ":pass=$::settings->{'video_pass'}" if $::settings->{'video_passes'} > 1; 219 } 220 if ( $::settings->{'video_codec'} eq 'xvid' ) { 221#---------------- 222#ORIGINAL $menc{'video'} = "-ovc xvid -xvidencopts $::settings->{'xvid_options'}:bitrate=$::settings->{'video_bitrate'}"; 223 $menc{'video'} = "-ovc xvid -xvidencopts "; 224 if ( $::settings->{'xvid_options'} eq '' ) 225 { 226 # my $msgaa = "AA You have no xvid_options set."; 227 # message($msgaa); 228 # print $msgaa . "\n"; 229 # my $msgbb = "BB You have no xvid_options set."; 230 # message($msgbb); 231 # print $msgbb . "\n"; 232 } 233 else 234 { 235 # my $msgaa = "AA You do have some xvid_options set."; 236 # message($msgaa); 237 # print $msgaa . "\n"; 238 # my $msgbb = "BB You do have some xvid_options set."; 239 # message($msgbb); 240 # print $msgbb . "\n"; 241 $menc{'video'} .= "$::settings->{'xvid_options'}:" ; 242 } 243 $menc{'video'} .= "bitrate=$::settings->{'video_bitrate'}"; 244 $menc{'video'} .= ":pass=$::settings->{'video_pass'}" if $::settings->{'video_passes'} > 1; 245 } 246 if ( $::settings->{'video_codec'} eq 'nuv' ) { 247 $menc{'video'} = "-ovc nuv -nuvopts $::settings->{'nuv_options'}"; 248 } 249 250 if ( $::dvd->{'source'} eq "dvd" ) { 251 $menc{'dvdplay'} = "dvd://$::settings->{'selected_track'}"; 252 $menc{'dvdplay'} .= " -dvd-device $::settings->{'dvd_device'}" if $::settings->{'dvd_device'} ne ''; 253 $menc{'dvdmenc'} = $menc{'dvdplay'}; 254 255 if ( $::settings->{'mplayer_version'} < 1 ) { 256 $menc{'dvdmenc'} = "-dvd $::settings->{'selected_track'}"; 257 $menc{'dvdmenc'} .= " -dvd-device $::settings->{'dvd_device'}" if $::settings->{'dvd_device'} ne ''; 258 } 259 if ( $::settings->{'mplayer_version'} < 0.9 ) { 260 $menc{'dvdplay'} = "-dvd $::settings->{'selected_track'}"; 261 $menc{'dvdplay'} .= " -dvd-device $::settings->{'dvd_device'}" if $::settings->{'dvd_device'} ne ''; 262 } 263 } 264 else { 265 $menc{'dvdplay'} = quotemeta( get_track()->{'filename'} ); 266 $menc{'dvdmenc'} = quotemeta( get_track()->{'filename'} ); 267 } 268 269 $menc{'audio_track'} = ''; 270 $menc{'audio_track'} = "-alang $::settings->{'language'}" if ( $::settings->{'selected_audio'} == -1 ); 271 $menc{'audio_track'} = "-nosound" if ( $::settings->{'selected_audio'} == -2 ); 272 $menc{'audio_track'} = join( " ", "-aid", $::settings->{'selected_audio'} + 127 ) if ( $::settings->{'selected_audio'} > 0 ); 273 274 $menc{'audio'} = "-oac $::settings->{'audio_codec'}"; 275 $menc{'audio'} .= " -lameopts $::settings->{'audio_mp3lame_options'}" if $::settings->{'audio_codec'} eq 'mp3lame'; 276 $menc{'audio'} .= " -lavcopts $::settings->{'audio_lavc_options'}" if $::settings->{'audio_codec'} eq 'lavc'; 277 $menc{'audio'} = '' if ( $::settings->{'selected_audio'} == -2 ); 278 279 $menc{'basename'} = substitute_filename( $::settings->{'filename'} ); 280 $menc{'basename'} = $menc{'basename'} . "-" . $::settings->{'this_block'} if $::settings->{'this_block'}; 281 282 $menc{'output'} = $::settings->{'video_pass'} == 1 ? "/dev/null" : $menc{'basename'} . ( $::settings->{'mpegfile'} ? ".mpg" : ".avi" ); 283 284 $menc{'af'} = $::settings->{'audio_gain'} == 0 ? "" : "-af volume=" . $::settings->{'audio_gain'} . ":sc"; 285 $menc{'af'} = '' if ( $::settings->{'selected_audio'} == -2 ); 286 287 $menc{'mpegfile'} = $::settings->{'mpegfile'} ? "-of mpeg" : ""; 288 289 $menc{'subp'} = $::settings->{'selected_subp'} > -1 ? "-sid " . ( $::settings->{'selected_subp'} - 1 ) : ""; 290 291 $menc{'subout'} = $::settings->{'vobsubout'} ? "-vobsubout $menc{'basename'}" : ""; 292 293 $menc{'scale'} = $::settings->{'scale_enable'} ? "scale=$::settings->{'scale_width'}:$::settings->{'scale_height'}" : ""; 294 295 $menc{'crop'} = 296 $::settings->{'crop_enable'} ? "crop=$::settings->{'crop_width'}:$::settings->{'crop_height'}:$::settings->{'crop_horizontal'}:$::settings->{'crop_vertical'}" : ''; 297 298 $menc{'vf'} = ( $::settings->{'mplayer_version'} < 1 ) ? "-vop" : "-vf"; 299 300 $menc{'vf_pre'} = $::settings->{'vf_pre'} if $::settings->{'vf_pre_enable'} && $::settings->{'vf_pre'} ne ''; 301 302 $menc{'vf_post'} = $::settings->{'vf_post'} if $::settings->{'vf_post_enable'} && $::settings->{'vf_post'} ne ''; 303 304 my $cw = $::settings->{'crop_width'} || get_track()->{'width'}; 305 my $ch = $::settings->{'crop_height'} || get_track()->{'height'}; 306 307 my @vfoptions; 308 if ( $::settings->{'mplayer_version'} < 1 ) { 309 push( @vfoptions, $menc{'vf_post'} ) if $menc{'vf_post'}; 310 push( @vfoptions, $menc{'scale'} ) if $menc{'scale'}; 311 push( @vfoptions, $menc{'crop'} ) if $menc{'crop'}; 312 push( @vfoptions, $menc{'vf_pre'} ) if $menc{'vf_pre'}; 313 314 $menc{'embed'} = 315 $::settings->{'embed_preview'} 316 ? " -vop scale=" . $::widgets->{'preview_socket'}->allocation->width . ":-2,$menc{'crop'} -wid " . $::widgets->{'preview_socket'}->get_id 317 : ( @vfoptions ? "$menc{'vf'} " . join( ",", @vfoptions ) : '' ); 318 } 319 else { 320 push( @vfoptions, $menc{'vf_pre'} ) if $menc{'vf_pre'}; 321 push( @vfoptions, $menc{'crop'} ) if $menc{'crop'}; 322 push( @vfoptions, $menc{'scale'} ) if $menc{'scale'}; 323 push( @vfoptions, $menc{'vf_post'} ) if $menc{'vf_post'}; 324 325 $menc{'crop'} .= "," if $menc{'crop'}; 326 327 $menc{'embed'} = 328 $::settings->{'embed_preview'} 329 ? " -vf $menc{'crop'}scale=" . $::widgets->{'preview_socket'}->allocation->width . ":-2 -wid " . $::widgets->{'preview_socket'}->get_id 330 : ( @vfoptions ? "$menc{'vf'} " . join( ",", @vfoptions ) : '' ); 331 } 332 333 $menc{'vf_filters'} = ($::settings->{'video_codec'} ne 'copy' && scalar(@vfoptions)) ? "$menc{'vf'} " . join( ",", @vfoptions ) : ""; 334 335 $menc{'chapter'} = ''; 336 if ( $::settings->{'total_blocks'} > 1 && $::settings->{'this_block'} > 0 && $::dvd->{'source'} eq "dvd") { 337 $menc{'chapter'} = "-chapter " . ( $::settings->{'blocks'}[ $::settings->{'this_block'} - 1 ] + 1 ) . "-" . $::settings->{'blocks'}[ $::settings->{'this_block'} ]; 338 $length = get_selection_length( $::settings->{'blocks'}[ $::settings->{'this_block'} - 1 ] + 1, $::settings->{'blocks'}[ $::settings->{'this_block'} ] ); 339 } 340 elsif ( $::settings->{'selected_chapters_start'} > 0 && $::settings->{'selected_chapters_end'} > 0 && $::dvd->{'source'} eq "dvd") { 341 $menc{'chapter'} = "-chapter $::settings->{'selected_chapters_start'}-$::settings->{'selected_chapters_end'}"; 342 $length = get_selection_length( $::settings->{'selected_chapters_start'}, $::settings->{'selected_chapters_end'} ); 343 } 344 345 my $frames = $::settings->{'ppc_bug'} ? 100 : 10; 346 my $sstep = "-sstep " . int $length / ( 3 * $frames ) + 1; 347 $sstep = "-ss " . int $length / 3 if $::settings->{'ppc_bug'}; 348 $menc{'frames'} = "-frames $frames $sstep"; 349 350 my $basename = basename substitute_filename( $::settings->{'filename'} ); 351 $menc{'cache'} = $::settings->{'cache_directory'} . "/" . $basename . "-cache"; 352 $menc{'cache'} = $::settings->{'cache_directory'} . "/" . $basename . "-" . $::settings->{'this_block'} . "-cache" if $::settings->{'this_block'}; 353 354 $menc{'more_options'} = $::settings->{'more_options'}; 355 356 return %menc; 357} 358 359sub get_command { 360 my $command = shift; 361 my %menc = get_parameters(); 362 363 return 364"$::settings->{'mencoder'} $menc{'cache'} $menc{'audio'} $menc{'audio_track'} $menc{'video'} $menc{'vf_filters'} $menc{'more_options'} $menc{'af'} $menc{'audio_track'} $menc{'mpegfile'} -o \"$menc{'output'}\"" 365 if $command eq "mencoder" && $::settings->{'cache'} && $::dvd->{'source'} eq "dvd"; 366 367 return 368"$::settings->{'mencoder'} $menc{'dvdmenc'} $menc{'chapter'} $menc{'audio_track'} $menc{'subp'} $menc{'subout'} $menc{'info'} $menc{'audio'} $menc{'af'} $menc{'video'} $menc{'vf_filters'} $menc{'mpegfile'} $menc{'more_options'} -o \"$menc{'output'}\"" 369 if $command eq "mencoder"; 370 371 return "$::settings->{'mplayer'} $menc{'dvdplay'} $menc{'audio_track'} $menc{'af'} $menc{'chapter'} $menc{'frames'} -nocache $menc{'embed'}" 372 if $command eq "preview" && $::settings->{'flickbook_preview'} && !$::settings->{'ppc_bug'}; 373 374 return "$::settings->{'mplayer'} $menc{'embed'} $menc{'dvdplay'} $menc{'af'} $menc{'audio_track'} $menc{'chapter'} $menc{'subp'} -nocache" 375 if $command eq "preview"; 376 377 return "$::settings->{'mplayer'} -quiet \"$menc{'output'}\"" 378 if $command eq "view"; 379 380 return "$::settings->{'mplayer'} $menc{'dvdplay'} $menc{'chapter'} -v -v -dumpstream -dumpfile \"$menc{'cache'}\"" 381 if $command eq "cache"; 382 383 return "$::settings->{'mplayer'} $menc{'vf'} cropdetect $menc{'dvdplay'} -nosound -vo null $menc{'frames'} -nocache" 384 if $command eq "cropdetect"; 385 386 return "$::settings->{'mencoder'} $menc{'cache'} $menc{'audio'} $menc{'audio_track'} $menc{'af'} -ovc frameno -o frameno.avi" 387 if $command eq "mencoder_frameno" && $::settings->{'cache'}; 388 389 return "$::settings->{'mencoder'} $menc{'dvdmenc'} $menc{'chapter'} $menc{'audio'} $menc{'audio_track'} $menc{'af'} -ovc frameno -o frameno.avi" 390 if $command eq "mencoder_frameno"; 391 392 return "$::settings->{'mencoder'} $menc{'cache'} -oac copy $menc{'video'} $menc{'vf_filters'} $menc{'more_options'} $menc{'audio_track'} $menc{'mpegfile'} -o \"$menc{'output'}\"" 393 if $command eq "mencoder_3pass" && $::settings->{'cache'}; 394 395 return 396"$::settings->{'mencoder'} $menc{'dvdmenc'} $menc{'chapter'} $menc{'subp'} $menc{'subout'} $menc{'info'} -oac copy $menc{'video'} $menc{'vf_filters'} $menc{'mpegfile'} $menc{'more_options'} -o \"$menc{'output'}\"" 397 if $command eq "mencoder_3pass"; 398 399 return "unlink \"$menc{'cache'}\"" if $command eq "del_cache"; 400 401 return "command not found!"; 402} 403 404sub set_bitrate { 405 return -1 if !defined $::dvd->{'track'}; 406 my $length; 407 my $size; 408 my $bitrate = 0; 409 my $audio_rate = 128; 410 my $this_track = get_track(); 411 412 if ( $::settings->{'audio_codec'} eq 'mp3lame' && $::settings->{'audio_mp3lame_options'} =~ /br=(\d+)/ ) { 413 $audio_rate = $1; 414 } 415 elsif ( $::settings->{'audio_codec'} eq 'lavc' && $::settings->{'audio_lavc_options'} =~ /abitrate=(\d+)/ ) { 416 $audio_rate = $1; 417 } 418 elsif ( $::settings->{'audio_codec'} eq 'copy' ) { 419 my $channels = $this_track->{'audio'}[ $::settings->{'selected_audio'} ]->{'channels'}; 420 $audio_rate = 192 if $channels == 2; 421 $audio_rate = 384 if $channels == 6; 422 } 423 424 if ( $::settings->{'this_block'} ) { 425 $length = get_selection_length( $::settings->{'blocks'}[ $::settings->{'this_block'} - 1 ] + 1, $::settings->{'blocks'}[ $::settings->{'this_block'} ] ); 426 $size = $::settings->{'filesize'}; 427 } 428 elsif ( $::settings->{'total_blocks'} > 1 ) { 429 $length = get_selection_length(); 430 $size = $::settings->{'filesize'} * ( scalar @{ $::settings->{'blocks'} } - 1 ); 431 } 432 else { 433 $length = get_selection_length(); 434 $size = $::settings->{'filesize'}; 435 } 436 437 if ( $::settings->{'video_bitrate_lock'} ) { 438 set_filesize( $length, $audio_rate ); 439 set_bpp(); 440 return -1; 441 } 442 443 if ( $size == 0 || $length == 0 || $size !~ /^\d+$/ ) { $bitrate = -1 } 444 else { $bitrate = int( ( ( $size * 8192 ) / $length ) - $audio_rate ) } 445 $bitrate = 5000 if $bitrate > 5000; 446 if ( $bitrate < 0 ) { message("Error setting bitrate") } 447 set_setting( 'video_bitrate', $bitrate ); 448 set_bpp(); 449} 450 451sub set_filesize ($$) { 452 my $length = shift; 453 my $audio_rate = shift; 454 my $bitrate = $::widgets->{'video_bitrate_spin'}->get_value_as_int; 455 my $size; 456 457 if ( $bitrate == 0 || $length == 0 || $audio_rate !~ /^\d+$/ ) { 458 $size = -1; 459 } 460 else { 461 $size = int( ( ( $audio_rate + $bitrate ) * $length ) / 8192 ); 462 } 463 if ( $size < 0 ) { message("Error estimating filesize") } 464 set_setting( 'filesize', $size ); 465 466 #set_bpp(); 467} 468 469sub set_bpp { 470 return -1 if ! defined $::dvd->{'track'}; 471 return -1 if ! scalar @{$::dvd->{'track'}}; 472 473 my $bpp = 0; 474 my $fps = get_track()->{'fps'} || -1; 475 my $wo = get_track()->{'width'} || -1; 476 my $ho = get_track()->{'height'} || -1; 477 my $ws = $::settings->{'scale_width'} || $wo; 478 my $hs = $::settings->{'scale_height'} || $ho; 479 my $br = $::settings->{'video_bitrate'}; 480 my $wc = $::settings->{'crop_width'} || $wo; 481 my $hc = $::settings->{'crop_height'} || $ho; 482 my $aa = 0; 483 if ( defined get_track()->{'aspect'} ) { 484 my $aa = eval( get_track()->{'aspect'} ); #eval to allow fraction string to equate to a float 485 } 486 $aa = $wo / $ho if !$aa; 487 488 if ( defined $aa && $br * $hc * $wc * $wo * $ho * $fps ) # moronic test for potential divide by zero! 489 { 490 $hs = $hs || $hc; 491 $ws = $ws || $ho * $wc * $aa / $wo; 492 $hs = $hc if $hs == -1; 493 $ws = $wc if $ws == -1; 494 $hs = ( $hc * $wo * $ws ) / ( $wc * $ho * $aa ) if $hs == -2; 495 $ws = ( $wc * $ho * $hs * $aa ) / ( $hc * $wo ) if $ws == -2; 496 497 $ws = sprintf( "%i", $ws ); 498 $hs = sprintf( "%i", $hs ); 499 $bpp = sprintf( "%.3f", ( $br * 1000 ) / ( $hs * $ws * $fps ) ) if $ws * $hs; 500 501 if ( defined $::widgets && $ws > 0 && $hs > 0 ) { 502 $::widgets->{'scale_height_estimate_entry'}->set_text($hs); 503 $::widgets->{'video_bpp_entry'}->set_text($bpp); 504 } 505 } 506 return $ws, $hs, $wc, $hc, $wo, $ho; 507} 508 509sub get_available_codecs { 510 my $count = 0; 511 512 #my $item; 513 my $menc = $::settings->{'mencoder'}; 514 system "$menc >/dev/null 2>&1"; 515 print "MEncoder was not found! Acidrip is utterly useless without it! go install!\n" if $? >> 8 != 1; 516 if ( open( MENC_VIDEO, "$menc -ovc help 2>&1 |" ) ) { 517 while (<MENC_VIDEO>) { 518 $::settings->{'mplayer_version'} = $1 if $_ =~ /MEncoder\s(\d\.\d)/; 519 if ( $_ =~ /\s+(\w+)\s+-\s+(.+)/ ) { 520 $::settings->{'available_video'}{$1} = "$1 - $2"; 521 if ( defined $::widgets and $1 ne "frameno" ) { 522 my $item = new Gtk2::MenuItem("$1"); 523 $::widgets->{'video_codec_option'}->get_menu->append($item); 524 $item->signal_connect( 'activate', \&on_option_changed, $1 ); 525 526 $::widgets->{'video_options_entry'}->set_text( $::settings->{ $::settings->{'video_codec'} . '_options' } or "" ); 527 $::widgets->{'video_codec_option'}->set_history($count) if $1 eq $::settings->{'video_codec'}; 528 $count++; 529 } 530 } 531 } 532 $::widgets->{'video_codec_option'}->show_all if defined $::widgets; 533 close MENC_VIDEO; 534 } 535 else { message("Mencoder codec test failed. Is MPlayer installed properly?") } 536 537 if ( open( MENC_AUDIO, "$menc -oac help 2>&1 |" ) ) { 538 my $got_mp3 = 0; 539 $count = 0; 540 while (<MENC_AUDIO>) { 541 if ( $_ =~ /\s+(\w+)\s+-(.*)/ ) { 542 $::settings->{'available_audio'}{$1} = "$1 - $2"; 543 $got_mp3 = 1 if $1 eq "mp3lame" or $1 eq "lavc"; 544 if ( defined $::widgets ) { 545 my $item = new Gtk2::MenuItem("$1"); 546 ( $::widgets->{'audio_codec_option'}->get_menu )->append($item); 547 $item->signal_connect( 'activate', \&on_option_changed, $1 ); 548 } 549 550 $::widgets->{'audio_options_entry'}->set_text( $::settings->{ "audio_" . $::settings->{'audio_codec'} . '_options' } or '' ); 551 $::widgets->{'audio_codec_option'}->set_history($count) if $1 eq $::settings->{'audio_codec'}; 552 $count++; 553 } 554 } 555 $::widgets->{'audio_codec_option'}->show_all if defined $::widgets; 556 print "AcidRip could NOT find MP3 support in MPlayer! if you do want MP3 sound in your films," 557 . "you will need to recompile MPlayer accordingly. See the docs on the MPlayer site.\n\n" 558 if !$got_mp3; 559 close MENC_AUDIO; 560 } 561 else { message("Mencoder codec test failed. Is MPlayer installed properly?") } 562} 563 564sub kill_mplayer { 565 if ( $::settings->{'mencoder_pid'} > 0 ) { 566 my $m = $::settings->{'mencoder_pid'} + 1; 567 kill 'INT', $::settings->{'mencoder_pid'}; 568 kill 'INT', $m if `ps $m | grep mencoder` || `ps $m | grep mplayer`; 569 message("Encoding stopped."); 570 $::settings->{'mencoder_pid'} = -1; 571 } 572 else { 573 message("Nothing to stop!"); 574 } 575} 576 577sub get_selection_length { 578 my ( $start, $end ) = @_; 579 my $length = 0; 580 if ( defined get_track()->{'chapter'} ) { 581 $start = ( $::settings->{'selected_chapters_start'} || 1 ) if !$start; 582 $end = ( $::settings->{'selected_chapters_end'} || get_track->{'chapter'}[-1]->{'ix'} ) if !$end; 583 for my $chapter ( $start .. $end ) { 584 $length += get_chapter($chapter)->{'length'}; 585 } 586 } 587 else { 588 $length = get_track_param('length'); 589 } 590 return $length; 591} 592 593sub read_source ($) { 594 my $path = shift; 595 if ( -b $path || -c $path ) { 596 return read_disc($path); 597 } 598 elsif ( -d $path ) { 599 my $return = read_disc($path); 600 if ($return) { 601 return read_src_file($path); 602 } 603 else { 604 return $return; 605 } 606 } 607 else { 608 return read_src_file($path); 609 } 610} 611 612sub read_disc ($) { 613 use vars qw(%lsdvd); 614 my $dvd_device = shift; 615 system("$::settings->{'lsdvd'} -h > /dev/null 2> /dev/null"); 616 if ( !$? ) { 617 eval(`$::settings->{'lsdvd'} -xp $dvd_device 2>/dev/null`); 618 if ( !$? ) { 619 $::dvd = {%lsdvd}; 620 $Data::Dumper::Indent = 0; 621 my $lsout = Dumper { %lsdvd }; 622 $::widgets->{'mencoder_output_text'}->get_buffer->insert_with_tags_by_name( $::widgets->{'mencoder_output_text'}->get_buffer->get_end_iter, $lsout . "\n", 'lsdvd' ); 623 $::dvd->{'status'} = "DVD read ok"; 624 $::dvd->{'source'} = "dvd"; 625 $Data::Dumper::Indent = 2; 626 } 627 else { 628 $::dvd = undef; 629 } 630 } 631 else { 632 $::dvd = undef; 633 } 634 $::dvd->{'status'} = "lsdvd not found" if $? >> 8 == 127; 635 $::dvd->{'status'} = "DVD device not found" if $? >> 8 == 1; 636 $::dvd->{'status'} = "DVD not found. Drive empty?" if $? >> 8 == 2; 637 system( "eject " . $dvd_device ) if $? >> 8 == 2 && $::settings->{'eject'}; 638 $::dvd->{'status'} = "Can't read DVD. Not a valid DVD drive!" if $? >> 8 == 3; 639 $::dvd->{'status'} = "Can't read DVD track. Faulty Disc?" if $? >> 8 == 4; 640 641 return $?; 642} 643 644sub read_src_file ($) { 645 my %files; 646 my $path = shift; 647 $files{'device'} = $path; 648 $files{'source'} = "file"; 649 650 open IDENTIFY, "$::settings->{'mplayer'} -identify -ao null -vo null -frames 0 $path" . ( -d $path ? '/*' : '' ) . " 2>&1 |"; 651 652 while (<IDENTIFY>) { 653 $files{'track'}[ scalar @{ $files{'track'} } ]{'filename'} = $1 if /ID_FILENAME=(.+)/; 654 $files{'track'}[ scalar @{ $files{'track'} } - 1 ]{'ix'} = scalar @{ $files{'track'} } if /ID_FILENAME=(.+)/; 655 $files{'track'}[ scalar @{ $files{'track'} } - 1 ]{'fps'} = $1 if /ID_VIDEO_FPS=(.+)/; 656 $files{'track'}[ scalar @{ $files{'track'} } - 1 ]{'width'} = $1 if /ID_VIDEO_WIDTH=(.+)/; 657 $files{'track'}[ scalar @{ $files{'track'} } - 1 ]{'height'} = $1 if /ID_VIDEO_HEIGHT=(.+)/; 658 $files{'track'}[ scalar @{ $files{'track'} } - 1 ]{'aspect'} = $1 if /ID_VIDEO_ASPECT=(.+)/ && $1; 659 $files{'track'}[ scalar @{ $files{'track'} } - 1 ]{'format'} = ( $1 eq '0x10000001' ? "MPEG1" : ( $1 eq '0x10000002' ? "MPEG2" : $1 ) ) if /ID_VIDEO_FORMAT=(.+)/; 660 $files{'track'}[ scalar @{ $files{'track'} } - 1 ]{'bitrate'} = $1 if /ID_VIDEO_BITRATE=(.+)/ && $1; 661 $files{'track'}[ scalar @{ $files{'track'} } - 1 ]{'audio'}[0]{'format'} = $1 if /ID_AUDIO_CODEC=(.+)/; 662 $files{'track'}[ scalar @{ $files{'track'} } - 1 ]{'audio'}[0]{'ix'} = 1 if /ID_AUDIO_CODEC=(.+)/; 663 $files{'track'}[ scalar @{ $files{'track'} } - 1 ]{'audio'}[0]{'aformat'} = $1 if /ID_AUDIO_FORMAT=(.+)/; 664 $files{'track'}[ scalar @{ $files{'track'} } - 1 ]{'audio'}[0]{'bitrate'} = $1 if /ID_AUDIO_BITRATE=(.+)/; 665 $files{'track'}[ scalar @{ $files{'track'} } - 1 ]{'audio'}[0]{'frequency'} = $1 if /ID_AUDIO_RATE=(.+)/; 666 $files{'track'}[ scalar @{ $files{'track'} } - 1 ]{'audio'}[0]{'channels'} = $1 if /ID_AUDIO_NCH=(.+)/; 667 if (/ID_LENGTH=(.+)/) { # this is the final line in the output, so might as well demlimit the files 668 $files{'track'}[ scalar @{ $files{'track'} } - 1 ]{'length'} = $1; 669 if ( defined $files{'track'}[ scalar @{ $files{'track'} } - 1 ]{'format'} && 670 defined $files{'track'}[ scalar @{ $files{'track'} } - 1 ]{'fps'} && 671 defined $files{'track'}[ scalar @{ $files{'track'} } - 1 ]{'bitrate'} && 672 $files{'track'}[ scalar @{ $files{'track'} } - 1 ]{'format'} ne 'DVSD') { 673 message("Scanning file \'$files{'track'}[scalar @{$files{'track'}} -1]{'filename'}\'"); 674 } 675 else { 676 pop @{ $files{'track'} }; 677 } 678 } 679 while ( Gtk2->events_pending() ) { Gtk2->main_iteration() } 680 } 681 682 close IDENTIFY; 683 $::dvd = {%files}; 684 if ( defined $files{'track'} ) { 685 $::dvd->{'status'} = scalar @{ $files{'track'} } . " file" . ( scalar @{ $files{'track'} } != 1 ? 's' : '' ) . " read OK"; 686 } 687 else { 688 $::dvd->{'status'} = "No valid files found"; 689 $::dvd->{'status'} = "No read access to $path" if !-r $path; 690 $::dvd->{'status'} = "$path does not exist!" if !-e $path; 691 } 692 693 return 0; 694} 695 696sub find_crop ($) { 697 open STDIN, '/dev/null' or message("Can't read /dev/null: $!. May fail if in background"); 698 699 my $crop_output; 700 if ( defined $::dvd->{'track'} ) { 701 my %crop; 702 message( "Running " . get_command("cropdetect") ); 703 open( CROP, get_command("cropdetect") . " 2>&1 |" ); 704 while (<CROP>) { 705 if ( $_ =~ /crop area.*\s(crop=\d*:\d*:\d*:\d*)/ ) { $crop{$1}++ } 706 $crop_output .= $_; 707 gui_check($_); 708 } 709 my @order = sort { $crop{$b} <=> $crop{$a} } keys %crop; 710 close CROP; 711 return ( $order[0], $crop_output ); 712 } 713 else { return ( -1, "crop detect failed" ) } 714} 715 716sub rebuild_queue_text { 717 my $buffer = $::widgets->{'queue_text'}->get_buffer; 718 $buffer->delete( $buffer->get_bounds ); 719 720 for ( 1 .. @{$::playlist} ) { 721 my %item = %{ @{$::playlist}[ $_ - 1 ] }; 722 $buffer->insert( $buffer->get_end_iter, $item{'command'} . "\n" ); 723 } 724} 725 726sub queued_encode_events { 727 my $events = 0; 728 foreach my $event (@{$::playlist}) { 729 my %e= %{$event}; 730 if ( $e{'command'} =~ /mencoder/ || $e{'command'} =~ /mplayer/ ) { 731 $events++; 732 } 733 } 734 return $events; 735} 736 737sub push_playlist_queue { 738 message("Pushed events onto queue"); 739 740 if ( !defined $::dvd->{'track'} ) { 741 message("Hey, you gotta load DVD or file(s) first!"); 742 return -1; 743 } 744 745 my %menc = get_parameters(); 746 747 if ( -e $menc{'output'} && !$::settings->{'overwrite'} && $menc{'output'} ne "/dev/null" ) { 748 message("File already exists, refusing to overwrite"); 749 return -1; 750 } 751 my $directory = dirname( substitute_filename( $::settings->{'filename'} ) ); 752 if ( !-d $directory ) { 753 message("Output directory does not exist!"); 754 return -1; 755 } 756 if ( !-w $directory ) { 757 message("Can't write to output directory!"); 758 return -1; 759 } 760 if ( ( !$::settings->{'enough_space'} ) && $::settings->{'enforce_space'} ) { 761 message("Not enough space in output directory!"); 762 return -1; 763 } 764 765 # Encode file 766 for ( 1 .. $::settings->{'total_blocks'} ) { 767 $::settings->{'this_block'} = $_ if $::settings->{'total_blocks'} > 1; 768 769 if ( $::settings->{'cache'} && $::dvd->{'source'} eq "dvd" ) { 770 $::settings->{'total_events'}++; 771 $::playlist->prepend( get_command('cache'), 'cache', "Caching title..." ) if $::settings->{'precache'}; 772 $::playlist->append( get_command('cache'), 'cache', "Caching title..." ) if !$::settings->{'precache'}; 773 $::playlist->append( "eject $::settings->{'dvd_device'}", 'system', 'Ejecting DVD' ) 774 if $::settings->{'eject'} && $::dvd->{'source'} eq "dvd" && ( 775 ( $::settings->{'this_block'} == $::settings->{'total_blocks'} && !$::settings->{'precache'} ) || # last block on precache 776 ( $::settings->{'this_block'} == 1 && $::settings->{'precache'} ) || # first block of normal cache 777 $::settings->{'total_blocks'} == 1 # single block 778 ); 779 } 780 781 my $message = "Encoding film"; 782 $message .= ", Block " . $::settings->{'this_block'} . " of " . $::settings->{'total_blocks'} if $::settings->{'this_block'} > 0; 783 784 my $twopassable = ( $::settings->{'video_codec'} eq "lavc" || $::settings->{'video_codec'} eq "divx4" || $::settings->{'video_codec'} eq "xvid" ); 785 786 $::playlist->append( "unlink frameno.avi 2> /dev/null", 'system', "Removing frameno.avi if it exists" ) 787 if $::settings->{'this_block'} == 1 || $::settings->{'total_blocks'} == 1; 788 789 if ( $::settings->{'video_passes'} > 1 && $twopassable ) { 790 791 $::playlist->append( get_command("mencoder_frameno"), 'encode', $message . ", frameno pass..." ) if $::settings->{'video_passes'} == 3; 792 793 $::settings->{'video_pass'} = 1; 794 $::playlist->append( get_command( "mencoder" . ( $::settings->{'video_passes'} == 3 ? "_3pass" : "" ) ), 'encode', $message . ", 1st pass..." ); 795 796 $::settings->{'video_pass'} = 2; 797 $::playlist->append( get_command( "mencoder" . ( $::settings->{'video_passes'} == 3 ? "_3pass" : "" ) ), 'encode', $message . ", 2nd pass..." ); 798 799 $::playlist->append( "unlink frameno.avi 2> /dev/null", 'system', "Removing frameno.avi" ) if $::settings->{'video_passes'} == 3; 800 801 $::playlist->append( "unlink divx2pass.log 2> /dev/null", 'system', "Removing divx2pass.log" ); 802 } 803 else { 804 $::playlist->append( get_command("mencoder"), 'encode', $message ); 805 } 806 $::playlist->append( get_command("del_cache"), 'system', "Deleting cache file" ) if $::settings->{'cache'} && $::settings->{'del_cache'} && $::dvd->{'source'} eq "dvd"; 807 } 808 $::playlist->append( "eject $::settings->{'dvd_device'} 2> /dev/null", 'system', 'Ejecting DVD' ) if $::settings->{'eject'} && !$::settings->{'cache'}; 809 $::playlist->append( "shutdown -h now", 'system', 'Shutting down... bye!' ) if $::settings->{'shutdown'}; 810} 811 812sub pop_playlist_queue { 813 my %item = $::playlist->get(); 814 message( "Running " . $item{'command'} ); 815 message( $item{'message'} ); 816 encode( $item{'command'} ) if $item{'type'} eq 'encode'; 817 cache( $item{'command'} ) if $item{'type'} eq 'cache'; 818 system( $item{'command'} ) if $item{'type'} eq 'system'; 819 $item{'type'} ne 'system' ? return $? : return 0; 820} 821 822sub cache { 823 824 #fork proofing 825 open STDIN, '/dev/null' or message("Can't read /dev/null: $!. May fail if in background"); 826 827 my $cache = shift; 828 $cache =~ /"(.+)"/; 829 my $file = $1; 830 my $this_cell = -1; 831 my $size = 0; 832 my $start_chapter; 833 my $stop_chapter; 834 my $this_track = get_track(); 835 836 if ( $::settings->{'total_blocks'} > 1 ) { 837 $cache =~/-(\d+)-cache/; 838 $start_chapter = $::settings->{'blocks'}[ $1 - 1 ] + 1; 839 $stop_chapter = $::settings->{'blocks'}[ $1 ]; 840 } 841 else { 842 $start_chapter = $::settings->{'selected_chapters_start'}; 843 $stop_chapter = $::settings->{'selected_chapters_end'}; 844 $start_chapter = 1 if $start_chapter == 0; 845 $stop_chapter = $this_track->{'chapter'}[-1]->{'ix'} if $stop_chapter == 0; 846 } 847 my $total_chapters = $stop_chapter - $start_chapter + 1; 848 my $this_event = $::settings->{'total_events'} - queued_encode_events(); 849 $::settings->{'mencoder_pid'} = open( CACHE, "nice $cache 2>&1 |" ); 850 while (<CACHE>) { 851 if (/### CELL (\d+)/) { 852 if ( $this_cell != $1 + 1 ) { 853 $this_cell = $1 + 1; 854 my $this_chapter = 0; 855 LOOP: foreach ( reverse( @{ $this_track->{'chapter'} } ) ) { 856 $this_chapter = $_->{'ix'}; 857 last LOOP if $_->{'startcell'} <= $this_cell; 858 } 859 $::widgets->{'cache_chapter'}->set_text( sprintf( "%d (%d/%d)", $this_chapter, $this_chapter + 1 - $start_chapter, $total_chapters ) ); 860 my $progress = sprintf("%d", ($this_event - 1 + ($this_chapter - $start_chapter) / $total_chapters)*100/$::settings->{'total_events'}); 861 $::widgets->{'acidrip'}->set_title(msg("acidrip") . ' - ' . $progress . '%'); 862 $::widgets->{'progress_dialog'}->set_title(msg("acidrip") . ' - ' . $progress . '%'); 863 } 864 $::widgets->{'cache_size'}->set_text( sprintf( "%d", ( -s $file ) / 1048576 ) . "Mb" ) if -e $file; 865 } 866 while ( Gtk2->events_pending() ) { Gtk2->main_iteration() } 867 } 868 close CACHE; 869 870 return $file; 871} 872 873sub encode { 874 875 #fork proofing 876 open STDIN, '/dev/null' or message("Can't read /dev/null: $!. May fail if in background"); 877 878 my $menc = shift; 879 880 if ( defined $::widgets ) { 881 my $buffer = $::widgets->{'mencoder_output_text'}->get_buffer; 882 my ( $sec, $fps, $size, $time, $rate, $prog ) = ( 0, 0, 0, 0, 0, -1 ); 883 my $this_event = $::settings->{'total_events'} - queued_encode_events(); 884 885 if ( $::settings->{'mencoder_pid'} = open( MENCODER, "$menc 2>&1 |" ) ) { 886 $/ = "\r"; 887 while (<MENCODER>) { 888 if (/^Pos:\s*(\d+).\ds\s+(\d+)f\s+\(\s*(\d+)%\)\s+(\d+fps)\sTrem:\s+(\d+min)\s+(\d+mb).+\[([\d:]+)\]/) { 889 if ( $1 ne $sec ) { $sec = $1; $::widgets->{'menc_seconds'}->set_text( hhmmss($1) ) } 890 if ( $4 ne $fps ) { $fps = $4; $::widgets->{'menc_fps'}->set_text($4) } 891 if ( $6 ne $size ) { $size = $6; $::widgets->{'menc_filesize'}->set_text($6) } 892 if ( $5 ne $time ) { $time = $5; $::widgets->{'menc_time'}->set_text($5) } 893 if ( $7 ne $rate ) { $rate = $7; $::widgets->{'menc_bitrate'}->set_text($7) } 894 if ( $3 ne $prog ) { 895 $prog = $3; 896 $::widgets->{'menc_progress'}->set_fraction( $3 / 100 ); 897 my $progress = sprintf("%d", ($this_event - 1 + ($3/100))*100/$::settings->{'total_events'}); 898 $::widgets->{'acidrip'}->set_title(msg("acidrip") . ' - ' . $progress . '%'); 899 $::widgets->{'progress_dialog'}->set_title(msg("acidrip") . ' - ' . $progress . '%'); 900 } 901 } 902 else { s/\r/\n/g; $buffer->insert_with_tags_by_name( $buffer->get_end_iter, $_, 'mplayer' ) } 903 while ( Gtk2->events_pending() ) { Gtk2->main_iteration() } 904 } 905 $/ = "\n"; 906 } 907 else { message( "Mencoder failed, is it properly installed?", 'error' ) } 908 } 909 else { 910 message( "Mencoder failed, is it properly installed?", 'error' ) if !( $::settings->{'mencoder_pid'} = open( MENCODER, "$menc" ) ); 911 } 912 $::widgets->{'view_button'}->set_sensitive( -r ( substitute_filename( $::settings->{'filename'} . ( $::settings->{'mpegfile'} ? ".mpg" : ".avi" ) ) ) ? 1 : 0 ); 913 close MENCODER; 914} 915 916package acidrip_settings; 917 918use vars qw($defaults); 919 920$defaults = { 921 'dvd_device' => '/dev/acd0', 922 'selected_track' => 0, 923 'selected_chapters_start' => 0, 924 'selected_chapters_end' => 0, 925 'filesize' => 700, 926 'total_blocks' => 1, 927 'this_block' => 0, 928 'blocks' => [], 929 'selected_audio' => -1, 930 'selected_subp' => -1, # Remember, the GUI is 1 based, mplayer is 0 based. 931 'audio_codec' => 'mp3lame', 932 'audio_gain' => 0, 933 'audio_options' => '', 934 'audio_mp3lame_options' => 'abr:br=128', 935 'audio_lavc_options' => 'acodec=mp3:abitrate=128', 936 'video_codec' => 'lavc', 937 'lavc_options' => 'vcodec=mpeg4:vhq:v4mv:vqmin=2', 938 'divx4_options' => '', 939 'xvid_options' => '', 940 'vuv_options' => '', 941 'video_options' => '', 942 'video_bitrate' => 0, 943 'video_bitrate_lock' => 0, 944 'filename' => $ENV{HOME} . '/%T', 945 'title' => 'unknown', 946 'mpegfile' => 0, 947 'length' => 0, 948 'scale_enable' => 1, 949 'scale_auto' => 1, 950 'scale_height' => -2, 951 'scale_width' => 480, 952 'crop_enable' => 1, 953 'crop_height' => 0, 954 'crop_width' => 0, 955 'crop_vertical' => 0, 956 'crop_horizontal' => 0, 957 'vf_pre' => 'pp=de', 958 'vf_pre_enable' => 1, 959 'vf_post' => '', 960 'vf_post_enable' => 0, 961 'video_pass' => 0, 962 'video_passes' => 1, 963 'more_options' => '', 964 'language' => 'English', 965 'mencoder' => 'mencoder', 966 'mplayer' => 'mplayer', 967 'lsdvd' => 'lsdvd', 968 'available_audio' => {}, 969 'available_video' => {}, 970 'mencoder_pid' => 0, 971 'autoload' => 0, 972 'overwrite' => 0, 973 'enforce_space' => 1, 974 'cache' => 0, 975 'precache' => 1, 976 'cache_directory' => '/tmp/', 977 'del_cache' => 0, 978 'tooltips' => 1, 979 'busy' => 0, 980 'UI' => 1, 981 'compact' => 1, 982 'enough_space' => 1, 983 'ppc_bug' => 0, 984 'embed_preview' => 1, 985 'eject' => 0, 986 'vobsubout' => 0, 987 'mplayer_version' => 1, 988 'flickbook_preview' => 0, 989 'export_script' => 0, 990 'info_artist' => '', 991 'info_genre' => '', 992 'info_name' => '', 993 'info_copyright' => '', 994 'info_subject' => '', 995 'shutdown' => 0, 996 'ui_language' => 'English', 997 'total_events' => 0 998}; 999 1000sub new { 1001 my $class = shift; 1002 my $settings = {}; 1003 foreach my $key ( keys %{$defaults} ) { $settings->{$key} = $defaults->{$key} } 1004 bless( $settings, $class ); 1005 return $settings; 1006} 1007 1008sub get_default ($$) { 1009 my ( $settings, $value ) = @_; 1010 return $defaults->{$value} if ( defined $settings->{$value} ); 1011 return "unknown setting! - $value"; 1012} 1013 1014sub restore_settings { 1015 my $settings = shift; 1016 foreach my $key ( keys %{$defaults} ) { $settings->{$key} = $defaults->{$key} unless $key eq "selected_track" } 1017 return $settings; 1018} 1019 1020sub save_settings { 1021 my $settings = shift; 1022 my @save = ( 1023 'dvd_device', 'filesize', 'filename', 'audio_codec', 'audio_mp3lame_options', 'audio_lavc_options', 1024 'video_codec', 'scale_enable', 'autoload', 'mpegfile', 'eject', 'scale_auto', 1025 'scale_height', 'scale_width', 'crop_enable', 'language', 'mencoder', 'mplayer', 1026 'lsdvd', 'tooltips', 'video_passes', 'video_bitrate_lock', 'lavc_options', 'xvid_options', 1027 'divx4_options', 'more_options', 'total_blocks', 'overwrite', 'cache', 'cache_directory', 1028 'vf_pre_enable', 'audio_gain', 'vf_post_enable', 'vf_pre', 'vf_post', 'del_cache', 1029 'ppc_bug', 'compact', 'flickbook_preview', 'enforce_space', 'vobsubout', 'video_bitrate', 1030 'ui_language' 1031 ); 1032 if ( open( CONFIGFILE, '>', "$ENV{HOME}/.acidriprc" ) ) { 1033 foreach my $key (@save) { 1034 print CONFIGFILE "$key = $settings->{$key}\n" if $settings->{$key} ne ''; 1035 } 1036 close CONFIGFILE; 1037 } 1038 else { 1039 acidrip::message("Can't open config file for writing!\n"); 1040 } 1041} 1042 1043sub load_settings { 1044 my $settings = shift; 1045 if ( open( CONFIGFILE, "$ENV{HOME}/.acidriprc" ) ) { 1046 while (<CONFIGFILE>) { 1047 if ( $_ =~ /(\w+)\s=\s(.+)/ ) { $settings->{$1} = $2 } 1048 } 1049 close CONFIGFILE; 1050 } 1051 else { 1052 acidrip::message("No configuration file found, nevermind."); 1053 } 1054 return $settings; 1055} 1056 1057package acidrip_playlist; 1058 1059use Data::Dumper; 1060 1061sub new { 1062 bless( [], shift ); 1063} 1064 1065sub append { 1066 my $playlist = shift; 1067 my %item; 1068 $item{'command'} = shift; 1069 $item{'type'} = shift; # system, encode, cache, eval 1070 $item{'message'} = shift; 1071 push( @{$playlist}, \%item ); 1072} 1073 1074sub prepend { 1075 my $playlist = shift; 1076 my %item; 1077 $item{'command'} = shift; 1078 $item{'type'} = shift; # system, encode, cache, eval 1079 $item{'message'} = shift; 1080 unshift( @{$playlist}, \%item ); 1081} 1082 1083sub clear { 1084 my $playlist = shift; 1085 while ( @{$::playlist} ) { 1086 shift @{$::playlist}; 1087 } 1088} 1089 1090sub get { 1091 my $playlist = shift; 1092 return %{ shift @{$playlist} }; 1093} 1094 10951; 1096