Commit 9af5ab43af105f458fad7a21814b20824f3157a9

Authored by 648540858
Committed by GitHub
2 parents 36cd31d6 5ab43285

Merge pull request #1 from lawrencehj/master

修正部分错误,简化音频判断逻辑
1 <?xml version="1.0"?> 1 <?xml version="1.0"?>
2 -<project 2 +<project
3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" 3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
4 xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 4 xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
5 <modelVersion>4.0.0</modelVersion> 5 <modelVersion>4.0.0</modelVersion>
@@ -12,7 +12,7 @@ @@ -12,7 +12,7 @@
12 <groupId>com.genersoft</groupId> 12 <groupId>com.genersoft</groupId>
13 <artifactId>wvp</artifactId> 13 <artifactId>wvp</artifactId>
14 <name>web video platform</name> 14 <name>web video platform</name>
15 - 15 +
16 <properties> 16 <properties>
17 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 17 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
18 18
@@ -42,15 +42,15 @@ @@ -42,15 +42,15 @@
42 <artifactId>spring-boot-starter-tomcat</artifactId> 42 <artifactId>spring-boot-starter-tomcat</artifactId>
43 </dependency> 43 </dependency>
44 <dependency> 44 <dependency>
45 - <groupId>org.springframework.boot</groupId>  
46 - <artifactId>spring-boot-starter-web</artifactId>  
47 - </dependency> 45 + <groupId>org.springframework.boot</groupId>
  46 + <artifactId>spring-boot-starter-web</artifactId>
  47 + </dependency>
48 <dependency> 48 <dependency>
49 - <groupId>org.springframework</groupId>  
50 - <artifactId>spring-context</artifactId>  
51 - </dependency>  
52 -  
53 - 49 + <groupId>org.springframework</groupId>
  50 + <artifactId>spring-context</artifactId>
  51 + </dependency>
  52 +
  53 +
54 <!-- druid --> 54 <!-- druid -->
55 <dependency> 55 <dependency>
56 <groupId>com.alibaba</groupId> 56 <groupId>com.alibaba</groupId>
@@ -62,7 +62,7 @@ @@ -62,7 +62,7 @@
62 <artifactId>mysql-connector-java</artifactId> 62 <artifactId>mysql-connector-java</artifactId>
63 <version>5.1.30</version> 63 <version>5.1.30</version>
64 </dependency> 64 </dependency>
65 - 65 +
66 <!--Mybatis --> 66 <!--Mybatis -->
67 <dependency> 67 <dependency>
68 <groupId>org.mybatis</groupId> 68 <groupId>org.mybatis</groupId>
@@ -74,7 +74,7 @@ @@ -74,7 +74,7 @@
74 <artifactId>mybatis-spring</artifactId> 74 <artifactId>mybatis-spring</artifactId>
75 <version>${mybatis.spring.version}</version> 75 <version>${mybatis.spring.version}</version>
76 </dependency> 76 </dependency>
77 - 77 +
78 <!--分页插件 --> 78 <!--分页插件 -->
79 <dependency> 79 <dependency>
80 <groupId>com.github.pagehelper</groupId> 80 <groupId>com.github.pagehelper</groupId>
@@ -99,7 +99,7 @@ @@ -99,7 +99,7 @@
99 <artifactId>fastjson</artifactId> 99 <artifactId>fastjson</artifactId>
100 <version>1.2.33</version> 100 <version>1.2.33</version>
101 </dependency> 101 </dependency>
102 - 102 +
103 <!--Swagger2 --> 103 <!--Swagger2 -->
104 <!--在线文档 --> 104 <!--在线文档 -->
105 <dependency> 105 <dependency>
@@ -112,13 +112,13 @@ @@ -112,13 +112,13 @@
112 <artifactId>springfox-swagger-ui</artifactId> 112 <artifactId>springfox-swagger-ui</artifactId>
113 <version>2.6.1</version> 113 <version>2.6.1</version>
114 </dependency> 114 </dependency>
115 - 115 +
116 <!-- 日志相关 --> 116 <!-- 日志相关 -->
117 <dependency> 117 <dependency>
118 <groupId>org.springframework.boot</groupId> 118 <groupId>org.springframework.boot</groupId>
119 <artifactId>spring-boot-starter-aop</artifactId> 119 <artifactId>spring-boot-starter-aop</artifactId>
120 </dependency> 120 </dependency>
121 - 121 +
122 <dependency> 122 <dependency>
123 <groupId>javax.sip</groupId> 123 <groupId>javax.sip</groupId>
124 <artifactId>jain-sip-ri</artifactId> 124 <artifactId>jain-sip-ri</artifactId>
src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java
@@ -103,7 +103,7 @@ public class SipLayer implements SipListener { @@ -103,7 +103,7 @@ public class SipLayer implements SipListener {
103 ListeningPoint udpListeningPoint = sipStack.createListeningPoint(sipConfig.getSipIp(), sipConfig.getSipPort(), "UDP"); 103 ListeningPoint udpListeningPoint = sipStack.createListeningPoint(sipConfig.getSipIp(), sipConfig.getSipPort(), "UDP");
104 SipProvider udpSipProvider = sipStack.createSipProvider(udpListeningPoint); 104 SipProvider udpSipProvider = sipStack.createSipProvider(udpListeningPoint);
105 udpSipProvider.addSipListener(this); 105 udpSipProvider.addSipListener(this);
106 - logger.info("Sip Server TCP 启动成功 port {" + sipConfig.getSipPort() + "}"); 106 + logger.info("Sip Server UDP 启动成功 port {" + sipConfig.getSipPort() + "}");
107 return udpSipProvider; 107 return udpSipProvider;
108 } 108 }
109 109
src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/OfflineEventListener.java
@@ -54,7 +54,5 @@ public class OfflineEventListener implements ApplicationListener&lt;OfflineEvent&gt; { @@ -54,7 +54,5 @@ public class OfflineEventListener implements ApplicationListener&lt;OfflineEvent&gt; {
54 54
55 // 处理离线监听 55 // 处理离线监听
56 storager.outline(event.getDeviceId()); 56 storager.outline(event.getDeviceId());
57 -  
58 - //  
59 } 57 }
60 } 58 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
@@ -203,7 +203,7 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor { @@ -203,7 +203,7 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
203 deviceChannel.setLongitude(itemDevice.element("Longitude") == null? 0.00:Double.parseDouble(XmlUtil.getText(itemDevice,"Longitude"))); 203 deviceChannel.setLongitude(itemDevice.element("Longitude") == null? 0.00:Double.parseDouble(XmlUtil.getText(itemDevice,"Longitude")));
204 deviceChannel.setLatitude(itemDevice.element("Latitude") == null? 0.00:Double.parseDouble(XmlUtil.getText(itemDevice,"Latitude"))); 204 deviceChannel.setLatitude(itemDevice.element("Latitude") == null? 0.00:Double.parseDouble(XmlUtil.getText(itemDevice,"Latitude")));
205 deviceChannel.setPTZType(itemDevice.element("PTZType") == null? 0:Integer.parseInt(XmlUtil.getText(itemDevice,"PTZType"))); 205 deviceChannel.setPTZType(itemDevice.element("PTZType") == null? 0:Integer.parseInt(XmlUtil.getText(itemDevice,"PTZType")));
206 - deviceChannel.setHasAudio(false); // 默认含有音频为false 206 + deviceChannel.setHasAudio(true); // 默认含有音频,播放时再检查是否有音频及是否AAC
207 storager.updateChannel(device.getDeviceId(), deviceChannel); 207 storager.updateChannel(device.getDeviceId(), deviceChannel);
208 } 208 }
209 209
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMUtils.java
@@ -36,7 +36,7 @@ public class ZLMUtils { @@ -36,7 +36,7 @@ public class ZLMUtils {
36 System.out.println(newPort); 36 System.out.println(newPort);
37 System.out.println(jsonObject.toJSONString()); 37 System.out.println(jsonObject.toJSONString());
38 return newPort; 38 return newPort;
39 - }else { 39 + } else {
40 return getNewRTPPort(ssrc); 40 return getNewRTPPort(ssrc);
41 } 41 }
42 } 42 }
@@ -48,11 +48,14 @@ public class ZLMUtils { @@ -48,11 +48,14 @@ public class ZLMUtils {
48 udpPortRangeArray[1] = Integer.parseInt(udpPortRangeStrArray[1]); 48 udpPortRangeArray[1] = Integer.parseInt(udpPortRangeStrArray[1]);
49 } 49 }
50 50
51 - if (currentPort == 0 || currentPort ++ > udpPortRangeArray[1]) { 51 + if (currentPort == 0 || currentPort++ > udpPortRangeArray[1]) {
52 currentPort = udpPortRangeArray[0]; 52 currentPort = udpPortRangeArray[0];
53 return udpPortRangeArray[0]; 53 return udpPortRangeArray[0];
54 - }else {  
55 - return currentPort ++; 54 + } else {
  55 + if (currentPort % 2 == 1) {
  56 + currentPort++;
  57 + }
  58 + return currentPort++;
56 } 59 }
57 } 60 }
58 } 61 }
src/main/resources/application.yml
@@ -46,6 +46,6 @@ media: #zlm服务器的ip与http端口, 重点: 这是http端口 @@ -46,6 +46,6 @@ media: #zlm服务器的ip与http端口, 重点: 这是http端口
46 streamNoneReaderDelayMS: 1800000 # 无人观看多久自动关闭流 46 streamNoneReaderDelayMS: 1800000 # 无人观看多久自动关闭流
47 rtp: # 启用udp多端口模式 47 rtp: # 启用udp多端口模式
48 enable: true 48 enable: true
49 - udpPortRange: 30000,300500 # 端口范围 49 + udpPortRange: 30000,30500 # 端口范围
50 50
51 51
web_src/index.html
@@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
3 <head> 3 <head>
4 <meta charset="utf-8"> 4 <meta charset="utf-8">
5 <meta name="viewport" content="width=device-width,initial-scale=1.0"> 5 <meta name="viewport" content="width=device-width,initial-scale=1.0">
6 - <title>gb_web</title> 6 + <title>GB28181·þÎñÆ÷</title>
7 </head> 7 </head>
8 <body> 8 <body>
9 <script type="text/javascript" src="./js/liveplayer-lib.min.js"></script> 9 <script type="text/javascript" src="./js/liveplayer-lib.min.js"></script>
web_src/src/components/channelList.vue
1 <template> 1 <template>
2 - <div id="channelList">  
3 - <el-container> 2 +<div id="channelList">
  3 + <el-container>
