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