LoginSignup
1
0

More than 1 year has passed since last update.

JavaCV で2つのMP4 ファイルを結合 & 開始時間終了時間を指定した切り出しを行う

Posted at

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();
	}

1
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0