4 4
5 - <el-header>  
6 - <uiHeader></uiHeader>  
7 - </el-header>  
8 - <el-main>  
9 - <div style="background-color: #FFFFFF; position: relative; padding: 1rem 0.5rem 0.5rem 0.5rem; text-align: center;">  
10 - <span style="font-size: 1rem; font-weight: 500; ">通道列表({{parentChannelId ==0 ? deviceId:parentChannelId}})</span> 5 + <el-header>
  6 + <uiHeader></uiHeader>
  7 + </el-header>
  8 + <el-main>
  9 + <div style="background-color: #FFFFFF; position: relative; padding: 1rem 0.5rem 0.5rem 0.5rem; text-align: center;">
  10 + <span style="font-size: 1rem; font-weight: 500; ">通道列表({{parentChannelId ==0 ? deviceId:parentChannelId}})</span>
11 11
12 - </div>  
13 - <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;font-size: 14px;">  
14 - <el-button icon="el-icon-arrow-left" size="mini" style="margin-right: 1rem;" @click="showDevice">返回</el-button>  
15 - 搜索: <el-input @input="search" style="margin-right: 1rem; width: auto;" size="mini" placeholder="关键字" prefix-icon="el-icon-search" v-model="searchSrt" clearable> </el-input> 12 + </div>
  13 + <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;font-size: 14px;">
  14 + <el-button icon="el-icon-arrow-left" size="mini" style="margin-right: 1rem;" type="primary" @click="showDevice">返回</el-button>
  15 + 搜索: <el-input @input="search" style="margin-right: 1rem; width: auto;" size="mini" placeholder="关键字" prefix-icon="el-icon-search" v-model="searchSrt" clearable> </el-input>
16 16
17 - 通道类型: <el-select size="mini" @change="search" style="margin-right: 1rem;" v-model="channelType" placeholder="请选择" default-first-option>  
18 - <el-option label="全部" value="" ></el-option>  
19 - <el-option label="设备" value="false"></el-option>  
20 - <el-option label="子目录" value="true" ></el-option>  
21 - </el-select>  
22 - 在线状态: <el-select size="mini" @change="search" v-model="online" placeholder="请选择" default-first-option>  
23 - <el-option label="全部" value=""></el-option>  
24 - <el-option label="在线" value="on"></el-option>  
25 - <el-option label="离线" value="off"></el-option>  
26 - </el-select> 17 + 通道类型: <el-select size="mini" @change="search" style="margin-right: 1rem;" v-model="channelType" placeholder="请选择" default-first-option>
  18 + <el-option label="全部" value=""></el-option>
  19 + <el-option label="设备" value="false"></el-option>
  20 + <el-option label="子目录" value="true"></el-option>
  21 + </el-select>
  22 + 在线状态: <el-select size="mini" @change="search" v-model="online" placeholder="请选择" default-first-option>
  23 + <el-option label="全部" value=""></el-option>
  24 + <el-option label="在线" value="on"></el-option>
  25 + <el-option label="离线" value="off"></el-option>
  26 + </el-select>
27 27
28 - </div>  
29 - <devicePlayer ref="devicePlayer"></devicePlayer>  
30 - <!--设备列表-->  
31 - <el-table ref="channelListTable" :data="deviceChannelList" :height="winHeight" border style="width: 100%">  
32 - <el-table-column prop="channelId" label="通道编号" width="210">  
33 - </el-table-column>  
34 - <el-table-column prop="name" label="通道名称">  
35 - </el-table-column>  
36 - <el-table-column prop="subCount" label="子节点数">  
37 - </el-table-column>  
38 - <el-table-column label="开启音频" align="center">  
39 - <template slot-scope="scope">  
40 - <el-switch  
41 - @change="updateChannel(scope.row)"  
42 - v-model="scope.row.hasAudio"  
43 - active-color="#409EFF">  
44 - </el-switch>  
45 - </template>  
46 - </el-table-column>  
47 - <el-table-column label="状态" width="180" align="center">  
48 - <template slot-scope="scope">  
49 - <div slot="reference" class="name-wrapper">  
50 - <el-tag size="medium" v-if="scope.row.status == 1">在线</el-tag>  
51 - <el-tag size="medium" type="info" v-if="scope.row.status == 0">离线</el-tag>  
52 - </div>  
53 - </template>  
54 - </el-table-column>  
55 - <el-table-column prop="ptztypeText" label="云台类型">  
56 - </el-table-column>  
57 - <el-table-column label="操作" width="280" align="center" fixed="right">  
58 - <template slot-scope="scope">  
59 - <el-button-group>  
60 - <el-button size="mini" icon="el-icon-video-play" v-if="scope.row.parental == 0" @click="sendDevicePush(scope.row)">播放</el-button>  
61 - <el-button size="mini" icon="el-icon-switch-button" type="danger" v-if="scope.row.play" @click="stopDevicePush(scope.row)">停止</el-button>  
62 - <el-button size="mini" icon="el-icon-s-open" type="primary" v-if="scope.row.parental == 1" @click="changeSubchannel(scope.row)">查看</el-button>  
63 -<!-- <el-button size="mini" icon="el-icon-video-camera" type="primary" >设备录象</el-button>-->  
64 - <!-- <el-button size="mini" @click="sendDevicePush(scope.row)">录像查询</el-button> -->  
65 - </el-button-group>  
66 - </template>  
67 - </el-table-column>  
68 - </el-table>  
69 - <el-pagination  
70 - style="float: right"  
71 - @size-change="handleSizeChange"  
72 - @current-change="currentChange"  
73 - :current-page="currentPage"  
74 - :page-size="count"  
75 - :page-sizes="[15, 20, 30, 50]"  
76 - layout="total, sizes, prev, pager, next"  
77 - :total="total">  
78 - </el-pagination> 28 + </div>
  29 + <devicePlayer ref="devicePlayer"></devicePlayer>
  30 + <!--设备列表-->
  31 + <el-table ref="channelListTable" :data="deviceChannelList" :height="winHeight" border style="width: 100%">
  32 + <el-table-column prop="channelId" label="通道编号" width="210">
  33 + </el-table-column>
  34 + <el-table-column prop="name" label="通道名称">
  35 + </el-table-column>
  36 + <el-table-column prop="subCount" label="子节点数">
  37 + </el-table-column>
  38 + <el-table-column label="开启音频" align="center">
  39 + <template slot-scope="scope">
  40 + <el-switch @change="updateChannel(scope.row)" v-model="scope.row.hasAudio" active-color="#409EFF">
  41 + </el-switch>
  42 + </template>
  43 + </el-table-column>
  44 + <el-table-column label="状态" width="180" align="center">
  45 + <template slot-scope="scope">
  46 + <div slot="reference" class="name-wrapper">
  47 + <el-tag size="medium" v-if="scope.row.status == 1">在线</el-tag>
  48 + <el-tag size="medium" type="info" v-if="scope.row.status == 0">离线</el-tag>
  49 + </div>
  50 + </template>
  51 + </el-table-column>
  52 + <el-table-column prop="ptztypeText" label="云台类型">
  53 + </el-table-column>
  54 + <el-table-column label="操作" width="280" align="center" fixed="right">
  55 + <template slot-scope="scope">
  56 + <el-button-group>
  57 + <el-button size="mini" icon="el-icon-video-play" v-if="scope.row.parental == 0" @click="sendDevicePush(scope.row)">播放</el-button>
  58 + <el-button size="mini" icon="el-icon-switch-button" type="danger" v-if="scope.row.play" @click="stopDevicePush(scope.row)">停止</el-button>
  59 + <el-button size="mini" icon="el-icon-s-open" type="primary" v-if="scope.row.parental == 1" @click="changeSubchannel(scope.row)">查看</el-button>
  60 + <!-- <el-button size="mini" icon="el-icon-video-camera" type="primary" >设备录象</el-button>-->
  61 + <!-- <el-button size="mini" @click="sendDevicePush(scope.row)">录像查询</el-button> -->
  62 + </el-button-group>
  63 + </template>
  64 + </el-table-column>
  65 + </el-table>
  66 + <el-pagination style="float: right" @size-change="handleSizeChange" @current-change="currentChange" :current-page="currentPage" :page-size="count" :page-sizes="[15, 20, 30, 50]" layout="total, sizes, prev, pager, next" :total="total">
  67 + </el-pagination>
