woo
This commit is contained in:
parent
4757720ac4
commit
c65e2a49b5
1 changed files with 30 additions and 25 deletions
55
pack-vid
55
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 or pads to 16:9 (crop default; --letterbox to pad)
|
// Crops or pads to 16:9 (letterbox default; --crop to crop)
|
||||||
// Strips audio (to override, pass --audio for 96 kbps AAC)
|
// Includes stereo audio (to strip, pass --no-audio)
|
||||||
// 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
|
||||||
|
@ -16,10 +16,10 @@ $maxBytes = 4000 * 1000; // fit in 4MB
|
||||||
$maxBytes = $maxBytes * 15 / 16; // leave some headroom
|
$maxBytes = $maxBytes * 15 / 16; // leave some headroom
|
||||||
|
|
||||||
$options = [
|
$options = [
|
||||||
'letterbox' => false,
|
'crop' => false,
|
||||||
'audio' => false,
|
'no-audio' => false,
|
||||||
'exposure' => '0',
|
'exposure' => '-0.5', // half stop down
|
||||||
'peak' => '10000',
|
'peak' => '1000', // '10000' is max
|
||||||
'fps' => '60',
|
'fps' => '60',
|
||||||
'size' => $maxBytes,
|
'size' => $maxBytes,
|
||||||
'quality' => 0.75,
|
'quality' => 0.75,
|
||||||
|
@ -40,8 +40,8 @@ if ( count ( $args ) < 2 ) {
|
||||||
die(
|
die(
|
||||||
"Usage: $self [options...] <srcfile.mp4> <destfile.mp4>\n" .
|
"Usage: $self [options...] <srcfile.mp4> <destfile.mp4>\n" .
|
||||||
"Options:\n" .
|
"Options:\n" .
|
||||||
" --letterbox pad instead of cropping\n" .
|
" --crop crop instead of padding\n" .
|
||||||
" --audio include audio\n" .
|
" --no-audio strip audio\n" .
|
||||||
" --exposure=n adjust exposure\n" .
|
" --exposure=n adjust exposure\n" .
|
||||||
" --peak=n set HDR peak nits\n" .
|
" --peak=n set HDR peak nits\n" .
|
||||||
" --fps=n frame rate limit\n" .
|
" --fps=n frame rate limit\n" .
|
||||||
|
@ -141,16 +141,21 @@ function convert( $src, $dest, $options ) {
|
||||||
$bitrate = floor( $maxBits / $duration );
|
$bitrate = floor( $maxBits / $duration );
|
||||||
|
|
||||||
|
|
||||||
if ( $options[ 'audio' ] ) {
|
if ( $options[ 'no-audio' ] ) {
|
||||||
$audioBitrate = 96 * 1000;
|
|
||||||
$audio = [ '-b:a', $audioBitrate ];
|
|
||||||
$bitrate -= $audioBitrate;
|
|
||||||
} else {
|
|
||||||
$audio = [ '-an' ];
|
$audio = [ '-an' ];
|
||||||
|
} else {
|
||||||
|
$audioBitrate = 96 * 1000;
|
||||||
|
$audio = [
|
||||||
|
'-ac', 2,
|
||||||
|
'-b:a', $audioBitrate,
|
||||||
|
];
|
||||||
|
$bitrate -= $audioBitrate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$bitrate = max( $bitrate, 16000 );
|
||||||
|
|
||||||
$mbits = 1000 * 1000;
|
$mbits = 1000 * 1000;
|
||||||
$base = intval( $mbits * $options['quality'] );
|
$base = intval( $mbits * floatval( $options['quality'] ) );
|
||||||
if ( $bitrate < 1 * $base || $height < 480 ) {
|
if ( $bitrate < 1 * $base || $height < 480 ) {
|
||||||
$frameWidth = 640;
|
$frameWidth = 640;
|
||||||
$frameHeight = 360;
|
$frameHeight = 360;
|
||||||
|
@ -167,22 +172,22 @@ function convert( $src, $dest, $options ) {
|
||||||
|
|
||||||
$aspect = $width / $height;
|
$aspect = $width / $height;
|
||||||
$wide = $aspect > ( $frameWidth / $frameHeight );
|
$wide = $aspect > ( $frameWidth / $frameHeight );
|
||||||
$pad = boolval( $options['letterbox'] );
|
$crop = boolval( $options['crop'] );
|
||||||
if ( $pad ) {
|
if ( $crop ) {
|
||||||
if ( $wide ) {
|
if ( $wide ) {
|
||||||
$scaleWidth = $frameWidth;
|
|
||||||
$scaleHeight = evenize( $frameWidth / $aspect );
|
|
||||||
} else {
|
|
||||||
$scaleHeight = $frameHeight;
|
$scaleHeight = $frameHeight;
|
||||||
$scaleWidth = evenize( $frameHeight * $aspect );
|
$scaleWidth = evenize( $frameHeight * $aspect );
|
||||||
|
} else {
|
||||||
|
$scaleWidth = $frameWidth;
|
||||||
|
$scaleHeight = evenize( $frameWidth / $aspect );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ( $wide ) {
|
if ( $wide ) {
|
||||||
$scaleHeight = $frameHeight;
|
|
||||||
$scaleWidth = evenize( $frameHeight * $aspect );
|
|
||||||
} else {
|
|
||||||
$scaleWidth = $frameWidth;
|
$scaleWidth = $frameWidth;
|
||||||
$scaleHeight = evenize( $frameWidth / $aspect );
|
$scaleHeight = evenize( $frameWidth / $aspect );
|
||||||
|
} else {
|
||||||
|
$scaleHeight = $frameHeight;
|
||||||
|
$scaleWidth = evenize( $frameHeight * $aspect );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,12 +206,12 @@ function convert( $src, $dest, $options ) {
|
||||||
$filters[] = "zscale=t=bt709:m=bt709:r=full";
|
$filters[] = "zscale=t=bt709:m=bt709:r=full";
|
||||||
}
|
}
|
||||||
$filters[] = "format=yuv420p";
|
$filters[] = "format=yuv420p";
|
||||||
if ( $options['letterbox'] ) {
|
if ( $crop ) {
|
||||||
|
$filters[] = "crop=w=$frameWidth:h=$frameHeight";
|
||||||
|
} else {
|
||||||
$offsetX = round( ( $frameWidth - $scaleWidth) / 2 );
|
$offsetX = round( ( $frameWidth - $scaleWidth) / 2 );
|
||||||
$offsetY = round( ( $frameHeight - $scaleHeight) / 2 );
|
$offsetY = round( ( $frameHeight - $scaleHeight) / 2 );
|
||||||
$filters[] = "pad=w=$frameWidth:h=$frameHeight:x=$offsetX:y=$offsetY";
|
$filters[] = "pad=w=$frameWidth:h=$frameHeight:x=$offsetX:y=$offsetY";
|
||||||
} else {
|
|
||||||
$filters[] = "crop=w=$frameWidth:h=$frameHeight";
|
|
||||||
}
|
}
|
||||||
$vf = implode( ',', $filters );
|
$vf = implode( ',', $filters );
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue