Java 在某些情况下,ffmpeg取消缩放以初始化线程
我再次发布这个问题,因为我之前发布的问题已经关闭 我在wildfly中运行了一个JAVA服务,它调用外部ffmpeg二进制文件将.au文件转换为.wav文件。正在执行的实际命令如下所示:Java 在某些情况下,ffmpeg取消缩放以初始化线程,java,multithreading,ffmpeg,wildfly,Java,Multithreading,Ffmpeg,Wildfly,我再次发布这个问题,因为我之前发布的问题已经关闭 我在wildfly中运行了一个JAVA服务,它调用外部ffmpeg二进制文件将.au文件转换为.wav文件。正在执行的实际命令如下所示: ffmpeg -y -i INPUT.au OUTPUT.wav 它运行平稳,但由于以下错误,每隔一段时间它就会创建一个空的.wav文件: Error: ffmpeg version c6710aa Copyright (c) 2000-2017 the FFmpeg developers built wi
ffmpeg -y -i INPUT.au OUTPUT.wav
它运行平稳,但由于以下错误,每隔一段时间它就会创建一个空的.wav文件:
Error: ffmpeg version c6710aa Copyright (c) 2000-2017 the FFmpeg
developers
built with gcc 5.4.0 (Ubuntu 5.4.0-6ubuntu1~16.04.4) 20160609
configuration: --prefix=/tmp/ffmpeg-static/target --pkg-config-flags=-
-static --extra-cflags=-I/tmp/ffmpeg-static/target/include --extra-
ldflags=-L/tmp/ffmpeg-static/target/lib --extra-ldexeflags=-static --
bindir=/tmp/ffmpeg-static/bin --enable-pic --enable-ffplay --enable-
ffserver --enable-fontconfig --enable-frei0r --enable-gpl --enable-
version3 --enable-libass --enable-libfribidi --enable-libfdk-aac --
enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --
enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --
enable-librtmp --enable-libsoxr --enable-libspeex --enable-libtheora -
-enable-libvidstab --enable-libvo-amrwbenc --enable-libvorbis --
enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --
enable-libxvid --enable-libzimg --enable-nonfree --enable-openssl
libavutil 55. 34.101 / 55. 34.101
libavcodec 57. 64.101 / 57. 64.101
libavformat 57. 56.101 / 57. 56.101
libavdevice 57. 1.100 / 57. 1.100
libavfilter 6. 65.100 / 6. 65.100
libswscale 4. 2.100 / 4. 2.100
libswresample 2. 3.100 / 2. 3.100
libpostproc 54. 1.100 / 54. 1.100
Input #0, ogg, from 'INPUT.au'
Duration: 00:00:34.08, start: 0.01500, bitrate: 15kb/s
Stream: #0.0: Audio: speex, 8000Hz, mono, s16, 15kb/s
[AVFilterGraph @ 0x43ec6e0] Error initializing threading.
[AVFilterGraph @ 0x43ec6e0] Error creating filter 'anull'
如果我尝试从命令行手动转换文件,它会工作。简短的互联网搜索()表明,这可能是由于ffmpeg
无法创建线程供内部使用。谁能详细说明一下吗
我遇到问题的服务器的负载相对较高。我已经看到wildfly正在创建接近1800个线程
谢谢
顺便说一句,我已经设法重现了这个问题。代码如下:
SystemCommandExecutor.java
import java.io.*;
import java.util.List;
public class SystemCommandExecutor {
private List<String> commandInformation;
private String adminPassword;
private ThreadedStreamHandler inputStreamHandler;
private ThreadedStreamHandler errorStreamHandler;
public SystemCommandExecutor(final List<String> commandInformation)
{
if (commandInformation==null) throw new NullPointerException("The commandInformation is required.");
this.commandInformation = commandInformation;
this.adminPassword = null;
}
public int executeCommand()
throws IOException, InterruptedException
{
int exitValue = -99;
try
{
ProcessBuilder pb = new ProcessBuilder(commandInformation);
Process process = pb.start();
OutputStream stdOutput = process.getOutputStream();
InputStream inputStream = process.getInputStream();
InputStream errorStream = process.getErrorStream();
inputStreamHandler = new ThreadedStreamHandler(inputStream, stdOutput, adminPassword);
errorStreamHandler = new ThreadedStreamHandler(errorStream);
inputStreamHandler.start();
errorStreamHandler.start();
exitValue = process.waitFor();
inputStreamHandler.interrupt();
errorStreamHandler.interrupt();
inputStreamHandler.join();
errorStreamHandler.join();
}
catch (IOException e)
{
throw e;
}
catch (InterruptedException e)
{
throw e;
}
finally
{
return exitValue;
}
}
public StringBuilder getStandardOutputFromCommand()
{
return inputStreamHandler.getOutputBuffer();
}
public StringBuilder getStandardErrorFromCommand()
{
return errorStreamHandler.getOutputBuffer();
}
}
FfmpegRunnable.java
import java.io.IOException;
import java.util.List;
public class FfmpegRunnable implements Runnable {
private List<String> command;
SystemCommandExecutor executor;
public FfmpegRunnable(List<String> command) {
this.command = command;
this.executor = new SystemCommandExecutor(command);
}
@Override
public void run() {
try {
int id = (int) Thread.currentThread().getId();
int result = executor.executeCommand();
if(result != 0) {
StringBuilder err = executor.getStandardErrorFromCommand();
System.out.println("[" + id + "]" + "[ERROR] " + err);
} else {
System.out.println("[" + id + "]" + "[SUCCESS]");
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
这里40是线程数,模拟不同的用户访问系统。每隔一段时间我就会遇到上面提到的错误。为什么要将线程id强制转换为
int
<代码>字符串dest=“/tmp/OUTPUT/OUTPUT_quot+(Math.random()*1000)+”.wav”可能比您预期的更频繁地产生名称冲突…@GyroGearless,我不明白。你是说Math.random()*1000
可能会给我相同的数字吗?我认为这可能是真的,尽管还没有发生。问题是ffmpeg正在使用pthread在内部创建线程,有时会失败。可能您达到了线程限制,ulimit-u
为运行服务的用户显示了什么?运行服务的机器有88个处理单元(输出nproc
)。我已经将ulimit-u
值增加到32768,早些时候是4096。问题仍然存在。
import java.io.IOException;
import java.util.List;
public class FfmpegRunnable implements Runnable {
private List<String> command;
SystemCommandExecutor executor;
public FfmpegRunnable(List<String> command) {
this.command = command;
this.executor = new SystemCommandExecutor(command);
}
@Override
public void run() {
try {
int id = (int) Thread.currentThread().getId();
int result = executor.executeCommand();
if(result != 0) {
StringBuilder err = executor.getStandardErrorFromCommand();
System.out.println("[" + id + "]" + "[ERROR] " + err);
} else {
System.out.println("[" + id + "]" + "[SUCCESS]");
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
public class FfmpegMain {
public static void main(String[] args) {
//boolean threading = false;
System.out.println(args[0]);
int nrThread = Integer.parseInt(args[0]);
boolean threading = Boolean.parseBoolean(args[1]);
System.out.println("nrThread : " + nrThread + ", threading : " + threading);
if(threading) {
System.out.println("ffmpeg threading enabled");
} else {
System.out.println("ffmpeg threading not enabled");
}
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(nrThread);
for(int i=0; i<nrThread*2; i++) {
List<String> cmd = new ArrayList<String>();
String dest = "/tmp/OUTPUT/output_" + (Math.random()*1000) + ".wav";
String cmdStr = "/tmp/FFMPEG/ffmpeg" + (threading ? " -threads 1 " : " ")
+ "-y -i /tmp/input.au " + dest;
cmd.add("/bin/sh");
cmd.add("-c");
cmd.add(cmdStr);
executor.submit(new FfmpegRunnable(cmd));
}
executor.shutdown();
}
}
java -jar JAR.jar 40 true