79 68
80 - </el-main>  
81 - </el-container> 69 + </el-main>
  70 + </el-container>
82 <Loading v-if="isLoging" marginTop="-50%"></Loading> 71 <Loading v-if="isLoging" marginTop="-50%"></Loading>
83 - </div> 72 +</div>
84 </template> 73 </template>
85 74
86 <script> 75 <script>
87 - import devicePlayer from './gb28181/devicePlayer.vue'  
88 - import uiHeader from './UiHeader.vue'  
89 - import Loading from './Loading.vue'  
90 - export default {  
91 - name: 'channelList',  
92 - components: {  
93 - devicePlayer,  
94 - uiHeader,  
95 - Loading  
96 - },  
97 - data() {  
98 - return {  
99 - deviceId: this.$route.params.deviceId,  
100 - parentChannelId: this.$route.params.parentChannelId,  
101 - deviceChannelList: [],  
102 - videoComponentList: [],  
103 - currentPlayerInfo: {}, //当前播放对象  
104 - updateLooper: 0, //数据刷新轮训标志  
105 - searchSrt: "",  
106 - channelType: "",  
107 - online: "",  
108 - winHeight: window.innerHeight - 250,  
109 - currentPage: parseInt(this.$route.params.page),  
110 - count: parseInt(this.$route.params.count),  
111 - total:0,  
112 - beforeUrl:"/videoList",  
113 - isLoging: false  
114 - };  
115 - }, 76 +import devicePlayer from './gb28181/devicePlayer.vue'
  77 +import uiHeader from './UiHeader.vue'
  78 +import Loading from './Loading.vue'
  79 +export default {
  80 + name: 'channelList',
  81 + components: {
  82 + devicePlayer,
  83 + uiHeader,
  84 + Loading
  85 + },
  86 + data() {
  87 + return {
  88 + deviceId: this.$route.params.deviceId,
  89 + parentChannelId: this.$route.params.parentChannelId,
  90 + deviceChannelList: [],
  91 + videoComponentList: [],
  92 + currentPlayerInfo: {}, //当前播放对象
  93 + updateLooper: 0, //数据刷新轮训标志
  94 + searchSrt: "",
  95 + channelType: "",
  96 + online: "",
  97 + winHeight: window.innerHeight - 250,
  98 + currentPage: parseInt(this.$route.params.page),
  99 + count: parseInt(this.$route.params.count),
  100 + total: 0,
  101 + beforeUrl: "/videoList",
  102 + isLoging: false
  103 + };
  104 + },
116 105
117 - mounted() {  
118 - this.initData();  
119 - // this.updateLooper = setInterval(this.initData, 10000);  
120 - },  
121 - destroyed() {  
122 - this.$destroy('videojs');  
123 - clearTimeout(this.updateLooper);  
124 - },  
125 - methods: {  
126 - initData: function() {  
127 - if (this.parentChannelId == "" || this.parentChannelId == 0 ) {  
128 - this.getDeviceChannelList();  
129 - }else{  
130 - this.showSubchannels();  
131 - } 106 + mounted() {
  107 + this.initData();
  108 + // this.updateLooper = setInterval(this.initData, 10000);
  109 + },
  110 + destroyed() {
  111 + this.$destroy('videojs');
  112 + clearTimeout(this.updateLooper);
  113 + },
  114 + methods: {
  115 + initData: function () {
  116 + if (this.parentChannelId == "" || this.parentChannelId == 0) {
  117 + this.getDeviceChannelList();
  118 + } else {
  119 + this.showSubchannels();
  120 + }
132 121
133 - },  
134 - initParam: function(){  
135 - this.deviceId= this.$route.params.deviceId;  
136 - this.parentChannelId= this.$route.params.parentChannelId;  
137 - this.currentPage= parseInt(this.$route.params.page);  
138 - this.count= parseInt(this.$route.params.count);  
139 - if (this.parentChannelId == "" || this.parentChannelId == 0 ) {  
140 - this.beforeUrl = "/videoList"  
141 - } 122 + },
  123 + initParam: function () {
  124 + this.deviceId = this.$route.params.deviceId;
  125 + this.parentChannelId = this.$route.params.parentChannelId;
  126 + this.currentPage = parseInt(this.$route.params.page);
  127 + this.count = parseInt(this.$route.params.count);
  128 + if (this.parentChannelId == "" || this.parentChannelId == 0) {
  129 + this.beforeUrl = "/videoList"
  130 + }
142 131
143 - },  
144 - currentChange: function(val){  
145 - var url = `/${this.$router.currentRoute.name}/${this.deviceId}/${this.parentChannelId}/${this.count}/${val}`  
146 - console.log(url)  
147 - this.$router.push(url).then(()=>{  
148 - this.initParam();  
149 - this.initData();  
150 - })  
151 - },  
152 - handleSizeChange: function(val){  
153 - var url = `/${this.$router.currentRoute.name}/${this.$router.params.deviceId}/${this.$router.params.parentChannelId}/${val}/1`  
154 - this.$router.push(url).then(()=>{  
155 - this.initParam();  
156 - this.initData();  
157 - }) 132 + },
  133 + currentChange: function (val) {
  134 + var url = `/${this.$router.currentRoute.name}/${this.deviceId}/${this.parentChannelId}/${this.count}/${val}`
  135 + console.log(url)
  136 + this.$router.push(url).then(() => {
  137 + this.initParam();
  138 + this.initData();
  139 + })
  140 + },
  141 + handleSizeChange: function (val) {
  142 + var url = `/${this.$router.currentRoute.name}/${this.$router.params.deviceId}/${this.$router.params.parentChannelId}/${val}/1`
  143 + this.$router.push(url).then(() => {
  144 + this.initParam();
  145 + this.initData();
  146 + })
158 147
159 - },  
160 - getDeviceChannelList: function() {  
161 - let that = this;  
162 - console.log(this.currentPage - 1) 148 + },
  149 + getDeviceChannelList: function () {
  150 + let that = this;
  151 + console.log(this.currentPage - 1)
163 152
164 - this.$axios.get(`/api/devices/${this.$route.params.deviceId}/channels`,{  
165 - params: {  
166 - page: that.currentPage - 1,  
167 - count: that.count,  
168 - query: that.searchSrt,  
169 - online: that.online,  
170 - channelType: that.channelType  
171 - }  
172 - } )  
173 - .then(function (res) {  
174 - console.log(res);  
175 - that.total = res.data.total;  
176 - that.deviceChannelList = res.data.data;  
177 - // 防止出现表格错位  
178 - that.$nextTick(()=>{  
179 - that.$refs.channelListTable.doLayout();  
180 - })  
181 - })  
182 - .catch(function (error) {  
183 - console.log(error);  
184 - }); 153 + this.$axios.get(`/api/devices/${this.$route.params.deviceId}/channels`, {
  154 + params: {
  155 + page: that.currentPage - 1,
  156 + count: that.count,
  157 + query: that.searchSrt,
  158 + online: that.online,
  159 + channelType: that.channelType
  160 + }
  161 + })
  162 + .then(function (res) {
  163 + console.log(res);
  164 + that.total = res.data.total;
  165 + that.deviceChannelList = res.data.data;
  166 + // 防止出现表格错位
  167 + that.$nextTick(() => {
  168 + that.$refs.channelListTable.doLayout();
  169 + })
  170 + })
  171 + .catch(function (error) {
  172 + console.log(error);
  173 + });
185 174
186 - }, 175 + },
187 176
  177 + //gb28181平台对接
  178 + //刷新设备信息
  179 + refDevice: function (itemData) {
  180 + ///api/devices/{deviceId}/sync
  181 + console.log("刷新对应设备:" + itemData.deviceId);
  182 + this.$axios({
  183 + method: 'post',
  184 + url: '/api/devices/' + itemData.deviceId + '/sync'
  185 + }).then(function (res) {
  186 + // console.log("刷新设备结果:"+JSON.stringify(res));
  187 + }).catch(function (e) {
  188 + that.$message({
  189 + showClose: true,
  190 + message: '请求成功',
  191 + type: 'success'
  192 + });
  193 + });
  194 + },
  195 + //通知设备上传媒体流
  196 + sendDevicePush: function (itemData) {
  197 + console.log(itemData)
  198 + let deviceId = this.deviceId;
  199 + this.isLoging = true;
  200 + let channelId = itemData.channelId;
  201 + console.log("通知设备推流1:" + deviceId + " : " + channelId);
  202 + let that = this;
  203 + this.$axios({
  204 + method: 'get',
  205 + url: '/api/play/' + deviceId + '/' + channelId
  206 + }).then(function (res) {
  207 + console.log(res.data)
  208 + let ssrc = res.data.ssrc;
  209 + that.isLoging = false;
  210 + if (!!ssrc) {
  211 + that.$refs.devicePlayer.play(res.data, deviceId, channelId, itemData.hasAudio);
  212 + that.initData();
  213 + } else {
  214 + that.$message.error(res.data);
  215 + }
  216 + }).catch(function (e) {});
  217 + },
  218 + stopDevicePush: function (itemData) {
  219 + console.log(itemData)
  220 + var that = this;
  221 + this.$axios({
  222 + method: 'post',
  223 + url: '/api/play/' + itemData.ssrc + '/stop'
  224 + }).then(function (res) {
  225 + console.log(JSON.stringify(res));
  226 + that.initData();
  227 + });
  228 + },
188 229
189 - //gb28181平台对接  
190 - //刷新设备信息  
191 - refDevice: function(itemData) {  
192 - ///api/devices/{deviceId}/sync  
193 - console.log("刷新对应设备:" + itemData.deviceId);  
194 - this.$axios({  
195 - method: 'post',  
196 - url: '/api/devices/' + itemData.deviceId + '/sync'  
197 - }).then(function(res) {  
198 - // console.log("刷新设备结果:"+JSON.stringify(res));  
199 - }).catch(function(e) {  
200 - that.$message({  
201 - showClose: true,  
202 - message: '请求成功',  
203 - type: 'success'  
204 - });  
205 - });  
206 - },  
207 - //通知设备上传媒体流  
208 - sendDevicePush: function(itemData) {  
209 - console.log(itemData)  
210 - let deviceId = this.deviceId;  
211 - this.isLoging = true;  
212 - let channelId = itemData.channelId;  
213 - console.log("通知设备推流1:" + deviceId + " : " + channelId);  
214 - let that = this;  
215 - this.$axios({  
216 - method: 'get',  
217 - url: '/api/play/' + deviceId + '/' + channelId  
218 - }).then(function(res) {  
219 - console.log(res.data)  
220 - let ssrc = res.data.ssrc;  
221 - that.isLoging = false  
222 - if (!!ssrc) {  
223 - that.$refs.devicePlayer.play(res.data,deviceId,channelId,itemData.hasAudio);  
224 - that.initData();  
225 - }else {  
226 - that.$message.error(res.data);  
227 - }  
228 - }).catch(function(e) {  
229 - });  
230 - },  
231 - stopDevicePush: function(itemData) {  
232 - console.log(itemData)  
233 - var that = this;  
234 - this.$axios({  
235 - method: 'post',  
236 - url: '/api/play/' + itemData.ssrc + '/stop'  
237 - }).then(function(res) {  
238 - console.log(JSON.stringify(res));  
239 - that.initData();  
240 - });  
241 - }, 230 + showDevice: function () {
  231 + this.$router.push(this.beforeUrl).then(() => {
  232 + this.initParam();
  233 + this.initData();
  234 + })
  235 + },
  236 + changeSubchannel(itemData) {
  237 + console.log(this.$router.currentRoute)
  238 + this.beforeUrl = this.$router.currentRoute.path;
242 239
243 - showDevice: function(){  
244 - this.$router.push(this.beforeUrl).then(()=>{  
245 - this.initParam();  
246 - this.initData();  
247 - })  
248 - },  
249 - changeSubchannel(itemData) {  
250 - console.log(this.$router.currentRoute)  
251 - this.beforeUrl = this.$router.currentRoute.path; 240 + var url = `/${this.$router.currentRoute.name}/${this.$router.currentRoute.params.deviceId}/${itemData.channelId}/${this.$router.currentRoute.params.count}/1`
  241 + this.$router.push(url).then(() => {
  242 + this.searchSrt = "";
  243 + this.channelType = "";
  244 + this.online = "";
  245 + this.initParam();
  246 + this.initData();
  247 + })
  248 + },
  249 + showSubchannels: function (channelId) {
  250 + let that = this;
252 251
253 - var url = `/${this.$router.currentRoute.name}/${this.$router.currentRoute.params.deviceId}/${itemData.channelId}/${this.$router.currentRoute.params.count}/1`  
254 - this.$router.push(url).then(()=>{  
255 - this.searchSrt= "";  
256 - this.channelType= "";  
257 - this.online= "";  
258 - this.initParam();  
259 - this.initData();  
260 - })  
261 - },  
262 - showSubchannels: function(channelId){  
263 - let that = this; 252 + this.$axios.get(`/api/subChannels/${this.deviceId}/${this.parentChannelId}/channels`, {
  253 + params: {
  254 + page: that.currentPage - 1,
  255 + count: that.count,
  256 + query: that.searchSrt,
  257 + online: that.online,
  258 + channelType: that.channelType
  259 + }
  260 + })
  261 + .then(function (res) {
  262 + that.total = res.data.total;
  263 + that.deviceChannelList = res.data.data;
  264 + // 防止出现表格错位
  265 + that.$nextTick(() => {
  266 + that.$refs.channelListTable.doLayout();
  267 + })
  268 + })
  269 + .catch(function (error) {
  270 + console.log(error);
  271 + });
  272 + },
  273 + search: function () {
  274 + console.log(this.searchSrt)
  275 + this.currentPage = 1;
  276 + this.total = 0;
  277 + this.initData();
  278 + },
  279 + updateChannel: function (row) {
  280 + console.log(row)
  281 + this.$axios({
  282 + method: 'post',
  283 + url: `/api/channel/update/${this.deviceId}`,
  284 + params: row
  285 + }).then(function (res) {
  286 + console.log(JSON.stringify(res));
  287 + });
  288 + }
264 289
265 - this.$axios.get(`/api/subChannels/${this.deviceId}/${this.parentChannelId}/channels`,{  
266 - params: {  
267 - page: that.currentPage - 1,  
268 - count: that.count,  
269 - query: that.searchSrt,  
270 - online: that.online,  
271 - channelType: that.channelType  
272 - }  
273 - } )  
274 - .then(function (res) {  
275 - that.total = res.data.total;  
276 - that.deviceChannelList = res.data.data;  
277 - // 防止出现表格错位  
278 - that.$nextTick(()=>{  
279 - that.$refs.channelListTable.doLayout();  
280 - })  
281 - })  
282 - .catch(function (error) {  
283 - console.log(error);  
284 - });  
285 - },  
286 - search: function() {  
287 - console.log(this.searchSrt)  
288 - this.currentPage = 1;  
289 - this.total = 0;  
290 - this.initData();  
291 - },  
292 - updateChannel: function(row) {  
293 - console.log(row)  
294 - this.$axios({  
295 - method: 'post',  
296 - url: `/api/channel/update/${this.deviceId}`,  
297 - params: row  
298 - }).then(function(res) {  
299 - console.log(JSON.stringify(res));  
300 - });  
301 - }  
302 -  
303 - }  
304 - }; 290 + }
  291 +};
