Commit e43587ecf39066c8e4a74297c2a29deda9384cc0

Authored by ww
1 parent ef71e5bb

feat: implement video component bind videoUrl

... ... @@ -32,6 +32,7 @@
32 32
33 33 <script src="./plugins/axios.min.js"></script>
34 34
  35 + <!-- video.js import -->
35 36 <link href="https://vjs.zencdn.net/7.10.2/video-js.min.css" rel="stylesheet">
36 37 <script src="https://vjs.zencdn.net/7.10.2/video.min.js"></script>
37 38
... ...
... ... @@ -5,7 +5,7 @@ class ConfigurationNodeApi {
5 5 * @param {string} levelId - 组态资源ID
6 6 */
7 7 static getConfigurationInfo(levelType, levelId) {
8   - return defHttp.get(`/yt/configuration/node/${ levelType }/${ levelId }`)
  8 + return defHttp.get(`/yt/configuration/node/${levelType}/${levelId}`)
9 9 }
10 10
11 11 /**
... ... @@ -22,7 +22,7 @@ class ConfigurationNodeApi {
22 22 * @returns {Promise<*>}
23 23 */
24 24 static getDeviceAttr(tbDeviceId) {
25   - return defHttp.get(`/plugins/telemetry/DEVICE/${ tbDeviceId }/keys/timeseries`)
  25 + return defHttp.get(`/plugins/telemetry/DEVICE/${tbDeviceId}/keys/timeseries`)
26 26 }
27 27
28 28 /**
... ... @@ -32,7 +32,7 @@ class ConfigurationNodeApi {
32 32 * @returns {Promise<*>}
33 33 */
34 34 static getDeviceUnderTheOrg(deviceType, orgId) {
35   - return defHttp.get(`/yt/device/list/${ deviceType }?organizationId=${ orgId }`)
  35 + return defHttp.get(`/yt/device/list/${deviceType}?organizationId=${orgId}`)
36 36 }
37 37
38 38 /**
... ... @@ -50,7 +50,7 @@ class ConfigurationNodeApi {
50 50 * @returns {Promise<*>}
51 51 */
52 52 static getDeviceChildDevice(deviceId) {
53   - return defHttp.get(`/yt/device/relation?page=1&pageSize=10&fromId=${ deviceId }`)
  53 + return defHttp.get(`/yt/device/relation?page=1&pageSize=10&fromId=${deviceId}`)
54 54 }
55 55
56 56 /**
... ... @@ -59,7 +59,7 @@ class ConfigurationNodeApi {
59 59 * @returns {Promise<*>}
60 60 */
61 61 static getMasterDevice(orgId) {
62   - return defHttp.get(`/yt/device/list/master/${ orgId }`)
  62 + return defHttp.get(`/yt/device/list/master/${orgId}`)
63 63 }
64 64
65 65 /**
... ... @@ -69,7 +69,7 @@ class ConfigurationNodeApi {
69 69 * @returns {Promise<*>}
70 70 */
71 71 static getSlaveDevice(orgId, masterDeviceId) {
72   - return defHttp.get(`/yt/device/list/slave/${ orgId }?masterId=${ masterDeviceId }`)
  72 + return defHttp.get(`/yt/device/list/slave/${orgId}?masterId=${masterDeviceId}`)
73 73 }
74 74
75 75 /**
... ... @@ -103,7 +103,7 @@ class ConfigurationNodeApi {
103 103 * @param {object} data - 数据
104 104 */
105 105 static sendInstructionOneWay(deviceId, data) {
106   - return defHttp.post(`/rpc/oneway/${ deviceId }`, data)
  106 + return defHttp.post(`/rpc/oneway/${deviceId}`, data)
107 107 }
108 108
109 109 /**
... ... @@ -112,7 +112,7 @@ class ConfigurationNodeApi {
112 112 * @param {object} data - 数据
113 113 */
114 114 static sendInstructionTwoWay(deviceId, data) {
115   - return defHttp.post(`/rpc/twoway/${ deviceId }`, data)
  115 + return defHttp.post(`/rpc/twoway/${deviceId}`, data)
116 116 }
117 117
118 118 /**
... ... @@ -122,8 +122,8 @@ class ConfigurationNodeApi {
122 122 * @param data
123 123 * @return {*}
124 124 */
125   - static sendInstruction(way,deviceId, data) {
126   - return defHttp.post(`/rpc/${way}/${ deviceId }`, data)
  125 + static sendInstruction(way, deviceId, data) {
  126 + return defHttp.post(`/rpc/${way}/${deviceId}`, data)
127 127 }
128 128
129 129 /**
... ... @@ -131,7 +131,7 @@ class ConfigurationNodeApi {
131 131 * @param deviceId
132 132 * @return {*}
133 133 */
134   - static deviceIsOnLine(deviceId){
  134 + static deviceIsOnLine(deviceId) {
135 135 return defHttp.get(`/plugins/telemetry/DEVICE/${deviceId}/values/attributes?keys=active`)
136 136 }
137 137
... ... @@ -140,7 +140,27 @@ class ConfigurationNodeApi {
140 140 * @param data
141 141 * @returns {*}
142 142 */
143   - static uploadImg(data){
  143 + static uploadImg(data) {
144 144 return defHttp.post('/yt/oss/upload', data)
145 145 }
  146 +
  147 + /**
  148 + * @description 获取流媒体
  149 + * @param {number} page
  150 + * @param {number} pageSize
  151 + * @returns
  152 + */
  153 + static getStreamingMediaList(organizationId, page = 1, pageSize = 10) {
  154 + return defHttp.get(`/yt/video`, { params: { organizationId, page, pageSize } })
  155 + }
  156 +
  157 +
  158 + /**
  159 + * @description 获取流媒体播放地址
  160 + * @param {string} id
  161 + * @returns
  162 + */
  163 + static getStreamingVideoPlayUrl(id) {
  164 + return defHttp.get(`/yt/video/url/${id}`)
  165 + }
146 166 }
... ...
... ... @@ -227,7 +227,7 @@
227 227 * @description 柱状图类型
228 228 */
229 229 BAR_CHART: 'barChart',
230   -
  230 +
231 231 /**
232 232 * @description 视频
233 233 */
... ... @@ -273,7 +273,8 @@
273 273 BAR_CHART_EXPAND: 'barChartExpandDataSource',
274 274 INTERACTION: 'interaction',
275 275 DYNAMIC_EFFECT: 'dynamicEffect',
276   - VAR_IMAGE: 'variableImage'
  276 + VAR_IMAGE: 'variableImage',
  277 + VIDEO: 'video'
277 278 }
278 279
279 280 /**
... ... @@ -627,8 +628,8 @@
627 628 //更多图形,显示出来的的标题跟id,同时包括图片
628 629
629 630 // TODO thingsKit 设置数据绑定展示面板
630   - const { LINE_CHART_EXPAND, BAR_CHART_EXPAND, DYNAMIC_EFFECT, DATA_SOURCE, VAR_IMAGE, INTERACTION } = this.enumPermissionPanel
631   - const { LINE, LINE_CHART, REAL_TIME, TITLE, VARIABLE, DEFAULT, BAR_CHART } = this.enumComponentType
  631 + const { LINE_CHART_EXPAND, BAR_CHART_EXPAND, DYNAMIC_EFFECT, DATA_SOURCE, VAR_IMAGE, INTERACTION, VIDEO: VIDEO_PANEL } = this.enumPermissionPanel
  632 + const { LINE, LINE_CHART, REAL_TIME, TITLE, VARIABLE, DEFAULT, BAR_CHART, VIDEO } = this.enumComponentType
632 633 this.setComponentPermission(LINE, [DYNAMIC_EFFECT])
633 634 this.setComponentPermission(DEFAULT, [DYNAMIC_EFFECT])
634 635 this.setComponentPermission(REAL_TIME, [DYNAMIC_EFFECT])
... ... @@ -637,6 +638,7 @@
637 638 this.setComponentPermission(VARIABLE, [DATA_SOURCE, INTERACTION, DYNAMIC_EFFECT])
638 639 this.setComponentPermission(BAR_CHART, [DATA_SOURCE, BAR_CHART_EXPAND])
639 640 this.setComponentPermission(LINE_CHART, [DATA_SOURCE, LINE_CHART_EXPAND])
  641 + this.setComponentPermission(VIDEO, [VIDEO_PANEL])
640 642
641 643 var thingskitEntries = [
642 644 { title: "风机", id: 'fan', image: IMAGE_PATH + '/thingskit/风机.png' },
... ...
... ... @@ -53,7 +53,7 @@
53 53 return this.createVertexTemplateFromCells([cell], cell.geometry.width, cell.geometry.height, '变量图片');
54 54 })),
55 55 this.addEntry(this.getTagsForStencil('mxgraph.basic', '视频', 'basic').join(' '), mxUtils.bind(this, function () {
56   - const template = createVideoTemplate()
  56 + const template = createVideoTemplate(300, 150)
57 57 const cell = new mxCell(template, new mxGeometry(0, 0, 300, 150), 'text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;');
58 58 cell.setVertex(true)
59 59 this.setCellAttributes(cell, { [basicAttr.COMPONENT_TYPE]: componentType.VIDEO })
... ... @@ -86,6 +86,7 @@
86 86
87 87 function createVideoTemplate(width = '100%', height = '100%') {
88 88 const m3u8 = 'http://d2zihajmogu5jn.cloudfront.net/bipbop-advanced/bipbop_16x9_variant.m3u8'
  89 + // const m3u8 = 'http://113.204.115.250:83/openUrl/iVnkGzK/live.m3u8'
89 90 const mp4 = 'http://vjs.zencdn.net/v/oceans.mp4'
90 91 const m3u8Type = 'application/x-mpegURL'
91 92 const mp4Type = 'video/mp4'
... ... @@ -93,7 +94,7 @@
93 94
94 95 // const cell = new mxCell('<video></video>', new mxGeometry(0, 0, 100, 95), 'image;image=images/thingskit/video.svg;imageAspect=0;');
95 96 const template = `<video controls preload="auto" muted="muted" width="${width}" height="${height}" poster="${poster}" data-setup='{}'>
96   - <source src="${mp4}" type="${mp4Type}">
  97 + <source src="${m3u8}" type="${m3u8Type}">
97 98 <p class="vjs-no-js">
98 99 要查看此视频,请启用JavaScript,并考虑升级web浏览器.
99 100 </p>
... ...
... ... @@ -5123,12 +5123,12 @@ DataFormatPanel.prototype.addDataFont = function (container) {
5123 5123
5124 5124 const renderMapping = {
5125 5125 [permissionKey.DATA_SOURCE]: createDataSourcePanel,
5126   - // [permissionKey.DISPLAY_TYPE]: createChartBindPanel,
5127 5126 [permissionKey.LINE_CHART_EXPAND]: createLineChartPanel,
5128 5127 [permissionKey.BAR_CHART_EXPAND]: createBarChartPanel,
5129 5128 [permissionKey.INTERACTION]: createInteractionPanel,
5130 5129 [permissionKey.DYNAMIC_EFFECT]: createDynamicEffectPanel,
5131 5130 [permissionKey.VAR_IMAGE]: createVarImagePanel,
  5131 + [permissionKey.VIDEO]: createVideoBindPanel
5132 5132 }
5133 5133
5134 5134
... ... @@ -5255,6 +5255,128 @@ DataFormatPanel.prototype.addDataFont = function (container) {
5255 5255 }
5256 5256
5257 5257 /**
  5258 + * @description 创建视频绑定面板
  5259 + */
  5260 + function createVideoBindPanel() {
  5261 +
  5262 + const enumConst = {
  5263 + ORG_ID: 'orgId',
  5264 + RECORD_ID: 'id',
  5265 + VIDEO_URL: 'videoUrl',
  5266 + ACCESSMODE: 'accessMode',
  5267 + VIDEO_FLAG: 'videoComponentFlag'
  5268 + }
  5269 +
  5270 + const enumActionEL = {
  5271 + VIDEO_FILTER: 'videoFilter',
  5272 + PANEL_EL: 'videoPanelControl',
  5273 + ORG_EL: 'orgTreeEl'
  5274 + }
  5275 +
  5276 + const fragment = document.createDocumentFragment()
  5277 + const title = createTitle('视频绑定')
  5278 + $(title).addClass('override__title--default')
  5279 +
  5280 + const defaultPanel = createPanel()
  5281 + $(defaultPanel).addClass('override__panel--default')
  5282 + $(defaultPanel).append(`<div id="${enumActionEL.ORG_EL}" class="video-panel-org__override"></div>`)
  5283 + $(defaultPanel).append(`<div class="layui-form-item" style="display: none;"><input name="${enumConst.ACCESSMODE}" /></div>`)
  5284 + $(defaultPanel).append(`<div class="layui-form-item" style="display: none;"><input name="${enumConst.VIDEO_FLAG}" value="true" /></div>`)
  5285 + $(defaultPanel).append(`<div class="layui-form-item" style="display: none;"><input name="${enumConst.VIDEO_URL}" /></div>`)
  5286 +
  5287 + const videoBindSelect = UseLayUi.createSelect({
  5288 + label: '视频流',
  5289 + layFilter: enumActionEL.VIDEO_FILTER,
  5290 + className: 'data-source__component-select',
  5291 + bindValueFiled: enumConst.RECORD_ID
  5292 + })
  5293 + $(defaultPanel).append(`<div id="${enumActionEL.PANEL_EL}">${videoBindSelect}</div>`)
  5294 +
  5295 + fragment.append(title)
  5296 + fragment.append(defaultPanel)
  5297 + $(container).append(fragment)
  5298 +
  5299 + function init() {
  5300 +
  5301 + let orgId = null;
  5302 +
  5303 + let recordOptions = []
  5304 +
  5305 + let treeList = []
  5306 +
  5307 + const refreshFN = echoRefreshFn
  5308 + echoRefreshFn = async function () {
  5309 + refreshFN.apply(this, arguments)
  5310 + await echoData()
  5311 + }
  5312 + async function echoData() {
  5313 + const { videoUrl, orgId: organizationId, accessMode, id } = currentNodeData?.dataSources?.[0]?.additional || {}
  5314 + orgId = organizationId
  5315 + await getStreamingMediaByOrgId()
  5316 + form.val(CONTAINER_FILTER, { videoUrl, accessMode, id })
  5317 + UseLayUi.nextTick(() => {
  5318 + const node = UseLayUi.findTreeObjectByField(treeList, organizationId)
  5319 + $(`#${enumActionEL.ORG_EL} input[name="${enumConst.ORG_ID}"]`).val(organizationId).parent().find('span').html(node?.name)
  5320 + })
  5321 + }
  5322 +
  5323 +
  5324 +
  5325 + /**
  5326 + * @description 创建组织树
  5327 + */
  5328 + async function createOrgTreeSelect() {
  5329 + const [err, res] = await to(ConfigurationNodeApi.getOrgTree())
  5330 + treeList = res
  5331 + if (err) return
  5332 + UseLayUi.createTreeSelect({
  5333 + elem: `#${enumActionEL.ORG_EL}`,
  5334 + layFilter: enumConst.ORG_ID,
  5335 + label: '组织',
  5336 + singleUsage: false,
  5337 + layVerify: 'required',
  5338 + layVerType: 'tips',
  5339 + treeProps: {
  5340 + data: res,
  5341 + onlyIconControl: true,
  5342 + click(node) {
  5343 + orgId = node.data.id
  5344 + getStreamingMediaByOrgId()
  5345 + form.val(CONTAINER_FILTER, {
  5346 + [enumConst.RECORD_ID]: null
  5347 + })
  5348 + },
  5349 + },
  5350 + })
  5351 + }
  5352 +
  5353 + async function getStreamingMediaByOrgId() {
  5354 + const [err, res] = await to(ConfigurationNodeApi.getStreamingMediaList(orgId))
  5355 + recordOptions = res.items
  5356 + const options = UseLayUi.generateOptionTemplate({ dataSource: res.items || [] })
  5357 + $(`#${enumActionEL.PANEL_EL} select[name="${enumConst.RECORD_ID}"]`).html(options)
  5358 + form.render()
  5359 + }
  5360 +
  5361 + function createLinsten() {
  5362 + form.on(`select(${enumActionEL.VIDEO_FILTER})`, event => {
  5363 + const { value } = event
  5364 + const item = recordOptions.find(item => item.id === value)
  5365 + form.val(CONTAINER_FILTER, {
  5366 + [enumConst.ACCESSMODE]: item[enumConst.ACCESSMODE],
  5367 + [enumConst.VIDEO_URL]: item[enumConst.VIDEO_URL],
  5368 + })
  5369 + })
  5370 + }
  5371 +
  5372 + createOrgTreeSelect()
  5373 + createLinsten()
  5374 + }
  5375 +
  5376 + init()
  5377 + }
  5378 +
  5379 + /**
5258 5380 * @description 是否是折线图
5259 5381 * @param {boolean} isLineChart
5260 5382 */
... ... @@ -5688,10 +5810,43 @@ DataFormatPanel.prototype.addDataFont = function (container) {
5688 5810 const panel = createPanel()
5689 5811 $(panel).addClass('data-source__submit-panel').append(`<button type="button" lay-submit lay-filter="formDataSource" class="layui-btn">保存</button>`)
5690 5812 $(container).append(panel)
5691   - const additionalKey = HandleDataSource.enumConst
5692 5813 form.on('submit(formDataSource)', async function (data) {
5693   - const ENABLED_FLAG = 'on'
5694 5814 const { field } = data
  5815 + const value = getValueOnSubmit(field)
  5816 + await to(autoSaveGraphInfo())
  5817 + const [err, res] = await to(ConfigurationNodeApi.updateNodeInfo(value))
  5818 + if (err) return
  5819 + UseLayUi.successMsg()
  5820 + await getNodeBindInfo()
  5821 + return false;
  5822 + });
  5823 + }
  5824 +
  5825 + function getValueOnSubmit(field) {
  5826 + const basicAttr = sidebarInstance.enumCellBasicAttribute
  5827 + const permissionKey = sidebarInstance.enumComponentType
  5828 +
  5829 +
  5830 + const renderMapping = {
  5831 + [permissionKey.VAR_IMAGE]: getSubmitValue,
  5832 + [permissionKey.CHARTS]: getSubmitValue,
  5833 + [permissionKey.TITLE]: getSubmitValue,
  5834 + [permissionKey.VARIABLE]: getSubmitValue,
  5835 + [permissionKey.LINE]: getSubmitValue,
  5836 + [permissionKey.REAL_TIME]: getSubmitValue,
  5837 + [permissionKey.LINE_CHART]: getSubmitValue,
  5838 + [permissionKey.DEFAULT]: getVideoSubmitValue,
  5839 + [permissionKey.VIDEO]: getVideoSubmitValue,
  5840 + }
  5841 +
  5842 + const cell = vertices[0]
  5843 + const permission = graph.getAttributeForCell(cell, basicAttr.COMPONENT_TYPE)
  5844 +
  5845 + return renderMapping[permission]?.() || {}
  5846 +
  5847 + function getSubmitValue() {
  5848 + const ENABLED_FLAG = 'on'
  5849 + const additionalKey = HandleDataSource.enumConst
5695 5850 const value = {
5696 5851 configurationId,
5697 5852 contentId: currentPageId.id,
... ... @@ -5701,7 +5856,6 @@ DataFormatPanel.prototype.addDataFont = function (container) {
5701 5856 [enumCategory.DATA_SOURCE]: {
5702 5857 [enumDataSourceConst.ORG_ID]: field[enumDataSourceConst.ORG_ID],
5703 5858 [enumDataSourceConst.DEVICE_ID]: field[enumDataSourceConst.DEVICE_ID],
5704   - // ...(field[enumDataSourceConst.SLAVE_DEVICE_ID] && { [enumDataSourceConst.SLAVE_DEVICE_ID]: field[enumDataSourceConst.SLAVE_DEVICE_ID] }),
5705 5859 [enumDataSourceConst.SLAVE_DEVICE_ID]: field[enumDataSourceConst.SLAVE_DEVICE_ID] ? field[enumDataSourceConst.SLAVE_DEVICE_ID] : '',
5706 5860 [enumDataSourceConst.ATTR]: field[enumDataSourceConst.ATTR],
5707 5861 [enumDataSourceConst.ADDITIONAL]: field[additionalKey.DATA_TYPE] ? {
... ... @@ -5728,13 +5882,24 @@ DataFormatPanel.prototype.addDataFont = function (container) {
5728 5882 })
5729 5883 }
5730 5884 }
5731   - await to(autoSaveGraphInfo())
5732   - const [err, res] = await to(ConfigurationNodeApi.updateNodeInfo(value))
5733   - if (err) return
5734   - UseLayUi.successMsg()
5735   - await getNodeBindInfo()
5736   - return false;
5737   - });
  5885 +
  5886 + return value
  5887 + }
  5888 +
  5889 + function getVideoSubmitValue() {
  5890 + const value = {
  5891 + configurationId,
  5892 + contentId: currentPageId.id,
  5893 + nodeId: graphId,
  5894 + [enumCategory.DATA_SOURCE]: {
  5895 + [enumDataSourceConst.ORG_ID]: 'b4dd6e2b-6e0f-413c-bf5a-70133bd571e8',
  5896 + [enumDataSourceConst.DEVICE_ID]: '6d9043f0-f1f7-11ec-98ad-a9680487d1e0',
  5897 + [enumDataSourceConst.ATTR]: 'attr',
  5898 + [enumDataSourceConst.ADDITIONAL]: field
  5899 + },
  5900 + }
  5901 + return value
  5902 + }
5738 5903 }
5739 5904
5740 5905 /**
... ... @@ -13260,6 +13425,11 @@ class HandleDynamicEffect {
13260 13425 enableActList
13261 13426
13262 13427 /**
  13428 + * @description 视频记录列表
  13429 + */
  13430 + videoRecordList
  13431 +
  13432 + /**
13263 13433 * @description 动效节点映射
13264 13434 * @type {Map<string, {display: boolean, value: Map<string, any>}>}
13265 13435 */
... ... @@ -13287,6 +13457,19 @@ class HandleDynamicEffect {
13287 13457 HIDDEN: 'hidden',
13288 13458 }
13289 13459
  13460 + static enumVideoConst = {
  13461 + ORG_ID: 'orgId',
  13462 + RECORD_ID: 'id',
  13463 + VIDEO_URL: 'videoUrl',
  13464 + ACCESSMODE: 'accessMode',
  13465 + VIDEO_FLAG: 'videoComponentFlag'
  13466 + }
  13467 +
  13468 + static enumVideoAccessMode = {
  13469 + MANUAL_ENTER: 0,
  13470 + STREAMING: 1
  13471 + }
  13472 +
13290 13473 constructor(DispatchInstance) {
13291 13474 this.DispatchInstance = DispatchInstance
13292 13475 this.init()
... ... @@ -13294,6 +13477,7 @@ class HandleDynamicEffect {
13294 13477
13295 13478 init() {
13296 13479 this.getEnableActList()
  13480 + this.getVideoRecord()
13297 13481 this.generatorMappingRelation()
13298 13482 }
13299 13483
... ... @@ -13326,6 +13510,15 @@ class HandleDynamicEffect {
13326 13510 }
13327 13511
13328 13512 /**
  13513 + * @description 筛选出视频数据源
  13514 + */
  13515 + getVideoRecord() {
  13516 + const { dataSources = [] } = this.DispatchInstance.contentData
  13517 + const { VIDEO_FLAG } = HandleDynamicEffect.enumVideoConst
  13518 + this.videoRecordList = dataSources.filter(item => item?.additional?.[VIDEO_FLAG])
  13519 + }
  13520 +
  13521 + /**
13329 13522 * @description 获取已开启的数据动效
13330 13523 */
13331 13524 getEnableActList() {
... ... @@ -13465,13 +13658,6 @@ class HandleDynamicEffect {
13465 13658 isShow = false
13466 13659 }
13467 13660 const updateFn = () => {
13468   - // let style = node.getStyle()
13469   - // const reg = /opacity=(-?)\w+(;?)/g
13470   - // style = style.replace(reg, '')
13471   - // style += `opacity=${isShow ? 100 : 0};`
13472   - // console.log(style)
13473   - // node.setStyle(style)
13474   -
13475 13661 if (!isShow) {
13476 13662 Object.keys(HandleDynamicEffect.enumActType).forEach(key => {
13477 13663 const delKey = node.id + key
... ... @@ -13534,53 +13720,111 @@ class HandleDynamicEffect {
13534 13720 }
13535 13721 }
13536 13722
13537   -
  13723 + /**
  13724 + * @description 播放视频
  13725 + */
13538 13726 videoPlay() {
13539 13727 const basicAttr = Sidebar.prototype.enumCellBasicAttribute
13540   - const videoCell = this.DispatchInstance.contentAllCell.filter(cell => cell.getAttribute(basicAttr.COMPONENT_TYPE) === 'video')
13541   - // const options = {
13542   - // hls: {
13543   - // withCredentials: true
13544   - // }
13545   - // }
13546   - // var player = videojs('my-player', options, function onPlayerReady() {
13547   - // videojs.log('Your player is ready!');
13548   -
13549   - // // In this context, `this` is the player that was created by Video.js.
13550   - // this.play();
13551   -
13552   - // // How about an event listener?
13553   - // this.on('ended', function () {
13554   - // videojs.log('Awww...over so soon?!');
13555   - // });
13556   - // });
13557   -
13558   - // console.log(player)
13559   - // for (const cell of videoCell) {
13560   - // this.graph.getModel().beginUpdate()
13561   - // try {
13562   - // const options = {
13563   - // hls: {
13564   - // withCredentials: true
13565   - // }
13566   - // }
13567   - // var player = videojs('my-player', options, function onPlayerReady() {
13568   - // videojs.log('Your player is ready!');
13569   -
13570   - // // In this context, `this` is the player that was created by Video.js.
13571   - // this.play();
13572   -
13573   - // // How about an event listener?
13574   - // this.on('ended', function () {
13575   - // videojs.log('Awww...over so soon?!');
13576   - // });
13577   - // });
13578   - // this.graph.refresh(cell);
13579   - // } finally {
13580   - // this.graph.getModel().endUpdate()
13581   - // }
13582   - // }
  13728 + const enumAccessMode = HandleDynamicEffect.enumVideoAccessMode
  13729 +
  13730 + const videoPlayConfig = {
  13731 + controls: true,
  13732 + bigPlayButton: true,
  13733 + textTrackDisplay: false,
  13734 + posterImage: false,
  13735 + errorDisplay: false,
  13736 + }
  13737 + for (const record of this.videoRecordList) {
  13738 + const { additional = {}, nodeId } = record
  13739 + const { accessMode, videoUrl, id } = additional
  13740 + const cell = this.getCellByCellId(nodeId)
  13741 + if (!cell) continue
  13742 + const { geometry = {} } = cell
  13743 + const { width, height } = geometry
  13744 + const idEl = getIdEl()
  13745 + if (Number(accessMode) === enumAccessMode.MANUAL_ENTER) {
  13746 + this.graph.getModel().beginUpdate()
  13747 + try {
  13748 + const template = this.createVideoTemplate(idEl, width, height, videoUrl)
  13749 + cell.setAttribute('label', template)
  13750 + this.graph.refresh(cell);
  13751 + } finally {
  13752 + this.graph.getModel().endUpdate()
  13753 + console.log(idEl)
  13754 + videojs(idEl,
  13755 + {
  13756 + ...videoPlayConfig
  13757 + },
  13758 + function () {
  13759 + const el = document.getElementById(idEl)
  13760 + const videoEl = el.getElementsByTagName('video')?.[0]
  13761 + videoEl.style.width = `${width}px`
  13762 + videoEl.style.height = `${height}px`
  13763 + this.play()
  13764 + })
  13765 + }
  13766 + } else {
  13767 + getStreamingVideoPlayUrl.call(this, id, nodeId)
  13768 + }
  13769 + }
  13770 +
  13771 + async function getStreamingVideoPlayUrl(id, nodeId) {
  13772 + const [err, res = {}] = await to(ConfigurationNodeApi.getStreamingVideoPlayUrl(id))
  13773 + const { url } = res?.data || {}
  13774 + if (!url) return
  13775 + const cell = this.getCellByCellId(nodeId)
  13776 + if (!cell) return
  13777 + const { geometry = {} } = cell
  13778 + const { width, height } = geometry
  13779 + const idEl = getIdEl()
  13780 + this.graph.getModel().beginUpdate()
  13781 + try {
  13782 + const template = this.createVideoTemplate(idEl, width, height, url, 'application/x-mpegURL')
  13783 + cell.setAttribute('label', template)
  13784 + this.graph.refresh(cell);
  13785 + } finally {
  13786 + this.graph.getModel().endUpdate()
  13787 + videojs(idEl,
  13788 + {
  13789 + ...videoPlayConfig,
  13790 + hls: {
  13791 + withCredentials: true
  13792 + }
  13793 + },
  13794 + function () {
  13795 + const el = document.getElementById(idEl)
  13796 + const videoEl = el.getElementsByTagName('video')?.[0]
  13797 + videoEl.style.width = `${width}px`
  13798 + videoEl.style.height = `${height}px`
  13799 + this.play()
  13800 + })
  13801 + }
  13802 + }
  13803 +
  13804 + function getIdEl() {
  13805 + return `video-play__${Date.now()}`
  13806 + }
  13807 + }
  13808 +
  13809 +
  13810 + createVideoTemplate(idEl, width, height, videoUrl, videoType = 'video/mp4') {
  13811 + const poster = `/thingskit-drawio/images/youtube.png`
  13812 + const template = `<video id="${idEl}" controls preload="auto" muted="muted" width="${width}" height="${height}" poster="${poster}" data-setup='{}'>
  13813 + <source src="${videoUrl}" type="${videoType}">
  13814 + <p class="vjs-no-js">
  13815 + 要查看此视频,请启用JavaScript,并考虑升级web浏览器.
  13816 + </p>
  13817 + </video>`
  13818 + return template
13583 13819 }
  13820 + /**
  13821 + * @description 获取cell 通过cell id
  13822 + */
  13823 + getCellByCellId(id) {
  13824 + const allCell = this.DispatchInstance.contentAllCell || []
  13825 + return allCell.find(item => item.id === id)
  13826 + }
  13827 +
13584 13828
13585 13829 /**
13586 13830 * @description 验证是否满足条件列表中的任意一条
... ...
... ... @@ -480,3 +480,15 @@
480 480 .chart-panel__style .layui-input-block {
481 481 margin-left: 0px !important;
482 482 }
  483 +
  484 +.video-panel-org__override .layui-form-item {
  485 + display: flex;
  486 +}
  487 +.video-panel-org__override .layui-form-item label{
  488 + width: 60px;
  489 + box-sizing: border-box;
  490 +}
  491 +.video-panel-org__override .layui-form-item .layui-input-block {
  492 + flex: auto;
  493 + margin-left: 0;
  494 +}
... ...