Ricoh Theta S - просмотр в прямом эфире в javascript

Я пытаюсь создать приложение, которое взаимодействует с камерой Ricoh Theta S с помощью HTTP-запросов... они совместимы с Open Spherical Camera API Version 1.0... вот их описание API

Поэтому я пытаюсь реализовать предварительный просмотр, который, как они говорят, поддерживает камера... Я делаю это в javascript, поэтому я попробовал каждую возможную комбинацию, чтобы получить двоичные данные, которые, по их словам, возвращают вызов api... пробовал vanilla js, jquery, angular... ничего... вот экран печати запроса... отладчик показывает его красным, хотя код состояния 200

enter image description here

ответ пуст... так что мой вопрос... есть ли способ реализовать Motion JPEG (10 кадров в секунду) в javascript через HTTP, используя запрос POST, который отправляет объект?

спасибо редкий

Ответ 1

Есть несколько вещей, которые вы можете попробовать здесь. Многие технологии на стороне сервера (включая .NET и Java) гораздо строже относительно того, что они считают допустимым JSON, чем Javascript. Многие были адаптированы из более ранних технологий, таких как SOAP, которые основывались на проверенном XML и считают JSON аналогичным строгим набором правил.

Кроме того, API, к которому вы подключаетесь, вероятно, был написан специалистами по прошивке встроенных камер, которые раньше никогда не писали код для Интернета. Они привыкли к C++ и Java, которые гораздо менее прощающие, чем JS.

Во-первых, их API указывает, что они ожидают, что заголовки HTTP будут:

Content-Type: application/json;charset=utf-8
Accept: application/json

Однако на скриншоте вы отправляете:

Content-Type: text/plain;charset=utf-8

Это сообщает серверу, что отправляемый вами текст - это текст, а не JSON. Даже если они ожидают только JSON, это приведет к сбою многих готовых реализаций JSON на стороне сервера.

Следующее, что нужно попробовать, это то, что многие парсеры JSON, которые на самом деле не являются Javascript, добавляют некоторые вполне определенные правила к тому, что они считают допустимым JSON.

Вы отправляете:

{name:camera._getLivePreview, parameters:{sessionId:SID_0001}}

Это допустимый JS, но на самом деле не действительный JSON по строгим XML-подобным правилам, потому что они ожидают, что все будет заключено в кавычки (единственные типы значений, которые вы не цитируете - это булевы и числа).

Так что постарайтесь:

{
    "name": "camera._getLivePreview", 
    "parameters": {
        "sessionId": "SID_0001"
    }
}

Если вы посмотрите на их руководство по началу работы, они отформатируют каждый запрос таким образом - процитируйте свойства и укажите значения.

Один из способов убедиться в том, что вы получите этот более строгий JSON, - это построить JS-объект вашего запроса и затем использовать JSON.stringify чтобы установить тело запроса, например:

const content = {name:'camera._getLivePreview', parameters:{sessionId:'SID_0001'}};

const response = await fetch('.../osc/commands/execute', {
    method: 'POST', 
    body: JSON.stringify(content),
    headers:{ 'Content-Type': 'application/json' }
});

Наконец, вы получаете видеопоток - поддержка этого в процессе fetch довольно слабая и практически отсутствует в XMLHttpRequest. Сервер будет продолжать посылать вам контент, а вы продолжаете направлять его во что-то, что может его визуализировать, и если вы остановитесь, вы увидите ошибку target_closed.

Вы должны продолжать перебирать поток:

// Get the fetch response as a stream 
const reader = await response.body.getReader();

// Async loop the stream
let chunk = await reader.read();
while (chunk && !chunk.done) {
    for (let index = 0; index < chunk.value.length; index++) {
         // parse the response in chunks       
    }
    chunk = await reader.read();
}

Уже существует множество реализаций JS MJPEG, здесь довольно простая