pee*_*tss 3 java transcode mp3 servlets ffmpeg
基本上,这就是我要做的事情:1.用户将URL作为GET参数传递给我的servlet.2. Servlet使用ProcessBuilder将该URL中包含的媒体转换为有效的媒体格式(即:MP3).3. servlet将由FFMPEG转码的输出文件流回到浏览器.
1和2工作正常,但它是3我有问题.我能做的最好的事情是为正在转码的输出文件创建一个FileInputStream,并将其作为响应发送,但它不起作用.我的猜测是,因为我正在尝试流式传输文件.
无论如何拦截FFMPEG中的输出文件参数并将其读入InputStream?在我看来,似乎不应该难以获取输入文件A,将其转码为输出文件B,然后将输出文件B流式传输回客户端.
ProcessBuilder pb = new ProcessBuilder("ffmpeg.exe", "-i", url, "file.mp3");
Process p = pb.start();
final InputStream inStream = p.getErrorStream();
new Thread(new Runnable() {
public void run() {
InputStreamReader reader = new InputStreamReader(inStream);
Scanner scan = new Scanner(reader);
while (scan.hasNextLine()) {
System.out.println(scan.nextLine());
}
}
}).start();
ServletOutputStream stream = null;
BufferedInputStream buf = null;
try {
stream = response.getOutputStream();
File mp3 = new File(file.mp3");
//set response headers
response.setContentType("audio/mpeg");
response.addHeader("Content-Disposition", "attachment; filename=file.mp3");
response.setContentLength(-1);
//response.setContentLength((int) mp3.length());
FileInputStream input = new FileInputStream(mp3);
buf = new BufferedInputStream(input);
int readBytes = 0;
//read from the file; write to the ServletOutputStream
while ((readBytes = buf.read()) != -1) {
stream.write(readBytes);
}
} catch (IOException ioe) {
throw new ServletException(ioe.getMessage());
} finally {
if (stream != null) {
stream.close();
}
if (buf != null) {
buf.close();
}
}
Run Code Online (Sandbox Code Playgroud)
FFmpeg不必写入文件.它可以写入stdout:
ffmpeg -i $input -f mp3 -
Run Code Online (Sandbox Code Playgroud)
-意味着标准输出.由于没有文件名,您需要指定格式-f.
如果你像这样调用它,你可以直接从Process's 读取mp3流InputStream.