HOWTO · Java

Java FFMPEG を使用してファイルをある形式から別の形式に変換する

この記事では、Java ラッパーと Java ランタイムを使用して FFMPEG を実行し、ファイルをある形式から別の形式に変換する方法を示します。

FFMPEG は、コンテンツクリエーター、またはほとんどの場合メディアファイルを操作するクリエーターに最適です。

今日は、Java FFMPEG ラッパーと Java ランタイムを使用してメディアファイルを変換し、コマンドラインから FFMPEG を実行する方法について説明します。また、一方を他方よりも優先するいくつかの理由についても説明します。

Fast-Forward MPEG(FFMPEG)

Fast-Forward MPEG(FFMPEG)は、まだ作成されていない多くのマルチメディアファイルのエンコード、デコード、マルチプレクサ、デマルチプレクサ、トランスコード、フィルタリング、ストリーミング、および再生に使用できるオープンソースの無料マルチメディアフレームワークです。

Windows、macOS X、Solaris、Linux で FFMPEG を使用でき、FFMPEG を使用して多くのことを実行できます。これには、回転、トリミング、トリミング、ビデオの反転、ビデオへのフィルターの追加、オーディオ圧縮、ビデオ圧縮、メディアファイルのサイズ変更、フェードイン/アウト、ビデオのさまざまな形式への変換などが含まれます。

プロジェクトのニーズに応じて、それらのいずれかを使用できます。FFMPEG は、メディア関連のソフトウェアプロジェクトの舞台裏で使用されており、iTunes、Plex、Blender、YouTube、VLCMediaPlayer などの多くのソフトウェアの内部部分としても使用されています。

Java ランタイムを使用して FFMPEG を実行し、ファイルをある形式から別の形式に変換する

ここでは、Java ランタイムを使用して FFMPEG を実行し、変換、ファイルサイズの縮小、オーディオの追加、オーディオの抽出、メディアファイルのトリミングなどのさまざまな機能を学習しています。

そのためには、FFMPEG をマシンにインストールする必要があります。お持ちでない場合は、公式サイトからダウンロードできます。

ダウンロードしてインストールすると、さまざまなコマンドを実行して練習できるようになります。それらのいくつかを以下に示します。

コンテナ形式の変換:

/*
By using this command, we are not converting the video
into different codecs but changing the container format
to contain the same video as the input file.
*/
ffmpeg - i input.mkv output1.mp4

ビデオおよびオーディオコーデックの変換:

/*
This command converts the input video file into
`vp9` codec and the audio contained in that container
into the `vorbis ogg` format.
*/
ffmpeg - i input.mkv - c : v vp9 - c : a libvorbis output2.webm

ビデオコーデックのみを変換します。

/*
This command converts the video codec to `vp9` and keeps
the audio codec as it is.
*/
ffmpeg - i input.mkv - c : v vp9 - c : a copy output3.webm

オーディオコーデックのみを変換します。

/*
Here, we convert the audio codec to `libvorbis`
and keep the video codec as it is.
*/
ffmpeg - i input.mkv - c : v copy - c : a libvorbis output4.mkv

ビットレートを下げる:

/*
This command keeps the audio codec as it is, converts
the video codec to `libx264` by reducing the bitrate to `1M`.
*/
ffmpeg - i input.mkv - c : a copy - c : v libx264 - b : v 1M output5.mp4

フレームレートを下げてファイルサイズを小さくします。

/*
This command keeps the audio codec as it is, converts the video
the codec to `libx264` and reduce the fps to 24.
*/
ffmpeg - i input.mkv - c : a copy - c : v libx264 - r 24 output6.mp4

解像度を下げる:

/*
This command keeps the audio codec as it is, converts the video
the codec to `libx264` reduces the resolution to `848x480`.
*/
ffmpeg - i input.mkv - c : a copy - c : v libx264 - s 848x480 output.mp4

ビットレート、解像度、フレームレートを下げる:

/*
This command keeps the audio codec as it is, converts the video
the codec to `libx264`, reduce the resolution to `848x480`, and bitrate for the video to `1M`, and
change fps to 30.
*/
ffmpeg - i input.mkv - c : a copy - c : v libx264 - b : v 1M - r 30 - s 848x480 output.mp4

ビデオファイルのトリミング:

/*
This command trims the video length to 10 seconds, starting
from the given beginning point.
*/
ffmpeg - i input.mkv - ss 00 : 00 : 10 - t 10 output.mkv

オーディオの抽出:

// it extracts the audio from a video file
ffmpeg - i input.mkv - vn output.m4a

オーディオの速度を変更します。

// it speeds up the audio
ffmpeg - i input.mkv - filter : a "atempo=2.0" - vn output.mkv

ビデオの速度を変更する:

// it changes the speed of the video
ffmpeg - i input.mkv - filter : v "setpts=0.125*PTS" output.mp4

以下は、上記の ffmpeg コマンドで使用した各フラグの説明です。

