camera.js 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. 'use strict';
  2. const { Controller } = require('ee-core');
  3. const Log = require('ee-core/log');
  4. const { checkCameraControlCmdExists, closeCameraControlTips, isProcessRunning, onProcessClosed, removeProcessClosedListener, getController } = require('../utils/camera');
  5. const {
  6. checkCamera,
  7. liveShow: liveShowApi, liveHide: liveHideApi, setParams, capture, getParams,CMD,captureLive,closeOtherWindow } = require('../api/camera');
  8. const { readConfigFile } = require('../utils/config');
  9. let isOPen = true
  10. let isSoftwareStarted = false; // 标记相机控制软件是否已经启动
  11. // 缓存相机列表数据,供多窗口共享(CameraLists 中已包含各相机的 ISO 配置)
  12. let cachedCameraList = [];
  13. // 注册进程关闭事件监听器,当软件被关闭时重置标志
  14. onProcessClosed(() => {
  15. Log.info('相机控制软件已关闭,重置 isSoftwareStarted 标志');
  16. isSoftwareStarted = false;
  17. });
  18. class CameraController extends Controller {
  19. constructor(ctx) {
  20. super(ctx);
  21. }
  22. async connect(params = {}) {
  23. const isMultiCameraMode = params?.isMultiCameraMode ?? false;
  24. try {
  25. console.log('==================');
  26. console.log(readConfigFile());
  27. console.log('[CAMERA-DEBUG] connect() - isMultiCameraMode:', isMultiCameraMode);
  28. // 主动检测:即使 isSoftwareStarted 为 true,也要检查进程是否还在运行(兜底机制)
  29. console.log('[CAMERA-DEBUG] connect() 检查状态 - isSoftwareStarted:', isSoftwareStarted, 'isProcessRunning():', isProcessRunning());
  30. if (isSoftwareStarted && !isProcessRunning()) {
  31. console.log('[CAMERA-DEBUG] 检测到 isSoftwareStarted 为 true 但进程已关闭,重置标志');
  32. Log.info('检测到 isSoftwareStarted 为 true 但进程已关闭,重置标志');
  33. isSoftwareStarted = false;
  34. }
  35. if (!isSoftwareStarted || !isProcessRunning()) {
  36. console.log('[CAMERA-DEBUG] 准备启动相机控制软件 - isSoftwareStarted:', isSoftwareStarted, 'isProcessRunning:', isProcessRunning());
  37. const ready = await checkCameraControlCmdExists();
  38. if (ready && ready.status === -1) {
  39. return ready;
  40. }
  41. isSoftwareStarted = true;
  42. const startedType = getController().type;
  43. console.log('[CAMERA-DEBUG] 相机控制软件已启动,类型:', startedType);
  44. if (startedType === 'digiCamControl') {
  45. await CMD('All_Minimize');
  46. await closeCameraControlTips();
  47. await new Promise(resolve => setTimeout(resolve, 5000));
  48. } else {
  49. Log.info('SmartShooter 软件启动完成,等待初始化...');
  50. await new Promise(resolve => setTimeout(resolve, 10000));
  51. }
  52. }
  53. // 启动完成后再读类型。选目录时可能把 digiCamControl 改成 SmartShooter6
  54. if (getController().type === 'digiCamControl') {
  55. console.log('========1==========');
  56. let res = await getParams('iso').catch(e=>{
  57. console.log('getParams failed:', e);
  58. isOPen = false;
  59. return null;
  60. });
  61. if(res === '未将对象引用设置到对象的实例。' || !res){
  62. return {
  63. status:-1,
  64. msg: "相机硬件未连接,请检查相机连接。",
  65. }
  66. }
  67. return {
  68. status:2,
  69. msg:res,
  70. }
  71. }
  72. console.log('[CAMERA-DEBUG] SmartShooter 分支 - isSoftwareStarted:', isSoftwareStarted, 'isProcessRunning():', isProcessRunning());
  73. let res = await checkCamera(isMultiCameraMode).catch(e=>{
  74. Log.info('checkCamera:'+e);
  75. isOPen = false;
  76. return { device_status: -1 };
  77. })
  78. if (res?.device_status === -1) {
  79. return {
  80. status: -1,
  81. msg: "相机硬件未连接,请检查相机连接。",
  82. };
  83. }
  84. if(res?.device_status === 2){
  85. isOPen = true;
  86. if (res.CameraLists) {
  87. cachedCameraList = res.CameraLists;
  88. }
  89. return {
  90. ...res,
  91. status:2
  92. };
  93. }
  94. return {
  95. status:-1,
  96. msg:"相机未连接,请链接相机。",
  97. }
  98. } catch (error) {
  99. const controlType = getController().type
  100. let msg = '请安装 Smart Shooter 5 或 Smart Shooter 6'
  101. if(controlType === 'SmartShooter') msg = '请安装 Smart Shooter 5'
  102. if(controlType === 'SmartShooter6') msg = '请安装 Smart Shooter 6 或 Smart Shooter 5'
  103. if(controlType === 'digiCamControl') msg = '请安装digiCamControl软件,并打开digiCamControl软件的web服务,端口为5513'
  104. return {
  105. status:-1,
  106. msg,
  107. }
  108. }
  109. }
  110. /**
  111. * 启动预览
  112. */
  113. async liveShow(data) {
  114. try {
  115. const point_name = data?.point_name || 'A';
  116. Log.info('liveShow:打开预览'+point_name);
  117. return await liveShowApi(point_name);
  118. if(readConfigFile().controlType === 'digiCamControl'){
  119. await CMD('All_Minimize')
  120. }
  121. return { success: true, point_name };
  122. } catch (error) {
  123. console.error('启动预览失败:', error);
  124. throw error;
  125. }
  126. }
  127. /**
  128. * 结束预览
  129. */
  130. async liveHide(data) {
  131. try {
  132. const point_name = data?.point_name || 'A';
  133. Log.info('liveShow:关闭'+point_name);
  134. return await liveHideApi(point_name);
  135. return { success: true, point_name };
  136. } catch (error) {
  137. throw error;
  138. }
  139. }
  140. /**
  141. * 设置参数
  142. */
  143. async setParams(params) {
  144. try {
  145. console.log(params);
  146. await setParams(params);
  147. return true;
  148. } catch (error) {
  149. throw error;
  150. }
  151. }
  152. async takePictures(isLive=true) {
  153. try {
  154. if(isLive){
  155. await captureLive();
  156. }else{
  157. await capture();
  158. }
  159. return true;
  160. } catch (error) {
  161. throw error;
  162. }
  163. }
  164. /**
  165. * 获取缓存的相机列表(供设置页面等子窗口调用)
  166. */
  167. async getCameraList() {
  168. return {
  169. CameraLists: cachedCameraList,
  170. status: cachedCameraList.length > 0 ? 2 : 0,
  171. msg: cachedCameraList.length > 0 ? '获取成功' : '暂无相机列表'
  172. };
  173. }
  174. // 示例:使用 fetchData 函数进行 HTTP 请求
  175. async fetchExampleData() {
  176. const options = {
  177. hostname: 'example.com',
  178. port: 443,
  179. path: '/api/data',
  180. method: 'GET'
  181. };
  182. try {
  183. const data = await fetchData(options);
  184. console.log('Fetched data:', data);
  185. return data;
  186. } catch (error) {
  187. console.error('Fetch data failed:', error);
  188. throw error;
  189. }
  190. }
  191. }
  192. CameraController.toString = () => '[class CameraController]';
  193. module.exports = CameraController;