林旭祥 hace 1 semana
padre
commit
4d6b1e0f45
Se han modificado 4 ficheros con 302 adiciones y 14 borrados
  1. 2 2
      src/components/OnlineFaceWindow/index.vue
  2. 162 0
      src/utils/bodyposeWs.ts
  3. 0 9
      src/utils/faceWs.ts
  4. 138 3
      src/views/game/fruit.vue

+ 2 - 2
src/components/OnlineFaceWindow/index.vue

@@ -32,7 +32,6 @@ const { faceWs, startDevice, checkFace, openFace, terminateFace, suspendFace, re
 const data = reactive<any>({
   faceCheckStu: {},//人脸信息
   faceState: false,//人脸识别窗口状态
-  direction: "",//动画方向
   parameter: {},//参数
   deviceInfo: {},//设备信息
   againNum: 0,//再次启动次数
@@ -40,7 +39,7 @@ const data = reactive<any>({
   wsState: false,//WS状态
 });
 
-const { faceCheckStu, faceState, direction, parameter, deviceInfo, againNum, againTimer, wsState } = toRefs(data);
+const { faceCheckStu, faceState, parameter, deviceInfo, againNum, againTimer, wsState } = toRefs(data);
 
 onBeforeMount(() => {
 })
@@ -141,6 +140,7 @@ const getInit = async () => {
     }
     if (e?.cmd == 'terminate_facecontroller') {
       if (e?.code == 0) {
+        closeWS();
         faceState.value = false;
       }
     }

+ 162 - 0
src/utils/bodyposeWs.ts

@@ -0,0 +1,162 @@
+import io from 'socket.io-client';
+import { ref, onMounted, onUnmounted, onBeforeUnmount } from 'vue';
+
+export function useWebSocket() {
+  const address: any = import.meta.env.VITE_APP_BASE_API;
+  const token: any = localStorage.getItem('token');
+  const myToken: any = 'JWT ' + token;
+  let socketBodypose: any = null; //ws实例对象
+
+  function bodyposeWs(callback: any) {
+    if (socketBodypose == null) {
+      socketBodypose = io(address + '/', { transports: ['websocket', 'polling'], query: { type: 'bodypose', Authorization: token ? myToken : '' } });
+    }
+    socketBodypose.on('my_response', (e: any) => {
+      callback(e);
+    });
+    socketBodypose.on('fe_device_init_result', (e: any) => {
+      e.type = "fe_device_init_result";
+      if (e.device_info == undefined) {
+        closeWS();
+      }
+      callback(e);
+    });
+    socketBodypose.on('bodyposecontroller_ack', (e: any) => {
+      callback(e);
+    });
+    socketBodypose.on('bodyposecontroller_result', (e: any) => {
+      e.type = "bodyposecontroller_result";
+      callback(e);
+    });
+    socketBodypose.on('disconnect', (e: any) => {
+      callback(e);
+    });
+  }
+
+  /**
+   * 发送消息
+   */
+  function sendMessage(type: string, data: any, callback?: () => void) {
+    if (socketBodypose == null) {
+      return false;
+    }
+    if (socketBodypose.connected) {
+      callback = callback || function () { };
+      socketBodypose.emit(type, data, callback);
+    }
+  }
+
+  /**
+   * 开始连接设备信息
+   */
+  function startDevice(data?: any, callback?: any) {
+    sendMessage(
+      'fe_device_init',
+      {
+        data: data
+      },
+      () => { }
+    );
+  }
+
+  /**
+   * 查看姿态识别模块是否可用
+   */
+  function checkBodypose(data?: any, callback?: any) {
+    sendMessage(
+      'bodyposecontroller',
+      {
+        cmd: 'check_bodyposecontroller_available',
+        ctrl_name: `bodyposecontroller_${data}`
+      },
+      () => { }
+    );
+  }
+
+  /**
+   * 开启姿态识别模块
+   */
+  function openBodypose(data?: any, callback?: any) {
+    sendMessage(
+      'bodyposecontroller',
+      {
+        cmd: 'open_bodyposecontroller',
+        ctrl_name: `bodyposecontroller_${data}`
+      },
+      () => { }
+    );
+  }
+
+  /**
+   * 关闭姿态识别模块
+   */
+  function terminateBodypose(data?: any, callback?: any) {
+    sendMessage(
+      'bodyposecontroller',
+      {
+        cmd: 'terminate_bodyposecontroller',
+        ctrl_name: `bodyposecontroller_${data}`
+      },
+      () => {
+      }
+    );
+  }
+
+  /**
+   * 暂停姿态识别模块
+   */
+  function suspendBodypose(data?: any, callback?: any) {
+    sendMessage(
+      'bodyposecontroller',
+      {
+        cmd: 'suspend_bodyposecontroller',
+        ctrl_name: `bodyposecontroller_${data}`
+      },
+      () => { }
+    );
+  }
+
+  /**
+   * 重启姿态识别模块
+   */
+  function resumeBodypose(data?: any, callback?: any) {
+    sendMessage(
+      'bodyposecontroller',
+      {
+        cmd: 'resume_bodyposecontroller',
+        ctrl_name: `bodyposecontroller_${data}`
+      },
+      () => { }
+    );
+  }
+
+  /**
+   * 获取姿态识别模块状态
+   */
+  function getBodyposeState(data?: any, callback?: any) {
+    sendMessage(
+      'bodyposecontroller',
+      {
+        cmd: 'get_bodyposecontroller_state',
+        ctrl_name: `bodyposecontroller_${data}`
+      },
+      () => { }
+    );
+  }
+
+  /**
+   * 关闭WS
+   */
+  function closeWS() {
+    if (socketBodypose) {
+      socketBodypose.close();
+      socketBodypose = null;
+    }
+  }
+
+  onBeforeUnmount(() => {
+    closeWS();
+  });
+
+  return { bodyposeWs, startDevice, sendMessage, checkBodypose, openBodypose, terminateBodypose, suspendBodypose, resumeBodypose, getBodyposeState, closeWS };
+}

+ 0 - 9
src/utils/faceWs.ts

@@ -22,15 +22,6 @@ export function useWebSocket() {
       callback(e);
     });
     socketFace.on('facecontroller_ack', (e: any) => {
-      // if (e?.cmd == 'check_facecontroller_available' && e?.code != 0) {
-      //   closeWS();
-      // }
-      // if (e?.cmd == 'get_facecontroller_state' && [3, 36].includes(e.state)) {
-      //   closeWS();
-      // }
-      if (e?.cmd == 'terminate_facecontroller' && e?.code == 0) {
-        closeWS();
-      }
       callback(e);
     });
     socketFace.on('facecontroller_result', (e: any) => {

+ 138 - 3
src/views/game/fruit.vue

@@ -5,16 +5,151 @@
 </template>
 
 <script setup name="Fruit" lang="ts">
+import { initSpeech, speckText, playMusic, controlMusic, speckCancel, chineseNumber } from '@/utils/speech';
+import { useWebSocket } from '@/utils/bodyposeWs';
+const { proxy } = getCurrentInstance() as any;
+const router = useRouter();
+const { bodyposeWs, startDevice, checkBodypose, openBodypose, terminateBodypose, suspendBodypose, resumeBodypose, getBodyposeState, closeWS } = useWebSocket();
+
 const data = reactive<any>({
+  bodyposeData: {},//姿态信息
+  bodyposeState: false,//姿态识别窗口状态
+  parameter: {},//参数
+  deviceInfo: {},//设备信息
+  againNum: 0,//再次启动次数
+  againTimer: null,//定时状态
+  wsState: false,//WS状态
 });
-const {
-} = toRefs(data);
 
+const { bodyposeData, bodyposeState, parameter, deviceInfo, againNum, againTimer, wsState } = toRefs(data);
+
+/**
+ * 初始化
+ */
+const getInit = async () => {
+  console.log("触发姿态识别")
+  let deviceid = localStorage.getItem('deviceid') || '';
+  if (!deviceid) {
+    proxy?.$modal.msgError(`请重新登录绑定设备号后使用`);
+    return false;
+  }
+  bodyposeState.value = true;
+  if (wsState.value) {
+    proxy?.$modal.msgWarning(`操作过快,请稍后重试`);
+    setTimeout(() => {
+      bodyposeState.value = false;
+    }, 1000)
+    return false;
+  }
+  speckText("请举右手看摄像头进行姿态识别");
+  bodyposeWs((e: any) => {
+    console.log("bodyposeWS", e)
+    if (e?.wksid) {
+      wsState.value = true;
+      //获取设备信息
+      startDevice({ deviceid: deviceid });
+      console.log("获取设备信息")
+    }
+    if (e?.type == 'fe_device_init_result') {
+      //接收设备信息并发送请求
+      if (e?.device_info) {
+        deviceInfo.value = e.device_info;
+        getCheckBodypose();
+        console.log("返回设备信息,检查是否支持姿态识别")
+      } else {
+        proxy?.$modal.msgError(`设备信息缺失,请重新登录绑定设备号后使用`);
+      }
+    }
+    if (e?.cmd == 'check_bodyposecontroller_available') {
+      let handcontroller_id = deviceInfo.value.handcontroller_id;
+      if (e?.code == 0) {
+        //查看姿态识别状态,如果不处于关闭就先关闭再重新启动(可能会APP退出然后工作站还在运行的可能性)
+        getBodyposeState(handcontroller_id);
+        againNum.value = 0;
+        againTimer.value = null;
+        clearTimeout(againTimer.value);
+        console.log("查看姿态识别状态")
+      } else {
+        //尝试多次查询姿态识别状态
+        if (againNum.value <= 2) {
+          againTimer.value = setTimeout(() => {
+            getCheckBodypose();
+          }, 500)
+          againNum.value++;
+        } else {
+          let msg = "";
+          if (e.code == 102402) {
+            msg = `多次连接失败请重试,姿态识别模块被占用`;
+          } else {
+            msg = `多次连接失败请重试,姿态识别模块不可用,code:${e.code}`;
+          }
+          proxy?.$modal.msgWarning(msg);
+          againNum.value = 0;
+          againTimer.value = null;
+          clearTimeout(againTimer.value);
+          getCloseBodypose();//直接关闭 
+        }
+
+      }
+    }
+    if (e?.cmd == 'get_bodyposecontroller_state') {
+      let handcontroller_id = deviceInfo.value.handcontroller_id;
+      //state说明: 0:关闭,3:空闲,36:工作中
+      if ([3, 36].includes(e.state)) {
+        getCloseBodypose();
+        proxy?.$modal.msgWarning(`请重新姿态识别`);
+      } else {
+        openBodypose(handcontroller_id);
+      }
+    }
+    if (e?.type == 'bodyposecontroller_result') {
+      console.log("data", e.data)
+      bodyposeData.value = e.data;
+    }
+    if (e?.cmd == 'terminate_bodyposecontroller') {
+      if (e?.code == 0) {
+        closeWS();
+        bodyposeState.value = false;
+      }
+    }
+    if (e?.type == 'disconnect') {
+      wsState.value = false;
+    }
+  });
+};
 
-onBeforeMount(() => {
 
+/**
+ * 查询姿态识别状态
+*/
+const getCheckBodypose = () => {
+  let handcontroller_id = deviceInfo.value.handcontroller_id;
+  //检查是否支持姿态识别
+  checkBodypose(handcontroller_id);
+};
+
+/**
+ * 关闭姿态识别
+*/
+const getCloseBodypose = () => {
+  let handcontroller_id = deviceInfo.value.handcontroller_id;
+  terminateBodypose(handcontroller_id);
+  bodyposeState.value = false;
+  speckCancel(); //停止播报
+  setTimeout(() => {
+    if (wsState.value) {
+      closeWS();
+    }
+  }, 3000)
+};
+
+onBeforeMount(() => {
+  getInit();
 });
 
+onMounted(() => {
+})
+
 onBeforeUnmount(() => {
 
 });