使用 Java FFMPEG 将文件从一种格式转换为另一种格式

Mehvish Ashiq 2023年10月12日
  1. Fast-forward MPEG (FFMPEG)
  2. 使用 Java 运行时执行 FFMPEG 将文件从一种格式转换为另一种格式
  3. 使用 FFMPEG 的 Java 包装器
  4. 优先考虑 Java 运行时执行 FFMPEG 而不是 Java FFMPEG Wrapper 或反之亦然的原因
使用 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、VLC 媒体播放器等。

使用 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 并运行代码。

如果我们只执行一次代码并制作一个 .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 运行时执行 FFMPEG 而不是 Java FFMPEG Wrapper 或反之亦然的原因

这是一个固执己见的观点,因人而异,但有一个非常明确的答案。

如果我们想以编程方式使用 FFMPEG 并解决 Java 应用程序中的问题,我们会选择 Java FFMPEG 包装器。在这里,我们可以根据我们的需求定义我们的逻辑,或者使用已经编写好的 API 来完成我们的任务。

通过使用 API,我们可以实现编译时安全、调用内置方法等等。如果我们不想弄乱 API 并寻找简单的解决方案,那么 CLI 选项是首选。

在这里,我们手动键入命令来完成任务。试想一下,如果我们每天必须为一个复杂的项目输入数千条命令?

长话短说,CLI 仅适用于简单的项目,但 Java Wrapper 可用于自动化事物并有利于复杂的项目。

作者: Mehvish Ashiq
Mehvish Ashiq avatar Mehvish Ashiq avatar

Mehvish Ashiq is a former Java Programmer and a Data Science enthusiast who leverages her expertise to help others to learn and grow by creating interesting, useful, and reader-friendly content in Computer Programming, Data Science, and Technology.

LinkedIn GitHub Facebook