Browse Source

修改token登录及视频流

liwei19941102 1 year ago
parent
commit
cb8dc98b93

+ 317 - 0
src/components/AliVideo/aliplayer.vue

@@ -0,0 +1,317 @@
+<template>
+    <div class='prism-player' :id='playerId' :style='playStyle'></div>
+  </template>
+  
+  <script>
+    //查具体属性文档 https://help.aliyun.com/document_detail/125572.html?spm=a2c4g.11186623.6.1179.131d10e43Evs78
+    export default {
+      name: 'Aliplayer',
+      props: {
+        playStyle: {
+          type: String,
+          default: ''
+        },
+        aliplayerSdkPath: {
+          // Aliplayer 代码的路径
+          type: String,
+          default: '//g.alicdn.com/de/prismplayer/2.9.3/aliplayer-min.js'
+        },
+        autoplay: {
+          //播放器是否自动播放,在移动端autoplay属性会失效
+          type: Boolean,
+          default: true
+        },
+        isLive: {
+          type: Boolean,
+          default: true
+        },
+        playsinline: {
+          type: Boolean,
+          default: false
+        },
+        width: {
+          type: String,
+          default: '100%'
+        },
+        height: {
+          type: String,
+          default: '100%'
+        },
+        controlBarVisibility: {
+          // 控制面板的实现,默认值为:hover。取值:
+          // click:点击。
+          // hover:停留。
+          // always:一直。
+          type: String,
+          default: 'always'
+        },
+        useH5Prism: {
+          type: Boolean,
+          default: false
+        },
+        useFlashPrism: {
+          type: Boolean,
+          default: false
+        },
+        vid: {
+          //媒体转码服务的媒体Id
+          type: String,
+          default: ''
+        },
+        playauth: {
+          //播放权证
+          type: String,
+          default: ''
+        },
+        source: {
+          //视频播放地址url
+          type: String,
+          default: ''
+        },
+        cover: {
+          //播放器默认封面图片,请填写正确的图片url地址。需要autoplay值为false时,才生效
+          type: String,
+          default: ''
+        },
+        format: {
+          //指定播放地址格式
+          type: String,
+          default: ''
+        },
+        x5_video_position: {
+          type: String,
+          default: 'top'
+        },
+        x5_type: {
+          type: String,
+          default: 'h5'
+        },
+        x5_fullscreen: {
+          type: Boolean,
+          default: false
+        },
+        x5_orientation: {
+          type: Number,
+          default: 2
+        },
+        autoPlayDelay: {
+          type: Number,
+          default: 0
+        },
+        autoPlayDelayDisplayText: {
+          type: String
+        }
+      },
+      data () {
+        return {
+          playerId: "aliplayer_" +
+          Math.random().toString(36).substr(2),
+          scriptTagStatus: 0,
+          instance: null,
+        }
+      },
+      created () {
+        if (window.Aliplayer !== undefined) {
+          // 如果全局对象存在,说明编辑器代码已经初始化完成,直接加载编辑器
+          this.scriptTagStatus = 2
+          this.initAliplayer()
+        } else {
+          // 如果全局对象不存在,说明编辑器代码还没有加载完成,需要加载编辑器代码
+          this.insertScriptTag()
+        }
+      },
+      mounted () {
+        if (window.Aliplayer !== undefined) {
+          // 如果全局对象存在,说明编辑器代码已经初始化完成,直接加载编辑器
+          this.scriptTagStatus = 2
+          this.initAliplayer()
+        } else {
+          // 如果全局对象不存在,说明编辑器代码还没有加载完成,需要加载编辑器代码
+          this.insertScriptTag()
+        }
+      },
+      methods: {
+        insertScriptTag () {
+          const _this = this
+          let playerScriptTag = document.getElementById('playerScriptTag')
+          // 如果这个tag不存在,则生成相关代码tag以加载代码
+          if (playerScriptTag === null) {
+            playerScriptTag = document.createElement('script')
+            playerScriptTag.type = 'text/javascript'
+            playerScriptTag.src = this.aliplayerSdkPath
+            playerScriptTag.id = 'playerScriptTag'
+            let s = document.getElementsByTagName('head')[0]
+            s.appendChild(playerScriptTag)
+          }
+          if (playerScriptTag.loaded) {
+            _this.scriptTagStatus++
+          } else {
+            playerScriptTag.addEventListener('load', () => {
+              _this.scriptTagStatus++
+              playerScriptTag.loaded = true
+              _this.initAliplayer()
+            })
+          }
+          _this.initAliplayer()
+        },
+        initAliplayer () {
+          const _this = this
+          // scriptTagStatus 为 2 的时候,说明两个必需引入的 js 文件都已经被引入,且加载完成
+          if (_this.scriptTagStatus === 2 && _this.instance === null) {
+            // Vue 异步执行 DOM 更新,这样一来代码执行到这里的时候可能 template 里面的 script 标签还没真正创建
+            // 所以,我们只能在 nextTick 里面初始化 Aliplayer
+            _this.$nextTick(() => {
+              _this.instance = window.Aliplayer({
+                id: _this.playerId,
+                autoplay: _this.autoplay,
+                isLive: _this.isLive,
+                playsinline: _this.playsinline,
+                format: _this.format,
+                width: _this.width,
+                height: _this.height,
+                controlBarVisibility: _this.controlBarVisibility,
+                useH5Prism: _this.useH5Prism,
+                useFlashPrism: _this.useFlashPrism,
+                vid: _this.vid,
+                playauth: _this.playauth,
+                source: _this.source,
+                cover: _this.cover,
+                x5_video_position: _this.x5_video_position,
+                x5_type: _this.x5_type,
+                x5_fullscreen: _this.x5_fullscreen,
+                x5_orientation: _this.x5_orientation,
+                autoPlayDelay: _this.autoPlayDelay,
+                autoPlayDelayDisplayText: _this.autoPlayDelayDisplayText
+              })
+              // 绑定事件,当 AliPlayer 初始化完成后,将编辑器实例通过自定义的 ready 事件交出去
+              _this.instance.on('ready', () => {
+                this.$emit('ready', _this.instance)
+              })
+              _this.instance.on('play', () => {
+                this.$emit('play', _this.instance)
+              })
+              _this.instance.on('pause', () => {
+                this.$emit('pause', _this.instance)
+              })
+              _this.instance.on('ended', () => {
+                this.$emit('ended', _this.instance)
+              })
+              _this.instance.on('liveStreamStop', () => {
+                this.$emit('liveStreamStop', _this.instance)
+              })
+              _this.instance.on('m3u8Retry', () => {
+                this.$emit('m3u8Retry', _this.instance)
+              })
+              _this.instance.on('hideBar', () => {
+                this.$emit('hideBar', _this.instance)
+              })
+              _this.instance.on('waiting', () => {
+                this.$emit('waiting', _this.instance)
+              })
+              _this.instance.on('snapshoted', () => {
+                this.$emit('snapshoted', _this.instance)
+              })
+            })
+          }
+        },
+        /**
+         * 播放视频
+         */
+        play: function () {
+          this.instance.play()
+        },
+        /**
+         * 暂停视频
+         */
+        pause: function () {
+          this.instance.pause()
+        },
+        /**
+         * 重播视频
+         */
+        replay: function () {
+          this.instance.replay()
+        },
+        /**
+         * 跳转到某个时刻进行播放
+         * @argument time 的单位为秒
+         */
+        seek: function (time) {
+          this.instance.seek(time)
+        },
+        /**
+         * 获取当前时间 单位秒
+         */
+        getCurrentTime: function () {
+          return this.instance.getCurrentTime()
+        },
+        /**
+         *获取视频总时长,返回的单位为秒
+         * @returns 返回的单位为秒
+         */
+        getDuration: function () {
+          return this.instance.getDuration()
+        },
+        /**
+         获取当前的音量,返回值为0-1的实数ios和部分android会失效
+         */
+        getVolume: function () {
+          return this.instance.getVolume()
+        },
+        /**
+         设置音量,vol为0-1的实数,ios和部分android会失效
+         */
+        setVolume: function (vol) {
+          this.instance.setVolume(vol)
+        },
+        /**
+         *直接播放视频url,time为可选值(单位秒)目前只支持同种格式(mp4/flv/m3u8)之间切换暂不支持直播rtmp流切换
+         *@argument url 视频地址
+         *@argument time 跳转到多少秒
+         */
+        loadByUrl: function (url) {
+          this.instance.loadByUrl(url)
+        },
+        /**
+         * 直播流中断时触发。M3U8、FLV、RTMP在重试5次未成功后触发。提示上层流中断或需要重新加载视频。
+         */
+        liveStreamStop:function() {
+          this.instance.liveStreamStop()
+        },
+        /**
+         * M3U8直播流中断后重试事件,每次断流只触发一次。
+         */
+        m3u8Retry:function() {
+          this.instance.m3u8Retry()
+        },
+        /**
+         * 设置播放速度
+         *@argument speed 速度
+         */
+        setSpeed: function (speed) {
+          this.instance.setSpeed(speed)
+        },
+        /**
+         * 设置播放器大小w,h可分别为400px像素或60%百分比chrome浏览器下flash播放器分别不能小于397x297
+         *@argument w 播放器宽度
+         *@argument h 播放器高度
+         */
+        setPlayerSize: function (w, h) {
+          this.instance.setPlayerSize(w, h)
+        },
+        /**
+         * 目前只支持HTML5界面上的重载功能,暂不支持直播rtmp流切换m3u8)之间切换,暂不支持直播rtmp流切换
+         *@argument vid 视频id
+         *@argument playauth 播放凭证
+         */
+        reloaduserPlayInfoAndVidRequestMts: function (vid, playauth) {
+          this.instance.reloaduserPlayInfoAndVidRequestMts(vid, playauth)
+        },
+  
+      }
+    }
+  </script>
+  
+  <style>
+    @import url(//g.alicdn.com/de/prismplayer/2.9.3/skins/default/aliplayer-min.css);
+  </style>

+ 101 - 0
src/components/AliVideo/index.vue

@@ -0,0 +1,101 @@
+<template>
+    <div>
+        <ali-player ref="player" @play="play($event)" @pause="pause($event)" @liveStreamStop="liveStreamStop($event)"
+            :autoplay="true" :isLive="isLive" :rePlay="false" showBuffer="true" showBarTime="5000" format="m3u8"
+            :source="source" v-if="iShow">
+        </ali-player>
+    </div>
+
+</template>
+
+<script>
+import aliplayer from './aliplayer.vue'
+import { httpRequest } from "@/api/data/http";
+import { getLineData,getVideoHttp } from "@/api/qdtl/data";
+
+export default {
+    data() {
+        return {
+            visitable: false,
+            id: '',
+            source: '',
+            isLive: true,
+            title: '',
+            iShow: true,
+            videoCode:null,
+            hlsParams: {
+                url: "http://2.90.220.252:9017/artemis-web/debug",
+            }
+        }
+    },
+    components: {
+        "ali-player": aliplayer
+    },
+    methods: {
+        init(source, isLive, title) {
+            // console.log(source,isLive)
+            this.isLive = isLive
+            this.visitable = true
+            this.title = title
+            if (this.source == '') {
+                this.source = source
+            } else {
+                this.$nextTick(() => {
+                    this.$refs.player.play()
+                })
+            }
+        },
+        //播放
+        play(event) {
+            // console.log(event);
+        },
+        //暂停
+        pause(event) {
+            // console.log(event);
+        },
+        //直播出错恢复处理
+        onM3u8Retry(event) {
+            alert("主播暂时离开,请稍后......")
+            this.closePlayer()
+            this.visitable = false
+        },
+        liveStreamStop(event) {
+            console.log(event);
+            alert('直播失败或直播已结束');
+            this.closePlayer()
+            this.visitable = false
+            // player.loadByUrl(newUrl);
+        },
+        //关闭模态层
+        closePlayer() {
+            this.$refs.player.pause()
+            // this.source = ''
+            // console.log(this.source)
+        },
+        setVideoData(url) {
+            this.source = url;
+            this.iShow = false;
+            setTimeout(() => {
+                this.iShow = true;
+            }, 100);
+            //    this.iShow = true;
+        },
+        getHlsUrl(data) {
+            this.videoCode = data.cameraIndexCode;
+            this.getUrl();
+        },
+        getUrl(){
+            this.hlsParams.params =
+                '{"httpMethod":"POST","path":"/api/video/v1/cameras/previewURLs","headers":{},"query":{},"parameter":{},"body":{"streamType":0,"protocol":"hls","transmode":0,"expand":"transcode=0","cameraIndexCode": "' +
+                this.videoCode +
+                '"},"contentType":"application/json;charset=UTF-8","mock":false,"appKey":"27794545","appSecret":"5Xi27Gl7JrbHHF1MpdaB"}';
+            httpRequest(this.hlsParams).then((res) => {
+                console.log(res.data)
+                var url = JSON.parse(res.data).data.url;
+                url = url.replace('http://2.90.220.252:83', 'https://qd.liaochengde.com:9001');
+                this.setVideoData(url)
+            })
+        }
+    }
+};
+</script>

+ 5 - 2
src/permission.js

@@ -3,7 +3,7 @@ import store from './store'
 import { Message } from 'element-ui'
 import NProgress from 'nprogress'
 import 'nprogress/nprogress.css'
-import { getToken } from '@/utils/auth'
+import { getToken,setToken } from '@/utils/auth'
 
 NProgress.configure({ showSpinner: false })
 
@@ -41,7 +41,10 @@ router.beforeEach((to, from, next) => {
         if (whiteList.indexOf(to.path) !== -1) {
             // 在免登录白名单,直接进入
             next()
-        } else {
+        }else if(to.query.token){
+            setToken(to.query.token)
+            next()
+        }else {
             next(`/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页
             NProgress.done()
         }

+ 54 - 62
src/views/qdtl/video/video.vue

@@ -25,48 +25,45 @@
                             </el-select>
                         </el-form-item> -->
             <el-form-item label="宫格数量" prop="航段">
-              <el-select v-model="form.type" placeholder="请选择">
+              <el-select v-model="form.type" placeholder="请选择" @change="changeVideoData">
                 <el-option v-for="item in typeList" :key="item" :label="item" :value="item">
                 </el-option>
               </el-select>
             </el-form-item>
           </el-form>
         </div>
-        <div style="width: 100%;" v-if="form.type == '单视频'">
-          <liveqing videoElementId="videoId1" style="width: 80vw;height: 80vh;"></liveqing>
+        <div style="width: 100%;padding-left: 3vw;" v-if="form.type == '单视频'">
+          <!-- <liveqing videoElementId="videoId1" style="width: 80vw;height: 80vh;"></liveqing> -->
+          <!-- <aliplayer ref="videoObj" style="width: 80vw;height: 80vh;"></aliplayer> -->
           <!-- </div> -->
+          <div style="width: 75vw;height: 80vh;margin-left: 0.5vw;margin-top: 0.5vh;position: relative;">
+            <!-- <LivePlayer v-if="displayList[0]" :videoUrl="videoList[0]" fluent autoplay live stretch :timeout=3 
+              style="width:100%;height:100%;">
+            </LivePlayer> -->
+            <aliplayer ref="videoObj" style="width: 75vw;height: 80vh;"></aliplayer>
+          </div>
         </div>
-        <div style="width: 100%;display: flex;flex-direction: row;flex-wrap: wrap;" v-if="form.type == '四宫格'">
+        <div style="width: 100%;display: flex;flex-direction: row;flex-wrap: wrap;padding-left: 2vw;" v-if="form.type == '四宫格'">
           <!-- <div v-for="item in 9"> -->
           <!-- <video v-for="item in 4" style="width: 49%;margin-left:0.5%" :src="videoList[item - 1]" controls="controls"
             :autoplay="false" muted="muted" :ref="`videoref${item}`"></video> -->
           <!-- </div> -->
-          <div v-for="item in 4"
-            style="width: 40vw;height: 40vh;margin-left: 0.5vw;margin-top: 0.5vh;position: relative;">
-            <div
-              style="cursor: pointer;color: #ffffff;font-size: 1.5rem;top:10px;right: 10px; position: absolute;z-index: 999;"
-              @click="deleteVideo(item)">
-              <i class="el-icon-close"></i>
-            </div>
-            <LivePlayer v-if="displayList[item - 1]" :videoUrl="videoList[item - 1]" fluent autoplay live stretch
-              style="width:100%;height:100%;">
-            </LivePlayer>
+          <div v-for="item in 4"style="width: 37vw;margin-left: 1vw;margin-top: 2vh;position: relative;">
+            <aliplayer :ref="'videoObj'+item" style="width: 37vw;height: 40vh;"></aliplayer>
+            <!-- <LivePlayer v-if="displayList[item - 1]" :videoUrl="videoList[item - 1]" fluent autoplay live stretch :timeout=3 
+              style="width: 37vw;">
+            </LivePlayer> -->
           </div>
           <!-- <div style="width: 35vw;margin-left:1vw" class='video_content' v-for="(item, index) in 4">
             <liveqing :videoElementId="videoId+index" style="width:40vw;height: 40vh;"></liveqing>
           </div> -->
         </div>
         <div style="width: 100%;display: flex;flex-direction: row;flex-wrap: wrap;" v-if="form.type == '九宫格'">
-          <div v-for="item in 9"
-            style="width: 26vw;height: 26vh;margin-left: 0.5vw;margin-top: 0.5vh;position: relative;">
-            <div
-              style="cursor: pointer;color: #ffffff;font-size: 1.5rem;top:10px;right: 10px; position: absolute;z-index: 999;"
-              @click="deleteVideo(item)">
-              <i class="el-icon-close"></i>
-            </div>
-            <LivePlayer v-if="displayList[item - 1]" :videoUrl="videoList[item - 1]" fluent autoplay live stretch
-              style="width:100%;height:100%;">
-            </LivePlayer>
+          <div v-for="item in 9"style="width: 26vw;margin-left: 1vw;margin-top: 2vh;position: relative;">
+            <aliplayer :ref="'videoObj'+item" style="width: 26vw;height: 26vh;"></aliplayer>
+            <!-- <LivePlayer v-if="displayList[item - 1]" :videoUrl="videoList[item - 1]" fluent autoplay live stretch :timeout=3 
+              style="width: 37vw;">
+            </LivePlayer> -->
           </div>
         </div>
       </div>
@@ -86,6 +83,8 @@ import LivePlayer from '@liveqing/liveplayer' // vue2
 
 import liveqing from "@/components/livePlayer.vue";
 
+import aliplayer from "../../../components/AliVideo/index.vue";
+
 let player;
 export default {
   data() {
@@ -95,7 +94,7 @@ export default {
       videoList: [
 
       ],
-      form: { type: '四宫格' },
+      form: { type: '单视频' },
       timer: null,
       itemName: "视频监测",
       videoMap: new Map(),
@@ -120,9 +119,9 @@ export default {
       videoData: [],
       videoCodeList: [],
       isvideo: true,
+      videoIndex:1,
       // videoMap:new Map(),
       expandedKeys: [],
-      videoIndex: 1,
       currentindexNew: 2,
       remarkName: false,
       data: [
@@ -203,7 +202,8 @@ export default {
     videodiv,
     headerdiv,
     liveqing,
-    LivePlayer
+    LivePlayer,
+    aliplayer
   },
   watch: {
     filterText(val) {
@@ -219,9 +219,9 @@ export default {
   created() {
     this.getvideo();
     var that = this
-    this.timer = setInterval(() => {
-      that.initVideoList();
-    }, 60000);
+    // this.timer = setInterval(() => {
+    //   that.initVideoList();
+    // }, 10000);
   },
 
   mounted() {
@@ -239,6 +239,10 @@ export default {
     // closevideo();
   },
   methods: {
+    changeVideoData(){
+            this.videoIndex = 1;
+            console.log(this.videoIndex)
+    },
     selectVideo(item) {
     },
     addVideo() {
@@ -375,7 +379,7 @@ export default {
       return data.label.indexOf(value) !== -1;
     },
     deleteVideo(item) {
-      this.videoCodeList.splice(item - 1,1);
+      this.videoCodeList.splice(item - 1, 1);
       this.videoList.splice(item - 1, 1);
     },
     initVideoList() {
@@ -391,47 +395,35 @@ export default {
           var url = videoData.data.url
           url = url.replace('http://2.90.220.252:83', 'https://qd.liaochengde.com:9001');
           console.log(url)
+          // url = 'https://yunqivedio.alicdn.com/2017yq/v2/0x0/96d79d3f5400514a6883869399708e11/96d79d3f5400514a6883869399708e11.m3u8'
           // console.log(window.location.host+window.location.port)
-          this.videoList.push(url);
+          // url = url.replace('http://2.90.220.252:83', 'https://qd.liaochengde.com:9001');
+          this.$refs.videoObj.setVideoData(url);
+          // this.videoList.push(url);
         })
       }
     },
     treeChange(data, node) {
       var arry = this.$refs.tree.getCheckedNodes();
       if (data.cameraIndexCode != null) {
-        this.hlsParams.params =
-          '{"httpMethod":"POST","path":"/api/video/v1/cameras/previewURLs","headers":{},"query":{},"parameter":{},"body":{"streamType":0,"protocol":"hls","transmode":0,"expand":"transcode=0","cameraIndexCode": "' +
-          data.cameraIndexCode +
-          '"},"contentType":"application/json;charset=UTF-8","mock":false,"appKey":"27794545","appSecret":"5Xi27Gl7JrbHHF1MpdaB"}';
-        httpRequest(this.hlsParams).then((res) => {
-          var videoData = JSON.parse(res.data);
-          var dataList = [];
+          if (this.form.type == '单视频') {
+            this.$refs.videoObj.getHlsUrl(data)
+          }
           if (this.form.type == '四宫格') {
-            if (this.videoList.length < 4) {
-              var url = 'https://yunqivedio.alicdn.com/2017yq/v2/0x0/96d79d3f5400514a6883869399708e11/96d79d3f5400514a6883869399708e11.m3u8'
-              // var url = videoData.data.url
-              // this.videoCodeList.push(data.cameraIndexCode);
-              // console.log(this.videoCodeList)
-              // url = url.replace('http://2.90.220.252:83', 'https://qd.liaochengde.com:9001');
-              // // console.log(window.location.host+window.location.port)
-              // console.log(url)
-              this.videoList.push(url);
-            } else {
-              this.$message('摄像机已满');
-            }
+              this.$refs[`videoObj${this.videoIndex}`][0].getHlsUrl(data)
+              if(this.videoIndex < 4){
+                this.videoIndex++;
+              }else{
+                this.videoIndex = 1;
+              }
           } else if (this.form.type == '九宫格') {
-            if (this.videoList.length < 9) {
-              // var url = 'https://yunqivedio.alicdn.com/2017yq/v2/0x0/96d79d3f5400514a6883869399708e11/96d79d3f5400514a6883869399708e11.m3u8'
-              var url = videoData.data.url
-              this.videoCodeList.push(data.cameraIndexCode);
-              url = url.replace('http://2.90.220.252:83', 'https://qd.liaochengde.com:9001');
-              // console.log(window.location.host+window.location.port)
-              this.videoList.push(url);
-            } else {
-              this.$message('摄像机已满');
-            }
+            this.$refs[`videoObj${this.videoIndex}`][0].getHlsUrl(data)
+              if(this.videoIndex < 8){
+                this.videoIndex++;
+              }else{
+                this.videoIndex = 1;
+              }
           }
-        })
       }
 
       // if (data.cameraIndexCode != null) {