|
| 1 | +package export_DivX; |
| 2 | + |
| 3 | +# Load the nuv utilities |
| 4 | + use nuv_utils; |
| 5 | + |
| 6 | +# Make sure we have pointers to the main:: namespace for certain variables |
| 7 | + *Prog = *main::Prog; |
| 8 | + *gui = *main::gui; |
| 9 | + |
| 10 | + sub new { |
| 11 | + my $class = shift; |
| 12 | + my $self = { |
| 13 | + 'name' => 'Export DivX', |
| 14 | + 'enabled' => 1, |
| 15 | + 'errors' => undef, |
| 16 | + 'episode' => undef, |
| 17 | + 'savepath' => '.', |
| 18 | + 'outfile' => 'out.avi', |
| 19 | + 'use_cutlist' => 0, |
| 20 | + 'a_bitrate' => 64, |
| 21 | + 'v_bitrate' => 256, |
| 22 | + 'h_res' => 320, |
| 23 | + 'v_res' => 240, |
| 24 | + 'sql_file' => undef, |
| 25 | + @_ #allows user-specified attributes to override the defaults |
| 26 | + }; |
| 27 | + bless($self, $class); |
| 28 | + # Return |
| 29 | + return $self; |
| 30 | + } |
| 31 | + |
| 32 | + sub gather_data { |
| 33 | + my $self = shift; |
| 34 | + my $default_filename; |
| 35 | + # Get the save path |
| 36 | + $self->{savepath} = $gui->query_savepath(); |
| 37 | + # Ask the user for the filename |
| 38 | + if($self->{episode}->{show_name} ne 'Untitled' and $self->{episode}->{title} ne 'Untitled') |
| 39 | + { |
| 40 | + $default_filename = $self->{episode}->{show_name}.' - '.$self->{episode}->{title}; |
| 41 | + } |
| 42 | + elsif($self->{episode}->{show_name} ne 'Untitled') |
| 43 | + { |
| 44 | + $default_filename = $self->{episode}->{show_name}; |
| 45 | + } |
| 46 | + elsif($self->{episode}->{title} ne 'Untitled') |
| 47 | + { |
| 48 | + $default_filename = $self->{episode}->{title}; |
| 49 | + } |
| 50 | + |
| 51 | + $self->{outfile} = $gui->query_filename($default_filename, 'avi', $self->{savepath}); |
| 52 | + # Ask the user if he/she wants to use the cutlist |
| 53 | + if ($self->{episode}->{cutlist} && $self->{episode}->{cutlist} =~ /\d/) { |
| 54 | + $self->{use_cutlist} = $gui->query_text('Enable Myth cutlist?', |
| 55 | + 'yesno', |
| 56 | + $self->{use_cutlist} ? 'Yes' : 'No'); |
| 57 | + } |
| 58 | + else { |
| 59 | + $gui->notify('No cutlist found. Hopefully this means that you already removed the commercials.'); |
| 60 | + } |
| 61 | + # Ask the user what audio bitrate he/she wants |
| 62 | + my $a_bitrate = $gui->query_text('Audio bitrate?', |
| 63 | + 'int', |
| 64 | + $self->{a_bitrate}); |
| 65 | + $self->{a_bitrate} = $a_bitrate; |
| 66 | + # Ask the user what video bitrate he/she wants |
| 67 | + my $v_bitrate = $gui->query_text('Video bitrate?', |
| 68 | + 'int', |
| 69 | + $self->{v_bitrate}); |
| 70 | + $self->{v_bitrate} = $v_bitrate; |
| 71 | + # Ask the user what horiz res he/she wants |
| 72 | + my $h_res = $gui->query_text('Horizontal resolution?', 'int', $self->{h_res}); |
| 73 | + $self->{h_res} = $h_res; |
| 74 | + # Ask the user what vert res he/she wants |
| 75 | + my $v_res = $gui->query_text('Vertical resolution?', 'int', $self->{v_res}); |
| 76 | + $self->{v_res} = $v_res; |
| 77 | + } |
| 78 | + |
| 79 | + sub execute { |
| 80 | + my $self = shift; |
| 81 | + # make sure that the fifo dir is clean |
| 82 | + if (-e 'fifodir/vidout' || -e 'fifodir/audout') { |
| 83 | + die "Possibly stale mythtranscode fifo's in fifodir.\nPlease remove them before running nuvexport.\n\n"; |
| 84 | + } |
| 85 | + # Gather any necessary data |
| 86 | + $self->{episode} = shift; |
| 87 | + $self->gather_data; |
| 88 | + # Load nuv info |
| 89 | + my %nuv_info = nuv_info($self->{episode}->{filename}); |
| 90 | + # Set this to true so that the cleanup routine actually runs |
| 91 | + $self->{started} = 1; |
| 92 | + # Create a directory for mythtranscode's fifo's |
| 93 | + unless (-d 'fifodir') { |
| 94 | + mkdir('fifodir', 0755) or die "Can't create fifodir: $!\n\n"; |
| 95 | + } |
| 96 | + # Here, we have to fork off a copy of mythtranscode |
| 97 | + my $command = "nice -n 19 mythtranscode -p autodetect -c $self->{episode}->{channel} -s $self->{episode}->{start_time_sep} -f fifodir"; |
| 98 | + $command .= ' --honorcutlist' if ($self->{use_cutlist}); |
| 99 | + push @{$self->{children}}, fork_command($command); |
| 100 | + # Sleep a bit to let mythtranscode start up |
| 101 | + my $overload = 0; |
| 102 | + while (++$overload < 30 && !(-e 'fifodir/audout' && -e 'fifodir/vidout')) { |
| 103 | + sleep 1; |
| 104 | + print "Waiting for mythtranscode to set up the fifos.\n"; |
| 105 | + } |
| 106 | + unless (-e 'fifodir/audout' && -e 'fifodir/vidout') { |
| 107 | + die "Waited too long for mythtranscode to create its fifos. Please try again.\n\n"; |
| 108 | + } |
| 109 | + # Now we fork off a process to encode everything |
| 110 | + $safe_outfile = shell_escape($self->{outfile}); |
| 111 | + $command = "nice -n 19 ffmpeg -y -f s16le -ar $nuv_info{audio_sample_rate} -ac 2 -i fifodir/audout -f rawvideo -s $nuv_info{width}x$nuv_info{height} -r $nuv_info{fps} -i fifodir/vidout -b $self->{v_bitrate} -ab $self->{a_bitrate} -s $self->{h_res}x$self->{v_res} $safe_outfile"; |
| 112 | + push @{$self->{children}}, fork_command($command); |
| 113 | + # Wait for child processes to finish |
| 114 | + 1 while (wait > 0); |
| 115 | + $self->{children} = undef; |
| 116 | + } |
| 117 | + |
| 118 | + sub cleanup { |
| 119 | + my $self = shift; |
| 120 | + return unless ($self->{started}); |
| 121 | + # Make sure any child processes also go away |
| 122 | + if ($self->{children} && @{$self->{children}}) { |
| 123 | + foreach my $child (@{$self->{children}}) { |
| 124 | + kill('INT', $child); |
| 125 | + } |
| 126 | + 1 while (wait > 0); |
| 127 | + } |
| 128 | + # Remove any temporary files |
| 129 | + foreach my $file ('fifodir/audout', 'fifodir/vidout') { |
| 130 | + unlink $file if (-e $file); |
| 131 | + } |
| 132 | + rmdir 'fifodir' if (-e 'fifodir'); |
| 133 | + } |
| 134 | + |
| 135 | +1; #return true |
0 commit comments