Following up from this thread, there’s currently some error passing the output from dcadec to aften via shell pipe.
error allocating read buffer Invalid count passed to aften_encode_frame Error encoding frame 0
So been looking at an alternative to that method. And for what it’s worth, ffmpeg can do that too, even in one step.
# ffmpeg -i tmp.dts -acodec ac3 -ac 6 -ab 448k tmp.ac3
So below is version 0.2 of the script, now depending on ffmpeg instead of dcadec and aften.
#!/usr/bin/perl # 0.1 - dcadec, aften for dts2ac3 # 0.2 - ffmpeg for dts2ac3 # usage: cd into your working directory, put all sub directories containing mkv's with dts track to encode to ac3 over there and run it use warnings; use strict; use File::Basename; my $FFMPEG="/usr/bin/ffmpeg"; my $MKVMERGE="/usr/bin/mkvmerge"; my $MKVEXTRACT="/usr/bin/mkvextract"; my $TMP_DTS="tmp.dts"; my $TMP_AC3="tmp.ac3"; my $PATTERN_DTS="A_DTS"; my $PATTERN_AC3="A_AC3"; sub dts2ac3 { my ($dts, $ac3) = @_; `$FFMPEG -i $dts -acodec ac3 -ac 6 -ab 448k $ac3`; } sub info { my ($mkv) = @_; return `$MKVMERGE -i $mkv`; } sub demux { my ($mkv, $id) = @_; `$MKVEXTRACT tracks $mkv $id:$TMP_DTS`; } sub mux { my ($mkv, $new, $ac3) = @_; #remove all tracks with -A, only add new `$MKVMERGE -A -o $new $mkv $ac3`; } sub clean { # delete 1.dts, 1.ac3, old mkv my ($dts, $ac3, $old) = @_; system("rm -f $dts"); system("rm -f $ac3"); system("rm -f $old"); } my $pwd=`pwd`; print "Processing all matches in $pwd...nn"; my @dirs=<*>; my $dir; my @files; my $file; my @buf; my $line; my $id; my $name; my $ext=".mkv";; my $output; foreach $dir (@dirs) { chdir $dir; @files=<*>; foreach $file (@files) { if($file=~m/mkv/i) { $id=-1; # 1. get dts track id from info @buf=info($file); foreach $line (@buf) { if($line=~m/$PATTERN_DTS/i) { $line=~m/(d+)/; $id = $1; # only the first print "found first match for DTS.n"; last; } if($line=~m/$PATTERN_AC3/i) { print "AC3 track found.n"; } } next if($id<0); # 2. demux dts track print "Demuxing DTS track from $file...n"; demux($file,$id); # 3. encode dts to ac3 print "Encoding DTS to AC3...n"; dts2ac3($TMP_DTS,$TMP_AC3); # 4. parse old name, create new if($file=~m/dts/i){ $output=$file; $output=~s/DTS/AC3/g; $output=~s/dts/AC3/g; } else { ($name, undef, $ext) = fileparse($file,qr".mkv"); $output="$name.AC3$ext"; } # 5. mux print "Creating new output with AC3 in $output...n"; mux($file, $output, $TMP_AC3); # 6. clean print "Deleting temp files and old mkv...n"; clean($TMP_DTS, $TMP_AC3, $file); # 7. info print info($output); } } chdir "../"; }
now the scripts only processes the first dts track, not the last in the loop.