305 </script> 292 </script>
306 293
307 <style> 294 <style>
308 - .videoList {  
309 - display: flex;  
310 - flex-wrap: wrap;  
311 - align-content: flex-start;  
312 - } 295 +.videoList {
  296 + display: flex;
  297 + flex-wrap: wrap;
  298 + align-content: flex-start;
  299 +}
313 300
314 - .video-item {  
315 - position: relative;  
316 - width: 15rem;  
317 - height: 10rem;  
318 - margin-right: 1rem;  
319 - background-color: #000000;  
320 - } 301 +.video-item {
  302 + position: relative;
  303 + width: 15rem;
  304 + height: 10rem;
  305 + margin-right: 1rem;
  306 + background-color: #000000;
  307 +}
321 308
322 - .video-item-img {  
323 - position: absolute;  
324 - top: 0;  
325 - bottom: 0;  
326 - left: 0;  
327 - right: 0;  
328 - margin: auto;  
329 - width: 100%;  
330 - height: 100%;  
331 - } 309 +.video-item-img {
  310 + position: absolute;
  311 + top: 0;
  312 + bottom: 0;
  313 + left: 0;
  314 + right: 0;
  315 + margin: auto;
  316 + width: 100%;
  317 + height: 100%;
  318 +}
332 319
333 - .video-item-img:after {  
334 - content: "";  
335 - display: inline-block;  
336 - position: absolute;  
337 - z-index: 2;  
338 - top: 0;  
339 - bottom: 0;  
340 - left: 0;  
341 - right: 0;  
342 - margin: auto;  
343 - width: 3rem;  
344 - height: 3rem;  
345 - background-image: url("../assets/loading.png");  
346 - background-size: cover;  
347 - background-color: #000000;  
348 - } 320 +.video-item-img:after {
  321 + content: "";
  322 + display: inline-block;
  323 + position: absolute;
  324 + z-index: 2;
  325 + top: 0;
  326 + bottom: 0;
  327 + left: 0;
  328 + right: 0;
  329 + margin: auto;
  330 + width: 3rem;
  331 + height: 3rem;
  332 + background-image: url("../assets/loading.png");
  333 + background-size: cover;
  334 + background-color: #000000;
  335 +}
