当前位置: 首页 > news >正文

【音频处理】java流式调用ffmpeg命令

今天发现一个ffmpeg的用法,用子进程直接从标准输入写入输入,就可以从标准流式输出获取转码结果。
这样的好处是不用去写ffmpeg的代码,只需要写对ffmpeg的命令、在输入输出的地方加缓存就能进行流式转码了,方便快捷。

package ffmpegPro;
import java.io.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;public class Main {public static void main(String[] argv) {ExecutorService executor = Executors.newFixedThreadPool(8);Future<?> f1 = executor.submit(()->{progress("D:\\data\\audio\\a_out.wav","D:\\data\\audio\\a_output.pcm", executor);});Future<?> f2 = executor.submit(()->{progress("D:\\data\\audio\\b_out.wav","D:\\data\\audio\\b_output.pcm", executor);});try {f1.get();f2.get();} catch (InterruptedException | ExecutionException e) {e.printStackTrace();}executor.shutdown();}public static void progress(String inputPath, String outputPath, ExecutorService executor) {try {// 1. 定义 FFmpeg 命令(示例:H264 → VP9,实时转码)String[] ffmpegCmd = {"ffmpeg","-loglevel", "error","-hide_banner", "-nostats", //关闭日志"-f", "wav",      // 输入格式"-i", "pipe:0",    // 从标准输入读取"-f", "s16le",      // 输出格式"-acodec", "pcm_s16le","-ar", "8000",       // 16kHz"-ac", "1",           // 单声道"pipe:1"           // 输出到标准输出};// 2. 启动 FFmpeg 进程ProcessBuilder pb = new ProcessBuilder(ffmpegCmd);Process process = pb.start();// 3. 获取输入/输出流OutputStream ffmpegStdin = process.getOutputStream(); // FFmpeg 的 stdinInputStream ffmpegStdout = process.getInputStream(); // FFmpeg 的 stdoutInputStream ffmpegStderr = process.getErrorStream();  // FFmpeg 的 stderr(日志)// 4. 异步读取转码后的数据(防止阻塞)// 线程1:读取 FFmpeg 的输出(转码后的数据)executor.submit(() -> {byte[] buffer = new byte[8192];int bytesRead;try {FileOutputStream pcmFile = new FileOutputStream(outputPath);while ((bytesRead = ffmpegStdout.read(buffer)) != -1) {// 处理转码后的数据(示例:写入文件或推送到网络)System.out.println("收到转码数据,长度: " + bytesRead);pcmFile.write(buffer, 0, bytesRead);}} catch (IOException e) {e.printStackTrace();}});// 线程2:打印 FFmpeg 的错误日志(调试用)executor.submit(() -> {try (BufferedReader reader = new BufferedReader(new InputStreamReader(ffmpegStderr))) {String line;while ((line = reader.readLine()) != null) {System.err.println("[FFmpeg] " + line);}} catch (IOException e) {e.printStackTrace();}});// 5. 模拟向 FFmpeg 发送原始数据(示例:从文件读取)try (InputStream rawVideoStream = new FileInputStream(inputPath)) {byte[] buffer = new byte[8192];int bytesRead;while ((bytesRead = rawVideoStream.read(buffer)) != -1) {ffmpegStdin.write(buffer, 0, bytesRead);System.out.println("已发送原始数据,长度: " + bytesRead);}ffmpegStdin.close(); // 关闭输入流,通知 FFmpeg 结束} catch (IOException e) {e.printStackTrace();}// 6. 等待 FFmpeg 结束try {int exitCode = process.waitFor();System.out.println("FFmpeg 进程结束,退出码: " + exitCode);} catch (InterruptedException e) {e.printStackTrace();}} catch (Exception e) {e.printStackTrace();}}
}

相关文章:

  • 【穷举】数字方格
  • Nat Commun项目文章 ▏小麦CUTTag助力解析转录因子TaTCP6调控小麦氮磷高效利用机制
  • Linux系统管理与编程24:基础条件准备-混搭“本地+阿里云”yum源
  • mqtt协议连接阿里云平台
  • 华为防火墙NAPT配置
  • Spark-Core Project
  • 深入解析注解框架实现原理:从源码到实战
  • 内存泄漏检测之Valgrind的使用
  • c++数据结构7——二叉树的遍历
  • 从实验室到商用!铁电液晶如何改写显示技术格局?
  • IT Tools 部署
  • 20中数组去重的方法20种数组去重的方法
  • 【数学】求最大公约数问题
  • 贝锐蒲公英工业路由器R300A海外版:支持多国4G频段,全球组网
  • Cadence Allegro中设置主画面最小显示间距
  • JAVA:Kafka 消息可靠性详解与实践样例
  • 常见关系型数据库对比指南
  • 【Linux笔记】Shell-脚本(下)|(常用命令详细版)
  • 利用Python制作环保志愿者招募海报
  • echarts主题切换实现
  • 国内网站开发 框架/seo怎么推广
  • 给政府做网站怎么报价/seo常用的工具
  • 网站的内链建设/磁力吧ciliba
  • 南通网站/网站代理公司
  • 北白象镇做公司网站哪里有/企业网站管理
  • gofair外贸建站/互联网app推广具体怎么做