将 wifi 接入点摄像头的视频流式传输到远程计算机
Streaming video of wifi access point camera to a remote computer
在花费数周时间搜索论坛并尝试不同的方法后,我没有找到解决我的具体问题的方法。感谢您提供的每一个提示。
我购买了 Kodak Pixpro 360 相机,它通过 wifi 提供取景器功能(即实时视频流)。现在我正在尝试将此摄像机用作可以从任何地方(不仅仅是本地网络)访问的监控摄像头。 ODROID 将通过 wifi 连接到相机,并使用第二个 wifi dongle 连接到 LAN。传入的视频流应实时转发给客户端(一次只有一个)。然后在用 Unity3d 编写的应用程序中查看收到的 360 度内容。
到目前为止,我已经设法获取了摄像头的 MJPEG 流并将其作为 JPEG 提供给 NodeJS 服务器。然后通过 WWW.LoadImageIntoTexture
方法呈现 JPEG。正如您想象的那样,对每一帧的 GET 请求非常慢,导致每秒大约 0.5 帧。
我的一位同事向我指出 WebRTC 和 Janus 网关是一种更优雅的解决方案。 This simple peer chat 使用 SocketIO 并且在我的网络摄像头上工作得很好,但我不知道如何更改此代码以使用来自 PIXPRO 而不是我的本地设备的视频流。渲染内容也应该很有趣,因为您需要一个 WebRTC 浏览器,我不确定其中有多少可以嵌入到 Unity3d 中。
不幸的是,相机不能自己连接到局域网,而是充当 wifi 接入点。这使得我为 ip cams 找到的所有解决方案都过时了。
我发现了一个类似的项目,它设法通过 Janus 和 WebRTC 转发他们的视频流,但我不确定我是否以及如何应用他们的方法。
https://babyis60.wordpress.com/2015/02/04/the-jumping-janus/
更新
好的,我自己设法缩小了我的问题范围。 PIXPRO 不支持 RTP,所以我只能使用 JPEG 流。现在我正在尝试通过搜索帧之间的边界来加快读取相机的 TCP 响应和 returns JPEG 的 paparazzo.js 实现。然后通过 http 响应提供这些 JPEG。我想通过使用 SocketIO 将这些帧推送到客户端并在那里呈现它们来加快此过程。
奇怪的是,服务器端的数据似乎很好(当我通过 fs.writeFileSync('testimage.jpg', buffer, 'binary');
导出它时,我得到了一个有效的 JPEG 图像,但在我发送图像后我无法在客户端工作通过 io.sockets.emit("stream",{image: image});
。当我尝试通过 $("#video").attr("src", "data:image/jpeg;," + data.image);
在浏览器中显示此图像时,图像未正确解析。检查器显示视频源已更新,但只有一个二进制字符串。
我终于成功了。二进制文件必须加载到缓冲区中并作为 base64 字符串发送。
paparazzo.on("update", (function(_this) {
return function(image) {
updatedImage = image;
var vals = new Buffer(image, 'binary');
//fs.writeFileSync('testimage.jpg', vals, 'binary');
io.sockets.emit("image",vals.toString('base64'));
return console.log("Downloaded " + image.length + " bytes");
};
})(this));
在客户端,我不得不使用图片标签,因为 canvas 解决方案似乎对我不起作用。
var image = document.getElementById('image');
socket.on("image", function(info) {
image.src = 'data:image/jpeg;base64,' + info;
});
浏览器输出只是实际 Unity3D 实现之前的测试。我为 Unity3D 尝试了很多 Websocket 库,但唯一在 Android 设备上工作的是 UnitySocketIO-WebsocketSharp 项目。
现在我可以简单地将我的 base64 图像转换为字节数组并将其加载到 Texture2D 中。
socket.On("image", (data) => {
bytes = Convert.FromBase64String (data.Json.args.GetValue(0).ToString());
});
void Update () {
tex.LoadImage (bytes);
}
LoadImage 似乎阻止了 UI 威胁,但它减慢了我的相机控制脚本的速度,因此我将不得不研究可以在较低级别重写纹理像素的 Unity 插件。使用适用于 Unity 的 Cardboard SDK 为我提供了一个解决方法,让我再次获得相当流畅的相机控制。
在花费数周时间搜索论坛并尝试不同的方法后,我没有找到解决我的具体问题的方法。感谢您提供的每一个提示。
我购买了 Kodak Pixpro 360 相机,它通过 wifi 提供取景器功能(即实时视频流)。现在我正在尝试将此摄像机用作可以从任何地方(不仅仅是本地网络)访问的监控摄像头。 ODROID 将通过 wifi 连接到相机,并使用第二个 wifi dongle 连接到 LAN。传入的视频流应实时转发给客户端(一次只有一个)。然后在用 Unity3d 编写的应用程序中查看收到的 360 度内容。
到目前为止,我已经设法获取了摄像头的 MJPEG 流并将其作为 JPEG 提供给 NodeJS 服务器。然后通过 WWW.LoadImageIntoTexture
方法呈现 JPEG。正如您想象的那样,对每一帧的 GET 请求非常慢,导致每秒大约 0.5 帧。
我的一位同事向我指出 WebRTC 和 Janus 网关是一种更优雅的解决方案。 This simple peer chat 使用 SocketIO 并且在我的网络摄像头上工作得很好,但我不知道如何更改此代码以使用来自 PIXPRO 而不是我的本地设备的视频流。渲染内容也应该很有趣,因为您需要一个 WebRTC 浏览器,我不确定其中有多少可以嵌入到 Unity3d 中。
不幸的是,相机不能自己连接到局域网,而是充当 wifi 接入点。这使得我为 ip cams 找到的所有解决方案都过时了。
我发现了一个类似的项目,它设法通过 Janus 和 WebRTC 转发他们的视频流,但我不确定我是否以及如何应用他们的方法。 https://babyis60.wordpress.com/2015/02/04/the-jumping-janus/
更新
好的,我自己设法缩小了我的问题范围。 PIXPRO 不支持 RTP,所以我只能使用 JPEG 流。现在我正在尝试通过搜索帧之间的边界来加快读取相机的 TCP 响应和 returns JPEG 的 paparazzo.js 实现。然后通过 http 响应提供这些 JPEG。我想通过使用 SocketIO 将这些帧推送到客户端并在那里呈现它们来加快此过程。
奇怪的是,服务器端的数据似乎很好(当我通过 fs.writeFileSync('testimage.jpg', buffer, 'binary');
导出它时,我得到了一个有效的 JPEG 图像,但在我发送图像后我无法在客户端工作通过 io.sockets.emit("stream",{image: image});
。当我尝试通过 $("#video").attr("src", "data:image/jpeg;," + data.image);
在浏览器中显示此图像时,图像未正确解析。检查器显示视频源已更新,但只有一个二进制字符串。
我终于成功了。二进制文件必须加载到缓冲区中并作为 base64 字符串发送。
paparazzo.on("update", (function(_this) {
return function(image) {
updatedImage = image;
var vals = new Buffer(image, 'binary');
//fs.writeFileSync('testimage.jpg', vals, 'binary');
io.sockets.emit("image",vals.toString('base64'));
return console.log("Downloaded " + image.length + " bytes");
};
})(this));
在客户端,我不得不使用图片标签,因为 canvas 解决方案似乎对我不起作用。
var image = document.getElementById('image');
socket.on("image", function(info) {
image.src = 'data:image/jpeg;base64,' + info;
});
浏览器输出只是实际 Unity3D 实现之前的测试。我为 Unity3D 尝试了很多 Websocket 库,但唯一在 Android 设备上工作的是 UnitySocketIO-WebsocketSharp 项目。 现在我可以简单地将我的 base64 图像转换为字节数组并将其加载到 Texture2D 中。
socket.On("image", (data) => {
bytes = Convert.FromBase64String (data.Json.args.GetValue(0).ToString());
});
void Update () {
tex.LoadImage (bytes);
}
LoadImage 似乎阻止了 UI 威胁,但它减慢了我的相机控制脚本的速度,因此我将不得不研究可以在较低级别重写纹理像素的 Unity 插件。使用适用于 Unity 的 Cardboard SDK 为我提供了一个解决方法,让我再次获得相当流畅的相机控制。