349 336
350 - .video-item-title {  
351 - position: absolute;  
352 - bottom: 0;  
353 - color: #000000;  
354 - background-color: #ffffff;  
355 - line-height: 1.5rem;  
356 - padding: 0.3rem;  
357 - width: 14.4rem;  
358 - } 337 +.video-item-title {
  338 + position: absolute;
  339 + bottom: 0;
  340 + color: #000000;
  341 + background-color: #ffffff;
  342 + line-height: 1.5rem;
  343 + padding: 0.3rem;
  344 + width: 14.4rem;
  345 +}
359 </style> 346 </style>
web_src/src/components/gb28181/devicePlayer.vue
1 <template> 1 <template>
2 - <div id="devicePlayer">  
3 - <el-dialog title="视频播放" top="0" :visible.sync="showVideoDialog" :destroy-on-close="true" @close="close()">  
4 - <LivePlayer v-if="showVideoDialog" ref="videoPlayer" :videoUrl="videoUrl" :error="videoError" :hasaudio="hasaudio" fluent autoplay live ></LivePlayer>  
5 - <div id="shared" style="text-align: right; margin-top: 1rem;">  
6 - <el-tabs v-model="tabActiveName">  
7 - <el-tab-pane label="媒体流信息" name="media">  
8 - <div style="margin-bottom: 0.5rem;">  
9 - <el-button type="primary" size="small" @click="playRecord(true, '')">播放</el-button>  
10 - <el-button type="primary" size="small" @click="startRecord()">录制</el-button>  
11 - <el-button type="primary" size="small" @click="stopRecord()">停止录制</el-button>  
12 - </div>  
13 - <div style="display: flex; margin-bottom: 0.5rem; height: 2.5rem;">  
14 - <span style="width: 5rem; line-height: 2.5rem; text-align: right;">播放地址:</span>  
15 - <el-input v-model="getPlayerShared.sharedUrl" :disabled="true" v-on:click.native="copySharedInfo(getPlayerShared.sharedUrl)"></el-input>  
16 - </div>  
17 - <div style="display: flex; margin-bottom: 0.5rem; height: 2.5rem;">  
18 - <span style="width: 5rem; line-height: 2.5rem; text-align: right;">iframe:</span>  
19 - <el-input v-model="getPlayerShared.sharedIframe" :disabled="true" v-on:click.native="copySharedInfo(getPlayerShared.sharedIframe)"></el-input>  
20 - </div>  
21 - <div style="display: flex; margin-bottom: 0.5rem; height: 2.5rem;">  
22 - <span style="width: 5rem; line-height: 2.5rem; text-align: right;">资源地址:</span>  
23 - <el-input v-model="getPlayerShared.sharedRtmp" :disabled="true" v-on:click.native="copySharedInfo(getPlayerShared.sharedRtmp)"></el-input>  
24 - </div>  
25 - </el-tab-pane>  
26 - <!--{"code":0,"data":{"paths":["22-29-30.mp4"],"rootPath":"/home/kkkkk/Documents/ZLMediaKit/release/linux/Debug/www/record/hls/kkkkk/2020-05-11/"}}-->  
27 - <el-tab-pane label="录像查询" name="second">  
28 - <el-date-picker v-model="videoHistory.startTime" type="datetime" value-format="yyyy-MM-dd HH:mm:ss" placeholder="开始时间"  
29 - @change="recordList()"></el-date-picker>  
30 - <el-date-picker v-model="videoHistory.endTime" type="datetime" value-format="yyyy-MM-dd HH:mm:ss" placeholder="结束时间"  
31 - @change="recordList()"></el-date-picker>  
32 - <el-table :data="videoHistory.searchHistoryResult" style="width: 100%">  
33 - <el-table-column label="名称" prop="name" width="150"></el-table-column>  
34 - <el-table-column label="文件" prop="filePath" width="300"></el-table-column>  
35 - <el-table-column label="开始时间" prop="startTime" width="160"></el-table-column>  
36 - <el-table-column label="结束时间" prop="endTime" width="160"></el-table-column> 2 +<div id="devicePlayer">
  3 + <el-dialog title="视频播放" top="0" :visible.sync="showVideoDialog" :destroy-on-close="true" @close="close()">
  4 + <LivePlayer v-if="showVideoDialog" ref="videoPlayer" :videoUrl="videoUrl" :error="videoError" :hasaudio="hasaudio" fluent autoplay live></LivePlayer>
  5 + <div id="shared" style="text-align: right; margin-top: 1rem;">
  6 + <el-tabs v-model="tabActiveName">
  7 + <el-tab-pane label="媒体流信息" name="media">
  8 + <div style="margin-bottom: 0.5rem;">
  9 + <el-button type="primary" size="small" @click="playRecord(true, '')">播放</el-button>
  10 + <el-button type="primary" size="small" @click="startRecord()">录制</el-button>
  11 + <el-button type="primary" size="small" @click="stopRecord()">停止录制</el-button>
  12 + </div>
  13 + <div style="display: flex; margin-bottom: 0.5rem; height: 2.5rem;">
  14 + <span style="width: 5rem; line-height: 2.5rem; text-align: right;">播放地址:</span>
  15 + <el-input v-model="getPlayerShared.sharedUrl" :disabled="true" v-on:click.native="copySharedInfo(getPlayerShared.sharedUrl)"></el-input>
  16 + </div>
  17 + <div style="display: flex; margin-bottom: 0.5rem; height: 2.5rem;">
  18 + <span style="width: 5rem; line-height: 2.5rem; text-align: right;">iframe:</span>
  19 + <el-input v-model="getPlayerShared.sharedIframe" :disabled="true" v-on:click.native="copySharedInfo(getPlayerShared.sharedIframe)"></el-input>
  20 + </div>
  21 + <div style="display: flex; margin-bottom: 0.5rem; height: 2.5rem;">
  22 + <span style="width: 5rem; line-height: 2.5rem; text-align: right;">资源地址:</span>
  23 + <el-input v-model="getPlayerShared.sharedRtmp" :disabled="true" v-on:click.native="copySharedInfo(getPlayerShared.sharedRtmp)"></el-input>
  24 + </div>
  25 + </el-tab-pane>
  26 + <!--{"code":0,"data":{"paths":["22-29-30.mp4"],"rootPath":"/home/kkkkk/Documents/ZLMediaKit/release/linux/Debug/www/record/hls/kkkkk/2020-05-11/"}}-->
  27 + <el-tab-pane label="录像查询" name="second">
  28 + <el-date-picker v-model="videoHistory.startTime" type="datetime" value-format="yyyy-MM-dd HH:mm:ss" placeholder="开始时间" @change="recordList()"></el-date-picker>
  29 + <el-date-picker v-model="videoHistory.endTime" type="datetime" value-format="yyyy-MM-dd HH:mm:ss" placeholder="结束时间" @change="recordList()"></el-date-picker>
  30 + <el-table :data="videoHistory.searchHistoryResult" style="width: 100%">
  31 + <el-table-column label="名称" prop="name" width="150"></el-table-column>
  32 + <el-table-column label="文件" prop="filePath" width="300"></el-table-column>
  33 + <el-table-column label="开始时间" prop="startTime" width="160"></el-table-column>
  34 + <el-table-column label="结束时间" prop="endTime" width="160"></el-table-column>
