BigShow.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. <!--大屏显示组件-->
  2. <template>
  3. <div>
  4. <draggable
  5. v-for="item in currentBigshow"
  6. element="div"
  7. v-model="signalPreList"
  8. :options="dragOptions2"
  9. :class="['split_screen', bigScreenObj[item.ID].splitStatus === 0 ? 'split_screen_one' : bigScreenObj[item.ID].splitStatus === 1 ? 'split_screen_four' : bigScreenObj[item.ID].splitStatus === 2 ? 'split_screen_nine' : 'split_screen_sixteen']"
  10. :style="{
  11. float:'left',
  12. width:item.Width*bigScale + 'px',
  13. height:item.Height*bigScale + 'px',
  14. left:item.Left*bigScale+'px',
  15. top:item.Top*bigScale+'px',
  16. zIndex:item.ZIndex,
  17. display:item.IsVisibility ? 'black' : 'none',
  18. }"
  19. :id="item.ID"
  20. >
  21. <VueDragResize
  22. v-for="itemV in bigScreenObj[item.ID].signalArr" :key="itemV.Id" class="sitem"
  23. :w="itemV.width" :h="itemV.height" :parentLimitation="false"
  24. :x="itemV.left" :y="itemV.top"
  25. @dragstop="(position) => dragStop(position,itemV,bigScreenObj,curOpeBigscreenId)"
  26. @resizestop="(size) => resizeSignal(size,itemV,bigScreenObj,curOpeBigscreenId)"
  27. >
  28. <div ref="signal" :id="itemV.ID">
  29. <!--{{itemV.deviceID}}-->
  30. <VideoPlayer
  31. ref="videoPlayer"
  32. :options="playerOptions"
  33. :playsinline="true"
  34. />
  35. <div class="closeBtn" @click.stop="closeSignal(itemV)">×</div>
  36. </div>
  37. </VueDragResize>
  38. <div v-for="itemD in bigScreenObj[item.ID].bindList" class="sitem2">
  39. {{itemD}}
  40. </div>
  41. </draggable>
  42. </div>
  43. </template>
  44. <script>
  45. import {mapState} from 'vuex'
  46. import draggable from 'vuedraggable'
  47. import VueDragResize from 'vue-drag-resize'
  48. import '../assets/less/splitscreen.less'
  49. import {elePosition, getElementLeft, getElementTop, getStaticFile, guId} from "../../utils/tools"
  50. import {reqRefreshView} from "../api"
  51. import VideoPlayer from "./player.vue"
  52. export default {
  53. data() {
  54. return {
  55. streamWindows:[], // 传递出去的信号源位置信息
  56. currentBigshow:[], // 当前显示的大屏
  57. playerOptions: { // rtmp视频流配置
  58. sources: [
  59. {
  60. "src": "rtmp://58.200.131.2:1935/livetv/ahhd",
  61. "type": "rtmp/flv"
  62. }
  63. ],
  64. // aspectRatio: '1:1',
  65. techOrder: ['flash'],
  66. autoplay: true,
  67. controls: false,
  68. fluid:true,
  69. preload: 'auto',
  70. notSupportedMessage: '此视频暂无法播放,请稍后再试',
  71. },
  72. screenPosition:{}, // 大屏在视口中的位置
  73. }
  74. },
  75. components: {
  76. draggable,
  77. VueDragResize,
  78. VideoPlayer
  79. },
  80. async beforeCreate() {
  81. // 加载大屏json文件
  82. const bigScreenJson = await getStaticFile('EnityBigScreen.Data')
  83. // 过滤出显示的大屏
  84. this.currentBigshow = bigScreenJson.filter(item => item.IsVisibility === true)
  85. // 给大屏对象进行初始化显示
  86. const obj = {}
  87. this.currentBigshow.forEach(item => {
  88. obj[item.ID] = {
  89. bindList:[],
  90. splitStatus:0,
  91. signalArr:[],
  92. width:item.Width,
  93. height:item.Height
  94. }
  95. const num = item.BindList.length
  96. // 拼接屏数量
  97. for(let i=0;i<num;i++){
  98. obj[item.ID].bindList.push(i+1)
  99. }
  100. // 根据拼接屏数量得到分屏状态
  101. obj[item.ID].splitStatus = Math.floor(Math.sqrt(num)-1)
  102. })
  103. this.$store.dispatch('updateBigscreenObj',obj)
  104. },
  105. updated() {
  106. // 获取大屏在视口中的位置
  107. this.currentBigshow.forEach(item => {
  108. const screenDiv = document.getElementById(item.ID)
  109. this.screenPosition[item.ID] = {
  110. top:getElementTop(screenDiv),
  111. left:getElementLeft(screenDiv)
  112. }
  113. })
  114. },
  115. methods: {
  116. // 大屏开窗接口提交
  117. async refreshBigScreen(obj,Id) {
  118. if(Id){
  119. const signals = obj[Id].signalArr
  120. const streamWindows = signals.map((item,index) => ({
  121. left:item.left,
  122. top:item.top,
  123. width:item.width,
  124. height:item.height,
  125. id:index,
  126. sourceId:item.sourceId,
  127. widthScale:item.widthScale,
  128. heightScale:item.heightScale,
  129. orginRect:{}
  130. }))
  131. await reqRefreshView({
  132. bigScreenId:Id,
  133. streamWindows
  134. })
  135. }
  136. },
  137. // 拖动结束
  138. dragStop(positon,item,obj,Id) {
  139. // 深度克隆对象
  140. const newObj = JSON.parse(JSON.stringify(obj))
  141. item.left = positon.left
  142. item.top = positon.top
  143. const arr = newObj[Id].signalArr.filter(s => s.Id !== item.Id)
  144. newObj[Id].signalArr = [...arr,item]
  145. this.refreshBigScreen(newObj,Id)
  146. },
  147. // 缩放结束
  148. resizeSignal(size,item,obj,Id) {
  149. const bigScale = this.$store.state.bigScale
  150. // 深度克隆对象
  151. const newObj = JSON.parse(JSON.stringify(obj))
  152. item.width = size.width
  153. item.height = size.height
  154. item.left = size.left
  155. item.top = size.top
  156. item.widthScale = item.width/(newObj[Id].width*bigScale)
  157. item.heightScale = item.height/(newObj[Id].height*bigScale)
  158. const arr = newObj[Id].signalArr.filter(s => s.Id !== item.Id)
  159. newObj[Id].signalArr = [...arr,item]
  160. this.refreshBigScreen(newObj,Id)
  161. },
  162. // 关闭信号源
  163. closeSignal(signal) {
  164. const bigscreenId = signal.bigscreenId
  165. const bigScreenObj = this.$store.state.bigScreenObj
  166. // 1.找出是哪个大屏下的信号源发生了改变,过滤掉删除的那个
  167. const newSignalPreList = this.bigScreenObj[bigscreenId].signalArr.filter(item => item.Id !== signal.Id)
  168. // 2.重新赋值
  169. bigScreenObj[bigscreenId].signalArr = newSignalPreList
  170. this.refreshBigScreen(bigScreenObj,bigscreenId)
  171. },
  172. },
  173. computed: {
  174. ...mapState(['splitScreenStatus', 'bigScale','positionNum','curOpeBigscreenId','bigScreenObj']),
  175. // 当前变动的信号源数组监控
  176. signalPreList: {
  177. get() {
  178. return this.$store.getters.currentSignalArr
  179. },
  180. set(arr) {
  181. setTimeout(() => {
  182. const bigscreenId = this.$store.state.curOpeBigscreenId
  183. const bigScreenObj = this.$store.state.bigScreenObj
  184. const bigScale = this.$store.state.bigScale
  185. const positionNum = this.$store.state.positionNum
  186. const arr2 = []
  187. arr.forEach(item => {
  188. arr2.push(JSON.parse(JSON.stringify(item)))
  189. })
  190. const newObj = arr2.filter(item => !item.Id)
  191. const otherSignals = arr2.filter(item => item.Id)
  192. newObj[0].Id = guId()
  193. newObj[0].bigscreenId = bigscreenId
  194. newObj[0].splitScreenStatus = bigScreenObj[bigscreenId].splitStatus + 1
  195. newObj[0].width = bigScreenObj[bigscreenId].width * bigScale / newObj[0].splitScreenStatus
  196. newObj[0].height = bigScreenObj[bigscreenId].height * bigScale / newObj[0].splitScreenStatus
  197. newObj[0].widthScale = newObj[0].width / (bigScreenObj[bigscreenId].width * bigScale)
  198. newObj[0].heightScale = newObj[0].height / (bigScreenObj[bigscreenId].height * bigScale)
  199. const positionInfo = elePosition(newObj[0].width,newObj[0].height,positionNum,this.screenPosition[bigscreenId].top,this.screenPosition[bigscreenId].left,bigScreenObj[bigscreenId].splitStatus+1)
  200. newObj[0].top = positionInfo.top - this.screenPosition[bigscreenId].top
  201. newObj[0].left = positionInfo.left - this.screenPosition[bigscreenId].left
  202. bigScreenObj[bigscreenId].signalArr = [...otherSignals,...newObj]
  203. this.refreshBigScreen(bigScreenObj,bigscreenId)
  204. })
  205. }
  206. },
  207. // 拖拽选项配置
  208. dragOptions1() {
  209. return {
  210. animation: 0,
  211. group: {
  212. name: "description",
  213. pull: 'clone',
  214. put: false
  215. },
  216. ghostClass: "ghost",
  217. }
  218. },
  219. dragOptions2() {
  220. return {
  221. animation: 0,
  222. group: "description",
  223. disabled:false,
  224. sort:false,
  225. }
  226. },
  227. player() {
  228. return this.$refs.videoPlayer.player
  229. },
  230. },
  231. watch: {
  232. // 监视分屏的状态
  233. /*splitScreenStatus: function(num) {
  234. console.log(num)
  235. this.$data.bindList = []
  236. for (let i=0;i<(num+1)*(num+1);i++){
  237. this.$data.bindList.push(i+1)
  238. }
  239. this.rfreshBigScreen(this.$data.streamWindows)
  240. }*/
  241. }
  242. }
  243. </script>