2009-04-24 9 views
0

Ich habe einen Strom von Jpegs Bilder‘und ich versuche, sie zu VLCKann Jpegs nicht Bilder über HTTP in C# streamen

Der Code, wenn der folgende mit HTTP-Stream:

public HttpListenerResponse StartListening(String where) 
    { 
     listener = new HttpListener(); 
     listener.Start(); 
     Console.WriteLine("listening on " + where); 
     listener.Prefixes.Add(where); 
     HttpListenerContext context = listener.GetContext(); 
     HttpListenerRequest request = context.Request; 
     // Obtain a response object. 
     HttpListenerResponse response = context.Response; 
     return response; 
    } 
public void StartStream() 
    { 
     HttpListenerResponse response = StartListening("http://localhost:8080/"); 
     MemoryStream mem = null; 

     for (;;) 
     { 
      Bitmap b = generateBitmap(); 
      //pictureBox1.Image = frm.GetFormImage(); 
      byte[] ar = BitmapToArray(b); 


      // Construct a response. 
      byte[] buffer = ar; 
      response.ContentType = "multipart/x-mixed-replace; boundary=--testboundary"; 
      ASCIIEncoding ae = new ASCIIEncoding(); 
      byte[] boundary = ae.GetBytes("\r\n--testboundary\r\nContent-Type: image/jpeg\r\nContent-Length:" + buffer.Length + "\r\n\r\n"); 
      mem = new MemoryStream(boundary); 
      mem.WriteTo(response.OutputStream); 
      mem = new MemoryStream(buffer); 
      mem.WriteTo(response.OutputStream); 
     } 
     mem.Close(); 
     listener.Stop();  

    } 

Aus irgendeinem Grund, wenn ich versuche, den Stream in Firefox zu öffnen, kommt es schwarz zurück, wenn ich versuche, es mit VLC zu öffnen, bekomme ich "Unable to open stream"

Wenn ich nur 1 Bild streamen, Firefox hat kein Problem damit klarkommen.

Tks im Voraus, Jose

Antwort

3

Sie können eine mehrteilige Bereichsanfrage versuchen. VLC fordert die Daten möglicherweise in "Chunks" an, aber Ihr HTTPHandler stellt diese Funktionalität nicht zur Verfügung. Hier ist ein kleiner (langer) Beispielcode unten. Ich hatte ein ähnliches Problem, wenn ich Musik auf meinen iPod Touch streamen wollte. Arbeitete wie ein Zauberer in Brower, arbeitete aber nicht mit dem Touch. Es stellte sich heraus, dass der iPod byte [] Chunks über mehrere Anfragen an meinen Handler anforderte, aber der Handler implementierte die benötigte Funktionalität nicht.

Ich habe einige meiner eigenen Bibliotheksklassen hier reingemischt, aber Sie werden das Bild gut genug bekommen.

public abstract class MultipartRangeHandler : IHttpHandler 
{ 
    protected const String HEADER_RANGE = "range"; 
    protected const String HEADER_CONTENT_TYPE = "Content-Type"; 
    protected const String HEADER_CONTENT_LENGTH = "Content-Length: "; 
    protected const String HEADER_CONTENT_DISPOSITION = "Content-Disposition"; 
    protected const String HEADER_CONTENT_RANGE = "Content-Range"; 
    protected const String HEADER_BOUNDARY_DELIMETER = "--"; 
    protected const String HEADER_STATUS_PARTIAL_CONTENT = "Partial Content"; 

    private const char COMMA = ','; 
    private const char EQUALS = '='; 
    private const char NEW_LINE = '\n'; 

    protected const String QS_OBJECT_ID = "cid"; 