37 35
38 - <el-table-column label="操作">  
39 - <template slot-scope="scope">  
40 - <el-button type="primary" size="mini" @click="playRecord(false, scope.row)">播放</el-button>  
41 - </template>  
42 - </el-table-column>  
43 - </el-table>  
44 - </el-tab-pane>  
45 - <!--遥控界面-->  
46 - <el-tab-pane label="云台控制" name="third">  
47 - <div style="display: flex; justify-content: center;">  
48 - <div class="control-wrapper">  
49 - <div class="control-btn control-top" @mousedown="ptzCamera(0, 1, 0)" @mouseup="ptzCamera(0, 0, 0)">  
50 - <i class="el-icon-caret-top"></i>  
51 - <div class="control-inner-btn control-inner"></div>  
52 - </div>  
53 - <div class="control-btn control-left" @mousedown="ptzCamera(1, 0, 0)" @mouseup="ptzCamera(0, 0, 0)">  
54 - <i class="el-icon-caret-left"></i>  
55 - <div class="control-inner-btn control-inner"></div>  
56 - </div>  
57 - <div class="control-btn control-bottom" @mousedown="ptzCamera(0, 2, 0)" @mouseup="ptzCamera(0, 0, 0)">  
58 - <i class="el-icon-caret-bottom"></i>  
59 - <div class="control-inner-btn control-inner"></div>  
60 - </div>  
61 - <div class="control-btn control-right" @mousedown="ptzCamera(2, 0, 0)" @mouseup="ptzCamera(0, 0, 0)">  
62 - <i class="el-icon-caret-right"></i>  
63 - <div class="control-inner-btn control-inner"></div>  
64 - </div>  
65 - <div class="control-round">  
66 - <div class="control-round-inner"><i class="fa fa-pause-circle"></i></div>  
67 - </div> 36 + <el-table-column label="操作">
  37 + <template slot-scope="scope">
  38 + <el-button type="primary" size="mini" @click="playRecord(false, scope.row)">播放</el-button>
  39 + </template>
  40 + </el-table-column>
  41 + </el-table>
  42 + </el-tab-pane>
  43 + <!--遥控界面-->
  44 + <el-tab-pane label="云台控制" name="third">
  45 + <div style="display: flex; justify-content: center;">
  46 + <div class="control-wrapper">
  47 + <div class="control-btn control-top" @mousedown="ptzCamera(0, 1, 0)" @mouseup="ptzCamera(0, 0, 0)">
  48 + <i class="el-icon-caret-top"></i>
  49 + <div class="control-inner-btn control-inner"></div>
  50 + </div>
  51 + <div class="control-btn control-left" @mousedown="ptzCamera(1, 0, 0)" @mouseup="ptzCamera(0, 0, 0)">
  52 + <i class="el-icon-caret-left"></i>
  53 + <div class="control-inner-btn control-inner"></div>
  54 + </div>
  55 + <div class="control-btn control-bottom" @mousedown="ptzCamera(0, 2, 0)" @mouseup="ptzCamera(0, 0, 0)">
  56 + <i class="el-icon-caret-bottom"></i>
  57 + <div class="control-inner-btn control-inner"></div>
  58 + </div>
  59 + <div class="control-btn control-right" @mousedown="ptzCamera(2, 0, 0)" @mouseup="ptzCamera(0, 0, 0)">
  60 + <i class="el-icon-caret-right"></i>
  61 + <div class="control-inner-btn control-inner"></div>
  62 + </div>
  63 + <div class="control-round">
  64 + <div class="control-round-inner"><i class="fa fa-pause-circle"></i></div>
  65 + </div>
68 66
69 - <div style="position: absolute; left: 7.25rem; top: 1.25rem" @mousedown="ptzCamera(0, 0, 2)" @mouseup="ptzCamera(0, 0, 0)"><i  
70 - class="el-icon-zoom-in" style="font-size: 1.875rem;"></i></div>  
71 - <div style="position: absolute; left: 7.25rem; top: 3.25rem; font-size: 1.875rem;" @mousedown="ptzCamera(0, 0, 1)"  
72 - @mouseup="ptzCamera(0, 0, 0)"><i class="el-icon-zoom-out"></i></div>  
73 - </div>  
74 - </div> 67 + <div style="position: absolute; left: 7.25rem; top: 1.25rem" @mousedown="ptzCamera(0, 0, 2)" @mouseup="ptzCamera(0, 0, 0)"><i class="el-icon-zoom-in" style="font-size: 1.875rem;"></i></div>
  68 + <div style="position: absolute; left: 7.25rem; top: 3.25rem; font-size: 1.875rem;" @mousedown="ptzCamera(0, 0, 1)" @mouseup="ptzCamera(0, 0, 0)"><i class="el-icon-zoom-out"></i></div>
  69 + </div>
  70 + </div>
75 71
76 - </el-tab-pane>  
77 - </el-tabs>  
78 - </div>  
79 - </el-dialog>  
80 - </div> 72 + </el-tab-pane>
  73 + </el-tabs>
  74 + </div>
  75 + </el-dialog>
  76 +</div>
