2013-09-27 47 views
1

是否有人熟悉通過HTTP協議發送的MJPEG文件中提取頭文件的方法?我在C#中遇到過HttpClient類,但是我對它沒有經驗,而且我還沒有看到有關MJPEG流的任何示例。我感謝您的幫助。試圖讀取C#中的MJPEG頭文件

回答

0

我不是專家,但我已經閱讀是一個廣泛的觀點,即MJPEG流封閉在兩個字節單個JPEG圖片的流程:FFD8和FFD9。

使用經過優化的裸C#磚如數組,測試和循環,您可以解析由HttpClient調用返回的流,以關閉其JPEG幀。

下面是顯示流的快速,簡單和愚蠢的東西。唯一的幻想是使用HttpClient的和異步功能:

async static Task Start(string url, Action<byte[]> action, int bufSize = 1024, CancellationToken? tk = null) { 

    var myTk = tk.HasValue ? tk.Value : CancellationToken.None; 

    using(var cli = new HttpClient()) { 

     var streamBuffer = new byte[bufSize]; 

     // Give it the maximum size in bytes of your picture 
     var frameBuffer = new List<byte>(1024 * 1024); 

     var ff = false; 
     var inPic = false; 

     using(var stream = await cli.GetStreamAsync(url).ConfigureAwait(false)) { 

      while(!myTk.IsCancellationRequested) { 

       var l = await stream.ReadAsync(streamBuffer, 0, bufSize).ConfigureAwait(false); 
       var idx = 0; 

       while(idx < l) { 
        var c = streamBuffer[idx++]; 

        // We have found a FF 
        if(c == 0xff) { 
         ff = true; 
        } 
        // We found a JPEG picture start 
        else if(ff && c == 0xd8) { 
         frameBuffer.Clear(); 
         frameBuffer.Add(0xff); 
         frameBuffer.Add(0xd8); 
         if(inPic) { 
          Console.WriteLine("Skipped frame : end expected"); 
         } 
         ff = false; 
         inPic = true; 
        } 
        // We found a JPEG picture end 
        else if(ff && c == 0xd9) { 
         frameBuffer.Add(0xff); 
         frameBuffer.Add(0xd9); 

         // Send the JPEG picture as an event 
         action(frameBuffer.ToArray()); 

         ff = false; 
         if(!inPic) { 
          Console.WriteLine("Skipped frame : start expected"); 
         } 
         inPic = false; 
        } 
        // We are inside a JPEG picture 
        else if(inPic) { 
         if(ff) { 
          frameBuffer.Add(0xff); 
          ff = false; 
         } 
         frameBuffer.Add(c); 
        } 
       } 
      } 
     } 
    } 
} 

要試一試,有一個圖片框在一個WinForms應用程序,然後在button_click:

var s = SynchronizationContext.Current; 

// assuming pb is your PictureBox 

await Start("http://whateverurlthatstreamsmjpegs.com", 
    img => { 
     s.Post(new SendOrPostCallback(i => { 
      if(pb.Image != null) 
       pb.Image.Dispose(); 
      pb.Image = (Image)new ImageConverter().ConvertFrom((byte[])i); 
     }), img); 
    }, 1024, CancellationToken.None); 

這遠遠一個專業的MJPEG解碼器和一些bug仍然存在,但是還有一個更加改進的版本I put in a gist。要點版本還包括登錄和密碼功能,以觀看來自某些IP攝像機的流。