package cn.org.hentai.jtt1078.util;
|
|
import java.io.*;
|
import java.nio.file.*;
|
|
public class AudioConverter {
|
|
public static byte[] convertWebmToPcm(byte[] webmBytes) throws IOException, InterruptedException {
|
// 1. 创建临时文件(自动删除)
|
File inputFile = File.createTempFile("audio", ".webm");
|
File outputFile = File.createTempFile("pcm", ".raw");
|
|
try {
|
// 2. 写入输入文件
|
Files.write(inputFile.toPath(), webmBytes);
|
|
// 3. 构建 FFmpeg 命令
|
ProcessBuilder pb = new ProcessBuilder(
|
"ffmpeg",
|
"-i", inputFile.getAbsolutePath(), // 输入文件
|
"-f", "s16le", // PCM 16-bit little-endian
|
"-acodec", "pcm_s16le", // 音频编码器
|
"-ar", "8000", // 采样率 8kHz
|
"-ac", "1", // 单声道
|
"-y", // 覆盖输出文件(如果存在)
|
outputFile.getAbsolutePath()
|
);
|
|
// 4. 捕获错误流(关键!)
|
pb.redirectErrorStream(true); // 合并标准输出和错误流
|
Process process = pb.start();
|
|
// 5. 读取 FFmpeg 输出(调试用)
|
try (BufferedReader reader = new BufferedReader(
|
new InputStreamReader(process.getInputStream()))) {
|
String line;
|
while ((line = reader.readLine()) != null) {
|
System.out.println("[FFmpeg] " + line); // 打印 FFmpeg 日志
|
}
|
}
|
|
// 6. 等待转换完成
|
int exitCode = process.waitFor();
|
if (exitCode != 0) {
|
throw new IOException("FFmpeg 转换失败,退出码: " + exitCode);
|
}
|
|
// 7. 读取 PCM 数据
|
return Files.readAllBytes(outputFile.toPath());
|
} finally {
|
// 8. 清理临时文件
|
inputFile.delete();
|
outputFile.delete();
|
}
|
}
|
public static void convertWebmToMp3(File webmFile, File mp3File) throws IOException, InterruptedException {
|
ProcessBuilder pb = new ProcessBuilder(
|
"ffmpeg", "-y",
|
"-i", webmFile.getAbsolutePath(),
|
"-ar", "44100", // 转换为标准 MP3 采样率
|
"-ac", "2", // 立体声
|
"-b:a", "128k",
|
mp3File.getAbsolutePath()
|
);
|
|
pb.redirectErrorStream(true);
|
Process process = pb.start();
|
process.waitFor();
|
}
|
}
|