【发布时间】:2019-02-02 19:22:36
【问题描述】:
对于个人项目,我正在尝试从 IP 摄像机的 MPEG 流中读取数据,并对收到的各个帧执行一些计算机视觉任务(使用 .NET Core 2.2)。
我向相机的 MPEG 端点执行 GET 请求,我收到了一个 multipart/x-mixed-replace 响应,该响应不断将看似单独的帧作为 JPEG 图像流式传输。
我无法理解的是从多部分响应中解析出帧的正确方法 - 如果有更好的解析方法,如何检索帧对我来说并不重要这种流,我当然愿意改变 - 视频检索/处理对我来说是一个全新的世界:)
供参考:
MPEG 端点:
GET http://192.168.0.14/mjpeg.cgi
示例响应标头:
Content-Type: multipart/x-mixed-replace;boundary=--video boundary--
示例响应正文:
Content-length: 41142
Date: 02-02-2019 12:43:19 AM
Content-type: image/jpeg
[payload]
--video boundary--
Content-length: 41220
Date: 02-02-2019 12:43:19 AM
Content-type: image/jpeg
[payload]
--video boundary--
我目前所拥有的:
var client = new HttpClient() {
BaseAddress = new Uri(streamUrl)
};
var stream = await client.GetStreamAsync(resource);
using (var streamReader = new StreamReader(stream)) {
while(true) {
await GetFrameStart(streamReader);
var frame = await ReadFrame(streamReader);
// Get byte[] from returned frame above and construct image
};
}
// ---
// Fast forward to the start of the Frame's bytes
static async Task GetFrameStart(StreamReader reader) {
string buffer = null;
while (buffer != string.Empty) {
buffer = await reader.ReadLineAsync();
}
}
// Read entire byte array until the video boundary is met
static async Task<String> ReadFrame(StreamReader reader) {
string result = string.Empty;
string line = null;
while(!isBoundary(line)) {
line = await reader.ReadLineAsync();
if (!isBoundary(line)) result += line;
};
return result;
}
上面的内容似乎将每个帧的单个 [payload] 返回给我,但是如果我将字符串转换为字节并写入磁盘时,图像不是有效的 jpeg:
var bytes = Encoding.UTF8.GetBytes(frame);
using (var fs = new FileStream("test.jpeg", FileMode.Create, FileAccess.Write)) {
fs.Write(bytes, 0, bytes.Length);
}
【问题讨论】:
-
啊,好吧,我在此过程中做了一些错误的假设。我是否认为 BinaryReader 是我完成这项工作所需的工具 - 将原始字节读入缓冲区并调整边界检查部分以删除任何与图像无关的数据?
-
方法isBoundary的作用是什么?
-
isBoundary 是一个简单的检查,看当前行是否包含边界分隔符,即
--video boundary--