国旗 説明
ffmpeg 使用しているコマンド名。
-i 入力ファイルの後に入力ファイルのパスが続きます。この場合、同じディレクトリに入力ファイルがあります。したがって、その名前を input.mkv と記述しているだけです。
-c:v ビデオファイルのコーデック。
-c:a オーディオファイルのコーデック。
copy コーデックは、その使用に基づいているため、そのままにしてください。 -c:v copy として使用された場合、ビデオファイルのコーデックは同じに保たれます。一方、-c:a copy として使用すると、オーディオトラックがそのまま保持されます。
-b:v ビデオファイルのビットレート。
1M コマンドの実行後に必要な特定のビットレート。
-r フレームレート(fps)の後にフレームレートの数が続きます。
-s サイズスイッチの後に新しいサイズ 848x480 が続きます。
-ss 開始タイムスタンプ。-t は、クリップの実際の長さを秒単位で指定します。
-vn ビデオはありません。入力ファイルから音声を抽出するだけです。
atempo オーディオを遅くしたり速くしたりするために使用されます。
-filter:a/-filter:v オーディオとビデオをそれぞれフィルタリングします。
setpts プレゼンテーションのタイムスタンプを設定します。
vp9/libx264 ビデオファイルのコーデック。
libvorbis オーディオファイルのコーデック。

FFMPEG を使用する Java ラッパー

ここでは、次のツールを使用しています。

  1. Java 18.0.1.1
  2. MongoDB 5.0.8
  3. NetBeans IDE 13
  4. Maven 依存関係をインストールします

サンプルコード:

// replace the package with your own if you have
package com.voidtesting.ffmpeg_java_wrapper;

// import necessary libraries
import java.io.File;
import java.io.IOException;

// FFMPEG_Java_Wrapper class
public class FFMPEG_Java_Wrapper {
  // main
  public static void main(String[] args) {
    // try block
    try {
      // create process
      Runtime rt = Runtime.getRuntime();
      // save the location
      File folder = new File("C:\\Users\\DelftStack\\Desktop\\MediaFiles");
      // save all files in an array that are retrieved from the specified folder
      File[] file = folder.listFiles();

      /*
      for each filename, open the command prompt
      and execute the specified command.
       */
      for (int i = 0; i < file.length; i++) {
        rt.exec("cmd.exe /c start "
                + "ffmpeg -i " + file[i].getName() + " -vn output" + (i + 1) + ".m4a",
            null, folder);
      } // end for

    } // end try
    catch (IOException e) {
      System.out.println(e);
    } // end catch

  } // end main
} // end FFMPEG_Java_Wrapper

このコードは、指定されたディレクトリ内のすべてのビデオファイルを反復処理し、それらからオーディオを抽出して、現在のディレクトリに保存します。このコードを実行するには、毎回 IDE を開いて、コードを実行する必要があります。

コードを 1 回だけ実行し、将来使用するために .jar ファイルを作成するとどうなりますか?そのために、pom.xml ファイルに次のコードを追加します。

サンプルコード:

<build>
        <plugins>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>2.4</version>
                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                    <archive>
                        <manifest>
                            <mainClass>
                               <!--make sure to replace the name
                                   of your Main file here-->
                               com.voidtesting.ffmpeg_java_wrapper
                                .FFMPEG_Java_Wrapper
                            </mainClass>
                        </manifest>
                    </archive>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

コードの実行後、この特定のプロジェクトのすべての .jar ファイルは、Maven のデフォルトディレクトリである C:\Users\AdministratorName\.m2\repository に保存されます。

ファイルを com.voidtesting.ffmpeg_java_wrapper パッケージに保存したため、.jar ファイルは次のパスになります。

C:\Users\Dell\\.m2\repository\com\voidtesting\ffmpeg_java_wrapper\FFMPEG_Java_Wrapper\1.0-SNAPSHOT

必ず yourFileName-1.0-SNAPSHOT-jar-with-dependencies のようなファイルを選択してください。そのファイルをマシンのどこにでも配置して、次のように実行できます。

java -jar FFMPEG_Java_Wrapper-1.0-SNAPSHOT-jar-with-dependencies.jar

Java ランタイムを優先して JavaFFMPEG ラッパーまたはその逆よりも FFMPEG を実行する理由

これは人によって異なる意見のポイントですが、それに対する明確な答えがあります。

プログラムで FFMPEG を使用し、Java アプリケーション内の問題を解決したい場合は、JavaFFMPEG ラッパーを使用します。ここでは、要件に基づいてロジックを定義するか、すでに作成されている API を使用してタスクを完了することができます。

API を使用することで、コンパイル時の安全性を実現したり、組み込みメソッドを呼び出したりすることができます。API をいじって簡単な解決策を探したくない場合は、CLI オプションをお勧めします。

ここでは、コマンドを手動で入力してタスクを実行します。複雑なプロジェクトで毎日何千ものコマンドを入力する必要があるとしたらどうでしょうか。

簡単に言うと、CLI は簡単で単純なプロジェクトにのみ役立ちますが、Java Wrapper は物事を自動化するのに役立ち、複雑なプロジェクトに役立ちます。