Ricoh Theta S - 在javascript中实时预览

时间:2015-11-04 09:44:14

标签: javascript ajax camera binary-data

我正在尝试使用HTTP请求创建一个与Ricoh Theta S相机对话的应用...它们符合Open Spherical Camera API Version 1.0 ... here is their api reference

所以我试图实现他们说相机支持的live preview ...我在javascript中这样做所以我尝试了所有可能的组合来获取他们说api调用返回的二进制数据...试过vanilla js,jquery,angular ... nothing ...这里是请求的打印屏幕...调试器显示为红色,尽管状态代码为200

enter image description here

回复是空的...... 所以我的问题是......有没有办法可以通过HTTP,使用发送对象的POST请求在javascript中实现Motion JPEG(10 fps)?

感谢, 拉雷什

1 个答案:

答案 0 :(得分:0)

您可以在这里尝试几种方法。许多服务器端技术(包括.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实现失败。

接下来要尝试的是,许多实际上不是Javascript的JSON解析器在他们认为有效的JSON上添加了一些specific rules

您正在发送:

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

这是有效的JS,但按照严格的类似XML的规则,它实际上不是有效的JSON,因为它们希望所有内容都用引号引起来(您唯一不引用的值类型是布尔值和数字)。

所以尝试:

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

如果您查看他们的getting started guide,他们会以这种方式格式化每个请求-用引号引用值。

确保获得更严格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();
}

here's a fairly simple one

已经有很多JS MJPEG实现。