基本的に、これは私がやろうとしていることです: 1. ユーザーは URL を GET パラメーターとしてサーブレットに渡します。2. サーブレットは ProcessBuilder を使用して、その URL に含まれるメディアを有効なメディア形式 (つまり、MP3) に変換します。3. サーブレットは、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();
}
}