Потоковое видео с Wi-Fi точки доступа камеры на удаленный компьютер
Потратив недели на поиск по форумам и испробовав разные подходы, я не нашел решения для своей вполне конкретной проблемы. Я благодарен за каждый совет, который вы можете дать.
Я купил камеру Kodak Pixpro 360, которая предлагает функцию видоискателя по Wi-Fi (то есть прямой видеопоток). Сейчас я пытаюсь использовать эту камеру в качестве камеры видеонаблюдения, к которой можно получить доступ из любого места (не только из локальной сети). ODROID будет подключен к камере через Wi-Fi и использовать второй ключ Wi-Fi для подключения к локальной сети. Входящий видеопоток должен быть перенаправлен клиенту в режиме реального времени (будет только один). Полученный 360-градусный контент затем просматривается в приложении, написанном на Unity3d.
До сих пор мне удалось захватить поток MJPEG камеры и использовать его в качестве JPEG-файлов без использования сервера NodeJS. Затем файлы JPEG визуализируются через WWW.LoadImageIntoTexture
метод. Как вы можете себе представить, запросы GET для каждого кадра ужасно медленны и приводят к примерно 0,5 кадрам в секунду.
Мой коллега указал мне на WebRTC и шлюз Janus как на более элегантное решение. Этот простой одноранговый чат использует SocketIO и прекрасно работает с моей веб-камерой, но я не могу понять, как изменить этот код, чтобы использовать видеопоток, поступающий из PIXPRO вместо моего локального устройства. Рендеринг контента тоже должен быть интересным, так как вам нужен браузер для WebRTC, и я не уверен, сколько из этого может быть встроено в Unity3d.
К сожалению, камера не может подключиться к локальной сети сама по себе, а действует как точка доступа Wi-Fi. Это делает все решения, которые я нашел для IP-камер, устарели.
Я нашел похожий проект, которому удалось переслать их видеопоток через Janus и WebRTC, но я не уверен, могу ли я применить их методы и каким образом. https://babyis60.wordpress.com/2015/02/04/the-jumping-janus/
ОБНОВИТЬ
Хорошо, ребята, мне удалось самостоятельно сузить проблему. PIXPRO не поддерживает RTP, поэтому я застрял с потоком JPEG. Теперь я пытаюсь ускорить реализацию paparazzo.js, которая считывает TCP-ответы камеры и возвращает JPEG-файлы путем поиска границы между кадрами. Эти JPEG-файлы затем отправляются через HTTP-ответ. Я хотел бы ускорить этот процесс с помощью SocketIO, чтобы передать эти кадры клиенту и отобразить их там. Странно то, что данные, кажется, просто отлично на стороне обслуживания (я получаю действительное изображение JPEG, когда я экспортирую его через fs.writeFileSync('testimage.jpg', buffer, 'binary');
, но я не могу заставить его работать на стороне клиента после отправки изображения через io.sockets.emit("stream",{image: image});
, Когда я пытаюсь отобразить это изображение в браузере через $("#video").attr("src", "data:image/jpeg;," + data.image);
Изображение не анализируется корректно. Инспектор показывает, что источник видео обновлен, но есть только двоичная строка.
1 ответ
Наконец мне удалось это сделать. Двоичный файл должен был быть загружен в буфер и отправлен в виде строки 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));
На стороне клиента я должен был использовать тег изображения, потому что решения для холста, казалось, не работали для меня.
var image = document.getElementById('image');
socket.on("image", function(info) {
image.src = 'data:image/jpeg;base64,' + info;
});
Вывод браузера был просто тестом до фактической реализации Unity3D. Я перепробовал множество библиотек Websocket для Unity3D, но единственной, которая работала на устройстве Android, был проект https://github.com/kaistseo/UnitySocketIO-WebSocketSharp. Теперь я могу просто преобразовать свое изображение base64 в байтовый массив и загрузить его в Texture2D.
socket.On("image", (data) => {
bytes = Convert.FromBase64String (data.Json.args.GetValue(0).ToString());
});
void Update () {
tex.LoadImage (bytes);
}
Однако, похоже, что LoadImage блокирует угрозу пользовательского интерфейса, что замедляет мой скрипт управления камерой, поэтому мне придется взглянуть на плагины Unity, которые могут переписывать пиксели текстуры на более низком уровне. Использование Cardboard SDK для Unity помогло мне снова получить довольно плавное управление камерой.