ventutil.ts 9.5 KB

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