    public void ProcessRequest(HttpContext context) 
    { 
     if (StringUtils.isNullOrEmpty(context.Request.QueryString[QS_OBJECT_ID])) 
     { 
      sendResponse(400, "400 Bad Request", "No resource was specified in the query string to retrieve.", context); 
     } 
     else 
     { 
      ContentItem contentItem = getContentItem(context.Request.QueryString[QS_OBJECT_ID]); 

      if (contentItem != null) 
      { 
       context.Response.Clear(); 
       context.Response.ClearHeaders(); 
       context.Response.ClearContent(); 

       if (context.Request.Headers[HEADER_RANGE] != null) 
       { 

        string range = context.Request.Headers[HEADER_RANGE]; 
        range = range.Substring(range.LastIndexOf(EQUALS) + 1); 
        bool isMultipartRange = range.Contains(COMMA.ToString()); 

        if (!isMultipartRange) 
        { 
         addHeader(context.Response, HEADER_CONTENT_TYPE, contentItem.MimeType); 
         addHeader(context.Response, HEADER_CONTENT_DISPOSITION, "inline; filename=\"" + contentItem.Filename + "\""); 

         string[] startEnd = range.Split('-'); 

         long startPos; 

         long.TryParse(startEnd[0], out startPos); 

         long endPos; 
         int fileSize = contentItem.FileBytes.Length; 

         if (startEnd.GetUpperBound(0) >= 1 && startEnd[1] != String.Empty) 
         { 
          long.TryParse(startEnd[1], out endPos); 
         } 
         else 
         { 
          endPos = fileSize - startPos; 
         } 

         if (endPos > fileSize) 
         { 
          endPos = fileSize - startPos; 
         } 

         context.Response.StatusCode = 206; 
         context.Response.StatusDescription = HEADER_STATUS_PARTIAL_CONTENT; 
         addHeader(context.Response, HEADER_CONTENT_RANGE, "bytes " + startPos + "-" + endPos + "/" + fileSize); 

         context.Response.BinaryWrite(ByteUtils.subByte(contentItem.FileBytes, (int)startPos, (int)(endPos - startPos) + 1)); 
        } 
        else 
        { 

         string boundary = "waynehartmanansmach"; 
         addHeader(context.Response, HEADER_CONTENT_TYPE, "multipart/byteranges; boundary=" + boundary); 

         List<string[]> ranges = new List<string[]>(); 
         string[] multiRange = range.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries); 
         foreach (string mr in multiRange) 
         { 
          ranges.Add(mr.Split(new string[] { "-" }, StringSplitOptions.RemoveEmptyEntries)); 
         } 

         // process the list of ranges 
         foreach (string[] rangeArray in ranges.ToArray()) 
         { 
          context.Response.Write(HEADER_BOUNDARY_DELIMETER + boundary + NEW_LINE); 
          context.Response.Write(HEADER_CONTENT_TYPE + ": " + contentItem.MimeType + NEW_LINE); 
          context.Response.Write(HEADER_CONTENT_RANGE + ": bytes " + rangeArray[0] + "-" + rangeArray[1] + "/" + contentItem.FileBytes + NEW_LINE + NEW_LINE); 
          long startPos = long.Parse(rangeArray[0]); 
          long endPos = long.Parse(rangeArray[1]); 

          context.Response.BinaryWrite(ByteUtils.subByte(contentItem.FileBytes, (int)startPos, (int)(endPos - startPos) + 1)); 

          context.Response.Write(NEW_LINE); 
          context.Response.Flush(); 
         } 

         context.Response.Write(HEADER_BOUNDARY_DELIMETER + boundary + HEADER_BOUNDARY_DELIMETER + NEW_LINE + NEW_LINE); 
        } 
       } 
       else 
       { 
        context.Response.ContentType = contentItem.MimeType; 
        addHeader(context.Response, HEADER_CONTENT_DISPOSITION, "attachment; filename=\"" + contentItem.Filename + "\""); 
        addHeader(context.Response, HEADER_CONTENT_LENGTH, contentItem.FileBytes.Length.ToString()); 

        context.Response.OutputStream.Write(contentItem.FileBytes, 0, contentItem.FileBytes.Length); 
       } 
      } 
      else 
      { 
       sendResponse(404, "404 Not Found", "The resource requested does not exist.", context);      
      } 
     } 
    } 

    private void sendResponse(int statusCode, String status, String statusMessage, HttpContext context) 
    { 
     System.Text.StringBuilder data = new System.Text.StringBuilder(); 

     data.AppendLine("<html><body>"); 
     data.AppendLine("<h1>"+status+"</h1>"); 
     data.AppendLine("<p>"+statusMessage+"</p>"); 
     data.AppendLine("</body></html>"); 

     byte[] headerData = System.Text.Encoding.ASCII.GetBytes(data.ToString()); 

     context.Response.ContentType = "text/html"; 
     context.Response.StatusCode = statusCode; 
     context.Response.Status = status; 

     addHeader(context.Response, HEADER_CONTENT_LENGTH, headerData.Length.ToString()); 

     //context.Response.AddHeader("Content-Length: ", headerData.Length.ToString()); 
     context.Response.OutputStream.Write(headerData, 0, headerData.Length); 
     context.Response.End(); 
    } 

    protected void addHeader(HttpResponse response, String key, String value) 
    { 
     response.AddHeader(key, value); 
    } 

    protected abstract com.waynehartman.util.web.handlers.multipartrange.ContentItem getContentItem(String objectID); 

    public bool IsReusable 
    { 
     get { return true; } 
    } 
} 
0

Legen Sie Ihre Präfixe, dann Anruf Start().

Von dem, was ich im Code und anderswo gesehen habe, können Sie Daten nicht mit HttpListener streamen. Sie müssen die Anforderung möglicherweise an einen anderen lokalen TCP-Socket weiterleiten, der die Daten zurückschreibt.

+0

Das funktioniert auch nicht – user361526

Verwandte Themen