携帯電話をリアルタイムの MJPEG ビデオ ソースとして使用しようとしています。これまでのところ、フレームをキャプチャして JPEG に変換することは大したことではありません。私の本当の問題は、マルチパート応答を適切に送信することです。マルチパート レスポンスの送信に関するドキュメントは山ほどありますが、それらの問題は、HTTP リクエストが受信された時点ですべての画像が利用可能であると想定していることです (マルチ画像のアップロードに使用される場合など)。もちろん、リアルタイムでストリーミングするには、本体に jpeg を継続的に追加しながら、マルチパート レスポンスの送信を開始できる必要があります。私は決して HTTP バフではないので、自分の HTTP 応答をロールしてソケットに直接書き込む必要があるのは望ましくありません。この種の動作をサポートするライブラリはありますか? インターネットで解決策を探しましたが、
何か案は?最悪の場合、マルチパート レスポンスを手動で記述する方法について人間が読める形式のドキュメントを参照したいと思いますが、可能であればライブラリを使用したいと思います。
前もって感謝します。
編集: sigmavirus の提案に従って orielly サーブレット ライブラリを使用して動作するようになりました。MJPEG ストリームは、image/jpeg のみを含む multipart/x-mixed-replace を送信しているという事実から、多かれ少なかれ暗黙のうちに推測されることに注意してください。これを実行するために必要な jetty ライブラリを示すチュートリアルについては、私のコードのコメントを確認してください。もちろん、Orielly サーブレット ライブラリである cos.jar も追加で必要です。コードは次のとおりです。
package edu.stevens.arpac.webclient;
import java.io.IOException;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Collections;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletRequest;
import org.apache.http.conn.util.InetAddressUtils;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.Request;
import com.oreilly.servlet.MultipartResponse;
import com.oreilly.servlet.ServletUtils;
import android.os.Environment;
import android.util.Log;
// holla at http://puregeekjoy.blogspot.com/2011/06/running-embedded-jetty-in-android-app.html
public class JettyServer extends Thread
{
private static final String TAG = "JettyServer";
private Server webServer;
private Boolean isStarted = false;
public JettyServer()
{
super();
Log.i(TAG, "Initializing server to port 8080");
webServer = new Server(8080);
Handler handler = new AbstractHandler() {
public void handle(String target, Request request, HttpServletRequest servletRequest,
HttpServletResponse servletResponse) throws IOException, ServletException {
ServletOutputStream out = servletResponse.getOutputStream();
MultipartResponse multi = new MultipartResponse(servletResponse);
Boolean go = true;
while( go )
{
try
{
multi.startResponse("image/jpeg");
ServletUtils.returnFile(Environment.getExternalStorageDirectory().getPath() + "/ARPac/twi.jpg", out);
multi.endResponse();
}
catch(IOException ex)
{
go = false;
Log.i(TAG, "IO Failed with exception " + ex.getMessage());
}
}
request.setHandled(true);
}
};
webServer.setHandler(handler);
try {
webServer.start();
Log.d(TAG, "started Web server @ " + getIPAddress());
isStarted = true;
}
catch (Exception e) {
Log.d(TAG, "unexpected exception starting Web server: " + e);
}
}
/**
* Get IP address from first non-localhost interface
* @return address or empty string
*/
private String getIPAddress()
{
try
{
List<NetworkInterface> interfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
for (NetworkInterface intf : interfaces)
{
List<InetAddress> addrs = Collections.list(intf.getInetAddresses());
for (InetAddress addr : addrs)
{
if (!addr.isLoopbackAddress())
{
String sAddr = addr.getHostAddress().toUpperCase();
if (InetAddressUtils.isIPv4Address(sAddr))
{
//Log.d(TAG, "IP address is: " + sAddr);
return sAddr;
}
}
}
}
}
catch (Exception ex)
{
Log.e(TAG, "could not get IP address: " + ex.getMessage());
} // for now eat exceptions
Log.e(TAG, "Could not find a non-loopback IPv4 address!");
return "";
}
public void teardown()
{
if( isStarted )
{
try {
webServer.stop();
isStarted = false;
} catch (Exception e) {
Log.e(TAG, "Couldn't stop server. Probably was called when server already stopped.");
}
}
}
public void run()
{
}
}