是否有人熟悉通过 HTTP 协议发送的 MJPEG 文件中提取标头的方法?我在 C# 中遇到过 HttpClient 类,但我对它缺乏经验,而且我还没有看到任何有关 MJPEG 流的示例。我感谢您的帮助。
问问题
1549 次
2 回答
2
我不是专家,但我认为 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 应用程序中有一个 PictureBox,然后在 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 解码器相去甚远,并且仍然存在一些错误,但我在 gist 中提供了一个改进得多的版本。gist 版本还包括用于观看来自某些 IP 摄像机的流的登录和密码功能。
于 2016-02-24T13:14:11.657 回答
0
在 Ch9 上试试这个 Coding4Fun 项目
于 2013-09-27T15:50:25.290 回答