ventutil.ts 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. import { render, h, nextTick } from 'vue';
  2. import LivePlayer from '@liveqing/liveplayer-v3';
  3. export function toEchartsData(list, option) {
  4. option.legend['data'] = [];
  5. option.yAxis.length = list.length;
  6. option.yAxis.series = list.length;
  7. list.forEach((item: any, index) => {
  8. option.legend['data'].push(`${item['legend']}(${item['unit']})`);
  9. const yAxiObj = {
  10. type: 'value',
  11. position: item['yaxispos'],
  12. axisLabel: { formatter: `{value} ${item['unit']}` },
  13. };
  14. const serieObj = {
  15. name: `${item['legend']}(${item['unit']})`,
  16. type: item['linetype'],
  17. yAxisIndex: item['sort'],
  18. };
  19. if (!option.yAxis[index]) {
  20. option.yAxis[index] = yAxiObj;
  21. } else {
  22. Object.assign(option.yAxis[index], yAxiObj);
  23. }
  24. if (!option.series[index]) {
  25. option.series[index] = serieObj;
  26. } else {
  27. Object.assign(option.series[index], serieObj);
  28. }
  29. });
  30. return option;
  31. }
  32. export function formatNum(data, len = 2) {
  33. return new Intl.NumberFormat('ja-JP', {
  34. minimumFractionDigits: len,
  35. maximumFractionDigits: len,
  36. }).format(data);
  37. }
  38. export function cameraInit(dom, rtspUrl) {
  39. let webRtcServer = undefined;
  40. // const ip = '//192.168.183.216:8000';
  41. webRtcServer = new window['WebRtcStreamer'](
  42. dom,
  43. VUE_APP_URL.webRtcUrl.startsWith('/') ? location.protocol + VUE_APP_URL.webRtcUrl : VUE_APP_URL.webRtcUrl
  44. );
  45. if (webRtcServer) webRtcServer.connect(rtspUrl);
  46. return { webRtcServer };
  47. }
  48. export function toTree(idName = 'id', parentIdName: 'parentId', titleName = 'name') {
  49. function toTreeNode(data) {
  50. return {
  51. id: data[idName],
  52. parentId: data[parentIdName],
  53. title: data[titleName],
  54. };
  55. }
  56. // 步骤2和3: 构建树
  57. function buildTree(array) {
  58. // 创建ID映射
  59. const idMap = {};
  60. array.forEach((item) => {
  61. const node = toTreeNode(item);
  62. idMap[node.id] = node;
  63. });
  64. // 构建父子关系
  65. array.forEach((item) => {
  66. const node = idMap[item.id];
  67. if (item.parentId !== '0') {
  68. const parentNode = idMap[item.parentId];
  69. if (parentNode) {
  70. if (!parentNode.children) parentNode.children = [];
  71. parentNode.children.push(node);
  72. }
  73. }
  74. });
  75. // 步骤4: 处理结果并返回根节点
  76. const roots = [];
  77. array.forEach((item) => {
  78. const node = idMap[item.id];
  79. if (node.parentId === '0') {
  80. roots.push(node);
  81. }
  82. });
  83. return roots;
  84. }
  85. return { buildTree };
  86. }
  87. // 模型监测加载视频
  88. export function deviceCameraInit(cameraAddrs, player: HTMLElement, webRtcServerList: any[] = []) {
  89. const playerDoms: (HTMLVideoElement | undefined | null)[] = [];
  90. const webRtcServer: any[] = [];
  91. let livePlayerDiv: HTMLElement | null = document.getElementById('LivePlayerBox');
  92. if (livePlayerDiv) {
  93. livePlayerDiv.remove();
  94. livePlayerDiv = null;
  95. }
  96. if (!livePlayerDiv) {
  97. const dom = document.createElement('div');
  98. dom.setAttribute('id', 'LivePlayerBox');
  99. livePlayerDiv = dom;
  100. player.appendChild(livePlayerDiv);
  101. }
  102. const videoParentDomList: (HTMLElement | [string, { name: string; addr: string }])[] = [];
  103. return new Promise((resolve) => {
  104. const playCamrea = () => {
  105. if (cameraAddrs.length > 0) {
  106. const promiseList: Promise<any>[] = [];
  107. cameraAddrs.forEach(async (cameraUrl: { name: string; addr: string }, index) => {
  108. const promise = new Promise(async (childResolve) => {
  109. let cameraNameDom: null | HTMLElement = null;
  110. console.log('摄像头地址--------->', cameraUrl, cameraUrl.addr.startsWith('rtsp://'), livePlayerDiv);
  111. if (cameraUrl.addr && cameraUrl.addr.startsWith('rtsp://')) {
  112. const server = webRtcServerList.shift();
  113. if (server) {
  114. try {
  115. const videoElement = server.videoElement as HTMLVideoElement;
  116. videoElement.volume = 0;
  117. const cameraNameDom = videoElement.parentElement?.getElementsByClassName('video-name')[0];
  118. if (cameraNameDom) cameraNameDom.innerText = cameraUrl.name;
  119. playerDoms.unshift(videoElement);
  120. webRtcServer.unshift(server);
  121. await server.connect(cameraUrl['addr']);
  122. videoElement.play();
  123. childResolve(null);
  124. } catch (error) {
  125. playerDoms.unshift(undefined);
  126. childResolve(null);
  127. }
  128. } else {
  129. const videoParentDom: HTMLElement = document.createElement('div');
  130. videoParentDom.setAttribute('class', 'video-parent');
  131. const videoDom: HTMLVideoElement = document.createElement('video');
  132. videoDom.volume = 0;
  133. videoDom.setAttribute('class', 'rtspVideo');
  134. videoDom.setAttribute('muted', 'muted');
  135. videoDom.setAttribute('poster', '/src/assets/images/vent/noSinge.png');
  136. videoDom.autoplay = true;
  137. videoParentDom.appendChild(videoDom);
  138. cameraNameDom = document.createElement('div');
  139. cameraNameDom.setAttribute('class', 'video-name');
  140. cameraNameDom.innerText = cameraUrl.name;
  141. videoParentDom.appendChild(cameraNameDom);
  142. videoParentDom.addEventListener('dblclick', () => {
  143. if (videoDom.requestFullscreen) {
  144. videoDom.requestFullscreen();
  145. videoDom.play();
  146. }
  147. });
  148. videoParentDomList.push(videoParentDom);
  149. try {
  150. const server = new window['WebRtcStreamer'](
  151. videoDom,
  152. VUE_APP_URL.webRtcUrl.startsWith('/') ? location.protocol + VUE_APP_URL.webRtcUrl : VUE_APP_URL.webRtcUrl
  153. );
  154. webRtcServer.unshift(server);
  155. await server.connect(cameraUrl.addr);
  156. videoDom.play();
  157. playerDoms.unshift(videoDom);
  158. childResolve(null);
  159. } catch (error) {
  160. console.log('WebRtcStreamer 抛出异常!!!!!!');
  161. playerDoms.unshift(null);
  162. childResolve(null);
  163. }
  164. }
  165. } else {
  166. try {
  167. fetch(cameraUrl.addr, {
  168. method: 'get',
  169. mode: 'no-cors',
  170. })
  171. .then(() => {
  172. videoParentDomList.push(['player', cameraUrl]);
  173. childResolve(null);
  174. })
  175. .catch(() => {
  176. videoParentDomList.push(['onPlayer' + index, cameraUrl]);
  177. childResolve(null);
  178. });
  179. } catch (error) {
  180. // console.log('可以捕获到异常吗?????');
  181. childResolve(null);
  182. }
  183. }
  184. });
  185. promiseList.push(promise);
  186. });
  187. Promise.all(promiseList).then(() => {
  188. resolve(null);
  189. });
  190. } else {
  191. resolve(null);
  192. }
  193. };
  194. playCamrea();
  195. }).then(() => {
  196. videoParentDomList.forEach((videoParentDom) => {
  197. if (typeof videoParentDom[0] === 'string') {
  198. const videoDom: HTMLElement = document.createElement('div');
  199. livePlayerDiv?.appendChild(videoDom);
  200. if (videoParentDom[0].startsWith('onPlayer')) {
  201. render(
  202. h(LivePlayer, {
  203. class: 'player',
  204. id: videoParentDom[0],
  205. muted: 'muted',
  206. autoplay: true,
  207. live: true,
  208. videoUrl: videoParentDom[1].addr,
  209. videoTitle: videoParentDom[1].name,
  210. alt: '无信号',
  211. poster: '/src/assets/images/vent/noSinge.png',
  212. }),
  213. videoDom
  214. );
  215. } else {
  216. render(
  217. h(LivePlayer, {
  218. class: 'player',
  219. muted: 'muted',
  220. autoplay: true,
  221. live: true,
  222. videoUrl: videoParentDom[1].addr,
  223. videoTitle: videoParentDom[1].name,
  224. alt: '无信号',
  225. poster: '/src/assets/images/vent/noSinge.png',
  226. }),
  227. videoDom
  228. );
  229. }
  230. } else {
  231. player.appendChild(videoParentDom as Node);
  232. }
  233. });
  234. const players = livePlayerDiv?.getElementsByClassName('player');
  235. if (players && players.length) {
  236. for (let i = 0; i < players.length; i++) {
  237. try {
  238. const isCanPlayer = !players[i].getAttribute('id')?.startsWith('onPlayer');
  239. const dom = players[i].getElementsByTagName('video')[0];
  240. if (dom && isCanPlayer) {
  241. playerDoms.unshift(dom);
  242. } else {
  243. playerDoms.unshift(null);
  244. }
  245. } catch (error) {
  246. console.log('可以捕获到异常吗?????');
  247. playerDoms.unshift(null);
  248. }
  249. }
  250. }
  251. if (webRtcServerList.length > 0) {
  252. for (let i = 0; i < webRtcServerList.length; i++) {
  253. webRtcServerList[i].videoElement.parentElement.remove();
  254. webRtcServerList[i].disconnect();
  255. webRtcServerList[i] = undefined;
  256. }
  257. }
  258. return { webRtcServerList: webRtcServer, playerDoms };
  259. });
  260. }