Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@mamemomonga
Last active October 19, 2023 03:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mamemomonga/31d2fd42dd748631fbe08f859b382c89 to your computer and use it in GitHub Desktop.
Save mamemomonga/31d2fd42dd748631fbe08f859b382c89 to your computer and use it in GitHub Desktop.
ffmpegを使ったビデオコンバータ

ffmpegで私がよく使うかもなコンバートスクリプト

  • MP4形式で出力
  • 29.97fpsインターレスを59.94fpsプログレッシブに変換
  • 5.1chは2chにダウンミックス
  • $OUTPUTDIR に出力される

使用例

マストドン投稿に最適なGIFVを作成する(オーディオなし,720p, AVC 4Mbps)

$ ./videoconv -g video.mov

再編集用にAVC 40Mbps/FLACで保存

$ ./videoconv -h video.mov

24fpsにする

$ ./videoconv -f video.mov
#!/usr/bin/env perl
use strict;
use warnings;
use feature 'say';
use File::Basename;
use Getopt::Long;
use POSIX qw(strftime);
our $OUTPUTDIR='/PATH/TO/OUTPUT/Video';
sub getFieldOrder {
my $filename=shift;
return '' if(!-e $filename);
my $ret=`ffprobe -show_streams -select_streams v:0 -loglevel quiet $filename`;
my $fo='';
if($ret=~/^field_order=(.+)$/mg) { $fo=$1 }
return lc($fo);
}
sub getAudioChannels {
my $filename=shift;
return '' if(!-e $filename);
my $ret=`ffprobe -show_streams -select_streams a:0 -loglevel quiet $filename`;
my $fo='';
if($ret=~/^channels=(.+)$/mg) { $fo=$1 }
return lc($fo);
}
my %opts=(
'gifv' => 0,
'high' => 0,
'film' => 0,
);
sub usage {
say "";
say "[USAGE]";
say " $0 [OPTIONS] [INFILE]";
say "[OPTIONS]";
say " -g | -gifv (720p/AVC 4Mbps/NoAudio)";
say " -x | -high (AVC 40Mbps/FLAC)";
say " -f | -film (24fps)";
say "";
exit(1);
}
GetOptions(
"gifv|g" => \$opts{gifv},
"high|x" => \$opts{high},
"film|f" => \$opts{film},
);
usage() if($#ARGV != 0);
my $timestamp=strftime('%y%m%d-%H%M%S',localtime(time));
my $srcfile=$ARGV[0];
my $dstfile="";
{
my ($basename, $dirname, $ext) = fileparse($srcfile, qr/\..*$/);
$dstfile=$OUTPUTDIR.'/'.$timestamp.'_'.$basename.'.mp4';
}
my $interlace=(getFieldOrder($srcfile) eq 'progressive') ? 0 : 1;
my $downmix=(getAudioChannels($srcfile) > 2) ? 1 : 0;
{
my @cmd=();
say "*********************************************";
push @cmd,'Deinterlace' if ($interlace);
push @cmd,'Downmix' if ($downmix);
push @cmd,'GIFV' if ($opts{gifv});
push @cmd,'40Mbps/FLAC' if ($opts{high});
say " ** ".join(", ",@cmd);
say " ** Source: $srcfile";
say " ** Destination: $dstfile";
say "*********************************************";
}
my @vf=();
my @fo=();
if($interlace) {
push @vf,'yadif=mode=1:parity=-1:deint=1';
}
if($downmix) {
push @fo,('-ac','2');
}
if($opts{film}) {
push @vf,'pullup';
# push @fo,('-r','24000/1001');
push @fo,('-r','24');
}
if($opts{gifv}) {
push @vf,'scale=1280:-1';
push @fo,('-an','-c:v','h264','-b:v','4M');
} elsif($opts{high}){
push @fo,('-c:v','h264','-b:v','40M','-c:a','flac')
}
my @cmd=('ffmpeg','-i',$srcfile);
if($#vf>-1) {
push @cmd,('-vf',join(",",@vf));
}
push @cmd,(@fo,$dstfile);
say join(" ",@cmd);
exec(@cmd);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment