3

基本上,这就是我想要做的: 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();
        }
    }
4

2 回答 2

6

FFmpeg 不必写入文件。它可以写入标准输出:

ffmpeg -i $input -f mp3 -

-表示标准输出。由于没有文件名,因此您需要使用-f.

如果你这样调用它,你可以直接从Process's读取 mp3 流InputStream

于 2012-10-05T17:00:13.377 回答
1

我想到了。

诀窍不是在文件系统上创建文件并尝试将其流式传输回客户端,而是将 ffmpeg 输出通过管道传输到 Java 中的 InputStream 和 f-in 瞧!

于 2012-10-05T22:02:03.140 回答