提取视频中的声音

1. JAVE 简介

JAVE(Java Audio Video Encoder)是一个开源的 Java 库,专门用于处理多媒体文件的编码和解码操作。JAVE 支持多种格式的音频和视频文件,提供了诸如格式转换、音频提取、视频帧截取等常见的多媒体处理功能。JAVE 底层通过封装 FFmpeg 实现多媒体处理,因此能够执行多种复杂的音视频操作。

2. Tio-boot 整合 JAVE

1. 如何使用 JAVE 提取视频中的音频

要使用 JAVE 提取视频中的音频,你可以按照以下步骤操作:

a. 添加 Maven 依赖

首先,在你的 pom.xml 文件中添加 JAVE 的依赖。jave-all-deps 是一个依赖项较多的库,请根据实际需求谨慎使用。

<dependency>
    <groupId>ws.schild</groupId>
    <artifactId>jave-all-deps</artifactId>
    <version>3.5.0</version>
</dependency>

你可以运行以下命令查看依赖树:

mvn dependency:tree

在实际部署时,请根据操作系统选择合适的依赖:

[INFO] +- ws.schild:jave-all-deps:jar:3.5.0:compile
[INFO] |  +- ws.schild:jave-core:jar:3.5.0:compile
[INFO] |  +- ws.schild:jave-nativebin-win32:jar:3.5.0:compile
[INFO] |  +- ws.schild:jave-nativebin-win64:jar:3.5.0:compile
[INFO] |  +- ws.schild:jave-nativebin-linux32:jar:3.5.0:compile
[INFO] |  +- ws.schild:jave-nativebin-linux64:jar:3.5.0:compile
[INFO] |  +- ws.schild:jave-nativebin-osx64:jar:3.5.0:compile
[INFO] |  +- ws.schild:jave-nativebin-osxm1:jar:3.5.0:compile
[INFO] |  +- ws.schild:jave-nativebin-linux-arm32:jar:3.5.0:compile
[INFO] |  \- ws.schild:jave-nativebin-linux-arm64:jar:3.5.0:compile

b. 提取视频中的音频

以下是使用 JAVE 提取视频文件中音频的代码示例:

import ws.schild.jave.Encoder;
import ws.schild.jave.MultimediaObject;
import ws.schild.jave.AudioAttributes;
import ws.schild.jave.EncodingAttributes;

import java.io.File;

public class AudioExtractor {

    public static void main(String[] args) throws Exception {
        File source = new File("input/video.mp4");
        File target = new File("output/audio.mp3");

        // 设置音频属性
        AudioAttributes audio = new AudioAttributes();
        audio.setCodec("libmp3lame");
        audio.setBitRate(128000);
        audio.setChannels(2);
        audio.setSamplingRate(44100);

        // 设置编码属性
        EncodingAttributes attrs = new EncodingAttributes();
        attrs.setFormat("mp3");
        attrs.setAudioAttributes(audio);

        // 开始编码
        Encoder encoder = new Encoder();
        encoder.encode(new MultimediaObject(source), target, attrs);
    }
}

此代码将视频文件中的音频提取并保存为 MP3 文件。

2. 整合 Tio-boot 进行文件上传并返回 MP3 音频

下面的代码示例展示了如何使用 Tio-boot 整合 JAVE,实现文件上传、音频提取并返回 MP3 文件给客户端:

import java.io.File;

import com.litongjava.tio.boot.http.TioRequestContext;
import com.litongjava.tio.http.common.HttpResponse;
import com.litongjava.tio.http.common.UploadFile;
import com.litongjava.tio.http.server.annotation.EnableCORS;
import com.litongjava.tio.http.server.annotation.RequestPath;
import com.litongjava.tio.http.server.util.Resps;
import com.litongjava.tio.utils.hutool.FileUtil;
import com.litongjava.tio.utils.resp.RespVo;

import ws.schild.jave.Encoder;
import ws.schild.jave.EncoderException;
import ws.schild.jave.InputFormatException;
import ws.schild.jave.MultimediaObject;
import ws.schild.jave.encode.AudioAttributes;
import ws.schild.jave.encode.EncodingAttributes;

@RequestPath("/api/v1/media")
@EnableCORS
public class ApiV1MediaController {

  public HttpResponse toMp3(UploadFile file) {

    HttpResponse response = TioRequestContext.getResponse();

    if (file == null) {
      response.setStatus(400);
      response.setJson(RespVo.fail("上传文件为空"));
      return response;
    }

    String inputFolderName = "input";
    String outputFolderName = "output";

    byte[] fileData = file.getData();
    File inputFolder = new File(inputFolderName);
    if (!inputFolder.exists()) {
      inputFolder.mkdirs();
    }
    File outputFolder = new File(outputFolderName);

    if (!outputFolder.exists()) {
      outputFolder.mkdirs();
    }

    File source = new File(inputFolderName + "/" + file.getName());
    FileUtil.writeBytes(fileData, source);

    File target = new File(outputFolder + "/audio.mp3");

    // 设置音频属性
    AudioAttributes audio = new AudioAttributes();
    audio.setCodec("libmp3lame");
    audio.setBitRate(128000);
    audio.setChannels(2);
    audio.setSamplingRate(44100);

    // 设置编码属性
    EncodingAttributes attrs = new EncodingAttributes();
    attrs.setInputFormat("mp4");
    attrs.setOutputFormat("mp3");
    attrs.setAudioAttributes(audio);

    // 开始编码
    Encoder encoder = new Encoder();
    try {
      encoder.encode(new MultimediaObject(source), target, attrs);
    } catch (IllegalArgumentException | InputFormatException | EncoderException e) {
      e.printStackTrace();
    }

    byte[] bytes = FileUtil.readBytes(target);
    return Resps.bytesWithContentType(response, bytes, "audio/mp3");
  }
}

这个示例展示了如何通过 Tio-boot 创建一个 API 来接收视频文件,提取音频并返回 MP3 文件给客户端。