148 changes: 148 additions & 0 deletions trunk/export_Trans_DVCD.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
package export_Trans_DVCD;

# Load the nuv utilities
use nuv_utils;

# Make sure we have pointers to the main:: namespace for certain variables
*Prog = *main::Prog;
*gui = *main::gui;

sub new {
my $class = shift;
my $self = {
'name' => 'Transcode export to VCD for DVD (48kHz audio)',
'enabled' => 1,
'started' => 0,
'children' => [],
'errors' => undef,
'episode' => undef,
'savepath' => '.',
'outfile' => 'out.mpg',
'use_cutlist' => 1,
'noise_reduction' => 0,
'deinterlace' => 1,
@_ #allows user-specified attributes to override the defaults
};
bless($self, $class);
# Make sure we have transcode
$Prog{transcode} = find_program('transcode');
push @{$self->{errors}}, 'You need transcode to use this exporter.' unless ($Prog{transcode});
# Make sure that we have an mp2 encoder
$Prog{mp2_encoder} = find_program('toolame', 'mp2enc');
push @{$self->{errors}}, 'You need toolame or mp2enc to export an vcd.' unless ($Prog{mp2_encoder});
# Make sure that we have an mplexer
$Prog{mplexer} = find_program('tcmplex', 'mplex');
push @{$self->{errors}}, 'You need tcmplex or mplex to export an vcd.' unless ($Prog{mplexer});
# Any errors? disable this function
$self->{enabled} = 0 if ($self->{errors} && @{$self->{errors}} > 0);
# Return
return $self;
}

sub gather_data {
my $self = shift;
my $default_filename;
# Get the save path
$self->{savepath} = $gui->query_savepath();
# Ask the user for the filename
if($self->{episode}->{show_name} ne 'Untitled' and $self->{episode}->{title} ne 'Untitled')
{
$default_filename = $self->{episode}->{show_name}.' - '.$self->{episode}->{title};
}
elsif($self->{episode}->{show_name} ne 'Untitled')
{
$default_filename = $self->{episode}->{show_name};
}
elsif($self->{episode}->{title} ne 'Untitled')
{
$default_filename = $self->{episode}->{title};
}

$self->{outfile} = $gui->query_filename($default_filename, 'mpg', $self->{savepath});
# Ask the user if he/she wants to use the cutlist
if ($self->{episode}->{cutlist} && $self->{episode}->{cutlist} =~ /\d/) {
$self->{use_cutlist} = $gui->query_text('Enable Myth cutlist?',
'yesno',
$self->{use_cutlist} ? 'Yes' : 'No');
}
else {
$gui->notify('No cutlist found. Hopefully this means that you already removed the commercials.');
}
# Ask the user if he/she wants noise reduction
# Noise reduction
$self->{noise_reduction} = $gui->query_text('Enable noise reduction (slower, but better results)?',
'yesno',
$self->{noise_reduction} ? 'Yes' : 'No');
$self->{deinterlace} = $gui->query_text('Enable deinterlacing?',
'yesno',
$self->{deinterlace} ? 'Yes' : 'No');
# Do we want bin/cue files, or just an mpeg?
# nothing, at the moment.
}

sub execute {
my $self = shift;

# Gather any necessary data
$self->{episode} = shift;
$self->gather_data;
# Load nuv info
my %nuv_info = nuv_info($self->{episode}->{filename});
# Set this to true so that the cleanup routine actually runs
$self->{started} = 1;

# Generate some names for the temporary audio and video files
my $safe_outfile = shell_escape($self->{outfile});
my $safe_outfile_sub = shell_escape(substr($self->{outfile},0,-4));

my $command = "nice -n 19 transcode -i $main::video_dir/$self->{episode}->{filename} -x mpeg2 -y mpeg2enc,mp2enc -F 1 -E 48000 -b 224 -o $safe_outfile_sub -V";

if ($nuv_info{fps} =~ /^2(?:5|4\.9)/) {
$command .= " -Z 352x288";
}
# Other options for NTSC
else {
$command .= " -Z 352x240";
}

if ($self->{use_cutlist}) {
@cuts = split("\n",$self->{episode}->{cutlist});
my @skiplist;
foreach my $cut (@cuts) {
push @skiplist, (split(" - ", $cut))[0]."-".(split(" - ", $cut))[1];
}
$command .= " -J skip=\"".join(" ", @skiplist)."\"";
}
if ($self->{deinterlace}) {
$command .= " -J smartdeinter";
}
if ($self->{noise_reduction}) {
$command .= " -J yuvdenoise";
}
push @{$self->{children}}, fork_command($command);

# Wait for child processes to finish
1 while (wait > 0);
$self->{children} = undef;

# Multiplex the streams
$command = "nice -n 19 mplex -f 1 $safe_outfile_sub.m1v $safe_outfile_sub.mpa -o $safe_outfile";
system($command);
}

sub cleanup {
my $self = shift;
return unless ($self->{started});
# Make sure any child processes also go away
if ($self->{children} && @{$self->{children}}) {
foreach my $child (@{$self->{children}}) {
kill('INT', $child);
}
1 while (wait > 0);
}
# Remove any temporary files
my $safe_outfile_sub = shell_escape(substr($self->{outfile},0,-4));
system("rm $safe_outfile_sub.m1v $safe_outfile_sub.mpa -f");
}

