# Part of the StreamDVD project package StreamDVD::Util; use strict; use vars qw($VERSION @ISA @EXPORT); require Exporter; @ISA = qw(Exporter); @EXPORT = qw( ); @EXPORT = qw( DVD_Probe DVD_Analyze DVD_Build DVD_Image DVD_Burn makedir ); $VERSION = '0.1'; use StreamDVD::Defs; use StreamDVD::Title; use StreamDVD::Streams; sub DVD_Probe { my ($c, $p, $reftitle_arr, $ref_text) = @_; my $oldtext = $$ref_text; my $movietitle = 1; my $command = $c->lsdvd() . " -xp " . $c->reader(); my %lsdvd; $command = `$command`; $command =~ s/^our//; eval($command); for( my $i=0 ; $i<=$#{$lsdvd{track}} ; $i++ ) { my $t = new StreamDVD::Title; $t->length ( $lsdvd{track}[$i]{length} ); $t->fps ( $lsdvd{track}[$i]{fps} ); $t->aspect ( $lsdvd{track}[$i]{aspect} ); $t->angle_count( $lsdvd{track}[$i]{angles} ); $t->resolution ( $lsdvd{track}[$i]{width} . "x" . $lsdvd{track}[$i]{height} ); $t->format ( $lsdvd{track}[$i]{format} ); $t->titlenum ( $lsdvd{track}[$i]{ix} ); for( my $x=0 ; $x<=$#{$lsdvd{track}[$i]{chapter}} ; $x++ ) { my $ch = new StreamDVD::Chapter; $ch->num ( $lsdvd{track}[$i]{chapter}[$x]{ix} ); $ch->length( $lsdvd{track}[$i]{chapter}[$x]{length} ); $ch->cell ( $lsdvd{track}[$i]{chapter}[$x]{cell} ); $t->chapter_add($ch); } for( my $x=0 ; $x<=$#{$lsdvd{track}[$i]{audio}} ; $x++ ) { my $a = new StreamDVD::Audio; $a->num ( $lsdvd{track}[$i]{audio}[$x]{ix} ); $a->langcode( $lsdvd{track}[$i]{audio}[$x]{langcode} ); $a->language( $lsdvd{track}[$i]{audio}[$x]{language} ); $a->format ( $lsdvd{track}[$i]{audio}[$x]{format} ); $a->freq ( $lsdvd{track}[$i]{audio}[$x]{frequency} ); $a->quant ( $lsdvd{track}[$i]{audio}[$x]{quantization} ); $a->channel ( $lsdvd{track}[$i]{audio}[$x]{channels} ); $a->content ( $lsdvd{track}[$i]{audio}[$x]{content} ); $a->id ( $lsdvd{track}[$i]{audio}[$x]{streamid} ); $t->audio_add($a); } for( my $x=0 ; $x<=$#{$lsdvd{track}[$i]{subp}} ; $x++ ) { my $s = new StreamDVD::Subtitle; $s->num ( $lsdvd{track}[$i]{subp}[$x]{ix} ); $s->langcode( $lsdvd{track}[$i]{subp}[$x]{langcode} ); $s->language( $lsdvd{track}[$i]{subp}[$x]{language} ); $s->content ( $lsdvd{track}[$i]{subp}[$x]{content} ); $s->id ( $lsdvd{track}[$i]{subp}[$x]{streamid} ); $t->subtitle_add($s); } push @$reftitle_arr, $t; } $p->title($lsdvd{longest_track}); return $p->title() -1; } sub DVD_Analyze { my ($c, $p, $t, $ref_text) = @_; my $command = $c->streamanalyze() . " -i " . $c->reader() . " -t " . $t->titlenum(); my @streamlist; my $line; my $ok = 0; push @streamlist, "0xe0"; for( my $i=0 ; $i<$t->audio_count() ; $i++ ) { # get id's of selected audio streams if( $p->audio_selected($i) ) { my $a = $t->audio($i); push @streamlist, sprintf("0x%x",$a->id()); } } for( my $i=0 ; $i<$t->subtitle_count() ; $i++ ) { # get id's of selected subtitle streams if( $p->subtitle_selected($i) ) { my $s = $t->subtitle($i); push @streamlist, sprintf("0x%x",$s->id()); } } $command .= " -s " . join(",", @streamlist); # build commandline $command .= " -c " . sprintf("%d",$p->chapter_first()+1); if( $p->chapter_first() != $p->chapter_last() ) { $command .= "-" . sprintf("%d",$p->chapter_last()+1); } $command .= " 2>&1"; print("Executing: $command\n"); $SIG{CHLD} = sub{ wait }; if( open ANALYZE, "$command |" ) { while( $line = ) { if( $line =~ /^Factor\s+:\s+(.*)$/ ) { my $factor = $1; if( $factor !~ /needed/ ) { $p->factor($factor); } else { $p->factor(1); } $ok = 1; } } close(ANALYZE); } $SIG{CHLD} = 'DEFAULT'; return $ok; } sub DVD_Build { my ($c, $p, $t, $ref_text) = @_; my $oldtext = $$ref_text; my $videofile; my $chaptertimes = "-c " . join(",", chaptertimelist($p,$t)); my $audio_options = ""; my $subtitle_options = ""; my $streamdvd_command = $c->streamdvd() . " -i " . $c->reader() . " -t " . $t->titlenum(); my $streamdvd_options; my $linelength = 90; my $ok = 0; my $command; my $line; $streamdvd_options = "-c " . sprintf("%d",$p->chapter_first()+1); # build streamdvd chapter options if( $p->chapter_first() != $p->chapter_last() ) { $streamdvd_options .= "-" . sprintf("%d",$p->chapter_last()+1); } $streamdvd_options .= " -f " . $p->factor() if($p->factor() > 1); $streamdvd_options .= " -s 0xe0"; for( my $i=0 ; $i<$t->audio_count() ; $i++ ) { # build audio track options if( not $p->audio_selected($i) ) { next; } my $a = $t->audio($i); $audio_options .= $a->format() . "+" . $a->langcode(); $audio_options .= "," if( (($i+1) < $t->audio_count()) && $p->audio_selected($i+1) ); $streamdvd_options .= "," . sprintf("0x%x",$a->id()); } if( $audio_options ne "" ) { $audio_options = "-a " . $audio_options; } for( my $i=0 ; $i<$t->subtitle_count() ; $i++ ) { # build subtitle track options if( not $p->subtitle_selected($i) ) { next; } my $s = $t->subtitle($i); $subtitle_options .= $s->langcode(); $subtitle_options .= "," if( ($i+1) < $t->subtitle_count() ); $streamdvd_options .= "," . sprintf("0x%x",$s->id()); } if( $subtitle_options ne "" ) { $subtitle_options = "-s " . $subtitle_options; } $command = $c->dvdauthor() . " -t -o " . $p->dir() . DIR_DVD; $command .= " $audio_options $subtitle_options $chaptertimes"; $command .= " -f '$streamdvd_command $streamdvd_options |' 2>&1"; print("Executing: $command\n"); $SIG{CHLD} = sub{ wait }; if( open AUTHOR, "$command |" ) { while( read(AUTHOR, $line, $linelength) ) { if( $line =~ /ERR:/ ) { $ok = 0; last; } elsif( $line =~ /STAT:\s+VOBU.*(\d+:\d+:\d+)/ ) { $$ref_text = $oldtext . "timecode $1"; } elsif( $line =~ /STAT:\s+fixing.*(\d+)\%/ ) { $$ref_text = $oldtext . "fixing"; } main::gui_refresh(); $ok = 1; } close(AUTHOR); if( $ok ) { $command = $c->dvdauthor() . " -T -o " . $p->dir() . DIR_DVD . " && echo SUCCESS"; print("Executing: $command\n"); my $result = `$command`; if( $result =~ /SUCCESS/ ) { $ok = 1; } else { $ok = 0; } } } $SIG{CHLD} = 'DEFAULT'; return $ok; } sub DVD_Image { my ($c, $p, $t, $ref_text) = @_; my $oldtext = $$ref_text; my $ok = 0; my $line; my $imagefile = $p->dir() . DIR_ISO . "/movie.iso"; my $named_pipe = $c->temp_dir() . "/recode.".$$; my $command = $c->mkisofs() . " -dvd-video -udf " . $p->dir() . DIR_DVD . " >$imagefile 2>$named_pipe &"; print("Executing: $command\n"); system($command); sleep(1); if( open MKISO, "$named_pipe" ) { while( $line = ) { if( $line =~ /(\S+)\%/ ) { $$ref_text = $oldtext . $1 . " %"; } main::gui_refresh(); } close(MKISO); $ok = 1 if(-f $imagefile); } else { print("ERROR opening Pipe $named_pipe\n"); } unlink $named_pipe; if( $ok ) { $command = "rm -rf " . $p->dir() . DIR_DVD . " && echo SUCCESS"; print("Executing: $command\n"); my $result = `$command`; $ok = 0 if($result !~ /SUCCESS/); } return $ok; } # growisofs -Z /dev/scd0 -dvd-video -udf . # 99.10% done, estimate finish Sun Mar 7 15:26:35 2004 sub DVD_Burn { my ($c, $p, $t, $ref_text) = @_; my $oldtext = $$ref_text; my $ok = 0; my $line; my $command = $c->growisofs() . " -Z " . $c->writer() . " -dvd-video -udf " . $p->dir() . DIR_DVD . " 2>&1"; print("Executing: $command\n"); $SIG{CHLD} = sub{ wait }; if( open BURN, "$command |" ) { while( $line = ) { if( $line =~ /(.*\%)/ ) { $$ref_text = $oldtext . $1; } elsif( $line =~ /reloading\s+tray/ ) { $ok = 1; } main::gui_refresh(); } close(BURN); } $SIG{CHLD} = 'DEFAULT'; return $ok; } sub chaptertimelist { my ($p, $t) = @_; my @list; my $selected; my $i = 0; my $time = ""; my $hour = ""; my $min = ""; my $sec = ""; my $sum = 0; $selected = $p->chapter_selected($i); while( (defined $selected) && (not $selected) ) { $i++; $selected = $p->chapter_selected($i); } push @list, "0"; while( (defined $selected) && ($selected) ) { my $c = $t->chapter($i); $sum += $c->length(); my $value = $sum; $time = ""; $hour = ""; $min = ""; $hour = int($value / 3600); $value -= ($hour * 3600); $time .= sprintf("%.2d:", $hour); $min = int($value / 60); $value -= ($min * 60); $time .= sprintf("%.2d:", $min); $sec = int($value); $time .= sprintf("%.2d", $sec); push @list, $time; $i++; $selected = $p->chapter_selected($i); } splice(@list, $#list, 1); return @list; } sub makedir { my ($path) = @_; my $ok = 1; my @dirnames = split /\//, $path; my $temp = "/"; foreach (@dirnames) { $temp .= $_ . "/"; if( not -d $temp ) { if( not mkdir($temp,0755) ) { $ok = 0; last; } } } return $ok; } 1;