81 </template> 77 </template>
82 78
83 <script> 79 <script>
84 - import LivePlayer from '@liveqing/liveplayer'  
85 - export default {  
86 - name: 'devicePlayer',  
87 - props: {},  
88 - components: {  
89 - LivePlayer  
90 - },  
91 - computed: {  
92 - getPlayerShared: function() { 80 +import LivePlayer from '@liveqing/liveplayer'
  81 +export default {
  82 + name: 'devicePlayer',
  83 + props: {},
  84 + components: {
  85 + LivePlayer
  86 + },
  87 + computed: {
  88 + getPlayerShared: function () {
  89 + return {
  90 + sharedUrl: window.location.host + '/' + this.videoUrl,
  91 + sharedIframe: '<iframe src="' + window.location.host + '/' + this.videoUrl + '"></iframe>',
  92 + sharedRtmp: this.videoUrl
  93 + };
  94 + }
  95 + },
  96 + created() {
  97 + // this.videoHistory.searchHistoryResult = falsificationData.recordData.recordList;
  98 + },
  99 + data() {
93 return { 100 return {
94 - sharedUrl: window.location.host + '/' + this.videoUrl,  
95 - sharedIframe: '<iframe src="' + window.location.host + '/' + this.videoUrl + '"></iframe>',  
96 - sharedRtmp: this.videoUrl  
97 - };  
98 - }  
99 - },  
100 - created() {  
101 - // this.videoHistory.searchHistoryResult = falsificationData.recordData.recordList;  
102 - },  
103 - data() {  
104 - return {  
105 - video:'http://lndxyj.iqilu.com/public/upload/2019/10/14/8c001ea0c09cdc59a57829dabc8010fa.mp4',  
106 - videoUrl: '',  
107 - videoHistory: {  
108 - startTime: '',  
109 - endTime: '',  
110 - searchHistoryResult: [] //媒体流历史记录搜索结果  
111 - },  
112 - showVideoDialog: false,  
113 - normalssrc: '',  
114 - ssrc: '',  
115 - deviceId: '',  
116 - channelId: '',  
117 - tabActiveName: 'media',  
118 - hasaudio: false 101 + video: 'http://lndxyj.iqilu.com/public/upload/2019/10/14/8c001ea0c09cdc59a57829dabc8010fa.mp4',
  102 + videoUrl: '',
  103 + videoHistory: {
  104 + startTime: '',
  105 + endTime: '',
  106 + searchHistoryResult: [] //媒体流历史记录搜索结果
  107 + },
  108 + showVideoDialog: false,
  109 + normalssrc: '',
  110 + ssrc: '',
  111 + deviceId: '',
  112 + channelId: '',
  113 + tabActiveName: 'media',
  114 + hasaudio: false
119 115
120 - };  
121 - },  
122 - methods: { 116 + };
  117 + },
  118 + methods: {
123 119
124 - play: function(streamInfo, deviceId, channelId, hasAudio) {  
125 - this.hasaudio = hasAudio;  
126 - // 根据媒体流信息二次判断  
127 - if( this.hasaudio && !!streamInfo.tracks && streamInfo.tracks.length > 0) {  
128 - var realHasAudio = false;  
129 - for (let i = 0; i < streamInfo.tracks; i++) {  
130 - if (streamInfo.tracks[i].codec_type == 1) { // 判断为音频  
131 - realHasAudio = true; 120 + play: function (streamInfo, deviceId, channelId, hasAudio) {
  121 + this.hasaudio = hasAudio;
  122 + // 根据媒体流信息二次判断
  123 + if (!!streamInfo.tracks && streamInfo.tracks.length > 0) {
  124 + var realHasAudio = false;
  125 + for (let i = 0; i < streamInfo.tracks.length; i++) {
  126 + if (streamInfo.tracks[i].codec_type == 1 && streamInfo.tracks[i].codec_id_name == "CodecAAC") { // 判断为AAC音频
  127 + realHasAudio = true;
  128 + }
  129 + }
  130 + this.hasaudio = realHasAudio; //&& this.hasaudio;
132 } 131 }
133 - }  
134 - this.hasaudio = realHasAudio && this.hasaudio;  
135 - }  
136 - this.ssrc = streamInfo.ssrc;  
137 - this.deviceId = deviceId;  
138 - this.channelId = channelId;  
139 - // this.$refs.videoPlayer.hasaudio = hasAudio;  
140 - // this.videoUrl = streamInfo.flv + "?" + new Date().getTime();  
141 - this.videoUrl = streamInfo.ws_flv;  
142 - this.showVideoDialog = true;  
143 - console.log(this.ssrc);  
144 - },  
145 - close: function() {  
146 - console.log('关闭视频');  
147 - this.$refs.videoPlayer.pause();  
148 - this.videoUrl = '';  
149 - this.showVideoDialog = false;  
150 - },  
151 - copySharedInfo: function(data) {  
152 - console.log('复制内容:' + data);  
153 - let _this = this;  
154 - this.$copyText(data).then(  
155 - function(e) {  
156 - _this.$message({  
157 - showClose: true,  
158 - message: '复制成功',  
159 - type: 'success'  
160 - });  
161 - },  
162 - function(e) {  
163 - _this.$message({  
164 - showClose: true,  
165 - message: '复制失败,请手动复制',  
166 - type: 'error'  
167 - });  
168 - }  
169 - );  
170 - }, 132 + this.ssrc = streamInfo.ssrc;
  133 + this.deviceId = deviceId;
  134 + this.channelId = channelId;
  135 + // this.$refs.videoPlayer.hasaudio = hasAudio;
  136 + // this.videoUrl = streamInfo.flv + "?" + new Date().getTime();
  137 + this.videoUrl = streamInfo.ws_flv;
  138 + this.showVideoDialog = true;
  139 + console.log(this.ssrc);
  140 + },
  141 + close: function () {
  142 + console.log('关闭视频');
  143 + this.$refs.videoPlayer.pause();
  144 + this.videoUrl = '';
  145 + this.showVideoDialog = false;
  146 + },
  147 + copySharedInfo: function (data) {
  148 + console.log('复制内容:' + data);
  149 + let _this = this;
  150 + this.$copyText(data).then(
  151 + function (e) {
  152 + _this.$message({
  153 + showClose: true,
  154 + message: '复制成功',
  155 + type: 'success'
  156 + });
  157 + },
  158 + function (e) {
  159 + _this.$message({
  160 + showClose: true,
  161 + message: '复制失败,请手动复制',
  162 + type: 'error'
  163 + });
  164 + }
  165 + );
  166 + },
171 167
172 - recordList: function() {  
173 - if (!this.videoHistory.startTime || !this.videoHistory.endTime) {  
174 - return;  
175 - }  
176 - let that = this;  
177 - this.$axios({  
178 - method: 'get',  
179 - url: '/api/record/' + this.deviceId + '/' + this.channelId + '?startTime=' + this.videoHistory  
180 - .startTime + '&endTime=' + this.videoHistory.endTime  
181 - }).then(function(res) {  
182 - console.log(JSON.stringify(res));  
183 - }).catch(function(e) {  
184 - // that.videoHistory.searchHistoryResult = falsificationData.recordData;  
185 - }); 168 + recordList: function () {
  169 + if (!this.videoHistory.startTime || !this.videoHistory.endTime) {
  170 + return;
  171 + }
  172 + let that = this;
  173 + this.$axios({
  174 + method: 'get',
  175 + url: '/api/record/' + this.deviceId + '/' + this.channelId + '?startTime=' + this.videoHistory
  176 + .startTime + '&endTime=' + this.videoHistory.endTime
  177 + }).then(function (res) {
  178 + console.log(JSON.stringify(res));
  179 + }).catch(function (e) {
  180 + // that.videoHistory.searchHistoryResult = falsificationData.recordData;
  181 + });
186 182
187 - },  
188 - playRecord: function(isBackLive, rowData) {  
189 - let that = this;  
190 - if(isBackLive){  
191 - this.videoUrl=this.getVideoUrlBySsrc(this.normalssrc);  
192 - return;  
193 - }  
194 - this.$axios({  
195 - method: 'get',  
196 - url: '/api/playback/' + this.deviceId + '/' + this.channelId + '?startTime=' + rowData.startTime + '&endTime=' +  
197 - rowData.endTime  
198 - }).then(function(res) {  
199 - let ssrc = res.data.ssrc;  
200 - that.videoUrl = that.getVideoUrlBySsrc(ssrc);  
201 - //that.videoUrl='http://hls.cntv.kcdnvip.com/asp/hls/main/0303000a/3/default/f466089412c04a759c5515dbfcc3ac3d/main.m3u8?maxbr=2048';  
202 - }); 183 + },
  184 + playRecord: function (isBackLive, rowData) {
  185 + let that = this;
  186 + if (isBackLive) {
  187 + this.videoUrl = this.getVideoUrlBySsrc(this.normalssrc);
  188 + return;
  189 + }
  190 + this.$axios({
  191 + method: 'get',
  192 + url: '/api/playback/' + this.deviceId + '/' + this.channelId + '?startTime=' + rowData.startTime + '&endTime=' +
  193 + rowData.endTime
  194 + }).then(function (res) {
  195 + let ssrc = res.data.ssrc;
  196 + that.videoUrl = that.getVideoUrlBySsrc(ssrc);
  197 + //that.videoUrl='http://hls.cntv.kcdnvip.com/asp/hls/main/0303000a/3/default/f466089412c04a759c5515dbfcc3ac3d/main.m3u8?maxbr=2048';
  198 + });
203 199
204 - },  
205 - ptzCamera: function(leftRight, upDown, zoom) {  
206 - console.log('云台控制:' + leftRight + ' : ' + upDown + " : " + zoom);  
207 - let that = this;  
208 - this.$axios({  
209 - method: 'post',  
210 - url: '/api/ptz/' + this.deviceId + '/' + this.channelId + '?leftRight=' + leftRight + '&upDown=' + upDown +  
211 - '&inOut=' + zoom + '&moveSpeed=50&zoomSpeed=50'  
212 - }).then(function(res) {});  
213 - },  
214 - //////////////////////播放器事件处理//////////////////////////  
215 - videoError:function(e){  
216 - console.log("播放器错误:"+JSON.stringify(e));  
217 - }  
218 - }  
219 - }; 200 + },
  201 + ptzCamera: function (leftRight, upDown, zoom) {
  202 + console.log('云台控制:' + leftRight + ' : ' + upDown + " : " + zoom);
  203 + let that = this;
  204 + this.$axios({
  205 + method: 'post',
  206 + url: '/api/ptz/' + this.deviceId + '/' + this.channelId + '?leftRight=' + leftRight + '&upDown=' + upDown +
  207 + '&inOut=' + zoom + '&moveSpeed=50&zoomSpeed=50'
  208 + }).then(function (res) {});
  209 + },
  210 + //////////////////////播放器事件处理//////////////////////////
  211 + videoError: function (e) {
  212 + console.log("播放器错误:" + JSON.stringify(e));
  213 + }
  214 + }
  215 +};
