Created
December 30, 2012 22:28
-
-
Save archydragon/4415682 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env perl | |
# dedicated to hatred of High 10 H.264 profile | |
# finds all MKV files in current directory and re-encodes them to kawaii High@* | |
# WARNING: make sure that your x264 is built with ffmpeg support | |
use strict; | |
use warnings; | |
use 5.010; | |
use Math::Round; # must be installed from CPAN | |
use XML::XPath; # must be installed from CPAN | |
# files and directories | |
my $dirTmp = "v4tmp"; # directory for temporary files | |
my $dirOut = "tabletized"; # destination directory for encoded video | |
my $tmpEnc = "$dirTmp/encoded.x264"; # filename for encoded video stream | |
my $tmpAudio = "$dirTmp/audio.raw"; # filename for audio stream | |
my $tmpSubs = "$dirTmp/subs.raw"; # filename for subtitles stream | |
my $tmpTC = "$dirTmp/timecodes.txt"; # filename for timecodes data | |
# some encoding options | |
my $height = 480; # \ | |
my $width = 800; # - default video encodig parameters; for my ONDA Vi10 Fashion with love | |
my $vbitrate = 1100; # / | |
################################################## | |
# find all MKV files in current directory | |
my @mkvFiles = <*.mkv>; | |
my $mkvFilesCount = @mkvFiles; | |
# if there are no suitable files, panic and exit | |
if ($mkvFilesCount == 0) { | |
say "No any MKV files found. Nothing to do here."; | |
exit 0; | |
} | |
# create temporary directory | |
`mkdir -p $dirTmp`; | |
# create output directory | |
`mkdir -p $dirOut`; | |
# process all the MKVs! | |
for my $mkv (@mkvFiles) { | |
process(quotemeta($mkv)); | |
} | |
# remove all temporary data | |
`rm -rf $dirTmp`; | |
################################################## | |
## Main file processing subroutine | |
sub process { | |
my $file = $_[0]; | |
my $xml = `mediainfo --Output=XML $file`; | |
my $parser = XML::XPath->new(xml=>$xml); | |
# getting video information | |
my %trackVideo; | |
for my $key ('ID', 'Width', 'Height') { | |
my $nodeValue = $parser->findvalue('//track[@type="Video"]/' . $key); | |
$nodeValue =~ s/[^0-9]//g; | |
$trackVideo{$key} = $nodeValue; | |
} | |
# getting audio information | |
my %trackAudio; | |
for my $key ('ID', 'Format') { | |
my $nodeValue = $parser->findvalue('//track[@type="Audio"]/' . $key); | |
$trackAudio{$key} = $nodeValue; | |
} | |
# getting subtitles ID | |
my $trackSubsId = $parser->findvalue('//track[@type="Text"]/ID'); | |
destroyMkv($file, $trackVideo{ID}, $trackAudio{ID}, $trackSubsId); | |
x264("$file", "$tmpEnc", $trackVideo{Width}, $trackVideo{Height}); | |
# lossless audio must be killed with fire^W^W^Wencoded to AAC | |
if ($trackAudio{Format} eq 'FLAC') { | |
flac2aac(); | |
} | |
mergeMkv("$file"); | |
} | |
## Extract audio, subtitles and timecode data from original MKV | |
sub destroyMkv { | |
my ($fileName, $videoId, $audioId, $subsId) = @_; | |
`mkvextract tracks $fileName $audioId:$tmpAudio $subsId:$tmpSubs`; | |
`mkvextract timecodes_v2 $fileName $videoId:$tmpTC`; | |
} | |
## Encode original video to downscaled (or upscaled if you have FullHD tablet) one | |
sub x264 { | |
my ($fileInput, $fileOutput, $srcWidth, $srcHeight) = @_; | |
my ($encWidth, $encHeight) = (0, 0); | |
# check do we need scale on long or short screen dimension | |
my $tabletRatio = $width/$height; | |
my $videoRatio = $srcWidth/$srcHeight; | |
if ($videoRatio > $tabletRatio) { | |
# scale on width | |
$encWidth = $width; | |
$encHeight = round($height/($videoRatio/$tabletRatio)); | |
} | |
else { | |
# scale on height | |
$encHeight = $height; | |
$encWidth = round($width/($tabletRatio/$videoRatio)); | |
} | |
# BE AWARE BEFORE EDITING VIDEO ENCODING PAREMETERS! | |
my $command = "x264 --output $fileOutput --input-res ${srcWidth}x${srcHeight} --profile high " . | |
"--preset medium --bitrate $vbitrate --crf 18 --video-filter " . | |
"resize:width=$encWidth,height=$encHeight,method=lanczos $fileInput"; | |
`$command`; | |
} | |
## Convert FLAC to AAC | |
sub flac2aac { | |
my $tmpAac = "$dirTmp/audio.aac"; # filename for temporary encoded AAC stream | |
`ffmpeg -y -acodec flac -i $tmpAudio $tmpAac`; | |
`rm $tmpAudio`; | |
`mv $tmpAac $tmpAudio`; | |
} | |
## Merge destination MKV | |
sub mergeMkv { | |
my $file = $_[0]; | |
`mkvmerge --timecodes 0:$tmpTC -o $dirOut/$file $tmpEnc $tmpAudio $tmpSubs`; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment