Commit 7f965a6922a079124671ad233e3c783da92c8e69
Committed by
GitHub
Merge pull request #448 from hotcoffie/wvp-28181-2.0
1.修正了播放地址无法正常播放视频的问题,包含两个错误:
Showing
6 changed files
with
277 additions
and
324 deletions
web_src/src/App.vue
| @@ -81,4 +81,24 @@ body, | @@ -81,4 +81,24 @@ body, | ||
| 81 | text-align: center; | 81 | text-align: center; |
| 82 | padding-top: 0px !important; | 82 | padding-top: 0px !important; |
| 83 | } | 83 | } |
| 84 | + | ||
| 85 | +/*定义滚动条高宽及背景 高宽分别对应横竖滚动条的尺寸*/ | ||
| 86 | +::-webkit-scrollbar { | ||
| 87 | + width: 8px; | ||
| 88 | + height: 8px; | ||
| 89 | +} | ||
| 90 | + | ||
| 91 | +/*定义滚动条轨道 内阴影+圆角*/ | ||
| 92 | +::-webkit-scrollbar-track { | ||
| 93 | + border-radius: 4px; | ||
| 94 | + background-color: #F5F5F5; | ||
| 95 | +} | ||
| 96 | + | ||
| 97 | +/*定义滑块 内阴影+圆角*/ | ||
| 98 | +::-webkit-scrollbar-thumb { | ||
| 99 | + border-radius: 4px; | ||
| 100 | + background-color: #c8c8c8; | ||
| 101 | + box-shadow: inset 0 0 6px rgba(0, 0, 0, .1); | ||
| 102 | + -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, .1); | ||
| 103 | +} | ||
| 84 | </style> | 104 | </style> |
web_src/src/components/common/jessibuca.vue
| 1 | <template> | 1 | <template> |
| 2 | - <div :id="containerId" :ref="containerId" @dblclick="fullscreenSwich"> | 2 | + <div id="container" ref="containerId" @dblclick="fullscreenSwich" style="width: 100%"> |
| 3 | <div class="buttons-box" id="buttonsBox"> | 3 | <div class="buttons-box" id="buttonsBox"> |
| 4 | <div class="buttons-box-left"> | 4 | <div class="buttons-box-left"> |
| 5 | <i v-if="!playing" class="iconfont icon-play jessibuca-btn" @click="playBtnClick"></i> | 5 | <i v-if="!playing" class="iconfont icon-play jessibuca-btn" @click="playBtnClick"></i> |
| @@ -44,7 +44,7 @@ export default { | @@ -44,7 +44,7 @@ export default { | ||
| 44 | forceNoOffscreen: false, | 44 | forceNoOffscreen: false, |
| 45 | }; | 45 | }; |
| 46 | }, | 46 | }, |
| 47 | - props: ['containerId', 'videoUrl', 'error', 'hasAudio', 'height'], | 47 | + props: ['videoUrl', 'error', 'hasAudio', 'height'], |
| 48 | mounted() { | 48 | mounted() { |
| 49 | window.onerror = (msg) => { | 49 | window.onerror = (msg) => { |
| 50 | // console.error(msg) | 50 | // console.error(msg) |
| @@ -71,19 +71,19 @@ export default { | @@ -71,19 +71,19 @@ export default { | ||
| 71 | }, | 71 | }, |
| 72 | methods: { | 72 | methods: { |
| 73 | updatePlayerDomSize() { | 73 | updatePlayerDomSize() { |
| 74 | - let dom = document.getElementById(this.containerId); | 74 | + let dom = document.getElementById('container'); |
| 75 | const width = dom.parentNode.clientWidth | 75 | const width = dom.parentNode.clientWidth |
| 76 | dom.style.width = width + 'px'; | 76 | dom.style.width = width + 'px'; |
| 77 | dom.style.height = (9 / 16) * width + "px"; | 77 | dom.style.height = (9 / 16) * width + "px"; |
| 78 | }, | 78 | }, |
| 79 | create() { | 79 | create() { |
| 80 | let options = {}; | 80 | let options = {}; |
| 81 | - console.log(this.$refs[this.containerId]) | 81 | + console.log(this.$refs.containerId) |
| 82 | console.log("hasAudio " + this.hasAudio) | 82 | console.log("hasAudio " + this.hasAudio) |
| 83 | 83 | ||
| 84 | this.jessibuca = new window.Jessibuca(Object.assign( | 84 | this.jessibuca = new window.Jessibuca(Object.assign( |
| 85 | { | 85 | { |
| 86 | - container: this.$refs[this.containerId], | 86 | + container: this.$refs.containerId, |
| 87 | videoBuffer: 0.2, // 最大缓冲时长,单位秒 | 87 | videoBuffer: 0.2, // 最大缓冲时长,单位秒 |
| 88 | isResize: true, | 88 | isResize: true, |
| 89 | decoder: "static/js/jessibuca/decoder.js", | 89 | decoder: "static/js/jessibuca/decoder.js", |
| @@ -204,19 +204,6 @@ export default { | @@ -204,19 +204,6 @@ export default { | ||
| 204 | 204 | ||
| 205 | }); | 205 | }); |
| 206 | }, | 206 | }, |
| 207 | - resize() { | ||
| 208 | - if (this.jessibuca) { | ||
| 209 | - this.jessibuca.resize() | ||
| 210 | - this.$nextTick(() => { | ||
| 211 | - let dom = document.getElementById(this.containerId); | ||
| 212 | - if (dom.parentNode.clientHeight == 0) { | ||
| 213 | - dom.style.height = (9 / 16) * dom.clientWidth + "px" | ||
| 214 | - } | ||
| 215 | - dom.style.height = dom.parentNode.clientHeight + "px"; | ||
| 216 | - dom.style.width = dom.parentNode.clientWidth + "px"; | ||
| 217 | - }) | ||
| 218 | - } | ||
| 219 | - }, | ||
| 220 | playBtnClick: function (event) { | 207 | playBtnClick: function (event) { |
| 221 | this.play(this.videoUrl) | 208 | this.play(this.videoUrl) |
| 222 | }, | 209 | }, |
web_src/src/components/dialog/devicePlayer.vue
| @@ -4,7 +4,7 @@ | @@ -4,7 +4,7 @@ | ||
| 4 | <el-dialog title="视频播放" top="0" :close-on-click-modal="false" :visible.sync="showVideoDialog" @close="close()"> | 4 | <el-dialog title="视频播放" top="0" :close-on-click-modal="false" :visible.sync="showVideoDialog" @close="close()"> |
| 5 | <!-- <LivePlayer v-if="showVideoDialog" ref="videoPlayer" :videoUrl="videoUrl" :error="videoError" :message="videoError" :hasaudio="hasaudio" fluent autoplay live></LivePlayer> --> | 5 | <!-- <LivePlayer v-if="showVideoDialog" ref="videoPlayer" :videoUrl="videoUrl" :error="videoError" :message="videoError" :hasaudio="hasaudio" fluent autoplay live></LivePlayer> --> |
| 6 | <div style="width: 100%; height: 100%"> | 6 | <div style="width: 100%; height: 100%"> |
| 7 | - <player containerId="container" ref="videoPlayer" :visible.sync="showVideoDialog" :videoUrl="videoUrl" :error="videoError" :message="videoError" height="100px" :hasAudio="hasAudio" fluent autoplay live ></player> | 7 | + <player ref="videoPlayer" :visible.sync="showVideoDialog" :videoUrl="videoUrl" :error="videoError" :message="videoError" height="100px" :hasAudio="hasAudio" fluent autoplay live ></player> |
| 8 | </div> | 8 | </div> |
| 9 | <div id="shared" style="text-align: right; margin-top: 1rem;"> | 9 | <div id="shared" style="text-align: right; margin-top: 1rem;"> |
| 10 | <el-tabs v-model="tabActiveName" @tab-click="tabHandleClick"> | 10 | <el-tabs v-model="tabActiveName" @tab-click="tabHandleClick"> |
web_src/src/components/live.vue
| 1 | <template> | 1 | <template> |
| 2 | <div id="devicePosition" style="width:100vw; height: 91vh"> | 2 | <div id="devicePosition" style="width:100vw; height: 91vh"> |
| 3 | - <el-container v-loading="loading" style="height: 91vh;" element-loading-text="拼命加载中" > | 3 | + <el-container v-loading="loading" style="height: 91vh;" element-loading-text="拼命加载中"> |
| 4 | <el-aside width="300px" style="background-color: #ffffff"> | 4 | <el-aside width="300px" style="background-color: #ffffff"> |
| 5 | - <DeviceTree :clickEvent="clickEvent" :contextMenuEvent="contextMenuEvent" ></DeviceTree> | 5 | + <DeviceTree :clickEvent="clickEvent" :contextMenuEvent="contextMenuEvent"></DeviceTree> |
| 6 | </el-aside> | 6 | </el-aside> |
| 7 | <el-container> | 7 | <el-container> |
| 8 | <el-header height="5vh" style="text-align: left;font-size: 17px;line-height:5vh"> | 8 | <el-header height="5vh" style="text-align: left;font-size: 17px;line-height:5vh"> |
| @@ -17,9 +17,8 @@ | @@ -17,9 +17,8 @@ | ||
| 17 | :style="liveStyle" :class="{redborder:playerIdx == (i-1)}" | 17 | :style="liveStyle" :class="{redborder:playerIdx == (i-1)}" |
| 18 | @click="playerIdx = (i-1)" | 18 | @click="playerIdx = (i-1)" |
| 19 | > | 19 | > |
| 20 | - <div v-if="!videoUrl[i-1]" style="color: #ffffff;font-size: 30px;font-weight: bold;">{{i}}</div> | ||
| 21 | - <player v-else :ref="'player'+i" :videoUrl="videoUrl[i-1]" fluent autoplay :height="true" | ||
| 22 | - :containerId="'player'+i" @screenshot="shot" @destroy="destroy"></player> | 20 | + <div v-if="!videoUrl[i-1]" style="color: #ffffff;font-size: 30px;font-weight: bold;">{{ i }}</div> |
| 21 | + <player v-else :videoUrl="videoUrl[i-1]" fluent autoplay @screenshot="shot" @destroy="destroy"/> | ||
| 23 | </div> | 22 | </div> |
| 24 | </div> | 23 | </div> |
| 25 | </el-main> | 24 | </el-main> |
| @@ -29,297 +28,268 @@ | @@ -29,297 +28,268 @@ | ||
| 29 | </template> | 28 | </template> |
| 30 | 29 | ||
| 31 | <script> | 30 | <script> |
| 32 | - import uiHeader from "../layout/UiHeader.vue"; | ||
| 33 | - import player from './common/jessibuca.vue' | ||
| 34 | - import DeviceTree from './common/DeviceTree.vue' | 31 | +import uiHeader from "../layout/UiHeader.vue"; |
| 32 | +import player from './common/jessibuca.vue' | ||
| 33 | +import DeviceTree from './common/DeviceTree.vue' | ||
| 35 | 34 | ||
| 36 | - export default { | ||
| 37 | - name: "live", | ||
| 38 | - components: { | ||
| 39 | - uiHeader, player, DeviceTree | ||
| 40 | - }, | ||
| 41 | - data() { | ||
| 42 | - return { | ||
| 43 | - showVideoDialog: true, | ||
| 44 | - hasAudio: false, | ||
| 45 | - videoUrl:[''], | ||
| 46 | - spilt:1,//分屏 | ||
| 47 | - playerIdx:0,//激活播放器 | 35 | +export default { |
| 36 | + name: "live", | ||
| 37 | + components: { | ||
| 38 | + uiHeader, player, DeviceTree | ||
| 39 | + }, | ||
| 40 | + data() { | ||
| 41 | + return { | ||
| 42 | + videoUrl: [''], | ||
| 43 | + spilt: 1,//分屏 | ||
| 44 | + playerIdx: 0,//激活播放器 | ||
| 48 | 45 | ||
| 49 | - deviceList: [], //设备列表 | ||
| 50 | - currentDevice: {}, //当前操作设备对象 | 46 | + updateLooper: 0, //数据刷新轮训标志 |
| 47 | + count: 15, | ||
| 48 | + total: 0, | ||
| 51 | 49 | ||
| 52 | - videoComponentList: [], | ||
| 53 | - updateLooper: 0, //数据刷新轮训标志 | ||
| 54 | - currentDeviceChannelsLenth:0, | ||
| 55 | - winHeight: window.innerHeight - 200, | ||
| 56 | - currentPage:1, | ||
| 57 | - count:15, | ||
| 58 | - total:0, | ||
| 59 | - getDeviceListLoading: false, | 50 | + //channel |
| 51 | + loading: false | ||
| 52 | + }; | ||
| 53 | + }, | ||
| 54 | + mounted() { | ||
| 60 | 55 | ||
| 61 | - //channel | ||
| 62 | - searchSrt: "", | ||
| 63 | - channelType: "", | ||
| 64 | - online: "", | ||
| 65 | - channelTotal:0, | ||
| 66 | - deviceChannelList:[], | ||
| 67 | - loading:false | ||
| 68 | - }; | ||
| 69 | - }, | ||
| 70 | - mounted() { | ||
| 71 | - this.initData(); | 56 | + }, |
| 57 | + created() { | ||
| 58 | + this.checkPlayByParam() | ||
| 59 | + }, | ||
| 72 | 60 | ||
| 61 | + computed: { | ||
| 62 | + liveStyle() { | ||
| 63 | + if (this.spilt == 1) { | ||
| 64 | + return {width: '100%', height: '100%'} | ||
| 65 | + } else if (this.spilt == 4) { | ||
| 66 | + return {width: '49%', height: '49%'} | ||
| 67 | + } else if (this.spilt == 9) { | ||
| 68 | + return {width: '32%', height: '32%'} | ||
| 69 | + } | ||
| 70 | + } | ||
| 71 | + }, | ||
| 72 | + watch: { | ||
| 73 | + spilt(newValue) { | ||
| 74 | + console.log("切换画幅;" + newValue) | ||
| 75 | + let that = this | ||
| 76 | + for (let i = 1; i <= newValue; i++) { | ||
| 77 | + if (!that.$refs['player' + i]) { | ||
| 78 | + continue | ||
| 79 | + } | ||
| 80 | + this.$nextTick(() => { | ||
| 81 | + if (that.$refs['player' + i] instanceof Array) { | ||
| 82 | + that.$refs['player' + i][0].resize() | ||
| 83 | + } else { | ||
| 84 | + that.$refs['player' + i].resize() | ||
| 85 | + } | ||
| 86 | + }) | ||
| 87 | + | ||
| 88 | + } | ||
| 89 | + window.localStorage.setItem('split', newValue) | ||
| 73 | }, | 90 | }, |
| 74 | - created(){ | ||
| 75 | - this.checkPlayByParam() | 91 | + '$route.fullPath': 'checkPlayByParam' |
| 92 | + }, | ||
| 93 | + destroyed() { | ||
| 94 | + clearTimeout(this.updateLooper); | ||
| 95 | + }, | ||
| 96 | + methods: { | ||
| 97 | + destroy(idx) { | ||
| 98 | + console.log(idx); | ||
| 99 | + this.clear(idx.substring(idx.length - 1)) | ||
| 76 | }, | 100 | }, |
| 77 | - | ||
| 78 | - computed:{ | ||
| 79 | - liveStyle(){ | ||
| 80 | - if(this.spilt==1){ | ||
| 81 | - return {width:'100%',height:'100%'} | ||
| 82 | - }else if(this.spilt==4){ | ||
| 83 | - return {width:'49%',height:'49%'} | ||
| 84 | - }else if(this.spilt==9){ | ||
| 85 | - return {width:'32%',height:'32%'} | ||
| 86 | - } | 101 | + clickEvent: function (data) { |
| 102 | + if (data.channelId && data.subCount == 0) { | ||
| 103 | + this.sendDevicePush(data) | ||
| 87 | } | 104 | } |
| 88 | }, | 105 | }, |
| 89 | - watch:{ | ||
| 90 | - spilt(newValue){ | ||
| 91 | - console.log("切换画幅;"+newValue) | ||
| 92 | - let that = this | ||
| 93 | - for (let i = 1; i <= newValue; i++) { | ||
| 94 | - if(!that.$refs['player'+i]){ | ||
| 95 | - continue | ||
| 96 | - } | ||
| 97 | - this.$nextTick(()=>{ | ||
| 98 | - if(that.$refs['player'+i] instanceof Array){ | ||
| 99 | - that.$refs['player'+i][0].resize() | ||
| 100 | - }else { | ||
| 101 | - that.$refs['player'+i].resize() | ||
| 102 | - } | ||
| 103 | - }) | 106 | + contextMenuEvent: function (data) { |
| 104 | 107 | ||
| 105 | - } | ||
| 106 | - window.localStorage.setItem('split',newValue) | ||
| 107 | - }, | ||
| 108 | - '$route.fullPath':'checkPlayByParam' | ||
| 109 | - }, | ||
| 110 | - destroyed() { | ||
| 111 | - clearTimeout(this.updateLooper); | ||
| 112 | }, | 108 | }, |
| 113 | - methods: { | ||
| 114 | - destroy(idx) { | ||
| 115 | - console.log(idx); | ||
| 116 | - this.clear(idx.substring(idx.length-1)) | ||
| 117 | - }, | ||
| 118 | - clickEvent: function (data) { | ||
| 119 | - if (data.channelId && data.subCount == 0) { | ||
| 120 | - this.sendDevicePush(data) | 109 | + //通知设备上传媒体流 |
| 110 | + sendDevicePush: function (itemData) { | ||
| 111 | + if (itemData.status === 0) { | ||
| 112 | + this.$message.error('设备离线!'); | ||
| 113 | + return | ||
| 114 | + } | ||
| 115 | + this.save(itemData) | ||
| 116 | + let deviceId = itemData.deviceId; | ||
| 117 | + // this.isLoging = true; | ||
| 118 | + let channelId = itemData.channelId; | ||
| 119 | + console.log("通知设备推流1:" + deviceId + " : " + channelId); | ||
| 120 | + let idxTmp = this.playerIdx | ||
| 121 | + let that = this; | ||
| 122 | + this.loading = true | ||
| 123 | + this.$axios({ | ||
| 124 | + method: 'get', | ||
| 125 | + url: '/api/play/start/' + deviceId + '/' + channelId | ||
| 126 | + }).then(function (res) { | ||
| 127 | + // that.isLoging = false; | ||
| 128 | + console.log('=====----=====') | ||
| 129 | + console.log(res) | ||
| 130 | + if (res.data.code == 0 && res.data.data) { | ||
| 131 | + itemData.playUrl = res.data.data.httpsFlv | ||
| 132 | + that.setPlayUrl(res.data.data.ws_flv, idxTmp) | ||
| 133 | + } else { | ||
| 134 | + that.$message.error(res.data.msg); | ||
| 121 | } | 135 | } |
| 122 | - }, | ||
| 123 | - contextMenuEvent: function (data) { | 136 | + }).catch(function (e) { |
| 137 | + }).finally(() => { | ||
| 138 | + that.loading = false | ||
| 139 | + }); | ||
| 140 | + }, | ||
| 141 | + setPlayUrl(url, idx) { | ||
| 142 | + this.$set(this.videoUrl, idx, url) | ||
| 143 | + let _this = this | ||
| 144 | + setTimeout(() => { | ||
| 145 | + window.localStorage.setItem('videoUrl', JSON.stringify(_this.videoUrl)) | ||
| 146 | + }, 100) | ||
| 124 | 147 | ||
| 125 | - }, | ||
| 126 | - //通知设备上传媒体流 | ||
| 127 | - sendDevicePush: function (itemData) { | ||
| 128 | - if(itemData.status===0){ | ||
| 129 | - this.$message.error('设备离线!'); | ||
| 130 | - return | 148 | + }, |
| 149 | + checkPlayByParam() { | ||
| 150 | + let {deviceId, channelId} = this.$route.query | ||
| 151 | + if (deviceId && channelId) { | ||
| 152 | + this.sendDevicePush({deviceId, channelId}) | ||
| 153 | + } | ||
| 154 | + }, | ||
| 155 | + shot(e) { | ||
| 156 | + // console.log(e) | ||
| 157 | + // send({code:'image',data:e}) | ||
| 158 | + var base64ToBlob = function (code) { | ||
| 159 | + let parts = code.split(';base64,'); | ||
| 160 | + let contentType = parts[0].split(':')[1]; | ||
| 161 | + let raw = window.atob(parts[1]); | ||
| 162 | + let rawLength = raw.length; | ||
| 163 | + let uInt8Array = new Uint8Array(rawLength); | ||
| 164 | + for (let i = 0; i < rawLength; ++i) { | ||
| 165 | + uInt8Array[i] = raw.charCodeAt(i); | ||
| 131 | } | 166 | } |
| 132 | - this.save(itemData) | ||
| 133 | - let deviceId = itemData.deviceId; | ||
| 134 | - // this.isLoging = true; | ||
| 135 | - let channelId = itemData.channelId; | ||
| 136 | - console.log("通知设备推流1:" + deviceId + " : " + channelId ); | ||
| 137 | - let idxTmp = this.playerIdx | ||
| 138 | - let that = this; | ||
| 139 | - this.loading = true | ||
| 140 | - this.$axios({ | ||
| 141 | - method: 'get', | ||
| 142 | - url: '/api/play/start/' + deviceId + '/' + channelId | ||
| 143 | - }).then(function (res) { | ||
| 144 | - // that.isLoging = false; | ||
| 145 | - console.log('=====----=====') | ||
| 146 | - console.log(res) | ||
| 147 | - if (res.data.code == 0 && res.data.data) { | ||
| 148 | - itemData.playUrl = res.data.data.httpsFlv | ||
| 149 | - that.setPlayUrl(res.data.data.ws_flv,idxTmp) | ||
| 150 | - }else { | ||
| 151 | - that.$message.error(res.data.msg); | ||
| 152 | - } | ||
| 153 | - }).catch(function (e) { | ||
| 154 | - }).finally(()=>{ | ||
| 155 | - that.loading = false | 167 | + return new Blob([uInt8Array], { |
| 168 | + type: contentType | ||
| 156 | }); | 169 | }); |
| 157 | - }, | ||
| 158 | - setPlayUrl(url,idx){ | ||
| 159 | - this.$set(this.videoUrl,idx,url) | ||
| 160 | - let _this = this | ||
| 161 | - setTimeout(()=>{ | ||
| 162 | - window.localStorage.setItem('videoUrl',JSON.stringify(_this.videoUrl)) | ||
| 163 | - },100) | ||
| 164 | - | ||
| 165 | - }, | ||
| 166 | - checkPlayByParam(){ | ||
| 167 | - let {deviceId,channelId} = this.$route.query | ||
| 168 | - if(deviceId && channelId){ | ||
| 169 | - this.sendDevicePush({deviceId,channelId}) | ||
| 170 | - } | ||
| 171 | - }, | ||
| 172 | - convertImageToCanvas(image) { | ||
| 173 | - var canvas = document.createElement("canvas"); | ||
| 174 | - canvas.width = image.width; | ||
| 175 | - canvas.height = image.height; | ||
| 176 | - canvas.getContext("2d").drawImage(image, 0, 0); | ||
| 177 | - return canvas; | ||
| 178 | - }, | ||
| 179 | - shot(e){ | ||
| 180 | - // console.log(e) | ||
| 181 | - // send({code:'image',data:e}) | ||
| 182 | - var base64ToBlob = function(code) { | ||
| 183 | - let parts = code.split(';base64,'); | ||
| 184 | - let contentType = parts[0].split(':')[1]; | ||
| 185 | - let raw = window.atob(parts[1]); | ||
| 186 | - let rawLength = raw.length; | ||
| 187 | - let uInt8Array = new Uint8Array(rawLength); | ||
| 188 | - for(let i = 0; i < rawLength; ++i) { | ||
| 189 | - uInt8Array[i] = raw.charCodeAt(i); | ||
| 190 | - } | ||
| 191 | - return new Blob([uInt8Array], { | ||
| 192 | - type: contentType | ||
| 193 | - }); | ||
| 194 | - }; | ||
| 195 | - let aLink = document.createElement('a'); | ||
| 196 | - let blob = base64ToBlob(e); //new Blob([content]); | ||
| 197 | - let evt = document.createEvent("HTMLEvents"); | ||
| 198 | - evt.initEvent("click", true, true); //initEvent 不加后两个参数在FF下会报错 事件类型,是否冒泡,是否阻止浏览器的默认行为 | ||
| 199 | - aLink.download = '截图'; | ||
| 200 | - aLink.href = URL.createObjectURL(blob); | ||
| 201 | - aLink.click(); | ||
| 202 | - }, | ||
| 203 | - save(item){ | ||
| 204 | - let dataStr = window.localStorage.getItem('playData') || '[]' | ||
| 205 | - let data = JSON.parse(dataStr); | ||
| 206 | - data[this.playerIdx] = item | ||
| 207 | - window.localStorage.setItem('playData',JSON.stringify(data)) | ||
| 208 | - }, | ||
| 209 | - clear(idx) { | ||
| 210 | - let dataStr = window.localStorage.getItem('playData') || '[]' | ||
| 211 | - let data = JSON.parse(dataStr); | ||
| 212 | - data[idx-1] = null; | ||
| 213 | - console.log(data); | ||
| 214 | - window.localStorage.setItem('playData',JSON.stringify(data)) | ||
| 215 | - }, | ||
| 216 | - loadAndPlay(){ | ||
| 217 | - let dataStr = window.localStorage.getItem('playData') || '[]' | ||
| 218 | - let data = JSON.parse(dataStr); | ||
| 219 | - | ||
| 220 | - data.forEach((item,i)=>{ | ||
| 221 | - if(item){ | ||
| 222 | - this.playerIdx = i | ||
| 223 | - this.sendDevicePush(item) | ||
| 224 | - } | ||
| 225 | - }) | ||
| 226 | - } | ||
| 227 | - } | ||
| 228 | - }; | 170 | + }; |
| 171 | + let aLink = document.createElement('a'); | ||
| 172 | + let blob = base64ToBlob(e); //new Blob([content]); | ||
| 173 | + let evt = document.createEvent("HTMLEvents"); | ||
| 174 | + evt.initEvent("click", true, true); //initEvent 不加后两个参数在FF下会报错 事件类型,是否冒泡,是否阻止浏览器的默认行为 | ||
| 175 | + aLink.download = '截图'; | ||
| 176 | + aLink.href = URL.createObjectURL(blob); | ||
| 177 | + aLink.click(); | ||
| 178 | + }, | ||
| 179 | + save(item) { | ||
| 180 | + let dataStr = window.localStorage.getItem('playData') || '[]' | ||
| 181 | + let data = JSON.parse(dataStr); | ||
| 182 | + data[this.playerIdx] = item | ||
| 183 | + window.localStorage.setItem('playData', JSON.stringify(data)) | ||
| 184 | + }, | ||
| 185 | + clear(idx) { | ||
| 186 | + let dataStr = window.localStorage.getItem('playData') || '[]' | ||
| 187 | + let data = JSON.parse(dataStr); | ||
| 188 | + data[idx - 1] = null; | ||
| 189 | + console.log(data); | ||
| 190 | + window.localStorage.setItem('playData', JSON.stringify(data)) | ||
| 191 | + }, | ||
| 192 | + } | ||
| 193 | +}; | ||
| 229 | </script> | 194 | </script> |
| 230 | <style> | 195 | <style> |
| 231 | - .btn{ | ||
| 232 | - margin: 0 10px; | 196 | +.btn { |
| 197 | + margin: 0 10px; | ||
| 233 | 198 | ||
| 234 | - } | ||
| 235 | - .btn:hover{ | ||
| 236 | - color: #409EFF; | ||
| 237 | - } | ||
| 238 | - .btn.active{ | ||
| 239 | - color: #409EFF; | 199 | +} |
| 240 | 200 | ||
| 241 | - } | ||
| 242 | - .redborder{ | ||
| 243 | - border: 2px solid red !important; | ||
| 244 | - } | ||
| 245 | - .play-box{ | ||
| 246 | - background-color: #000000; | ||
| 247 | - border: 2px solid #505050; | ||
| 248 | - display: flex; | ||
| 249 | - align-items: center; | ||
| 250 | - justify-content: center; | ||
| 251 | - } | 201 | +.btn:hover { |
| 202 | + color: #409EFF; | ||
| 203 | +} | ||
| 204 | + | ||
| 205 | +.btn.active { | ||
| 206 | + color: #409EFF; | ||
| 207 | + | ||
| 208 | +} | ||
| 209 | + | ||
| 210 | +.redborder { | ||
| 211 | + border: 2px solid red !important; | ||
| 212 | +} | ||
| 213 | + | ||
| 214 | +.play-box { | ||
| 215 | + background-color: #000000; | ||
| 216 | + border: 2px solid #505050; | ||
| 217 | + display: flex; | ||
| 218 | + align-items: center; | ||
| 219 | + justify-content: center; | ||
| 220 | +} | ||
| 252 | </style> | 221 | </style> |
| 253 | <style> | 222 | <style> |
| 254 | - .videoList { | ||
| 255 | - display: flex; | ||
| 256 | - flex-wrap: wrap; | ||
| 257 | - align-content: flex-start; | ||
| 258 | - } | 223 | +.videoList { |
| 224 | + display: flex; | ||
| 225 | + flex-wrap: wrap; | ||
| 226 | + align-content: flex-start; | ||
| 227 | +} | ||
| 259 | 228 | ||
| 260 | - .video-item { | ||
| 261 | - position: relative; | ||
| 262 | - width: 15rem; | ||
| 263 | - height: 10rem; | ||
| 264 | - margin-right: 1rem; | ||
| 265 | - background-color: #000000; | ||
| 266 | - } | 229 | +.video-item { |
| 230 | + position: relative; | ||
| 231 | + width: 15rem; | ||
| 232 | + height: 10rem; | ||
| 233 | + margin-right: 1rem; | ||
| 234 | + background-color: #000000; | ||
| 235 | +} | ||
| 267 | 236 | ||
| 268 | - .video-item-img { | ||
| 269 | - position: absolute; | ||
| 270 | - top: 0; | ||
| 271 | - bottom: 0; | ||
| 272 | - left: 0; | ||
| 273 | - right: 0; | ||
| 274 | - margin: auto; | ||
| 275 | - width: 100%; | ||
| 276 | - height: 100%; | ||
| 277 | - } | 237 | +.video-item-img { |
| 238 | + position: absolute; | ||
| 239 | + top: 0; | ||
| 240 | + bottom: 0; | ||
| 241 | + left: 0; | ||
| 242 | + right: 0; | ||
| 243 | + margin: auto; | ||
| 244 | + width: 100%; | ||
| 245 | + height: 100%; | ||
| 246 | +} | ||
| 278 | 247 | ||
| 279 | - .video-item-img:after { | ||
| 280 | - content: ""; | ||
| 281 | - display: inline-block; | ||
| 282 | - position: absolute; | ||
| 283 | - z-index: 2; | ||
| 284 | - top: 0; | ||
| 285 | - bottom: 0; | ||
| 286 | - left: 0; | ||
| 287 | - right: 0; | ||
| 288 | - margin: auto; | ||
| 289 | - width: 3rem; | ||
| 290 | - height: 3rem; | ||
| 291 | - background-image: url("../assets/loading.png"); | ||
| 292 | - background-size: cover; | ||
| 293 | - background-color: #000000; | ||
| 294 | - } | 248 | +.video-item-img:after { |
| 249 | + content: ""; | ||
| 250 | + display: inline-block; | ||
| 251 | + position: absolute; | ||
| 252 | + z-index: 2; | ||
| 253 | + top: 0; | ||
| 254 | + bottom: 0; | ||
| 255 | + left: 0; | ||
| 256 | + right: 0; | ||
| 257 | + margin: auto; | ||
| 258 | + width: 3rem; | ||
| 259 | + height: 3rem; | ||
| 260 | + background-image: url("../assets/loading.png"); | ||
| 261 | + background-size: cover; | ||
| 262 | + background-color: #000000; | ||
| 263 | +} | ||
| 295 | 264 | ||
| 296 | - .video-item-title { | ||
| 297 | - position: absolute; | ||
| 298 | - bottom: 0; | ||
| 299 | - color: #000000; | ||
| 300 | - background-color: #ffffff; | ||
| 301 | - line-height: 1.5rem; | ||
| 302 | - padding: 0.3rem; | ||
| 303 | - width: 14.4rem; | ||
| 304 | - } | 265 | +.video-item-title { |
| 266 | + position: absolute; | ||
| 267 | + bottom: 0; | ||
| 268 | + color: #000000; | ||
| 269 | + background-color: #ffffff; | ||
| 270 | + line-height: 1.5rem; | ||
| 271 | + padding: 0.3rem; | ||
| 272 | + width: 14.4rem; | ||
| 273 | +} | ||
| 305 | 274 | ||
| 306 | - .baidumap { | ||
| 307 | - width: 100%; | ||
| 308 | - height: 100%; | ||
| 309 | - border: none; | ||
| 310 | - position: absolute; | ||
| 311 | - left: 0; | ||
| 312 | - top: 0; | ||
| 313 | - right: 0; | ||
| 314 | - bottom: 0; | ||
| 315 | - margin: auto; | ||
| 316 | - } | 275 | +.baidumap { |
| 276 | + width: 100%; | ||
| 277 | + height: 100%; | ||
| 278 | + border: none; | ||
| 279 | + position: absolute; | ||
| 280 | + left: 0; | ||
| 281 | + top: 0; | ||
| 282 | + right: 0; | ||
| 283 | + bottom: 0; | ||
| 284 | + margin: auto; | ||
| 285 | +} | ||
| 317 | 286 | ||
| 318 | - /* 去除百度地图版权那行字 和 百度logo */ | ||
| 319 | - .baidumap > .BMap_cpyCtrl { | ||
| 320 | - display: none !important; | ||
| 321 | - } | ||
| 322 | - .baidumap > .anchorBL { | ||
| 323 | - display: none !important; | ||
| 324 | - } | 287 | +/* 去除百度地图版权那行字 和 百度logo */ |
| 288 | +.baidumap > .BMap_cpyCtrl { | ||
| 289 | + display: none !important; | ||
| 290 | +} | ||
| 291 | + | ||
| 292 | +.baidumap > .anchorBL { | ||
| 293 | + display: none !important; | ||
| 294 | +} | ||
| 325 | </style> | 295 | </style> |
web_src/src/layout/index.vue
| @@ -24,26 +24,6 @@ export default { | @@ -24,26 +24,6 @@ export default { | ||
| 24 | } | 24 | } |
| 25 | </script> | 25 | </script> |
| 26 | <style> | 26 | <style> |
| 27 | -/*定义滚动条高宽及背景 高宽分别对应横竖滚动条的尺寸*/ | ||
| 28 | -::-webkit-scrollbar { | ||
| 29 | - width: 8px; | ||
| 30 | - height: 8px; | ||
| 31 | -} | ||
| 32 | - | ||
| 33 | -/*定义滚动条轨道 内阴影+圆角*/ | ||
| 34 | -::-webkit-scrollbar-track { | ||
| 35 | - border-radius: 4px; | ||
| 36 | - background-color: #F5F5F5; | ||
| 37 | -} | ||
| 38 | - | ||
| 39 | -/*定义滑块 内阴影+圆角*/ | ||
| 40 | -::-webkit-scrollbar-thumb { | ||
| 41 | - border-radius: 4px; | ||
| 42 | - background-color: #c8c8c8; | ||
| 43 | - box-shadow: inset 0 0 6px rgba(0, 0, 0, .1); | ||
| 44 | - -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, .1); | ||
| 45 | -} | ||
| 46 | - | ||
| 47 | /*定义标题栏*/ | 27 | /*定义标题栏*/ |
| 48 | .page-header { | 28 | .page-header { |
| 49 | background-color: #FFFFFF; | 29 | background-color: #FFFFFF; |
| @@ -64,10 +44,6 @@ export default { | @@ -64,10 +44,6 @@ export default { | ||
| 64 | } | 44 | } |
| 65 | </style> | 45 | </style> |
| 66 | <style scoped> | 46 | <style scoped> |
| 67 | -.el-main { | ||
| 68 | - margin: 0; | ||
| 69 | -} | ||
| 70 | - | ||
| 71 | .fade-enter { | 47 | .fade-enter { |
| 72 | visibility: hidden; | 48 | visibility: hidden; |
| 73 | opacity: 0; | 49 | opacity: 0; |
web_src/src/router/index.js
| @@ -99,16 +99,6 @@ export default new VueRouter({ | @@ -99,16 +99,6 @@ export default new VueRouter({ | ||
| 99 | component: media, | 99 | component: media, |
| 100 | }, | 100 | }, |
| 101 | { | 101 | { |
| 102 | - path: '/play/wasm/:url', | ||
| 103 | - name: 'wasmPlayer', | ||
| 104 | - component: wasmPlayer, | ||
| 105 | - }, | ||
| 106 | - { | ||
| 107 | - path: '/play/rtc/:url', | ||
| 108 | - name: 'rtcPlayer', | ||
| 109 | - component: rtcPlayer, | ||
| 110 | - }, | ||
| 111 | - { | ||
| 112 | path: '/map', | 102 | path: '/map', |
| 113 | name: 'devicePosition', | 103 | name: 'devicePosition', |
| 114 | component: devicePosition, | 104 | component: devicePosition, |
| @@ -125,5 +115,15 @@ export default new VueRouter({ | @@ -125,5 +115,15 @@ export default new VueRouter({ | ||
| 125 | name: 'deviceTree', | 115 | name: 'deviceTree', |
| 126 | component: deviceTree, | 116 | component: deviceTree, |
| 127 | }, | 117 | }, |
| 118 | + { | ||
| 119 | + path: '/play/wasm/:url', | ||
| 120 | + name: 'wasmPlayer', | ||
| 121 | + component: wasmPlayer, | ||
| 122 | + }, | ||
| 123 | + { | ||
| 124 | + path: '/play/rtc/:url', | ||
| 125 | + name: 'rtcPlayer', | ||
| 126 | + component: rtcPlayer, | ||
| 127 | + }, | ||
| 128 | ] | 128 | ] |
| 129 | }) | 129 | }) |