add --letterbox and --audio options
This commit is contained in:
parent
af0592e892
commit
868f2d9d4f
1 changed files with 61 additions and 24 deletions
69
pack-vid
69
pack-vid
|
@ -2,8 +2,8 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Squishes given video input into sub-4000kb .mp4
|
// Squishes given video input into sub-4000kb .mp4
|
||||||
// Crops to 16:9
|
// Crops or pads to 16:9 (crop default; --letterbox to pad)
|
||||||
// Strips audio
|
// Strips audio (to override, pass --audio for 96 kbps AAC)
|
||||||
// HDR to SDR tonemapping
|
// HDR to SDR tonemapping
|
||||||
// Picks bitrate to match
|
// Picks bitrate to match
|
||||||
// Picks resolution based on bitrate target
|
// Picks resolution based on bitrate target
|
||||||
|
@ -11,12 +11,26 @@
|
||||||
|
|
||||||
$args = $_SERVER['argv'];
|
$args = $_SERVER['argv'];
|
||||||
$self = array_shift( $args );
|
$self = array_shift( $args );
|
||||||
|
$options = [
|
||||||
|
'letterbox' => false,
|
||||||
|
'audio' => false,
|
||||||
|
];
|
||||||
|
|
||||||
|
while ( count( $args ) > 0 && substr( $args[0], 0, 2 ) == '--' ) {
|
||||||
|
$option = substr( array_shift( $args ), 2 );
|
||||||
|
$options[$option] = true;
|
||||||
|
}
|
||||||
|
|
||||||
if ( count ( $args ) < 2 ) {
|
if ( count ( $args ) < 2 ) {
|
||||||
die( "Usage: $self <srcfile.mp4> <destfile.mp4>\n" );
|
die(
|
||||||
|
"Usage: $self [options...] <srcfile.mp4> <destfile.mp4>\n" .
|
||||||
|
"Options:\n" .
|
||||||
|
" --letterbox pad instead of cropping\n" .
|
||||||
|
" --audio include audio\n"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
[ $src, $dest ] = $args;
|
[ $src, $dest ] = $args;
|
||||||
convert( $src, $dest );
|
convert( $src, $dest, $options );
|
||||||
exit(0);
|
exit(0);
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -65,7 +79,7 @@ function evenize( $n ) {
|
||||||
return $n;
|
return $n;
|
||||||
}
|
}
|
||||||
|
|
||||||
function convert( $src, $dest ) {
|
function convert( $src, $dest, $options ) {
|
||||||
$maxBits = 4000 * 1000 * 8; // fit in 4Mb
|
$maxBits = 4000 * 1000 * 8; // fit in 4Mb
|
||||||
$maxBits = $maxBits * 7 / 8; // leave some headroom
|
$maxBits = $maxBits * 7 / 8; // leave some headroom
|
||||||
|
|
||||||
|
@ -84,18 +98,34 @@ function convert( $src, $dest ) {
|
||||||
|
|
||||||
$bitrate = floor( $maxBits / $duration );
|
$bitrate = floor( $maxBits / $duration );
|
||||||
|
|
||||||
|
|
||||||
|
if ( $options[ 'audio' ] ) {
|
||||||
|
$audioBitrate = 96 * 1000;
|
||||||
|
$audio = [ '-b:a', $audioBitrate ];
|
||||||
|
$bitrate -= $audioBitrate;
|
||||||
|
} else {
|
||||||
|
$audio = [ '-an' ];
|
||||||
|
}
|
||||||
|
|
||||||
$mbits = 1000 * 1000;
|
$mbits = 1000 * 1000;
|
||||||
if ( $bitrate < 2 * $mbits ) {
|
if ( $bitrate < 2 * $mbits ) {
|
||||||
$cropWidth = 854;
|
$frameWidth = 854;
|
||||||
$scaleHeight = 480;
|
$frameHeight = 480;
|
||||||
} else if ( $bitrate <= 4 * $mbits ) {
|
} else if ( $bitrate <= 4 * $mbits ) {
|
||||||
$cropWidth = 1280;
|
$frameWidth = 1280;
|
||||||
$scaleHeight = 720;
|
$frameHeight = 720;
|
||||||
} else {
|
} else {
|
||||||
$cropWidth = 1920;
|
$frameWidth = 1920;
|
||||||
$scaleHeight = 1080;
|
$frameHeight = 1080;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $options['letterbox'] ) {
|
||||||
|
$scaleWidth = $frameWidth;
|
||||||
|
$scaleHeight = evenize( $height * $frameWidth / $width );
|
||||||
|
} else {
|
||||||
|
$scaleHeight = $frameHeight;
|
||||||
|
$scaleWidth = evenize( $width * $frameHeight / $height );
|
||||||
}
|
}
|
||||||
$scaleWidth = evenize( $width * $scaleHeight / $height );
|
|
||||||
|
|
||||||
$filters = [ "scale=w=$scaleWidth:h=$scaleHeight" ];
|
$filters = [ "scale=w=$scaleWidth:h=$scaleHeight" ];
|
||||||
if ( $hdr ) {
|
if ( $hdr ) {
|
||||||
|
@ -104,7 +134,12 @@ function convert( $src, $dest ) {
|
||||||
$filters[] = "zscale=t=bt709:m=bt709:r=full";
|
$filters[] = "zscale=t=bt709:m=bt709:r=full";
|
||||||
}
|
}
|
||||||
$filters[] = "format=yuv420p";
|
$filters[] = "format=yuv420p";
|
||||||
$filters[] = "crop=w=$cropWidth";
|
if ( $options['letterbox'] ) {
|
||||||
|
$offset = round( ( $frameHeight - $scaleHeight) / 2 );
|
||||||
|
$filters[] = "pad=h=$frameHeight:y=$offset";
|
||||||
|
} else {
|
||||||
|
$filters[] = "crop=w=$frameWidth";
|
||||||
|
}
|
||||||
$vf = implode( ',', $filters );
|
$vf = implode( ',', $filters );
|
||||||
|
|
||||||
run( 'ffmpeg', [
|
run( 'ffmpeg', [
|
||||||
|
@ -119,7 +154,8 @@ function convert( $src, $dest ) {
|
||||||
'-an',
|
'-an',
|
||||||
'-y', '/dev/null'
|
'-y', '/dev/null'
|
||||||
] );
|
] );
|
||||||
run( 'ffmpeg', [
|
run( 'ffmpeg',
|
||||||
|
array_merge( [
|
||||||
'-i', $src,
|
'-i', $src,
|
||||||
'-vf', $vf,
|
'-vf', $vf,
|
||||||
'-c:v', 'libx264',
|
'-c:v', 'libx264',
|
||||||
|
@ -127,9 +163,10 @@ function convert( $src, $dest ) {
|
||||||
'-preset', 'veryslow',
|
'-preset', 'veryslow',
|
||||||
'-pass', '2',
|
'-pass', '2',
|
||||||
'-g', $keyframeInt,
|
'-g', $keyframeInt,
|
||||||
'-an',
|
], $audio, [
|
||||||
'-y', $dest
|
'-y', $dest
|
||||||
] );
|
] )
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue