Commit d81f3f3a7d840952aca9fca11655e9435b09588b

Authored by guzijian
1 parent d34371a9

feat: 新增水印

src/main/resources/Aserver.keystore 0 → 100644
No preview for this file type
src/main/resources/application-dev.yml
... ... @@ -13,13 +13,13 @@ spring:
13 13 # REDIS数据库配置
14 14 redis:
15 15 # [必须修改] Redis服务器IP, REDIS安装在本机的,使用127.0.0.1
16   - host: 127.0.0.1
  16 + host: 192.168.168.124
17 17 # [必须修改] 端口号
18 18 port: 6379
19 19 # [可选] 数据库 DB
20 20 database: 7
21 21 # [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接
22   - password: luna
  22 +# password: luna
23 23 # [可选] 超时时间
24 24 timeout: 10000
25 25 # mysql数据源
... ... @@ -30,9 +30,9 @@ spring:
30 30 master:
31 31 type: com.zaxxer.hikari.HikariDataSource
32 32 driver-class-name: com.mysql.cj.jdbc.Driver
33   - url: jdbc:mysql://127.0.0.1:3306/wvp2?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&serverTimezone=PRC&useSSL=false&allowMultiQueries=true
  33 + url: jdbc:mysql://192.168.168.124:3306/wvp2?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&serverTimezone=PRC&useSSL=false&allowMultiQueries=true
34 34 username: root
35   - password: root123
  35 + password: guzijian
36 36 hikari:
37 37 connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数
38 38 initialSize: 50 # 连接池初始化连接数
... ... @@ -60,36 +60,36 @@ sip:
60 60 # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4
61 61 # 如果不明白,就使用0.0.0.0,大部分情况都是可以的
62 62 # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。
63   - ip: 172.19.128.50
  63 + ip: 192.168.168.124
64 64 # [可选] 28181服务监听的端口
65   - port: 8116
  65 + port: 5060
66 66 # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007)
67 67 # 后两位为行业编码,定义参照附录D.3
68 68 # 3701020049标识山东济南历下区 信息行业接入
69 69 # [可选]
70   - domain: 4101050000
  70 + domain: 3402000000
71 71 # [可选]
72   - id: 41010500002000000001
  72 + id: 34020000002000000001
73 73 # [可选] 默认设备认证密码,后续扩展使用设备单独密码, 移除密码将不进行校验
74   - password: bajiuwulian1006
  74 + password: 12345678
75 75 # 是否存储alarm信息
76 76 alarm: true
77 77  
78 78 #zlm 默认服务器配置
79 79 media:
80   - id: zlmediakit-local
  80 + id: your_server_id
81 81 # [必须修改] zlm服务器的内网IP
82   - ip: 172.19.128.50
  82 + ip: 192.168.168.124
83 83 # [必须修改] zlm服务器的http.port
84   - http-port: 9092
  84 + http-port: 9090
85 85 # [可选] 返回流地址时的ip,置空使用 media.ip
86   - stream-ip: 172.19.128.50
  86 + stream-ip: 61.169.120.202
87 87 # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip
88   - sdp-ip: 172.19.128.50
  88 + sdp-ip: 192.168.168.124
89 89 # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip
90   - hook-ip: 172.19.128.50
  90 + hook-ip: 192.168.168.124
91 91 # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置
92   - http-ssl-port: 1443
  92 + http-ssl-port: 7443
93 93 # [可选] zlm服务器的hook.admin_params=secret
94 94 secret: 10000
95 95 # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试
... ... @@ -97,9 +97,9 @@ media:
97 97 # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输
98 98 enable: true
99 99 # [可选] 在此范围内选择端口用于媒体流传输, 必须提前在zlm上配置该属性,不然自动配置此属性可能不成功
100   - port-range: 50000,50300 # 端口范围
  100 + port-range: 30000,30500 # 端口范围
101 101 # [可选] 国标级联在此范围内选择端口发送媒体流,
102   - send-port-range: 50000,50300 # 端口范围
  102 + send-port-range: 30000,30500 # 端口范围
103 103 # 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用
104 104 record-assist-port: 18081
105 105 # [根据业务需求配置]
... ...
web_src/build/utils.js
... ... @@ -95,7 +95,7 @@ exports.createNotifierCallback = () => {
95 95 title: packageConfig.name,
96 96 message: severity + ': ' + error.name,
97 97 subtitle: filename || '',
98   - icon: path.join(__dirname, 'logo.png')
  98 + icon: path.join(__dirname, 'favicon_tuohua.ico')
99 99 })
100 100 }
101 101 }
... ...
web_src/config/index.js
... ... @@ -12,14 +12,14 @@ module.exports = {
12 12 assetsPublicPath: '/',
13 13 proxyTable: {
14 14 '/debug': {
15   - target: 'http://127.0.0.1:18082',
  15 + target: 'https://192.169.1.31:18080',
16 16 changeOrigin: true,
17 17 pathRewrite: {
18 18 '^/debug': '/'
19 19 }
20 20 },
21 21 '/static/snap': {
22   - target: 'http://127.0.0.1:18082',
  22 + target: 'https://192.169.1.31:18080',
23 23 changeOrigin: true,
24 24 // pathRewrite: {
25 25 // '^/static/snap': '/static/snap'
... ...
web_src/src/components/Login.vue
1 1 <template>
2   -<div class="login" id="login">
3   - <div class="limiter">
4   - <div class="container-login100">
5   - <div class="wrap-login100">
6   - <span class="login100-form-title p-b-26">WVP视频平台</span>
7   - <span class="login100-form-title p-b-48">
8   - <i class="fa fa-video-camera"></i>
9   - </span>
  2 + <div class="login-container">
  3 + <div class="login" id="login">
  4 + <div class="limiter">
  5 + <div class="container-login100">
  6 + <div class="wrap-login100">
  7 + <span class="login100-form-title p-b-26">综合视频平台</span>
  8 + <span class="login100-form-title p-b-48">
  9 + <i class="fa fa-video-camera"></i>
  10 + </span>
10 11  
11   - <div class="wrap-input100 validate-input" data-validate = "Valid email is: a@b.c">
12   - <input :class="'input100 ' + (username==''?'':'has-val')" type="text" v-model="username" name="username">
13   - <span class="focus-input100" data-placeholder="用户名"></span>
14   - </div>
  12 + <div class="wrap-input100 validate-input" data-validate="Valid email is: a@b.c">
  13 + <input :class="'input100 ' + (username == '' ? '' : 'has-val')" type="text" v-model="username"
  14 + name="username">
  15 + <span class="focus-input100" data-placeholder="用户名"></span>
  16 + </div>
15 17  
16   - <div class="wrap-input100 validate-input" data-validate="Enter password">
17   - <span class="btn-show-pass">
18   - <i :class="'fa ' + (!showPassword?'fa-eye':'fa-eye-slash')" @click="showPassword = !showPassword"></i>
19   - </span>
20   - <input :class="'input100 ' + (password==''?'':'has-val')" :type="(!showPassword?'password':'text')" v-model="password" name="password">
21   - <span class="focus-input100" data-placeholder="密码"></span>
22   - </div>
  18 + <div class="wrap-input100 validate-input" data-validate="Enter password">
  19 + <span class="btn-show-pass">
  20 + <i :class="'fa ' + (!showPassword ? 'fa-eye' : 'fa-eye-slash')"
  21 + @click="showPassword = !showPassword"></i>
  22 + </span>
  23 + <input :class="'input100 ' + (password == '' ? '' : 'has-val')"
  24 + :type="(!showPassword ? 'password' : 'text')" v-model="password" name="password">
  25 + <span class="focus-input100" data-placeholder="密码"></span>
  26 + </div>
23 27  
24   - <div class="container-login100-form-btn">
25   - <div class="wrap-login100-form-btn" :class="{'login-loading': isLoging}" v-loading="isLoging" element-loading-background="rgb(0 0 0 / 0%);" element-loading-custom-class="login-loading-class">
26   - <div class="login100-form-bgbtn"></div>
27   - <button class="login100-form-btn" @click="login">登录</button>
  28 + <div class="container-login100-form-btn">
  29 + <div class="wrap-login100-form-btn" :class="{ 'login-loading': isLoging }" v-loading="isLoging"
  30 + element-loading-background="rgb(0 0 0 / 0%);" element-loading-custom-class="login-loading-class">
  31 + <div class="login100-form-bgbtn"></div>
  32 + <button class="login100-form-btn" @click="login">登录</button>
  33 + </div>
28 34 </div>
29 35 </div>
  36 + </div>
  37 + <div class="company-author">
  38 + <span>@2024 上海巴士拓华科技发展有限公司 版权所有</span>
  39 + </div>
30 40 </div>
31 41 </div>
32 42 </div>
33   -</div>
  43 +
34 44 </template>
35 45  
36 46 <script>
37   -import crypto from 'crypto'
  47 +import crypto from 'crypto';
38 48 import userService from "./service/UserService";
39 49 export default {
40 50 name: 'Login',
41   - data(){
42   - return {
  51 + data() {
  52 + return {
43 53 isLoging: false,
44 54 showPassword: false,
45 55 loginLoading: false,
46   - username: '',
47   - password: ''
48   - }
  56 + username: '',
  57 + password: ''
  58 + }
49 59 },
50   - created(){
  60 + created() {
51 61 var that = this;
52   - document.onkeydown = function(e) {
  62 + document.onkeydown = function (e) {
53 63 var key = window.event.keyCode;
54 64 if (key == 13) {
55 65 that.login();
56 66 }
57 67 }
58 68 },
59   - methods:{
  69 + methods: {
60 70  
61   - //登录逻辑
62   - login(){
63   - if(this.username!='' && this.password!=''){
64   - this.toLogin();
65   - }
66   - },
  71 + //登录逻辑
  72 + login() {
  73 + if (this.username != '' && this.password != '') {
  74 + this.toLogin();
  75 + }
  76 + },
67 77  
68   - //登录请求
69   - toLogin(){
70   - //需要想后端发送的登录参数
71   - let loginParam = {
72   - username: this.username,
73   - password: crypto.createHash('md5').update(this.password, "utf8").digest('hex')
74   - }
  78 + //登录请求
  79 + toLogin() {
  80 + //需要想后端发送的登录参数
  81 + let loginParam = {
  82 + username: this.username,
  83 + password: crypto.createHash('md5').update(this.password, "utf8").digest('hex')
  84 + }
75 85 var that = this;
76 86 //设置在登录状态
77 87 this.isLoging = true;
78   - let timeoutTask = setTimeout(()=>{
  88 + let timeoutTask = setTimeout(() => {
79 89 that.$message.error("登录超时");
80 90 that.isLoging = false;
81 91 }, 1000)
82 92  
83 93 this.$axios({
84   - method: 'get',
85   - url:"/api/user/login",
  94 + method: 'get',
  95 + url: "/api/user/login",
86 96 params: loginParam
87 97 }).then(function (res) {
88 98 window.clearTimeout(timeoutTask)
89 99 console.log(res);
90 100 console.log("登录成功");
91   - if (res.data.code === 0 ) {
92   - userService.setUser(res.data.data)
93   - //登录成功后
94   - that.cancelEnterkeyDefaultAction();
95   - that.$router.push('/');
96   - }else{
97   - that.isLoging = false;
98   - that.$message({
99   - showClose: true,
100   - message: '登录失败,用户名或密码错误',
101   - type: 'error'
102   - });
103   - }
  101 + if (res.data.code === 0) {
  102 + userService.setUser(res.data.data)
  103 + //登录成功后
  104 + that.cancelEnterkeyDefaultAction();
  105 + that.$router.push('/');
  106 + } else {
  107 + that.isLoging = false;
  108 + that.$message({
  109 + showClose: true,
  110 + message: '登录失败,用户名或密码错误',
  111 + type: 'error'
  112 + });
  113 + }
104 114 }).catch(function (error) {
105 115 console.log(error)
106 116 window.clearTimeout(timeoutTask)
... ... @@ -108,8 +118,8 @@ export default {
108 118 that.isLoging = false;
109 119 });
110 120 },
111   - cancelEnterkeyDefaultAction: function() {
112   - document.onkeydown = function(e) {
  121 + cancelEnterkeyDefaultAction: function () {
  122 + document.onkeydown = function (e) {
113 123 var key = window.event.keyCode;
114 124 if (key == 13) {
115 125 return false;
... ... @@ -119,4 +129,11 @@ export default {
119 129 }
120 130 }
121 131 </script>
122   -
  132 +<style scoped>
  133 +.container-login100 {
  134 + background: url("../assets/login-bg.jpg") no-repeat;
  135 + background-size: 100% 100%;
  136 + width: 100vw;
  137 + height: 100vh;
  138 +}
  139 +</style>
... ...
web_src/src/components/common/easyPlayer.vue
1 1 <template>
2   - <div id="easyplayer" ></div>
  2 + <div id="easyplayer"></div>
3 3 </template>
4 4  
5 5 <script>
  6 +import userService from '../service/UserService';
6 7 export default {
7   - name: 'player',
8   - data() {
9   - return {
10   - easyPlayer: null
11   - };
  8 + name: 'player',
  9 + data() {
  10 + return {
  11 + timer: null,
  12 + easyPlayer: null,
  13 + config: {
  14 + userName: userService.getUser().username,
  15 + nowTime: "2024-03-01 12:00:00"
  16 + } // 水印
  17 + };
  18 + },
  19 + props: ['videoUrl', 'error', 'hasaudio', 'height'],
  20 + mounted() {
  21 + let paramUrl = decodeURIComponent(this.$route.params.url)
  22 + this.$nextTick(() => {
  23 + if (typeof (this.videoUrl) == "undefined") {
  24 + this.videoUrl = paramUrl;
  25 + }
  26 + console.log("初始化时的地址为: " + this.videoUrl)
  27 + this.play(this.videoUrl)
  28 + })
  29 + },
  30 + watch: {
  31 + videoUrl(newData, oldData) {
  32 + this.play(newData)
12 33 },
13   - props: ['videoUrl', 'error', 'hasaudio', 'height'],
14   - mounted () {
15   - let paramUrl = decodeURIComponent(this.$route.params.url)
16   - this.$nextTick(() =>{
17   - if (typeof (this.videoUrl) == "undefined") {
18   - this.videoUrl = paramUrl;
19   - }
20   - console.log("初始化时的地址为: " + this.videoUrl)
21   - this.play(this.videoUrl)
22   - })
  34 + immediate: true
  35 + },
  36 + methods: {
  37 + play: function (url) {
  38 + console.log(this.height)
  39 + if (this.easyPlayer != null) {
  40 + this.easyPlayer.destroy();
  41 + }
  42 + if (typeof (this.height) == "undefined") {
  43 + this.height = false
  44 + }
  45 + this.easyPlayer = new WasmPlayer(null, 'easyplayer', this.eventcallbacK, { Height: this.height })
  46 + this.easyPlayer.play(url, 1)
23 47 },
24   - watch:{
25   - videoUrl(newData, oldData){
26   - this.play(newData)
27   - },
28   - immediate:true
29   - },
30   - methods: {
31   - play: function (url) {
32   - console.log(this.height)
33   - if (this.easyPlayer != null) {
34   - this.easyPlayer.destroy();
35   - }
36   - if (typeof (this.height) == "undefined") {
37   - this.height = false
38   - }
39   - this.easyPlayer = new WasmPlayer(null, 'easyplayer', this.eventcallbacK, {Height: this.height})
40   - this.easyPlayer.play(url, 1)
41   - },
42   - pause: function () {
43   - this.easyPlayer.destroy();
44   - this.easyPlayer = null
45   - },
46   - eventcallbacK: function(type, message) {
47   - // console.log("player 事件回调")
48   - // console.log(type)
49   - // console.log(message)
50   - }
51   - },
52   - destroyed() {
  48 + pause: function () {
53 49 this.easyPlayer.destroy();
  50 + this.easyPlayer = null
54 51 },
  52 + eventcallbacK: function (type, message) {
  53 + // console.log("player 事件回调")
  54 + // console.log(type)
  55 + // console.log(message)
  56 + }
  57 + },
  58 + destroyed() {
  59 + this.easyPlayer.destroy();
  60 + },
55 61 }
56 62 </script>
57 63  
58 64 <style>
59   - .LodingTitle {
60   - min-width: 70px;
61   - }
62   - /* 隐藏logo */
63   - .iconqingxiLOGO {
64   - display: none !important;
65   - }
  65 +.LodingTitle {
  66 + min-width: 70px;
  67 +}
66 68  
  69 +/* 隐藏logo */
  70 +.iconqingxiLOGO {
  71 + display: none !important;
  72 +}
67 73 </style>
... ...
web_src/src/components/common/jessibuca.vue
1 1 <template>
2 2 <div ref="container" @dblclick="fullscreenSwich"
3   - style="width:100%; height: 100%; background-color: #000000;margin:0 auto;position: relative;">
  3 + style="width:100%; height: 100%; background-color: #000000;margin:0 auto;position: relative;">
4 4 <div class="buttons-box" id="buttonsBox">
5 5 <div class="buttons-box-left">
6 6 <i v-if="!playing" class="iconfont icon-play jessibuca-btn" @click="playBtnClick"></i>
... ... @@ -14,7 +14,7 @@
14 14 <!-- <i class="iconfont icon-file-record1 jessibuca-btn"></i>-->
15 15 <!-- <i class="iconfont icon-xiangqing2 jessibuca-btn" ></i>-->
16 16 <i class="iconfont icon-camera1196054easyiconnet jessibuca-btn" @click="screenshot"
17   - style="font-size: 1rem !important"></i>
  17 + style="font-size: 1rem !important"></i>
18 18 <i class="iconfont icon-shuaxin11 jessibuca-btn" @click="playBtnClick"></i>
19 19 <i v-if="!fullscreen" class="iconfont icon-weibiaoti10 jessibuca-btn" @click="fullscreenSwich"></i>
20 20 <i v-if="fullscreen" class="iconfont icon-weibiaoti11 jessibuca-btn" @click="fullscreenSwich"></i>
... ... @@ -24,6 +24,9 @@
24 24 </template>
25 25  
26 26 <script>
  27 +import watermark from '../../../utils/waterMark.js';
  28 +import userService from '../service/UserService';
  29 +
27 30 let jessibucaPlayer = {};
28 31 export default {
29 32 name: 'jessibuca',
... ... @@ -43,6 +46,11 @@ export default {
43 46 rotate: 0,
44 47 vod: true, // 点播
45 48 forceNoOffscreen: false,
  49 + watermarkTimer: null,
  50 + config: {
  51 + userName: userService.getUser().username,
  52 + nowTime: "2024-03-01 12:00:00"
  53 + } // 水印
46 54 };
47 55 },
48 56 props: ['videoUrl', 'error', 'hasAudio', 'height'],
... ... @@ -56,6 +64,7 @@ export default {
56 64 this.videoUrl = paramUrl;
57 65 }
58 66 this.btnDom = document.getElementById("buttonsBox");
  67 + this.watermarkTimer = watermark(this.$refs.container, this.config);
59 68 })
60 69 },
61 70 // mounted() {
... ... @@ -140,7 +149,7 @@ export default {
140 149 wcsUseVideoRender: true
141 150 };
142 151 console.log("Jessibuca -> options: ", options);
143   - jessibucaPlayer[this._uid] = new window.Jessibuca({...options});
  152 + jessibucaPlayer[this._uid] = new window.Jessibuca({ ...options });
144 153  
145 154 let jessibuca = jessibucaPlayer[this._uid];
146 155 let _this = this;
... ... @@ -267,6 +276,7 @@ export default {
267 276 this.playing = false;
268 277 this.loaded = false;
269 278 this.performance = "";
  279 + clearInterval(this.watermarkTimer);
270 280 },
271 281 }
272 282 </script>
... ...
web_src/src/components/dialog/rtcPlayer.vue
... ... @@ -2,36 +2,49 @@
2 2 <div id="rtcPlayer">
3 3 <video id='webRtcPlayerBox' controls autoplay style="text-align:left;">
4 4 Your browser is too old which doesn't support HTML5 video.
5   - </video>
  5 + </video>
6 6 </div>
7 7 </template>
8 8  
9 9 <script>
  10 +import watermark from '../../../utils/waterMark.js';
  11 +import userService from '../service/UserService';
10 12 let webrtcPlayer = null;
11 13 export default {
12 14 name: 'rtcPlayer',
13 15 data() {
14 16 return {
15   - timer: null
  17 + timer: null,
  18 + watermarkTimer: null,
  19 + config: {
  20 + userName: userService.getUser().username,
  21 + nowTime: "2024-03-01 12:00:00"
  22 + }
16 23 };
17 24 },
18 25 props: ['videoUrl', 'error', 'hasaudio'],
19   - mounted () {
20   - let paramUrl = decodeURIComponent(this.$route.params.url)
21   - this.$nextTick(() =>{
22   - if (typeof (this.videoUrl) == "undefined") {
23   - this.videoUrl = paramUrl;
24   - }
25   - console.log("初始化时的地址为: " + this.videoUrl)
26   - this.play(this.videoUrl)
  26 + mounted() {
  27 + let paramUrl = decodeURIComponent(this.$route.params.url)
  28 + this.$nextTick(() => {
  29 + if (typeof (this.videoUrl) == "undefined") {
  30 + this.videoUrl = paramUrl;
  31 + }
  32 + console.log("初始化时的地址为: " + this.videoUrl)
  33 + this.play(this.videoUrl)
27 34 })
28 35 },
29   - watch:{
30   - videoUrl(newData, oldData){
  36 + watch: {
  37 + videoUrl(newData, oldData) {
31 38 this.pause();
32 39 this.play(newData);
33 40 },
34   - immediate:true
  41 + immediate: true
  42 + },
  43 + created() {
  44 + this.$nextTick(() => {
  45 + this.rtcPlayer = document.getElementById("rtcPlayer");
  46 + this.watermarkTimer = watermark(this.rtcPlayer, this.config);
  47 + })
35 48 },
36 49 methods: {
37 50 play: function (url) {
... ... @@ -45,22 +58,22 @@ export default {
45 58 videoEnable: true,
46 59 recvOnly: true,
47 60 })
48   - webrtcPlayer.on(ZLMRTCClient.Events.WEBRTC_ICE_CANDIDATE_ERROR,(e)=>{// ICE 协商出错
  61 + webrtcPlayer.on(ZLMRTCClient.Events.WEBRTC_ICE_CANDIDATE_ERROR, (e) => {// ICE 协商出错
49 62 console.error('ICE 协商出错')
50 63 this.eventcallbacK("ICE ERROR", "ICE 协商出错")
51 64 });
52 65  
53   - webrtcPlayer.on(ZLMRTCClient.Events.WEBRTC_ON_REMOTE_STREAMS,(e)=>{//获取到了远端流,可以播放
54   - console.log('播放成功',e.streams)
  66 + webrtcPlayer.on(ZLMRTCClient.Events.WEBRTC_ON_REMOTE_STREAMS, (e) => {//获取到了远端流,可以播放
  67 + console.log('播放成功', e.streams)
55 68 this.eventcallbacK("playing", "播放成功")
56 69 });
57 70  
58   - webrtcPlayer.on(ZLMRTCClient.Events.WEBRTC_OFFER_ANWSER_EXCHANGE_FAILED,(e)=>{// offer anwser 交换失败
59   - console.error('offer anwser 交换失败',e)
  71 + webrtcPlayer.on(ZLMRTCClient.Events.WEBRTC_OFFER_ANWSER_EXCHANGE_FAILED, (e) => {// offer anwser 交换失败
  72 + console.error('offer anwser 交换失败', e)
60 73 this.eventcallbacK("OFFER ANSWER ERROR ", "offer anwser 交换失败")
61   - if (e.code ==-400 && e.msg=="流不存在"){
  74 + if (e.code == -400 && e.msg == "流不存在") {
62 75 console.log("流不存在")
63   - this.timer = setTimeout(()=>{
  76 + this.timer = setTimeout(() => {
64 77 this.webrtcPlayer.close();
65 78 this.play(url)
66 79 }, 100)
... ... @@ -68,7 +81,7 @@ export default {
68 81 }
69 82 });
70 83  
71   - webrtcPlayer.on(ZLMRTCClient.Events.WEBRTC_ON_LOCAL_STREAM,(s)=>{// 获取到了本地流
  84 + webrtcPlayer.on(ZLMRTCClient.Events.WEBRTC_ON_LOCAL_STREAM, (s) => {// 获取到了本地流
72 85  
73 86 // document.getElementById('selfVideo').srcObject=s;
74 87 this.eventcallbacK("LOCAL STREAM", "获取到了本地流")
... ... @@ -82,7 +95,7 @@ export default {
82 95 }
83 96  
84 97 },
85   - eventcallbacK: function(type, message) {
  98 + eventcallbacK: function (type, message) {
86 99 console.log("player 事件回调")
87 100 console.log(type)
88 101 console.log(message)
... ... @@ -90,25 +103,28 @@ export default {
90 103 },
91 104 destroyed() {
92 105 clearTimeout(this.timer);
  106 + clearInterval(this.watermarkTimer);
93 107 },
94 108 }
95 109 </script>
96 110  
97 111 <style>
98   - .LodingTitle {
99   - min-width: 70px;
100   - }
101   - #rtcPlayer{
102   - width: 100%;
103   - }
104   - #webRtcPlayerBox{
105   - width: 100%;
106   - max-height: 56vh;
107   - background-color: #000;
108   - }
109   - /* 隐藏logo */
110   - /* .iconqingxiLOGO {
  112 +.LodingTitle {
  113 + min-width: 70px;
  114 +}
  115 +
  116 +#rtcPlayer {
  117 + width: 100%;
  118 +}
  119 +
  120 +#webRtcPlayerBox {
  121 + width: 100%;
  122 + max-height: 56vh;
  123 + background-color: #000;
  124 +}
  125 +
  126 +/* 隐藏logo */
  127 +/* .iconqingxiLOGO {
111 128 display: none !important;
112 129 } */
113   -
114 130 </style>
... ...
web_src/static/js/config.js
1 1  
2   -window.baseUrl = ""
  2 +window.baseUrl = "https://192.169.1.31:18080"
3 3  
4 4 // map组件全局参数, 注释此内容可以关闭地图功能
5 5 window.mapParam = {
... ...