简体   繁体   English

Android手机作为实时MJPEG视频服务器

[英]Android Phone as Realtime MJPEG Video Server

I'm trying to use my phone as a realtime MJPEG video source. 我正在尝试将手机用作实时MJPEG视频源。 So far, capturing frames and converting them into JPEGs is no big deal. 到目前为止,捕获帧并将其转换为JPEG并不是什么大问题。 My real issue is sending the multipart response properly. 我真正的问题是正确发送多部分响应。 There's tons of documentation about sending multipart responses out there, but the issue with them is that they all expect that all of the images are available at the time the HTTP request comes in (such as would be used for a multi-image upload). 有很多关于发送多部分响应的文档,但是它们的问题是它们都希望在HTTP请求进入时所有图像都可用(例如用于多图像上传)。 In order to stream in realtime, of course, I need to be able to begin to send the multipart response while continually adding jpegs in the body. 当然,为了实时流式传输,我需要能够开始发送多部分响应,同时在身体中不断添加jpeg。 I'm by no means a HTTP buff, so it's not desirable for me be required to roll my own HTTP response and write directly to a socket. 我绝不是一个HTTP buff,因此我不希望自己滚动自己的HTTP响应并直接写入套接字。 Is there a library out there that supports this kind of behavior? 那里有一个支持这种行为的图书馆吗? I've scoured the internet for solutions, but I really don't see anything useful out there. 我已经在互联网上寻找解决方案,但我真的没有看到任何有用的东西。

Any ideas? 有任何想法吗? Worst case scenario, I'd be willing to look at human-readable documentation of how to write a multipart response by hand, but I'd really just rather use a library if that's possible. 最糟糕的情况是,我愿意看看如何手动编写多部分响应的人类可读文档,但如果可能的话,我真的只是使用库。

Thanks in advance. 提前致谢。

edit: got it working using the orielly servlet library as per sigmavirus' suggestion. 编辑:根据sigmavirus的建议使用orielly servlet库使其正常工作。 Note that the MJPEG stream is more or less implicitly inferred from the fact that I'm sending a multipart/x-mixed-replace that only has image/jpeg's in it. 请注意,MJPEG流或多或少是从我发送只包含image / jpeg的multipart / x-mixed-replace的事实中隐式推断出来的。 Check out the comment in my code for a tutorial that shows what jetty libraries you'll need to get this running. 查看我的代码中的注释,以获得一个教程,该教程显示了运行这些库所需的jetty库。 Of course, you'll additionally need cos.jar, the Orielly servlet library. 当然,你还需要cos.jar,Orielly servlet库。 The code follows: 代码如下:

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() 
 {

 }

} }

Have you seen this? 你见过这个吗? http://www.servlets.com/cos/javadoc/com/oreilly/servlet/MultipartResponse.html It looks like the example sends each part individually and waits a specified time limit before sending the next or receiving an interrupt. http://www.servlets.com/cos/javadoc/com/oreilly/servlet/MultipartResponse.html看起来该示例单独发送每个部分并在发送下一个或接收中断之前等待指定的时间限制。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM