/*****************************************************************************************       * You must replace parameters with your own. Refer to the FAQ for more detail on how to configure them:       * https://docs.altumview.com/FAQ.pdf       * For demo, these settings are configured to an AltumView account on the Canadian server.       * If you do not see any skeleton rendering, the sensor is no longer available.        *        * Last updated: March 18, 2022 by Andrew A.      ******************************************************************************************/      const oauthUrl = "https://oauth.ailecare.cn/v1.0";      const apiUrl = "https://api.ailecare.cn/v1.0";      const mqttUrl = "beijing.altumview.com.cn";      const clientId = "HkJMDXEe6G1tJ66s";      const clientSecret = "zFAl2CSkB6hGdzcIwfMMRbFErh8ValC7CS9ISsbnYZyH6xZdXbltoKrVAD7lQ4Xm";      const serialNumber = "23E94A5DACD323EE"; // Use the mobile app to get the serial number      const streamToken = "701406606"; // Call GET '/cameras/:id/streamtoken' endpoint to get Stream Token      const groupId = 72; // Call GET '/info' endpoint to get Group ID       const getCredentials = () => {        $.ajax({          "type": "POST",          "url": `${oauthUrl}/token`,          "headers": {            "Content-Type": "application/x-www-form-urlencoded"          },          "data": {            "client_id": clientId,            "client_secret": clientSecret,            "grant_type": "client_credentials",            "scope": "camera:write camera:read",          },          "success": function(response) {            token = response.access_token;            console.log("token", token)            var url = `${apiUrl}/mqttAccount`;            var xhr = new XMLHttpRequest();            xhr.open("GET", url);            xhr.setRequestHeader("Authorization", "Bearer " + token);            xhr.onreadystatechange = function() {              if (xhr.readyState === 4) {                console.log(xhr.responseText)                const response = JSON.parse(xhr.responseText);                username = response.data.mqtt_account.username;                password = response.data.mqtt_account.passcode;                const canvasWidth = 960;                const canvasHeight = 540;                const onFailure = () => {                  const reconnectTimeout = 2000;                  console.log("Connect failed. Trying to reconnect after 2 sec");                  setTimeout(MQTTConnect, reconnectTimeout);                }                 const onMessageArrived = (message) => {                  const byteList = message.payloadBytes                  const frameNum = parseStringInt32(byteList, 0)                  const numPeople = parseStringInt32(byteList, 4)                   const people = []                  for (let i = 0; i < numPeople; i++) {                    const pos = 8 + 152 * i;                    const personId = parseStringInt32(byteList, pos);                    const person = {};                    for (let j = 0; j < 18; j++) {                      const x = parseStringFloat(byteList, pos + 8 + j * 4);                      const y = parseStringFloat(byteList, pos + 80 + j * 4);                      if (x && y) person[j] = new Point(x, y);                    }                    person.name = personId;                    people.push(person);                  }                   const canvas = document.getElementById('canvas');                  if (canvas && people) {                    const ctx = canvas.getContext('2d');                    ctx.clearRect(0, 0, canvasWidth, canvasHeight);                     people.forEach(person => {                      drawSkeleton(ctx, 4, person);                    })                  }                }                 const drawSkeleton = (ctx, lineWidth, points) => {                  ctx.lineWidth = lineWidth;                  ctx.lineCap = 'round';                   let minX = 1;                  let minY = 1;                  pointPairs.forEach(pair => {                    const startPoint = points[pair.start];                    const endPoint = points[pair.end];                    if (startPoint !== undefined && endPoint !== undefined) {                      if (endPoint.x < minX) minX = endPoint.x;                      if (endPoint.y < minY) minY = endPoint.y;                      ctx.strokeStyle = pair.color;                      drawLine(ctx, startPoint.x * canvasWidth, startPoint.y * canvasHeight, endPoint.x * canvasWidth, endPoint.y * canvasHeight);                    }                  })                }                 function Point(x, y) {                  this.x = x;                  this.y = y;                }                 const drawLine = (ctx, x0, y0, x1, y1) => {                  ctx.beginPath();                  ctx.moveTo(x0, y0);                  ctx.lineTo(x1, y1);                  ctx.stroke();                }                 const pointPairs = [                   { start: 0, end: 1, color: 'pink' },                   { start: 1, end: 2, color: 'orange' },                   { start: 2, end: 3, color: 'yellow' },                   { start: 3, end: 4, color: 'lightYellow' },                   { start: 1, end: 5, color: 'darkSalmon' },                   { start: 5, end: 6, color: 'salmon' },                   { start: 6, end: 7, color: 'lightSalmon' },                   { start: 1, end: 8, color: 'darkTurquoise' },                   { start: 8, end: 9, color: 'turquoise' },                   { start: 9, end: 10, color: 'paleTurquoise' },                   { start: 1, end: 11, color: 'darkRed' },                   { start: 11, end: 12, color: 'red' },                   { start: 12, end: 13, color: 'orange' },                   { start: 0, end: 14, color: 'purple' },                   { start: 14, end: 16, color: 'purple' },                   { start: 0, end: 15, color: 'violet' },                   { start: 15, end: 17, color: 'violet' }                 ]                 const parseStringInt32 = (stringData, startIndex) => {                  const t = stringData.slice(startIndex, startIndex + 4);                  return new DataView(t.buffer).getInt32(0, true);                }                 const parseStringFloat = (stringData, startIndex) => {                  const t = stringData.slice(startIndex, startIndex + 4);                  return new DataView(t.buffer).getFloat32(0, true);                }                 const onConnect = () => {                  console.log('connect success');                  var soptions = {                    qos: 0                  };                   // Next, subscribe to this topic with the aforementioned stream token appended                  const subscribeTopic = `mobileClient/${groupId}/camera/${serialNumber}/skeleton/${streamToken}`;                  mqtt.subscribe(subscribeTopic, soptions);                   console.log(`subscribe to ${subscribeTopic}`);                  // Finally, publish the same stream token as a message to the camera in order to start streaming. You must publish this message every 45 seconds to keep streaming going.                  const publishTopic = `mobile/${groupId}/camera/${serialNumber}/token/mobileStreamToken`;                  message = new Paho.MQTT.Message(streamToken);                  message.destinationName = publishTopic;                  message.qos = 2;                  message.retained = false;                  mqtt.send(message);                   console.log("Connected");                   const reconnectTimeout = 44000;                  setTimeout(MQTTConnect, reconnectTimeout);                }                 const MQTTConnect = async (id) => {                  const port = 8084;                  console.log(`connecting to ${mqttUrl}:${port}`);                  mqtt = new Paho.MQTT.Client(mqttUrl, port, username);                  const options = {                    timeout: 3,                    onSuccess: onConnect,                    onFailure: onFailure,                    useSSL: true,                    userName: username,                    password: password                  };                  mqtt.onMessageArrived = onMessageArrived;                  mqtt.connect(options);                }                MQTTConnect(1);              }            };            xhr.send();          },          "error": function(errorThrown) {            alert(JSON.stringify(errorThrown.error()));          }        });      }   

中国·yl34511线路中心(股份有限公司)-Official website

      

This is a demo of the Skeleton Streaming

               
XML 地图




这段代码是一个HTML页面,用于展示一个基于MQTT协议的在线直播演示,具体是展示火柴人动画。下面是对代码的详细解析:


代码概述

  1. HTML结构:页面包含一个元素,用于绘制动画。

  2. JavaScript逻辑:

    • 引入了jQuery、MQTT WebSocket客户端库和Polyfill库。

    • 获取URL参数,如客户名称和应用类型。

    • 动态设置画布尺寸以适应不同屏幕。

    • 使用Ajax请求获取访问令牌和MQTT账户信息。

    • 连接到MQTT服务器,并订阅特定主题以接收动画数据。

    • 接收到数据后,解析并在画布上绘制火柴人动画。

    • 还包含了一些辅助函数,如绘制线条、解析数据等。

详细解析

  1. HTML头部:

    • 引入了必要的JavaScript库。

    • 设置了页面标题。

  2. HTML主体:

    • 一个

      容器包裹了一个元素,用于显示动画。

  3. JavaScript代码:

    • drawSkeleton:绘制火柴人的骨架。

    • Point:表示点的类。

    • drawLine:绘制线条。

    • parseStringInt32和parseStringFloat:解析二进制数据。

    • 解析接收到的数据,提取出火柴人的位置信息。

    • 在画布上绘制火柴人动画。

    • 使用获取的用户名和密码连接到MQTT服务器。

    • 订阅特定主题以接收火柴人动画数据。

    • 定期发布消息以保持连接。

    • 参数获取:从URL中获取客户名称和应用类型。

    • 画布尺寸设置:根据窗口大小动态调整画布尺寸。

    • 获取凭证:通过Ajax请求获取OAuth令牌和MQTT账户信息。

    • MQTT连接:

    • 数据处理:

    • 辅助函数:


