2013-01-08 37 views
3

我試圖將我的手機用作實時MJPEG視頻源。到目前爲止,捕獲幀並將其轉換爲JPEG並不是什麼大不了的事情。我真正的問題是正確地發送multipart響應。關於發送多部分響應的文檔有很多,但問題在於他們都希望所有圖像在HTTP請求進入時都可用(例如用於多圖像上傳)。爲了實時流式傳輸,當然,我需要能夠開始發送多部分響應,同時不斷在主體中添加jpeg。我絕不是一個HTTP緩衝區,所以我不需要推出自己的HTTP響應並直接寫入套接字。有支持這種行爲的圖書館嗎?我在互聯網上尋找解決方案,但我真的沒有看到任何有用的東西。作爲實時MJPEG視頻服務器的Android手機

任何想法?最糟糕的情況是,我願意看看如何手動編寫多部分響應的人類可讀文檔,但如果可能的話,我真的只想使用一個庫。

在此先感謝。

編輯:根據sigmavirus的建議使用orielly servlet庫得到它的工作。請注意,MJPEG流或多或少是通過我發送只包含圖像/ jpeg的multipart/x-mixed-replace的事實來隱含推斷的。查看我的代碼中的評論以獲得一個教程,該教程顯示了您需要運行哪些碼頭庫。當然,你還需要cos.jar,Orielly servlet庫。代碼如下:

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

} 

}

+0

不好意思,我的JettyServer類擴展了Thread但是什麼也沒做。你不需要那樣做。這只是我的代碼的方向。 – mercurytw

回答

1

你見過嗎? http://www.servlets.com/cos/javadoc/com/oreilly/servlet/MultipartResponse.html看起來這個例子單獨發送每個部分並在發送下一個或接收中斷之前等待指定的時間限制。

+0

你知道嗎,我記得碰到過這個。這個庫取決於一些其他的庫,它們沒有安裝Android,所以我沒有去追求它。我想我會再次嘗試這個,因爲它似乎確實滿足了我的需求。 – mercurytw

+0

就像我說的,如果你把它貼在@ quora上,我會確保200多人也看到它。他們可能在那裏有一些見解。 –

相關問題