220 </script> 216 </script>
221 217
222 <style> 218 <style>
223 - .control-wrapper {  
224 - position: relative;  
225 - width: 6.25rem;  
226 - height: 6.25rem;  
227 - max-width: 6.25rem;  
228 - max-height: 6.25rem;  
229 - margin: 0 auto;  
230 - border-radius: 100%;  
231 - float: left;  
232 - } 219 +.control-wrapper {
  220 + position: relative;
  221 + width: 6.25rem;
  222 + height: 6.25rem;
  223 + max-width: 6.25rem;
  224 + max-height: 6.25rem;
  225 + margin: 0 auto;
  226 + border-radius: 100%;
  227 + float: left;
  228 +}
233 229
234 - .control-btn {  
235 - display: flex;  
236 - justify-content: center;  
237 - position: absolute;  
238 - width: 44%;  
239 - height: 44%;  
240 - border-radius: 5px;  
241 - border: 1px solid #78aee4;  
242 - box-sizing: border-box;  
243 - transition: all 0.3s linear;  
244 - } 230 +.control-btn {
  231 + display: flex;
  232 + justify-content: center;
  233 + position: absolute;
  234 + width: 44%;
  235 + height: 44%;
  236 + border-radius: 5px;
  237 + border: 1px solid #78aee4;
  238 + box-sizing: border-box;
  239 + transition: all 0.3s linear;
  240 +}
245 241
246 - .control-btn i {  
247 - font-size: 20px;  
248 - color: #78aee4;  
249 - display: flex;  
250 - justify-content: center;  
251 - align-items: center;  
252 - } 242 +.control-btn i {
  243 + font-size: 20px;
  244 + color: #78aee4;
  245 + display: flex;
  246 + justify-content: center;
  247 + align-items: center;
  248 +}
253 249
254 - .control-round {  
255 - position: absolute;  
256 - top: 21%;  
257 - left: 21%;  
258 - width: 58%;  
259 - height: 58%;  
260 - background: #fff;  
261 - border-radius: 100%;  
262 - } 250 +.control-round {
  251 + position: absolute;
  252 + top: 21%;
  253 + left: 21%;
  254 + width: 58%;
  255 + height: 58%;
  256 + background: #fff;
  257 + border-radius: 100%;
  258 +}
263 259
264 - .control-round-inner {  
265 - position: absolute;  
266 - left: 15%;  
267 - top: 15%;  
268 - display: flex;  
269 - justify-content: center;  
270 - align-items: center;  
271 - width: 70%;  
272 - height: 70%;  
273 - font-size: 40px;  
274 - color: #78aee4;  
275 - border: 1px solid #78aee4;  
276 - border-radius: 100%;  
277 - transition: all 0.3s linear;  
278 - } 260 +.control-round-inner {
  261 + position: absolute;
  262 + left: 15%;
  263 + top: 15%;
  264 + display: flex;
  265 + justify-content: center;
  266 + align-items: center;
  267 + width: 70%;
  268 + height: 70%;
  269 + font-size: 40px;
  270 + color: #78aee4;
  271 + border: 1px solid #78aee4;
  272 + border-radius: 100%;
  273 + transition: all 0.3s linear;
  274 +}
279 275
280 - .control-inner-btn {  
281 - position: absolute;  
282 - width: 60%;  
283 - height: 60%;  
284 - background: #fafafa;  
285 - } 276 +.control-inner-btn {
  277 + position: absolute;
  278 + width: 60%;
  279 + height: 60%;
  280 + background: #fafafa;
  281 +}
286 282
287 - .control-top {  
288 - top: -8%;  
289 - left: 27%;  
290 - transform: rotate(-45deg);  
291 - border-radius: 5px 100% 5px 0;  
292 - } 283 +.control-top {
  284 + top: -8%;
  285 + left: 27%;
  286 + transform: rotate(-45deg);
  287 + border-radius: 5px 100% 5px 0;
  288 +}
293 289
294 - .control-top i {  
295 - transform: rotate(45deg);  
296 - border-radius: 5px 100% 5px 0;  
297 - } 290 +.control-top i {
  291 + transform: rotate(45deg);
  292 + border-radius: 5px 100% 5px 0;
  293 +}
298 294
299 - .control-top .control-inner {  
300 - left: -1px;  
301 - bottom: 0;  
302 - border-top: 1px solid #78aee4;  
303 - border-right: 1px solid #78aee4;  
304 - border-radius: 0 100% 0 0;  
305 - } 295 +.control-top .control-inner {
  296 + left: -1px;
  297 + bottom: 0;
  298 + border-top: 1px solid #78aee4;
  299 + border-right: 1px solid #78aee4;
  300 + border-radius: 0 100% 0 0;
  301 +}
306 302
307 - .control-top .fa {  
308 - transform: rotate(45deg) translateY(-7px);  
309 - } 303 +.control-top .fa {
  304 + transform: rotate(45deg) translateY(-7px);
  305 +}
310 306
311 - .control-left {  
312 - top: 27%;  
313 - left: -8%;  
314 - transform: rotate(45deg);  
315 - border-radius: 5px 0 5px 100%;  
316 - } 307 +.control-left {
  308 + top: 27%;
  309 + left: -8%;
  310 + transform: rotate(45deg);
  311 + border-radius: 5px 0 5px 100%;
  312 +}
317 313
318 - .control-left i {  
319 - transform: rotate(-45deg);  
320 - } 314 +.control-left i {
  315 + transform: rotate(-45deg);
  316 +}
321 317
322 - .control-left .control-inner {  
323 - right: -1px;  
324 - top: -1px;  
325 - border-bottom: 1px solid #78aee4;  
326 - border-left: 1px solid #78aee4;  
327 - border-radius: 0 0 0 100%;  
328 - } 318 +.control-left .control-inner {
  319 + right: -1px;
  320 + top: -1px;
  321 + border-bottom: 1px solid #78aee4;
  322 + border-left: 1px solid #78aee4;
  323 + border-radius: 0 0 0 100%;
  324 +}
329 325
330 - .control-left .fa {  
331 - transform: rotate(-45deg) translateX(-7px);  
332 - } 326 +.control-left .fa {
  327 + transform: rotate(-45deg) translateX(-7px);
  328 +}
333 329
334 - .control-right {  
335 - top: 27%;  
336 - right: -8%;  
337 - transform: rotate(45deg);  
338 - border-radius: 5px 100% 5px 0;  
339 - } 330 +.control-right {
  331 + top: 27%;
  332 + right: -8%;
  333 + transform: rotate(45deg);
  334 + border-radius: 5px 100% 5px 0;
  335 +}
340 336
341 - .control-right i {  
342 - transform: rotate(-45deg);  
343 - } 337 +.control-right i {
  338 + transform: rotate(-45deg);
  339 +}
344 340
345 - .control-right .control-inner {  
346 - left: -1px;  
347 - bottom: -1px;  
348 - border-top: 1px solid #78aee4;  
349 - border-right: 1px solid #78aee4;  
350 - border-radius: 0 100% 0 0;  
351 - } 341 +.control-right .control-inner {
  342 + left: -1px;
  343 + bottom: -1px;
  344 + border-top: 1px solid #78aee4;
  345 + border-right: 1px solid #78aee4;
  346 + border-radius: 0 100% 0 0;
  347 +}
352 348
353 - .control-right .fa {  
354 - transform: rotate(-45deg) translateX(7px);  
355 - } 349 +.control-right .fa {
  350 + transform: rotate(-45deg) translateX(7px);
  351 +}
356 352
357 - .control-bottom {  
358 - left: 27%;  
359 - bottom: -8%;  
360 - transform: rotate(45deg);  
361 - border-radius: 0 5px 100% 5px;  
362 - } 353 +.control-bottom {
  354 + left: 27%;
  355 + bottom: -8%;
  356 + transform: rotate(45deg);
  357 + border-radius: 0 5px 100% 5px;
  358 +}
363 359
364 - .control-bottom i {  
365 - transform: rotate(-45deg);  
366 - } 360 +.control-bottom i {
  361 + transform: rotate(-45deg);
  362 +}
367 363
368 - .control-bottom .control-inner {  
369 - top: -1px;  
370 - left: -1px;  
371 - border-bottom: 1px solid #78aee4;  
372 - border-right: 1px solid #78aee4;  
373 - border-radius: 0 0 100% 0;  
374 - } 364 +.control-bottom .control-inner {
  365 + top: -1px;
  366 + left: -1px;
  367 + border-bottom: 1px solid #78aee4;
  368 + border-right: 1px solid #78aee4;
  369 + border-radius: 0 0 100% 0;
  370 +}
375 371
376 - .control-bottom .fa {  
377 - transform: rotate(-45deg) translateY(7px);  
378 - } 372 +.control-bottom .fa {
  373 + transform: rotate(-45deg) translateY(7px);
  374 +}
379 </style> 375 </style>