1; #return true
9 changes: 7 additions & 2 deletions trunk/export_VCD.pm
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,13 @@ package export_VCD;
fifos_wait($self->{fifodir});
# Now we fork off a process to encode the audio
if ($Prog{mp2_encoder} =~ /\btoolame$/) {
$sample = $nuv_info{audio_sample_rate} / 1000;
$command = "nice -n 19 toolame -s $sample -m j -b 224 $self->{fifodir}/audout $self->{tmp_a}";
$sample = $nuv_info{audio_sample_rate};
if ($sample != 44100) {
$command = "nice -n 19 sox -t raw -r $sample -s -w -c 2 $self->(fifodir)/audout -t raw -r 44100 -s -w -c 2 /dev/stdout resample -qs"
." | nice -n 19 toolame -s 44.1 -m j -b 224 /dev/stdin $self->(tmp_a)";
} else {
$command = "nice -n 19 toolame -s $sample -m j -b 224 $self->{fifodir}/audout $self->{tmp_a}";
}
}
else {
$command = "nice -n 19 ffmpeg -f s16le -ar $nuv_info{audio_sample_rate} -ac 2 -i $self->{fifodir}/audout -vn -f wav -"
Expand Down
1 change: 1 addition & 0 deletions trunk/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# First, install nuvexport itself
install -Dv -o root -g root -m 0755 nuvexport /usr/local/bin/nuvexport
install -Dv -o root -g root -m 0755 nuvinfo /usr/local/bin/nuvinfo
install -Dv -o root -g root -m 0755 mpeg2cut /usr/local/bin/mpeg2cut

# Next, create the nuvexport shared directory
mkdir -pvm 0755 /usr/local/share/nuvexport
Expand Down
73 changes: 73 additions & 0 deletions trunk/mpeg2cut
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#! /bin/sh
#
# Cut MPEG2 files to remove cutlists...
# Written by Gavin Hurlbut <gjhurlbu@beirdo.ca>
#
# Prerequisites:
# avidemux2 - http://fixounet.free.fr/avidemux/
# transcode - http://zebra.fh-weingarten.de/~transcode/
# lvemux - http://lvempeg.sourceforge.net/
# gdk2-cursed - http://zemljanka.sourceforge.net/cursed/
#
# Usage: mpeg2cut inputfile outputfile segmentList
# where segmentList is a space separated list of frame regions to keep
# (i.e. -1999 3000-5000 6000-)

export LD_PRELOAD=libgdk-cursed-2.0.so:libgtk-cursed-2.0.so

FILENAME=$1
OUTFILE=$2
BASENAME=`basename ${FILENAME} .nuv`

echo Filename \"${FILENAME}\"
echo OutFile \"${OUTFILE}\"

shift
shift
CUTLIST=$*

echo Cutlist \"${CUTLIST}\"

if [ ! -f ${FILENAME}.idx ]
then
nice -n 19 avidemux2 --index-mpeg ${FILENAME} ${FILENAME}.idx C0 \
--audio-codec MP2 --quit 2> /dev/null
fi

OFFSET=`(tcprobe -i ${FILENAME} 2> /dev/null) | grep av_fine_ms | \
sed -e 's/^.*av_fine_ms //' | cut -d " " -f 1`

count=0
SLICELIST=""

for i in ${CUTLIST}
do
START=`echo $i | cut -d '-' -f 1`
END=`echo $i | cut -d '-' -f 2`
SLICE=${BASENAME}_${count}

if [ .${START}. != .. ]
then
START="--begin ${START}"
fi

if [ .${END}. != .. ]
then
END="--end ${END}"
fi

nice -n 19 avidemux2 --load ${FILENAME} ${START} ${END} \
--audio-codec MP2 --save-raw-video ${SLICE}.m2v \
--save-raw-audio ${SLICE}.mp2 --quit 2> /dev/null
nice -n 19 lvemux -sh $((-1 * ${OFFSET})) -v ${SLICE}.m2v \
-a ${SLICE}.mp2 -o ${SLICE}.mpg
rm ${SLICE}.m2v ${SLICE}.m2v.idx ${SLICE}.mp2

SLICELIST="${SLICELIST} ${SLICE}.mpg"
count=$((${count} + 1))
done

echo Concatenating ${count} segments
nice -n 19 cat ${SLICELIST} > ${OUTFILE}
rm ${SLICELIST} ${FILENAME}.idx

8 changes: 7 additions & 1 deletion trunk/nuvexport
Original file line number Diff line number Diff line change
Expand Up @@ -115,13 +115,16 @@ format and use Microsoft's Windows Media Encoder to encode a WMV file.
use export_NUV_SQL;
use export_SVCD;
use export_VCD;
use export_DVCD;
use export_DVD;
use export_OGM;
use export_WMV;
use export_MP3;
use export_Trans_XviD;
use export_Trans_VCD;
use export_Trans_DVCD;
use export_Trans_SVCD;
use export_MPEG2_cut;

# Make sure that we have mythtranscode installed
$Prog{mythtranscode} = find_program('mythtranscode');
Expand All @@ -141,12 +144,15 @@ format and use Microsoft's Windows Media Encoder to encode a WMV file.
export_DivX->new,
export_WMV->new,
export_VCD->new,
export_DVCD->new,
export_DVD->new,
export_OGM->new,
export_MP3->new,
export_Trans_XviD->new,
export_Trans_VCD->new,
export_Trans_SVCD->new;
export_Trans_DVCD->new,
export_Trans_SVCD->new,
export_MPEG2_cut->new;

# Set up the signal handlers
$SIG{INT} = \&Quit;
Expand Down