2009-04-24 9 views
0

J'ai un flux d'images JPEG et je suis en train de les diffuser avec HTTP VLCImpossible diffuser des images Jpeg sur http en C#

Le code si les conditions suivantes:

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

    } 

Pour une raison quelconque, Si j'essaie d'ouvrir le flux dans Firefox il revient tout noir, Si j'essaie de l'ouvrir avec VLC je reçois "Impossible d'ouvrir le flux"

Si je ne stream que 1 image, firefox n'a pas de problème traiter avec.

TKS à l'avance, Jose

Répondre

3

Vous pouvez tenter une demande de plage en plusieurs parties. VLC peut demander les données en «morceaux», mais votre HTTPHandler ne fournit pas cette fonctionnalité. Voici un exemple de code (long) ci-dessous. J'ai eu un problème similaire en essayant de diffuser de la musique sur mon iPod Touch. Travaillé comme un charme dans le sourcil, mais n'a pas travaillé avec le toucher. Il s'avère que l'iPod demandait des octets [] en plusieurs requêtes à mon gestionnaire, mais le gestionnaire n'a pas implémenté la fonctionnalité dont il avait besoin.

Je me suis mêlé à certains de mes propres cours de bibliothèque ici, mais vous obtiendrez assez bien l'image.

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

Définissez vos préfixes, puis appel Start(). D'après ce que j'ai vu dans le code et ailleurs, vous ne pouvez pas streamer des données en utilisant HttpListener. Vous devrez peut-être transférer la demande vers un autre socket TCP local qui réécrit les données.

+0

Cela ne marche pas non plus – user361526

Questions connexes