JavaCV を使った動画ファイル制御を備忘として記録。
環境
- java version 1.8.0_51
- javacv 1.4.4
- opencv 4.0.1
- ffmpeg 4.1
実装(MP4 ファイルを結合&切り出し)
- 1本目の動画(20秒)を 10 ~ 20秒切り出し
- 2本目の動画(20秒)を 0 ~ 15秒切り出し
- 1本目 + 2本目を結合して25秒の動画を出力する
※配列でURLリストを取得しているが結合しているのはとりあえず2つだけ
/**
* 録画ファイルデータ結合
* 複数の.mp4形式のファイルを結合します。
*
* @param inputFileUrlList 入力URLList
* @param outputPath 出力先パス
* @throws org.bytedeco.javacv.FrameRecorder.Exception
* @throws org.bytedeco.javacv.FrameGrabber.Exception
* @throws org.bytedeco.javacv.FrameFilter.Exception
*/
public void mergeMovie(String[] inputFileUrlList, String outputPath)
throws org.bytedeco.javacv.FrameRecorder.Exception, org.bytedeco.javacv.FrameGrabber.Exception,
org.bytedeco.javacv.FrameFilter.Exception {
int audioSample = 0;
String format = "mp4";
double videoQuality = 1;
Long startTimeStamp = 10000000; // 1秒 = 1,000,000 で開始時間の調整が可能(← 開始10秒から切り出し)
Long endTimeStamp = 15000000; // 15秒で動画を切る
// 入力ファイル1 を取得
FFmpegFrameGrabber grabber1 = new FFmpegFrameGrabber(inputFileUrlList[0]);
grabber1.start();
grabber1.setTimestamp(startTimeStamp);
// 入力ファイル2 を取得
FFmpegFrameGrabber grabber2 = new FFmpegFrameGrabber(inputFileUrlList[1]);
grabber2.start();
// 出力動画ファイルの設定
int imageWidth = grabber1.getImageWidth();
int imageHeight = grabber1.getImageHeight();
double frameRate = grabber1.getFrameRate();
FFmpegFrameRecorder mRecorder = new FFmpegFrameRecorder(outputPath, imageWidth, imageHeight, audioSample); //パス、サイズ、音声を使うかを指定
mRecorder.setFormat(format); // 動画の拡張子
mRecorder.setVideoCodec(avcodec.AV_CODEC_ID_H264); // 動画の拡張子
mRecorder.setVideoQuality(videoQuality); // 映像品質
mRecorder.setFrameRate(frameRate); // フレームレート
mRecorder.setVideoOption("preset", "ultrafast"); // エンコード速度設定
mRecorder.setTimestamp(0);
double gop = 1;
mRecorder.setGopSize((int) (frameRate * gop)); // GoP長
mRecorder.start(); // 開始
Frame frame;
// 入力ファイル1 を出力
while ((frame = grabber1.grabFrame()) != null) {
mRecorder.record(frame);
}
// 入力ファイル2 を出力(結合)(フレームのタイムスタンプにより終了時間を調整)
while (((frame = grabber2.grabFrame()) != null) && (frame.timestamp < endTimeStamp)) {
mRecorder.record(frame);
}
// 開放
mRecorder.stop();
mRecorder.close();
mRecorder.release();
grabber1.stop();
grabber1.close();
grabber1.release();
grabber2.stop();
grabber2.close();
grabber2.release();
}