java 调用ffmpeg_使用java调用FFMPEG进行转码

本文介绍如何使用Java调用FFmpeg工具进行流媒体转码。通过Runtime.getRuntime().exec(cmd)启动FFmpeg进程,并创建线程分别读取标准输出和错误流,确保进程不会阻塞。示例代码展示了从rtmp源转码到另一个rtmp目标的过程。
部署运行你感兴趣的模型镜像

使用java调用FFMPEG进行转码

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.io.OutputStream;

public class TestFFmpeg {

static String ffmpeg_cmd = "/home/andrew/Work/FFmpeg/ffmpeg-3.2/ffmpeg";

//static String in = "/home/andrew/Work/FFmpeg/ffmpeg-3.2/test_2200kbps.flv";

//static String out = "/home/andrew/Work/FFmpeg/ffmpeg-3.2/test_out.flv";

static String in = "rtmp://223.203.1.34:1936/live?vhost=cc.com/stream1_1";

static String out = "rtmp://223.203.1.34:1936/live?vhost=cc.com/stream2";

static Process p;

public static void main(String[] args) {

Runtime rt = Runtime.getRuntime() ;

int r = -1;

Thread stoppingThread;

Thread errorStream;

Thread inputStream;

System.out.println(in);

System.out.println(out);

String[] cmd1 = new String[] {ffmpeg_cmd, "-re", "-i", in, "-acodec", "aac", "-ar", "44100", "-vcodec", "copy", "-report" , "-y", "-f", "flv", out};

//String cmd1 = ffmpeg_cmd + " -re" + " -i " + in + " -acodec", " aac", " -ar" + " 44100" + " -vcodec" + " copy" + " -report" + " -y"," -f" + " flv " + out;

try {

System.out.println(cmd1);

p = rt.exec(cmd1);

StopTranscoder stopRunnable = new StopTranscoder(p);

stoppingThread = new Thread(stopRunnable);

stoppingThread.start();

final InputStream is1 = p.getErrorStream ();

final InputStream is2 = p.getInputStream ();

//启动两个线程,一个线程负责读标准输出流,另一个负责读标准错误流

GetStream streamErr = new GetStream(is1);

errorStream = new Thread(streamErr);

errorStream.start();

GetStream streamIn = new GetStream(is2);

inputStream = new Thread(streamIn);

inputStream.start();

System.out.println("waiting for");

try {

r = p.waitFor();

} catch (InterruptedException e) {

e.printStackTrace();

}

} catch (Exception e) {

e.printStackTrace();

}

System.out.println(r);

p.destroy();

}

}

class StopTranscoder implements Runnable {

private Process process = null;

public StopTranscoder(Process proc){

this.process = proc;

}

public void run() {

try {

System.out.println("kill before sleep");

Thread.sleep(10000);

System.out.println("kill after sleep");

this.process.destroy();

} catch (Exception e) {

e.printStackTrace();

}

}

}

class GetStream implements Runnable {

private InputStream is;

public GetStream(InputStream stream) {

is = stream;

}

public void run() {

BufferedReader br = new BufferedReader(new InputStreamReader(is));

try {

String line = null;

while ((line = br.readLine()) != null) {

if (line != null){

System.out.println(line);

}

}

} catch (IOException e) {

e.printStackTrace();

}

finally{

try {

is.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

执行FFMPEG

启动FFMPEG进程,Runtime.getRuntime().exec(cmd)

启动两个线程,一个线程负责读标准输出流,另一个负责读标准错误流

当Runtime对象调用exec(cmd)后,JVM会启动一个子进程,该进程会与JVM进程建立三个管道连接:标准输入,标准输出和标准错误流。假设该程序不断在向标准输出流和标准错误流写数据,而JVM不读取的话,当缓冲区满之后将无法继续写入数据,最终造成阻塞在waitfor()这里。

注释:

之前遇到过调用process.destroy()有可能无法使FFMPEG退出的情况,所以增加了类StopTranscoder()进行测试,但是没有复现之前的问题。

您可能感兴趣的与本文相关的镜像

Qwen-Image-Edit-2509

Qwen-Image-Edit-2509

图片编辑
Qwen

Qwen-Image-Edit-2509 是阿里巴巴通义千问团队于2025年9月发布的最新图像编辑AI模型,主要支持多图编辑,包括“人物+人物”、“人物+商品”等组合玩法

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值