基于MQTT的Web​获取火柴人(骨架数据)的实时数据并播放开发指南(pic12)

错误处理

请注意,根据文档说明,您需要每15分钟获取一次流令牌以保持数据流的活跃状态。


总结

这段代码是一个完整的在线直播演示页面,展示了如何使用MQTT协议和Web技术(HTML、JavaScript)来实现实时动画的展示。它涵盖了从前端界面设计,后端数据处理的完整流程,包括网络通信、数据解析和图形绘制等关键技术。

这个过程需要您的应用程序能够处理网络请求、WebSocket连接、二进制数据处理和图形渲染。您可能需要根据您应用程序的具体技术栈选择合适的库和工具来实现上述功能。

如果您遇到任何问题,可以参考我们API文档或联系技术支持获取帮助。



了解火柴人摄像头,请参考:【推荐好物】火柴人隐私摄像头 AI智能行为检测跌倒报警



    查看我们的在线示例:Skeleton Stream Demo火柴人动画在线直播演示 (/html/live/streamDemo01.html)

请注意,这个过程需要您的应用程序能够处理网络请求、WebSocket连接、二进制数据处理和图形渲染。您可能需要根据您应用程序的具体技术栈选择合适的库和工具来实现上述功能。如果您遇到任何问题,可以参考我们API文档或联系技术支持获取帮助。


API参考文档

火柴人摄像头Skeleton在线OAuthAPI文档_SUNSHINE SILICON (/doc_6.html)

火柴人摄像头Skeleton在线API文档_SUNSHINE SILICON (/doc_3.html)

开源地址

https://gitee.com/lojam/mqtt-web-stream-demo/tree/master/streamDemo

火柴人隐私保护摄像头 AI智能行为检测跌倒报警简介
基于MQTT的Web​获取火柴人(骨架数据)的实时数据并播放开发指南(pic13) 基于MQTT的Web​获取火柴人(骨架数据)的实时数据并播放开发指南(pic14)

立即购买



在线演示:

火柴人摄像头Skeleton在线直播演示_在线工具_yl34511线路中心科技 (sunsili.com)

这款火柴人隐私保护摄像头内置NPU(人工智能神经网络处理器),运行多种深度学习算法,可以检测测人员的活动,并应用大数平台对各种行为(躺、站、坐、弯腰)进入统计分析,从而实现跌倒风险评估。当发生紧急情况时(例如跌倒),传感器会立即向家人或护 理人员发送报警信息。为保护隐私,传感器通过AI算法将原始图像计算成火柴人动画数据,只上传火柴人动画数据到云平台(APP和后台只能查看火柴人动画),绝不上传原始视频,因此火柴人传感器可以安装在家里的任何房间,包括卧室和浴室。火柴人动画还是极有价值的医疗数据,可以有多种用途,如可以分析老人的健康状况,协助事故调查和分析,改进养老机构的服务质量,帮助医生提前发现一些疾病,例如帕金森症、阿兹海默症、抑郁症等,并帮助医生和病人进行康复治疗。


加入收藏
Tag: 火柴人 MQTT Web​ 播放动画 开发指南
  • 账号登录
社交账号登录