|  |  |  | 
|---|
|  |  |  | <template> | 
|---|
|  |  |  | <div id="devicePosition" style="height: 100%"> | 
|---|
|  |  |  | <el-container style="height: 100%"> | 
|---|
|  |  |  | <el-header> | 
|---|
|  |  |  | <uiHeader></uiHeader> | 
|---|
|  |  |  | </el-header> | 
|---|
|  |  |  | <el-container v-loading="loading" element-loading-text="拼命加载中"> | 
|---|
|  |  |  | <el-aside width="300px" style="background-color: #ffffff"> | 
|---|
|  |  |  | <div style="text-align: center;padding-top: 20px;">设备列表</div> | 
|---|
|  |  |  | <el-menu  v-loading="loading"> | 
|---|
|  |  |  | <el-submenu v-for="device in deviceList" :key="device.deviceId" :index="device.deviceId" @click="sendDevicePush(item)"> | 
|---|
|  |  |  | <template slot="title" > | 
|---|
|  |  |  | <i class="el-icon-location-outline"></i> | 
|---|
|  |  |  | {{device.name}} | 
|---|
|  |  |  | </template> | 
|---|
|  |  |  | <ChannelTree :device="device" @sendDevicePush="sendDevicePush"></ChannelTree> | 
|---|
|  |  |  | </el-submenu> | 
|---|
|  |  |  | </el-menu> | 
|---|
|  |  |  | </el-aside> | 
|---|
|  |  |  | <el-container> | 
|---|
|  |  |  | <!-- <LivePlay></LivePlay> --> | 
|---|
|  |  |  | <el-header height="40px" style="text-align: left;font-size: 17px;line-height: 40px;"> | 
|---|
|  |  |  | 分屏: | 
|---|
|  |  |  | <i class="el-icon-full-screen btn" :class="{active:spilt==1}" @click="spilt=1"/> | 
|---|
|  |  |  | <i class="el-icon-menu btn" :class="{active:spilt==4}" @click="spilt=4"/> | 
|---|
|  |  |  | <i class="el-icon-s-grid btn" :class="{active:spilt==9}" @click="spilt=9"/> | 
|---|
|  |  |  | </el-header> | 
|---|
|  |  |  | <el-main> | 
|---|
|  |  |  | <div style="width: 100%;height: calc( 100vh - 110px );display: flex;flex-wrap: wrap;background-color: #000;"> | 
|---|
|  |  |  | <div v-for="i in spilt" :key="i" class="play-box" | 
|---|
|  |  |  | :style="liveStyle" :class="{redborder:playerIdx == (i-1)}" | 
|---|
|  |  |  | @click="playerIdx = (i-1)" | 
|---|
|  |  |  | > | 
|---|
|  |  |  | <div v-if="!videoUrl[i-1]" style="color: #ffffff;font-size: 30px;font-weight: bold;">{{i}}</div> | 
|---|
|  |  |  | <player v-else :ref="'player'+i" :videoUrl="videoUrl[i-1]"  fluent autoplay :height="true" | 
|---|
|  |  |  | :idx="'player'+i" @screenshot="shot" @destroy="destroy"></player> | 
|---|
|  |  |  | <!-- <player v-else ref="'player'+i" :idx="'player'+i" :visible.sync="showVideoDialog" :videoUrl="videoUrl[i-1]"  :height="true" :hasAudio="hasAudio" fluent autoplay live ></player> --> | 
|---|
|  |  |  | </div> | 
|---|
|  |  |  | </div> | 
|---|
|  |  |  | </el-main> | 
|---|
|  |  |  | </el-container> | 
|---|
|  |  |  | <div id="devicePosition" style="width:100vw; height: 91vh"> | 
|---|
|  |  |  | <el-container v-loading="loading" style="height: 91vh;" element-loading-text="拼命加载中"> | 
|---|
|  |  |  | <el-aside width="300px" style="background-color: #ffffff"> | 
|---|
|  |  |  | <DeviceTree :clickEvent="clickEvent" :contextMenuEvent="contextMenuEvent"></DeviceTree> | 
|---|
|  |  |  | </el-aside> | 
|---|
|  |  |  | <el-container> | 
|---|
|  |  |  | <el-header height="5vh" style="text-align: left;font-size: 17px;line-height:5vh"> | 
|---|
|  |  |  | 分屏: | 
|---|
|  |  |  | <i class="el-icon-full-screen btn" :class="{active:spilt==1}" @click="spilt=1"/> | 
|---|
|  |  |  | <i class="el-icon-menu btn" :class="{active:spilt==4}" @click="spilt=4"/> | 
|---|
|  |  |  | <i class="el-icon-s-grid btn" :class="{active:spilt==9}" @click="spilt=9"/> | 
|---|
|  |  |  | </el-header> | 
|---|
|  |  |  | <el-main style="padding: 0;"> | 
|---|
|  |  |  | <div style="width: 99%;height: 85vh;display: flex;flex-wrap: wrap;background-color: #000;"> | 
|---|
|  |  |  | <div v-for="i in spilt" :key="i" class="play-box" | 
|---|
|  |  |  | :style="liveStyle" :class="{redborder:playerIdx == (i-1)}" | 
|---|
|  |  |  | @click="playerIdx = (i-1)"> | 
|---|
|  |  |  | <div v-if="!videoUrl[i-1]" style="color: #ffffff;font-size: 30px;font-weight: bold;">{{ i }}</div> | 
|---|
|  |  |  | <player ref="player" v-else :videoUrl="videoUrl[i-1]" fluent autoplay @screenshot="shot" | 
|---|
|  |  |  | @destroy="destroy"/> | 
|---|
|  |  |  | </div> | 
|---|
|  |  |  | </div> | 
|---|
|  |  |  | </el-main> | 
|---|
|  |  |  | </el-container> | 
|---|
|  |  |  | </el-container> | 
|---|
|  |  |  | </div> | 
|---|
|  |  |  | </template> | 
|---|
|  |  |  |  | 
|---|
|  |  |  | <script> | 
|---|
|  |  |  | import uiHeader from "./UiHeader.vue"; | 
|---|
|  |  |  | import player from './dialog/jessibuca.vue' | 
|---|
|  |  |  | import ChannelTree from './channelTree.vue' | 
|---|
|  |  |  | import uiHeader from "../layout/UiHeader.vue"; | 
|---|
|  |  |  | import player from './common/jessibuca.vue' | 
|---|
|  |  |  | import DeviceTree from './common/DeviceTree.vue' | 
|---|
|  |  |  |  | 
|---|
|  |  |  | export default { | 
|---|
|  |  |  | name: "live", | 
|---|
|  |  |  | components: { | 
|---|
|  |  |  | uiHeader, player, ChannelTree | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | data() { | 
|---|
|  |  |  | return { | 
|---|
|  |  |  | showVideoDialog: true, | 
|---|
|  |  |  | hasAudio: false, | 
|---|
|  |  |  | videoUrl:[''], | 
|---|
|  |  |  | spilt:1,//分屏 | 
|---|
|  |  |  | playerIdx:0,//激活播放器 | 
|---|
|  |  |  | export default { | 
|---|
|  |  |  | name: "live", | 
|---|
|  |  |  | components: { | 
|---|
|  |  |  | uiHeader, player, DeviceTree | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | data() { | 
|---|
|  |  |  | return { | 
|---|
|  |  |  | videoUrl: [''], | 
|---|
|  |  |  | spilt: 1,//分屏 | 
|---|
|  |  |  | playerIdx: 0,//激活播放器 | 
|---|
|  |  |  |  | 
|---|
|  |  |  | deviceList: [], //设备列表 | 
|---|
|  |  |  | currentDevice: {}, //当前操作设备对象 | 
|---|
|  |  |  | updateLooper: 0, //数据刷新轮训标志 | 
|---|
|  |  |  | count: 15, | 
|---|
|  |  |  | total: 0, | 
|---|
|  |  |  |  | 
|---|
|  |  |  | videoComponentList: [], | 
|---|
|  |  |  | updateLooper: 0, //数据刷新轮训标志 | 
|---|
|  |  |  | currentDeviceChannelsLenth:0, | 
|---|
|  |  |  | winHeight: window.innerHeight - 200, | 
|---|
|  |  |  | currentPage:1, | 
|---|
|  |  |  | count:15, | 
|---|
|  |  |  | total:0, | 
|---|
|  |  |  | getDeviceListLoading: false, | 
|---|
|  |  |  | //channel | 
|---|
|  |  |  | loading: false | 
|---|
|  |  |  | }; | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | mounted() { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //channel | 
|---|
|  |  |  | searchSrt: "", | 
|---|
|  |  |  | channelType: "", | 
|---|
|  |  |  | online: "", | 
|---|
|  |  |  | channelTotal:0, | 
|---|
|  |  |  | deviceChannelList:[], | 
|---|
|  |  |  | loading:false | 
|---|
|  |  |  | }; | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | mounted() { | 
|---|
|  |  |  | this.initData(); | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | created() { | 
|---|
|  |  |  | this.checkPlayByParam() | 
|---|
|  |  |  | }, | 
|---|
|  |  |  |  | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | created(){ | 
|---|
|  |  |  | this.checkPlayByParam() | 
|---|
|  |  |  | }, | 
|---|
|  |  |  |  | 
|---|
|  |  |  | computed:{ | 
|---|
|  |  |  | liveStyle(){ | 
|---|
|  |  |  | if(this.spilt==1){ | 
|---|
|  |  |  | return {width:'100%',height:'100%'} | 
|---|
|  |  |  | }else if(this.spilt==4){ | 
|---|
|  |  |  | return {width:'49%',height:'49%'} | 
|---|
|  |  |  | }else if(this.spilt==9){ | 
|---|
|  |  |  | return {width:'32%',height:'32%'} | 
|---|
|  |  |  | } | 
|---|
|  |  |  | computed: { | 
|---|
|  |  |  | liveStyle() { | 
|---|
|  |  |  | let style = {width: '100%', height: '100%'} | 
|---|
|  |  |  | switch (this.spilt) { | 
|---|
|  |  |  | case 4: | 
|---|
|  |  |  | style = {width: '49%', height: '49%'} | 
|---|
|  |  |  | break | 
|---|
|  |  |  | case 9: | 
|---|
|  |  |  | style = {width: '32%', height: '32%'} | 
|---|
|  |  |  | break | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | watch:{ | 
|---|
|  |  |  | spilt(newValue){ | 
|---|
|  |  |  | console.log("切换画幅;"+newValue) | 
|---|
|  |  |  | let that = this | 
|---|
|  |  |  | for (let i = 1; i <= newValue; i++) { | 
|---|
|  |  |  | if(!that.$refs['player'+i]){ | 
|---|
|  |  |  | continue | 
|---|
|  |  |  | } | 
|---|
|  |  |  | this.$nextTick(()=>{ | 
|---|
|  |  |  | if(that.$refs['player'+i] instanceof Array){ | 
|---|
|  |  |  | that.$refs['player'+i][0].resize() | 
|---|
|  |  |  | }else { | 
|---|
|  |  |  | that.$refs['player'+i].resize() | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }) | 
|---|
|  |  |  |  | 
|---|
|  |  |  | this.$nextTick(() => { | 
|---|
|  |  |  | for (let i = 0; i < this.spilt; i++) { | 
|---|
|  |  |  | const player = this.$refs.player | 
|---|
|  |  |  | player && player[i] && player[i].updatePlayerDomSize() | 
|---|
|  |  |  | } | 
|---|
|  |  |  | window.localStorage.setItem('split',newValue) | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | '$route.fullPath':'checkPlayByParam' | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | destroyed() { | 
|---|
|  |  |  | clearTimeout(this.updateLooper); | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | methods: { | 
|---|
|  |  |  | initData: function () { | 
|---|
|  |  |  | this.getDeviceList(); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | destroy(idx) { | 
|---|
|  |  |  | console.log(idx); | 
|---|
|  |  |  | this.clear(idx.substring(idx.length-1)) | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | getDeviceList: function() { | 
|---|
|  |  |  | let that = this; | 
|---|
|  |  |  | this.$axios({ | 
|---|
|  |  |  | method: 'get', | 
|---|
|  |  |  | url:`/api/device/query/devices`, | 
|---|
|  |  |  | params: { | 
|---|
|  |  |  | page: that.currentPage, | 
|---|
|  |  |  | count: that.count | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }).then(function (res) { | 
|---|
|  |  |  | console.log(res.data.list); | 
|---|
|  |  |  | that.total = res.data.total; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | that.deviceList = res.data.list.map(item=>{return {deviceChannelList:[],...item}}); | 
|---|
|  |  |  | that.getDeviceListLoading = false; | 
|---|
|  |  |  | }).catch(function (error) { | 
|---|
|  |  |  | console.log(error); | 
|---|
|  |  |  | that.getDeviceListLoading = false; | 
|---|
|  |  |  | }); | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | //通知设备上传媒体流 | 
|---|
|  |  |  | sendDevicePush: function (itemData) { | 
|---|
|  |  |  | if(itemData.status===0){ | 
|---|
|  |  |  | this.$message.error('设备离线!'); | 
|---|
|  |  |  | return | 
|---|
|  |  |  | }) | 
|---|
|  |  |  | return style | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | watch: { | 
|---|
|  |  |  | spilt(newValue) { | 
|---|
|  |  |  | console.log("切换画幅;" + newValue) | 
|---|
|  |  |  | let that = this | 
|---|
|  |  |  | for (let i = 1; i <= newValue; i++) { | 
|---|
|  |  |  | if (!that.$refs['player' + i]) { | 
|---|
|  |  |  | continue | 
|---|
|  |  |  | } | 
|---|
|  |  |  | this.save(itemData) | 
|---|
|  |  |  | let deviceId = itemData.deviceId; | 
|---|
|  |  |  | // this.isLoging = true; | 
|---|
|  |  |  | let channelId = itemData.channelId; | 
|---|
|  |  |  | console.log("通知设备推流1:" + deviceId + " : " + channelId ); | 
|---|
|  |  |  | let idxTmp = this.playerIdx | 
|---|
|  |  |  | let that = this; | 
|---|
|  |  |  | this.loading = true | 
|---|
|  |  |  | this.$axios({ | 
|---|
|  |  |  | method: 'get', | 
|---|
|  |  |  | url: '/api/play/start/' + deviceId + '/' + channelId | 
|---|
|  |  |  | }).then(function (res) { | 
|---|
|  |  |  | // that.isLoging = false; | 
|---|
|  |  |  | console.log('=====----=====') | 
|---|
|  |  |  | console.log(res) | 
|---|
|  |  |  | if (res.data.code == 0 && res.data.data) { | 
|---|
|  |  |  | itemData.playUrl = res.data.data.httpsFlv | 
|---|
|  |  |  | that.setPlayUrl(res.data.data.ws_flv,idxTmp) | 
|---|
|  |  |  | }else { | 
|---|
|  |  |  | that.$message.error(res.data.msg); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }).catch(function (e) { | 
|---|
|  |  |  | }).finally(()=>{ | 
|---|
|  |  |  | that.loading = false | 
|---|
|  |  |  | }); | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | setPlayUrl(url,idx){ | 
|---|
|  |  |  | this.$set(this.videoUrl,idx,url) | 
|---|
|  |  |  | let _this = this | 
|---|
|  |  |  | setTimeout(()=>{ | 
|---|
|  |  |  | window.localStorage.setItem('videoUrl',JSON.stringify(_this.videoUrl)) | 
|---|
|  |  |  | },100) | 
|---|
|  |  |  |  | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | checkPlayByParam(){ | 
|---|
|  |  |  | let {deviceId,channelId} = this.$route.query | 
|---|
|  |  |  | if(deviceId && channelId){ | 
|---|
|  |  |  | this.sendDevicePush({deviceId,channelId}) | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | convertImageToCanvas(image) { | 
|---|
|  |  |  | var canvas = document.createElement("canvas"); | 
|---|
|  |  |  | canvas.width = image.width; | 
|---|
|  |  |  | canvas.height = image.height; | 
|---|
|  |  |  | canvas.getContext("2d").drawImage(image, 0, 0); | 
|---|
|  |  |  | return canvas; | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | shot(e){ | 
|---|
|  |  |  | // console.log(e) | 
|---|
|  |  |  | // send({code:'image',data:e}) | 
|---|
|  |  |  | var base64ToBlob = function(code) { | 
|---|
|  |  |  | let parts = code.split(';base64,'); | 
|---|
|  |  |  | let contentType = parts[0].split(':')[1]; | 
|---|
|  |  |  | let raw = window.atob(parts[1]); | 
|---|
|  |  |  | let rawLength = raw.length; | 
|---|
|  |  |  | let uInt8Array = new Uint8Array(rawLength); | 
|---|
|  |  |  | for(let i = 0; i < rawLength; ++i) { | 
|---|
|  |  |  | uInt8Array[i] = raw.charCodeAt(i); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return new Blob([uInt8Array], { | 
|---|
|  |  |  | type: contentType | 
|---|
|  |  |  | }); | 
|---|
|  |  |  | }; | 
|---|
|  |  |  | let aLink = document.createElement('a'); | 
|---|
|  |  |  | let blob = base64ToBlob(e); //new Blob([content]); | 
|---|
|  |  |  | let evt = document.createEvent("HTMLEvents"); | 
|---|
|  |  |  | evt.initEvent("click", true, true); //initEvent 不加后两个参数在FF下会报错  事件类型,是否冒泡,是否阻止浏览器的默认行为 | 
|---|
|  |  |  | aLink.download = '截图'; | 
|---|
|  |  |  | aLink.href = URL.createObjectURL(blob); | 
|---|
|  |  |  | aLink.click(); | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | save(item){ | 
|---|
|  |  |  | let dataStr = window.localStorage.getItem('playData') || '[]' | 
|---|
|  |  |  | let data = JSON.parse(dataStr); | 
|---|
|  |  |  | data[this.playerIdx] = item | 
|---|
|  |  |  | window.localStorage.setItem('playData',JSON.stringify(data)) | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | clear(idx) { | 
|---|
|  |  |  | let dataStr = window.localStorage.getItem('playData') || '[]' | 
|---|
|  |  |  | let data = JSON.parse(dataStr); | 
|---|
|  |  |  | data[idx-1] = null; | 
|---|
|  |  |  | console.log(data); | 
|---|
|  |  |  | window.localStorage.setItem('playData',JSON.stringify(data)) | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | loadAndPlay(){ | 
|---|
|  |  |  | let dataStr = window.localStorage.getItem('playData') || '[]' | 
|---|
|  |  |  | let data = JSON.parse(dataStr); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | data.forEach((item,i)=>{ | 
|---|
|  |  |  | if(item){ | 
|---|
|  |  |  | this.playerIdx = i | 
|---|
|  |  |  | this.sendDevicePush(item) | 
|---|
|  |  |  | this.$nextTick(() => { | 
|---|
|  |  |  | if (that.$refs['player' + i] instanceof Array) { | 
|---|
|  |  |  | that.$refs['player' + i][0].resize() | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | that.$refs['player' + i].resize() | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }) | 
|---|
|  |  |  |  | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }; | 
|---|
|  |  |  | window.localStorage.setItem('split', newValue) | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | '$route.fullPath': 'checkPlayByParam' | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | destroyed() { | 
|---|
|  |  |  | clearTimeout(this.updateLooper); | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | methods: { | 
|---|
|  |  |  | destroy(idx) { | 
|---|
|  |  |  | console.log(idx); | 
|---|
|  |  |  | this.clear(idx.substring(idx.length - 1)) | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | clickEvent: function (device, data, isCatalog) { | 
|---|
|  |  |  | if (data.channelId && !isCatalog) { | 
|---|
|  |  |  | if (device.online === 0) { | 
|---|
|  |  |  | this.$message.error('设备离线!不允许点播'); | 
|---|
|  |  |  | }else { | 
|---|
|  |  |  | this.sendDevicePush(data) | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | contextMenuEvent: function (device, event, data, isCatalog) { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | //通知设备上传媒体流 | 
|---|
|  |  |  | sendDevicePush: function (itemData) { | 
|---|
|  |  |  | // if (itemData.status === 0) { | 
|---|
|  |  |  | //   this.$message.error('设备离线!'); | 
|---|
|  |  |  | //   return | 
|---|
|  |  |  | // } | 
|---|
|  |  |  | this.save(itemData) | 
|---|
|  |  |  | let deviceId = itemData.deviceId; | 
|---|
|  |  |  | // this.isLoging = true; | 
|---|
|  |  |  | let channelId = itemData.channelId; | 
|---|
|  |  |  | console.log("通知设备推流1:" + deviceId + " : " + channelId); | 
|---|
|  |  |  | let idxTmp = this.playerIdx | 
|---|
|  |  |  | let that = this; | 
|---|
|  |  |  | this.loading = true | 
|---|
|  |  |  | this.$axios({ | 
|---|
|  |  |  | method: 'get', | 
|---|
|  |  |  | url: '/api/play/start/' + deviceId + '/' + channelId | 
|---|
|  |  |  | }).then(function (res) { | 
|---|
|  |  |  | if (res.data.code === 0 && res.data.data) { | 
|---|
|  |  |  | itemData.playUrl = res.data.data.httpsFlv | 
|---|
|  |  |  | that.setPlayUrl(res.data.data.ws_flv, idxTmp) | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | that.$message.error(res.data.msg); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }).catch(function (e) { | 
|---|
|  |  |  | }).finally(() => { | 
|---|
|  |  |  | that.loading = false | 
|---|
|  |  |  | }); | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | setPlayUrl(url, idx) { | 
|---|
|  |  |  | this.$set(this.videoUrl, idx, url) | 
|---|
|  |  |  | let _this = this | 
|---|
|  |  |  | setTimeout(() => { | 
|---|
|  |  |  | window.localStorage.setItem('videoUrl', JSON.stringify(_this.videoUrl)) | 
|---|
|  |  |  | }, 100) | 
|---|
|  |  |  |  | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | checkPlayByParam() { | 
|---|
|  |  |  | let {deviceId, channelId} = this.$route.query | 
|---|
|  |  |  | if (deviceId && channelId) { | 
|---|
|  |  |  | this.sendDevicePush({deviceId, channelId}) | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | shot(e) { | 
|---|
|  |  |  | // console.log(e) | 
|---|
|  |  |  | // send({code:'image',data:e}) | 
|---|
|  |  |  | var base64ToBlob = function (code) { | 
|---|
|  |  |  | let parts = code.split(';base64,'); | 
|---|
|  |  |  | let contentType = parts[0].split(':')[1]; | 
|---|
|  |  |  | let raw = window.atob(parts[1]); | 
|---|
|  |  |  | let rawLength = raw.length; | 
|---|
|  |  |  | let uInt8Array = new Uint8Array(rawLength); | 
|---|
|  |  |  | for (let i = 0; i < rawLength; ++i) { | 
|---|
|  |  |  | uInt8Array[i] = raw.charCodeAt(i); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return new Blob([uInt8Array], { | 
|---|
|  |  |  | type: contentType | 
|---|
|  |  |  | }); | 
|---|
|  |  |  | }; | 
|---|
|  |  |  | let aLink = document.createElement('a'); | 
|---|
|  |  |  | let blob = base64ToBlob(e); //new Blob([content]); | 
|---|
|  |  |  | let evt = document.createEvent("HTMLEvents"); | 
|---|
|  |  |  | evt.initEvent("click", true, true); //initEvent 不加后两个参数在FF下会报错  事件类型,是否冒泡,是否阻止浏览器的默认行为 | 
|---|
|  |  |  | aLink.download = '截图'; | 
|---|
|  |  |  | aLink.href = URL.createObjectURL(blob); | 
|---|
|  |  |  | aLink.click(); | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | save(item) { | 
|---|
|  |  |  | let dataStr = window.localStorage.getItem('playData') || '[]' | 
|---|
|  |  |  | let data = JSON.parse(dataStr); | 
|---|
|  |  |  | data[this.playerIdx] = item | 
|---|
|  |  |  | window.localStorage.setItem('playData', JSON.stringify(data)) | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | clear(idx) { | 
|---|
|  |  |  | let dataStr = window.localStorage.getItem('playData') || '[]' | 
|---|
|  |  |  | let data = JSON.parse(dataStr); | 
|---|
|  |  |  | data[idx - 1] = null; | 
|---|
|  |  |  | console.log(data); | 
|---|
|  |  |  | window.localStorage.setItem('playData', JSON.stringify(data)) | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }; | 
|---|
|  |  |  | </script> | 
|---|
|  |  |  | <style> | 
|---|
|  |  |  | .btn{ | 
|---|
|  |  |  | margin: 0 10px; | 
|---|
|  |  |  | .btn { | 
|---|
|  |  |  | margin: 0 10px; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | } | 
|---|
|  |  |  | .btn:hover{ | 
|---|
|  |  |  | color: #409EFF; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | .btn.active{ | 
|---|
|  |  |  | color: #409EFF; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | } | 
|---|
|  |  |  | .redborder{ | 
|---|
|  |  |  | border: 2px solid red !important; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | .play-box{ | 
|---|
|  |  |  | background-color: #000000; | 
|---|
|  |  |  | border: 2px solid #505050; | 
|---|
|  |  |  | display: flex; | 
|---|
|  |  |  | align-items: center; | 
|---|
|  |  |  | justify-content: center; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | .btn:hover { | 
|---|
|  |  |  | color: #409EFF; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | .btn.active { | 
|---|
|  |  |  | color: #409EFF; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | .redborder { | 
|---|
|  |  |  | border: 2px solid red !important; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | .play-box { | 
|---|
|  |  |  | background-color: #000000; | 
|---|
|  |  |  | border: 2px solid #505050; | 
|---|
|  |  |  | display: flex; | 
|---|
|  |  |  | align-items: center; | 
|---|
|  |  |  | justify-content: center; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | </style> | 
|---|
|  |  |  | <style> | 
|---|
|  |  |  | .videoList { | 
|---|
|  |  |  | display: flex; | 
|---|
|  |  |  | flex-wrap: wrap; | 
|---|
|  |  |  | align-content: flex-start; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | .videoList { | 
|---|
|  |  |  | display: flex; | 
|---|
|  |  |  | flex-wrap: wrap; | 
|---|
|  |  |  | align-content: flex-start; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | .video-item { | 
|---|
|  |  |  | position: relative; | 
|---|
|  |  |  | width: 15rem; | 
|---|
|  |  |  | height: 10rem; | 
|---|
|  |  |  | margin-right: 1rem; | 
|---|
|  |  |  | background-color: #000000; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | .video-item { | 
|---|
|  |  |  | position: relative; | 
|---|
|  |  |  | width: 15rem; | 
|---|
|  |  |  | height: 10rem; | 
|---|
|  |  |  | margin-right: 1rem; | 
|---|
|  |  |  | background-color: #000000; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | .video-item-img { | 
|---|
|  |  |  | position: absolute; | 
|---|
|  |  |  | top: 0; | 
|---|
|  |  |  | bottom: 0; | 
|---|
|  |  |  | left: 0; | 
|---|
|  |  |  | right: 0; | 
|---|
|  |  |  | margin: auto; | 
|---|
|  |  |  | width: 100%; | 
|---|
|  |  |  | height: 100%; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | .video-item-img { | 
|---|
|  |  |  | position: absolute; | 
|---|
|  |  |  | top: 0; | 
|---|
|  |  |  | bottom: 0; | 
|---|
|  |  |  | left: 0; | 
|---|
|  |  |  | right: 0; | 
|---|
|  |  |  | margin: auto; | 
|---|
|  |  |  | width: 100%; | 
|---|
|  |  |  | height: 100%; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | .video-item-img:after { | 
|---|
|  |  |  | content: ""; | 
|---|
|  |  |  | display: inline-block; | 
|---|
|  |  |  | position: absolute; | 
|---|
|  |  |  | z-index: 2; | 
|---|
|  |  |  | top: 0; | 
|---|
|  |  |  | bottom: 0; | 
|---|
|  |  |  | left: 0; | 
|---|
|  |  |  | right: 0; | 
|---|
|  |  |  | margin: auto; | 
|---|
|  |  |  | width: 3rem; | 
|---|
|  |  |  | height: 3rem; | 
|---|
|  |  |  | background-image: url("../assets/loading.png"); | 
|---|
|  |  |  | background-size: cover; | 
|---|
|  |  |  | background-color: #000000; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | .video-item-img:after { | 
|---|
|  |  |  | content: ""; | 
|---|
|  |  |  | display: inline-block; | 
|---|
|  |  |  | position: absolute; | 
|---|
|  |  |  | z-index: 2; | 
|---|
|  |  |  | top: 0; | 
|---|
|  |  |  | bottom: 0; | 
|---|
|  |  |  | left: 0; | 
|---|
|  |  |  | right: 0; | 
|---|
|  |  |  | margin: auto; | 
|---|
|  |  |  | width: 3rem; | 
|---|
|  |  |  | height: 3rem; | 
|---|
|  |  |  | background-image: url("../assets/loading.png"); | 
|---|
|  |  |  | background-size: cover; | 
|---|
|  |  |  | background-color: #000000; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | .video-item-title { | 
|---|
|  |  |  | position: absolute; | 
|---|
|  |  |  | bottom: 0; | 
|---|
|  |  |  | color: #000000; | 
|---|
|  |  |  | background-color: #ffffff; | 
|---|
|  |  |  | line-height: 1.5rem; | 
|---|
|  |  |  | padding: 0.3rem; | 
|---|
|  |  |  | width: 14.4rem; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | .video-item-title { | 
|---|
|  |  |  | position: absolute; | 
|---|
|  |  |  | bottom: 0; | 
|---|
|  |  |  | color: #000000; | 
|---|
|  |  |  | background-color: #ffffff; | 
|---|
|  |  |  | line-height: 1.5rem; | 
|---|
|  |  |  | padding: 0.3rem; | 
|---|
|  |  |  | width: 14.4rem; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | .baidumap { | 
|---|
|  |  |  | width: 100%; | 
|---|
|  |  |  | height: 100%; | 
|---|
|  |  |  | border: none; | 
|---|
|  |  |  | position: absolute; | 
|---|
|  |  |  | left: 0; | 
|---|
|  |  |  | top: 0; | 
|---|
|  |  |  | right: 0; | 
|---|
|  |  |  | bottom: 0; | 
|---|
|  |  |  | margin: auto; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | .baidumap { | 
|---|
|  |  |  | width: 100%; | 
|---|
|  |  |  | height: 100%; | 
|---|
|  |  |  | border: none; | 
|---|
|  |  |  | position: absolute; | 
|---|
|  |  |  | left: 0; | 
|---|
|  |  |  | top: 0; | 
|---|
|  |  |  | right: 0; | 
|---|
|  |  |  | bottom: 0; | 
|---|
|  |  |  | margin: auto; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /* 去除百度地图版权那行字 和 百度logo */ | 
|---|
|  |  |  | .baidumap > .BMap_cpyCtrl { | 
|---|
|  |  |  | display: none !important; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | .baidumap > .anchorBL { | 
|---|
|  |  |  | display: none !important; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | /* 去除百度地图版权那行字 和 百度logo */ | 
|---|
|  |  |  | .baidumap > .BMap_cpyCtrl { | 
|---|
|  |  |  | display: none !important; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | .baidumap > .anchorBL { | 
|---|
|  |  |  | display: none !important; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | </style> | 
|---|