Edited at

ffmpegを用いて、動画を分割するスクリプト

More than 1 year has passed since last update.


なにこれ


  • 長い動画を指定時間ごとに分割できる。


  • -c copyオプションを使っているため、割りとはやい。

  • なんかあったら怖いから、ファイル名の空白をアンダーバーに置換するスクリプトも同梱。

  • ぶっちゃけ、空白潰しだけでも便利。

  • 何かあれば、ぼくのGithubアカウント

  • こっちのほうが連絡つく、ぼくのTwitterアカウント


動作環境


  • Linux localhost 2.6.32-642.11.1.el6.i686 #1 SMP Fri Nov 18 18:48:28 UTC 2016 i686 i686 i386 GNU/Linux

  • ffmpeg-3.1.2 (自動スクリプト拾った)


ソースコード


空白潰し


rename.pl

#!/usr/bin/env perl

#Current Directoryにある指定した拡張子の、ファイル名の空白をアンダーバーに全置換

#拡張子指定
$stat='mp4';
$fl='*'.'.'.$stat.'*';

@file=glob $fl;

foreach(@file){
$new=$_;
$new=~s!\s!_!g;
print $_."-".$new."\n";
system("mv \"$_\" $new");
}



動画ファイル分割


split.pl

#!/usr/bin/env perl

#
# 動画を分割する Perl Script
# 元ファイルが"sample_data.mp4"のとき、
# 出力ファイルは"sample_data_0.mp4","sample_data_1.mp4",...
# である。
#

# $of ファイル名
# $of_ka 拡張子
my $of="sample_data";
my $of_ka=".mp4";
my $rf=$of.$of_ka;

# 何秒ごとに分割するか
my $split_sec=20*60;

# ffmpeg コマンド
# -i:入力ファイル
my $ffmpeg="/opt/ffmpeg_build/bin/ffmpeg -i $rf";

# 元動画ファイルの長さ
my $max_sec=&count_time;

for(my $i=0,$j=0;;$i+=$split_sec,$j++){
#元動画ファイルよりも後ろの部分を切り取ろうとしたら、終了
if($i>$max_sec+1){
last;
}

#オプション
#配列にしてあるので、好みで変更できる
#-c :codecのコピー
#-ss:指定した時間から変換を始める
#-t :指定秒変換する
my @option1=("-c copy","-ss $i","-t $split_sec");

my $option=&mkop(\@option1);

#コマンド作成
$exe=$ffmpeg.$option;
#出力ファイル
$exe.=" $of"."_".$j.$of_ka;

#コマンド実行
print $exe."\n";
print "system=".system($exe)."\n";
}

#オプション作成
sub mkop{
my ($op)=@_;
my $cmd="";

foreach(@$op){
$cmd.=" ".$_;
}

return $cmd;
}

#動画の長さを取得(単位:秒)
sub count_time{
my $from_time=`$ffmpeg 2>&1 | grep Duration |cut -c 13-20`;
my @time=split(/:/,$from_time);
my $max_sec=0;
foreach(@time){
$max_sec*=60;
$max_sec+=$_;
}

return $max_sec;
}



なぜCPANとかのmoduleを使わない?


  • めんどくさい

  • 他環境への移行に手間がかかる


注意点


  • ffmpegのバージョンが古いと、オプションが足りなかったり、動画の長さが取得できなかったりする。

  • CentOS6.8に登録されているRepositoryだと古いので、自動スクリプトを頑張って探してください。

  • 派手に標準出力するので、nohupコマンドをうまいこと利用すると便利!

  • 何か問題があれば消します。


感想


  • Perlはいいぞ