Commit 7dc8fd4a1e8c5afb6fad53454935419c239838c0

Authored by panlinlin
1 parent 56859d09

添加拉流代理与国标关联, 支持代理rtsp/rtmp/...,转发到国标

Showing 42 changed files with 1395 additions and 225 deletions
src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java
... ... @@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSONArray;
4 4  
5 5 public class StreamInfo {
6 6  
  7 + private String app;
7 8 private String streamId;
8 9 private String deviceID;
9 10 private String channelId;
... ... @@ -19,6 +20,14 @@ public class StreamInfo {
19 20 private String rtsp;
20 21 private JSONArray tracks;
21 22  
  23 + public String getApp() {
  24 + return app;
  25 + }
  26 +
  27 + public void setApp(String app) {
  28 + this.app = app;
  29 + }
  30 +
22 31 public String getDeviceID() {
23 32 return deviceID;
24 33 }
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/bean/GbStream.java 0 → 100644
  1 +package com.genersoft.iot.vmp.gb28181.bean;
  2 +
  3 +/**
  4 + * 直播流关联国标上级平台
  5 + */
  6 +public class GbStream extends PlatformGbStream{
  7 +
  8 + private String app;
  9 + private String stream;
  10 + private String gbId;
  11 + private String name;
  12 + private double longitude;
  13 + private double latitude;
  14 + private String streamType;
  15 +
  16 + public String getApp() {
  17 + return app;
  18 + }
  19 +
  20 + public void setApp(String app) {
  21 + this.app = app;
  22 + }
  23 +
  24 + public String getStream() {
  25 + return stream;
  26 + }
  27 +
  28 + public void setStream(String stream) {
  29 + this.stream = stream;
  30 + }
  31 +
  32 + public String getGbId() {
  33 + return gbId;
  34 + }
  35 +
  36 + public void setGbId(String gbId) {
  37 + this.gbId = gbId;
  38 + }
  39 +
  40 + public String getName() {
  41 + return name;
  42 + }
  43 +
  44 + public void setName(String name) {
  45 + this.name = name;
  46 + }
  47 +
  48 + public double getLongitude() {
  49 + return longitude;
  50 + }
  51 +
  52 + public void setLongitude(double longitude) {
  53 + this.longitude = longitude;
  54 + }
  55 +
  56 + public double getLatitude() {
  57 + return latitude;
  58 + }
  59 +
  60 + public void setLatitude(double latitude) {
  61 + this.latitude = latitude;
  62 + }
  63 +
  64 + public String getStreamType() {
  65 + return streamType;
  66 + }
  67 +
  68 + public void setStreamType(String streamType) {
  69 + this.streamType = streamType;
  70 + }
  71 +}
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/bean/PlatformGbStream.java 0 → 100644
  1 +package com.genersoft.iot.vmp.gb28181.bean;
  2 +
  3 +public class PlatformGbStream {
  4 + private String app;
  5 + private String stream;
  6 + private String platformId;
  7 +
  8 + public String getApp() {
  9 + return app;
  10 + }
  11 +
  12 + public void setApp(String app) {
  13 + this.app = app;
  14 + }
  15 +
  16 + public String getStream() {
  17 + return stream;
  18 + }
  19 +
  20 + public void setStream(String stream) {
  21 + this.stream = stream;
  22 + }
  23 +
  24 + public String getPlatformId() {
  25 + return platformId;
  26 + }
  27 +
  28 + public void setPlatformId(String platformId) {
  29 + this.platformId = platformId;
  30 + }
  31 +}
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/bean/SendRtpItem.java
... ... @@ -27,6 +27,11 @@ public class SendRtpItem {
27 27 */
28 28 private String deviceId;
29 29  
  30 + /**
  31 + * 直播流的应用名
  32 + */
  33 + private String app;
  34 +
30 35 /**
31 36 * 通道id
32 37 */
... ... @@ -40,10 +45,6 @@ public class SendRtpItem {
40 45 */
41 46 private int status = 0;
42 47  
43   - /**
44   - * 设备推流的app
45   - */
46   - private String app = "rtp";
47 48  
48 49 /**
49 50 * 设备推流的streamId
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
... ... @@ -91,7 +91,9 @@ public class SIPCommander implements ISIPCommander {
91 91 @Autowired
92 92 private SipSubscribe sipSubscribe;
93 93  
94   -
  94 + public SipConfig getSipConfig() {
  95 + return sipConfig;
  96 + }
95 97  
96 98 /**
97 99 * 云台方向放控制,使用配置文件中的默认镜头移动速度
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java
... ... @@ -197,7 +197,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
197 197 @Override
198 198 public boolean catalogQuery(DeviceChannel channel, ParentPlatform parentPlatform, String sn, String fromTag, int size) {
199 199  
200   - if (channel == null || parentPlatform ==null) {
  200 + if ( parentPlatform ==null) {
201 201 return false;
202 202 }
203 203 try {
... ... @@ -210,20 +210,22 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
210 210 catalogXml.append("<SumNum>" + size + "</SumNum>\r\n");
211 211 catalogXml.append("<DeviceList Num=\"1\">\r\n");
212 212 catalogXml.append("<Item>\r\n");
  213 + if (channel != null) {
  214 + catalogXml.append("<DeviceID>" + channel.getChannelId() + "</DeviceID>\r\n");
  215 + catalogXml.append("<Name>" + channel.getName() + "</Name>\r\n");
  216 + catalogXml.append("<Manufacturer>" + channel.getManufacture() + "</Manufacturer>\r\n");
  217 + catalogXml.append("<Model>" + channel.getModel() + "</Model>\r\n");
  218 + catalogXml.append("<Owner>" + channel.getOwner() + "</Owner>\r\n");
  219 + catalogXml.append("<CivilCode>" + channel.getCivilCode() + "</CivilCode>\r\n");
  220 + catalogXml.append("<Address>" + channel.getAddress() + "</Address>\r\n");
  221 + catalogXml.append("<Parental>" + channel.getParental() + "</Parental>\r\n");// TODO 当前不能添加分组, 所以暂时没有父节点
  222 + catalogXml.append("<ParentID>" + channel.getParentId() + "</ParentID>\r\n"); // TODO 当前不能添加分组, 所以暂时没有父节点
  223 + catalogXml.append("<Secrecy>" + channel.getSecrecy() + "</Secrecy>\r\n");
  224 + catalogXml.append("<RegisterWay>" + channel.getRegisterWay() + "</RegisterWay>\r\n");
  225 + catalogXml.append("<Status>" + (channel.getStatus() == 0?"OFF":"ON") + "</Status>\r\n");
  226 + catalogXml.append("<Info></Info>\r\n");
  227 + }
213 228  
214   - catalogXml.append("<DeviceID>" + channel.getChannelId() + "</DeviceID>\r\n");
215   - catalogXml.append("<Name>" + channel.getName() + "</Name>\r\n");
216   - catalogXml.append("<Manufacturer>" + channel.getManufacture() + "</Manufacturer>\r\n");
217   - catalogXml.append("<Model>" + channel.getModel() + "</Model>\r\n");
218   - catalogXml.append("<Owner>" + channel.getOwner() + "</Owner>\r\n");
219   - catalogXml.append("<CivilCode>" + channel.getCivilCode() + "</CivilCode>\r\n");
220   - catalogXml.append("<Address>" + channel.getAddress() + "</Address>\r\n");
221   - catalogXml.append("<Parental>" + channel.getParental() + "</Parental>\r\n");// TODO 当前不能添加分组, 所以暂时没有父节点
222   - catalogXml.append("<ParentID>" + channel.getParentId() + "</ParentID>\r\n"); // TODO 当前不能添加分组, 所以暂时没有父节点
223   - catalogXml.append("<Secrecy>" + channel.getSecrecy() + "</Secrecy>\r\n");
224   - catalogXml.append("<RegisterWay>" + channel.getRegisterWay() + "</RegisterWay>\r\n");
225   - catalogXml.append("<Status>" + (channel.getStatus() == 0?"OFF":"ON") + "</Status>\r\n");
226   - catalogXml.append("<Info></Info>\r\n");
227 229  
228 230 catalogXml.append("</Item>\r\n");
229 231 catalogXml.append("</DeviceList>\r\n");
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/AckRequestProcessor.java
... ... @@ -43,14 +43,23 @@ public class AckRequestProcessor extends SIPRequestAbstractProcessor {
43 43 SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(platformGbId, channelId);
44 44 String is_Udp = sendRtpItem.isTcp() ? "0" : "1";
45 45 String deviceId = sendRtpItem.getDeviceId();
46   - StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId);
47   - sendRtpItem.setStreamId(streamInfo.getStreamId());
  46 + StreamInfo streamInfo = null;
  47 + if (deviceId == null) {
  48 + streamInfo = new StreamInfo();
  49 + streamInfo.setApp(sendRtpItem.getApp());
  50 + streamInfo.setStreamId(sendRtpItem.getStreamId());
  51 + }else {
  52 + streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId);
  53 + sendRtpItem.setStreamId(streamInfo.getStreamId());
  54 + streamInfo.setApp("rtp");
  55 + }
  56 +
48 57 redisCatchStorage.updateSendRTPSever(sendRtpItem);
49 58 System.out.println(platformGbId);
50 59 System.out.println(channelId);
51 60 Map<String, Object> param = new HashMap<>();
52 61 param.put("vhost","__defaultVhost__");
53   - param.put("app","rtp");
  62 + param.put("app",streamInfo.getApp());
54 63 param.put("stream",streamInfo.getStreamId());
55 64 param.put("ssrc", sendRtpItem.getSsrc());
56 65 param.put("dst_url",sendRtpItem.getIp());
... ... @@ -63,7 +72,7 @@ public class AckRequestProcessor extends SIPRequestAbstractProcessor {
63 72 while (!rtpPushed) {
64 73 try {
65 74 if (System.currentTimeMillis() - startTime < 30 * 1000) {
66   - if (zlmrtpServerFactory.isRtpReady(streamInfo.getStreamId())) {
  75 + if (zlmrtpServerFactory.isStreamReady(streamInfo.getApp(), streamInfo.getStreamId())) {
67 76 rtpPushed = true;
68 77 System.out.println("已获取设备推流,开始向上级推流");
69 78 zlmrtpServerFactory.startSendRtpStream(param);
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/ByeRequestProcessor.java
... ... @@ -51,12 +51,12 @@ public class ByeRequestProcessor extends SIPRequestAbstractProcessor {
51 51 String streamId = sendRtpItem.getStreamId();
52 52 Map<String, Object> param = new HashMap<>();
53 53 param.put("vhost","__defaultVhost__");
54   - param.put("app","rtp");
  54 + param.put("app",sendRtpItem.getApp());
55 55 param.put("stream",streamId);
56 56 System.out.println("停止向上级推流:" + streamId);
57 57 zlmrtpServerFactory.stopSendRtpStream(param);
58 58 redisCatchStorage.deleteSendRTPServer(platformGbId, channelId);
59   - if (zlmrtpServerFactory.totalReaderCount(streamId) == 0) {
  59 + if (zlmrtpServerFactory.totalReaderCount(sendRtpItem.getApp(), streamId) == 0) {
60 60 System.out.println(streamId + "无其它观看者,通知设备停止推流");
61 61 cmder.streamByeCmd(streamId);
62 62 }
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java
... ... @@ -12,13 +12,12 @@ import javax.sip.message.Request;
12 12 import javax.sip.message.Response;
13 13  
14 14 import com.genersoft.iot.vmp.conf.MediaServerConfig;
15   -import com.genersoft.iot.vmp.gb28181.bean.Device;
16   -import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
17   -import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
18   -import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
  15 +import com.genersoft.iot.vmp.gb28181.bean.*;
  16 +import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
19 17 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
20 18 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
21 19 import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor;
  20 +import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe;
22 21 import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
23 22 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
24 23 import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
... ... @@ -30,6 +29,8 @@ import org.slf4j.Logger;
30 29 import org.slf4j.LoggerFactory;
31 30  
32 31 import java.text.ParseException;
  32 +import java.util.HashMap;
  33 +import java.util.Map;
33 34 import java.util.Vector;
34 35  
35 36 /**
... ... @@ -93,12 +94,14 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
93 94 if (platform != null) {
94 95 // 查询平台下是否有该通道
95 96 DeviceChannel channel = storager.queryChannelInParentPlatform(requesterId, channelId);
96   - if (channel == null) {
  97 + GbStream gbStream = storager.queryStreamInParentPlatform(requesterId, channelId);
  98 + // 不是通道可能是直播流
  99 + if (channel != null || gbStream != null ) {
  100 + responseAck(evt, Response.CALL_IS_BEING_FORWARDED); // 通道存在,发181,呼叫转接中
  101 + }else {
97 102 logger.info("通道不存在,返回404");
98 103 responseAck(evt, Response.NOT_FOUND); // 通道不存在,发404,资源不存在
99 104 return;
100   - }else {
101   - responseAck(evt, Response.CALL_IS_BEING_FORWARDED); // 通道存在,发181,呼叫转接中
102 105 }
103 106 // 解析sdp消息, 使用jainsip 自带的sdp解析方式
104 107 String contentString = new String(request.getRawContent());
... ... @@ -153,67 +156,120 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
153 156 String addressStr = sdp.getOrigin().getAddress();
154 157 //String sessionName = sdp.getSessionName().getValue();
155 158 logger.info("[上级点播]用户:{}, 地址:{}:{}, ssrc:{}", username, addressStr, port, ssrc);
  159 + Device device = null;
  160 + // 通过 channel 和 gbStream 是否为null 值判断来源是直播流合适国标
  161 + if (channel != null) {
  162 + device = storager.queryVideoDeviceByPlatformIdAndChannelId(requesterId, channelId);
  163 + if (device == null) {
  164 + logger.warn("点播平台{}的通道{}时未找到设备信息", requesterId, channel);
  165 + responseAck(evt, Response.SERVER_INTERNAL_ERROR);
  166 + return;
  167 + }
  168 + SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(addressStr, port, ssrc, requesterId,
  169 + device.getDeviceId(), channelId,
  170 + mediaTransmissionTCP);
  171 + if (tcpActive != null) {
  172 + sendRtpItem.setTcpActive(tcpActive);
  173 + }
  174 + if (sendRtpItem == null) {
  175 + logger.warn("服务器端口资源不足");
  176 + responseAck(evt, Response.BUSY_HERE);
  177 + return;
  178 + }
156 179  
157   - Device device = storager.queryVideoDeviceByPlatformIdAndChannelId(requesterId, channelId);
158   - if (device == null) {
159   - logger.warn("点播平台{}的通道{}时未找到设备信息", requesterId, channel);
160   - responseAck(evt, Response.SERVER_INTERNAL_ERROR);
161   - return;
162   - }
163   - SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(addressStr, port, ssrc, requesterId, device.getDeviceId(), channelId,
164   - mediaTransmissionTCP);
165   - if (tcpActive != null) {
166   - sendRtpItem.setTcpActive(tcpActive);
167   - }
168   - if (sendRtpItem == null) {
169   - logger.warn("服务器端口资源不足");
170   - responseAck(evt, Response.BUSY_HERE);
171   - return;
172   - }
173   -
174   - // 写入redis, 超时时回复
175   - redisCatchStorage.updateSendRTPSever(sendRtpItem);
176   - // 通知下级推流,
177   - PlayResult playResult = playService.play(device.getDeviceId(), channelId, (responseJSON)->{
178   - // 收到推流, 回复200OK, 等待ack
179   - sendRtpItem.setStatus(1);
  180 + // 写入redis, 超时时回复
180 181 redisCatchStorage.updateSendRTPSever(sendRtpItem);
181   - // TODO 添加对tcp的支持
182   - MediaServerConfig mediaInfo = redisCatchStorage.getMediaInfo();
183   - StringBuffer content = new StringBuffer(200);
184   - content.append("v=0\r\n");
185   - content.append("o="+"00000"+" 0 0 IN IP4 "+mediaInfo.getWanIp()+"\r\n");
186   - content.append("s=Play\r\n");
187   - content.append("c=IN IP4 "+mediaInfo.getWanIp()+"\r\n");
188   - content.append("t=0 0\r\n");
189   - content.append("m=video "+ sendRtpItem.getLocalPort()+" RTP/AVP 96\r\n");
190   - content.append("a=sendonly\r\n");
191   - content.append("a=rtpmap:96 PS/90000\r\n");
192   - content.append("y="+ ssrc + "\r\n");
193   - content.append("f=\r\n");
194   -
195   - try {
196   - responseAck(evt, content.toString());
197   - } catch (SipException e) {
198   - e.printStackTrace();
199   - } catch (InvalidArgumentException e) {
200   - e.printStackTrace();
201   - } catch (ParseException e) {
202   - e.printStackTrace();
  182 + // 通知下级推流,
  183 + PlayResult playResult = playService.play(device.getDeviceId(), channelId, (responseJSON)->{
  184 + // 收到推流, 回复200OK, 等待ack
  185 + if (sendRtpItem == null) return;
  186 + sendRtpItem.setStatus(1);
  187 + redisCatchStorage.updateSendRTPSever(sendRtpItem);
  188 + // TODO 添加对tcp的支持
  189 + MediaServerConfig mediaInfo = redisCatchStorage.getMediaInfo();
  190 + StringBuffer content = new StringBuffer(200);
  191 + content.append("v=0\r\n");
  192 + content.append("o="+"00000"+" 0 0 IN IP4 "+mediaInfo.getWanIp()+"\r\n");
  193 + content.append("s=Play\r\n");
  194 + content.append("c=IN IP4 "+mediaInfo.getWanIp()+"\r\n");
  195 + content.append("t=0 0\r\n");
  196 + content.append("m=video "+ sendRtpItem.getLocalPort()+" RTP/AVP 96\r\n");
  197 + content.append("a=sendonly\r\n");
  198 + content.append("a=rtpmap:96 PS/90000\r\n");
  199 + content.append("y="+ ssrc + "\r\n");
  200 + content.append("f=\r\n");
  201 +
  202 + try {
  203 + responseAck(evt, content.toString());
  204 + } catch (SipException e) {
  205 + e.printStackTrace();
  206 + } catch (InvalidArgumentException e) {
  207 + e.printStackTrace();
  208 + } catch (ParseException e) {
  209 + e.printStackTrace();
  210 + }
  211 + } ,(event -> {
  212 + // 未知错误。直接转发设备点播的错误
  213 + Response response = null;
  214 + try {
  215 + response = getMessageFactory().createResponse(event.getResponse().getStatusCode(), evt.getRequest());
  216 + getServerTransaction(evt).sendResponse(response);
  217 + } catch (ParseException | SipException | InvalidArgumentException e) {
  218 + e.printStackTrace();
  219 + }
  220 + }));
  221 + if (logger.isDebugEnabled()) {
  222 + logger.debug(playResult.getResult().toString());
  223 + }
  224 +
  225 + }else if (gbStream != null) {
  226 + SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(addressStr, port, ssrc, requesterId,
  227 + gbStream.getApp(), gbStream.getStream(), channelId,
  228 + mediaTransmissionTCP);
  229 +
  230 + if (tcpActive != null) {
  231 + sendRtpItem.setTcpActive(tcpActive);
  232 + }
  233 + if (sendRtpItem == null) {
  234 + logger.warn("服务器端口资源不足");
  235 + responseAck(evt, Response.BUSY_HERE);
  236 + return;
203 237 }
204   - },(event -> {
205   - // 未知错误。直接转发设备点播的错误
206   - Response response = null;
207   - try {
208   - response = getMessageFactory().createResponse(event.getResponse().getStatusCode(), evt.getRequest());
209   - getServerTransaction(evt).sendResponse(response);
210   - } catch (ParseException | SipException | InvalidArgumentException e) {
211   - e.printStackTrace();
  238 +
  239 + // 写入redis, 超时时回复
  240 + redisCatchStorage.updateSendRTPSever(sendRtpItem);
  241 +
  242 + // 检测直播流是否在线
  243 + Boolean streamReady = zlmrtpServerFactory.isStreamReady(gbStream.getApp(), gbStream.getStream());
  244 + if (streamReady) {
  245 + sendRtpItem.setStatus(1);
  246 + redisCatchStorage.updateSendRTPSever(sendRtpItem);
  247 + // TODO 添加对tcp的支持
  248 + MediaServerConfig mediaInfo = redisCatchStorage.getMediaInfo();
  249 + StringBuffer content = new StringBuffer(200);
  250 + content.append("v=0\r\n");
  251 + content.append("o="+"00000"+" 0 0 IN IP4 "+mediaInfo.getWanIp()+"\r\n");
  252 + content.append("s=Play\r\n");
  253 + content.append("c=IN IP4 "+mediaInfo.getWanIp()+"\r\n");
  254 + content.append("t=0 0\r\n");
  255 + content.append("m=video "+ sendRtpItem.getLocalPort()+" RTP/AVP 96\r\n");
  256 + content.append("a=sendonly\r\n");
  257 + content.append("a=rtpmap:96 PS/90000\r\n");
  258 + content.append("y="+ ssrc + "\r\n");
  259 + content.append("f=\r\n");
  260 +
  261 + try {
  262 + responseAck(evt, content.toString());
  263 + } catch (SipException e) {
  264 + e.printStackTrace();
  265 + } catch (InvalidArgumentException e) {
  266 + e.printStackTrace();
  267 + } catch (ParseException e) {
  268 + e.printStackTrace();
  269 + }
212 270 }
213   - }));
214   - if (logger.isDebugEnabled()) {
215   - logger.debug(playResult.getResult().toString());
216 271 }
  272 +
217 273 } else {
218 274 // 非上级平台请求,查询是否设备请求(通常为接收语音广播的设备)
219 275 Device device = storager.queryVideoDevice(requesterId);
... ... @@ -298,6 +354,7 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
298 354 }
299 355 }
300 356  
  357 +
301 358 /***
302 359 * 回复状态码
303 360 * 100 trying
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
... ... @@ -529,13 +529,44 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
529 529 String sn = snElement.getText();
530 530 // 准备回复通道信息
531 531 List<ChannelReduce> channelReduces = storager.queryChannelListInParentPlatform(parentPlatform.getServerGBId());
  532 + // 查询关联的直播通道
  533 + List<GbStream> gbStreams = storager.queryGbStreamListInPlatform(parentPlatform.getServerGBId());
  534 + int size = channelReduces.size() + gbStreams.size();
  535 + // 回复级联的通道
532 536 if (channelReduces.size() > 0) {
533 537 for (ChannelReduce channelReduce : channelReduces) {
534 538 DeviceChannel deviceChannel = storager.queryChannel(channelReduce.getDeviceId(), channelReduce.getChannelId());
535   - cmderFroPlatform.catalogQuery(deviceChannel, parentPlatform, sn, fromHeader.getTag(), channelReduces.size());
  539 + cmderFroPlatform.catalogQuery(deviceChannel, parentPlatform, sn, fromHeader.getTag(), size);
536 540 }
537 541 }
  542 + // 回复直播的通道
  543 + if (gbStreams.size() > 0) {
  544 + for (GbStream gbStream : gbStreams) {
  545 + DeviceChannel deviceChannel = new DeviceChannel();
  546 + deviceChannel.setChannelId(gbStream.getGbId());
  547 + deviceChannel.setName(gbStream.getName());
  548 + deviceChannel.setLongitude(gbStream.getLongitude());
  549 + deviceChannel.setLatitude(gbStream.getLatitude());
  550 + deviceChannel.setDeviceId(parentPlatform.getDeviceGBId());
  551 + deviceChannel.setManufacture("wvp-pro");
  552 + deviceChannel.setStatus(1);
  553 +// deviceChannel.setParentId(parentPlatform.getDeviceGBId());
  554 + deviceChannel.setRegisterWay(1);
  555 + deviceChannel.setCivilCode(cmder.getSipConfig().getSipDomain());
  556 + deviceChannel.setModel("live");
  557 + deviceChannel.setOwner("wvp-pro");
  558 +// deviceChannel.setAddress("test");
  559 + deviceChannel.setParental(0);
  560 + deviceChannel.setSecrecy("0");
  561 + deviceChannel.setSecrecy("0");
538 562  
  563 + cmderFroPlatform.catalogQuery(deviceChannel, parentPlatform, sn, fromHeader.getTag(), size);
  564 + }
  565 + }
  566 + if (size == 0) {
  567 + // 回复无通道
  568 + cmderFroPlatform.catalogQuery(null, parentPlatform, sn, fromHeader.getTag(), size);
  569 + }
539 570 }
540 571  
541 572  
... ...
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java
... ... @@ -96,7 +96,7 @@ public class ZLMRTPServerFactory {
96 96 }
97 97  
98 98 /**
99   - * 创建一个推流
  99 + * 创建一个国标推流
100 100 * @param ip 推流ip
101 101 * @param port 推流端口
102 102 * @param ssrc 推流唯一标识
... ... @@ -122,6 +122,39 @@ public class ZLMRTPServerFactory {
122 122 sendRtpItem.setDeviceId(deviceId);
123 123 sendRtpItem.setChannelId(channelId);
124 124 sendRtpItem.setTcp(tcp);
  125 + sendRtpItem.setApp("rtp");
  126 + sendRtpItem.setLocalPort(localPort);
  127 + return sendRtpItem;
  128 + }
  129 +
  130 + /**
  131 + * 创建一个直播推流
  132 + * @param ip 推流ip
  133 + * @param port 推流端口
  134 + * @param ssrc 推流唯一标识
  135 + * @param platformId 平台id
  136 + * @param channelId 通道id
  137 + * @param tcp 是否为tcp
  138 + * @return SendRtpItem
  139 + */
  140 + public SendRtpItem createSendRtpItem(String ip, int port, String ssrc, String platformId, String app, String stream, String channelId, boolean tcp){
  141 + String playSsrc = SsrcUtil.getPlaySsrc();
  142 + int localPort = createRTPServer(SsrcUtil.getPlaySsrc());
  143 + if (localPort != -1) {
  144 + closeRTPServer(playSsrc);
  145 + }else {
  146 + logger.error("没有可用的端口");
  147 + return null;
  148 + }
  149 + SendRtpItem sendRtpItem = new SendRtpItem();
  150 + sendRtpItem.setIp(ip);
  151 + sendRtpItem.setPort(port);
  152 + sendRtpItem.setSsrc(ssrc);
  153 + sendRtpItem.setApp(app);
  154 + sendRtpItem.setStreamId(stream);
  155 + sendRtpItem.setPlatformId(platformId);
  156 + sendRtpItem.setChannelId(channelId);
  157 + sendRtpItem.setTcp(tcp);
125 158 sendRtpItem.setLocalPort(localPort);
126 159 return sendRtpItem;
127 160 }
... ... @@ -153,12 +186,20 @@ public class ZLMRTPServerFactory {
153 186 }
154 187  
155 188 /**
  189 + * 查询待转推的流是否就绪
  190 + */
  191 + public Boolean isStreamReady(String app, String streamId) {
  192 + JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo(app, "rtmp", streamId);
  193 + return (mediaInfo.getInteger("code") == 0 && mediaInfo.getBoolean("online"));
  194 + }
  195 +
  196 + /**
156 197 * 查询转推的流是否有其它观看者
157 198 * @param streamId
158 199 * @return
159 200 */
160   - public int totalReaderCount(String streamId) {
161   - JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo("rtp", "rtmp", streamId);
  201 + public int totalReaderCount(String app, String streamId) {
  202 + JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo(app, "rtmp", streamId);
162 203 return mediaInfo.getInteger("totalReaderCount");
163 204 }
164 205  
... ...
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java
... ... @@ -4,7 +4,7 @@ import com.alibaba.fastjson.JSON;
4 4 import com.alibaba.fastjson.JSONArray;
5 5 import com.alibaba.fastjson.JSONObject;
6 6 import com.genersoft.iot.vmp.conf.MediaServerConfig;
7   -import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyDto;
  7 +import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
8 8 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
9 9 //import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
10 10 import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
... ... @@ -165,8 +165,8 @@ public class ZLMRunner implements CommandLineRunner {
165 165 // 更新流列表
166 166 zlmMediaListManager.updateMediaList();
167 167 // 恢复流代理
168   - List<StreamProxyDto> streamProxyListForEnable = storager.getStreamProxyListForEnable(true);
169   - for (StreamProxyDto streamProxyDto : streamProxyListForEnable) {
  168 + List<StreamProxyItem> streamProxyListForEnable = storager.getStreamProxyListForEnable(true);
  169 + for (StreamProxyItem streamProxyDto : streamProxyListForEnable) {
170 170 logger.info("恢复流代理," + streamProxyDto.getApp() + "/" + streamProxyDto.getStream());
171 171 streamProxyService.addStreamProxyToZlm(streamProxyDto);
172 172 }
... ...
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamProxyDto.java renamed to src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamProxyItem.java
1 1 package com.genersoft.iot.vmp.media.zlm.dto;
2 2  
3   -public class StreamProxyDto {
  3 +import com.genersoft.iot.vmp.gb28181.bean.GbStream;
  4 +
  5 +public class StreamProxyItem extends GbStream {
  6 +
4 7 private String type;
5 8 private String app;
6 9 private String stream;
... ... @@ -109,4 +112,6 @@ public class StreamProxyDto {
109 112 public void setEnable_mp4(boolean enable_mp4) {
110 113 this.enable_mp4 = enable_mp4;
111 114 }
  115 +
  116 +
112 117 }
... ...
src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java
... ... @@ -2,12 +2,9 @@ package com.genersoft.iot.vmp.storager;
2 2  
3 3 import java.util.List;
4 4  
5   -import com.genersoft.iot.vmp.gb28181.bean.Device;
6   -import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
7   -import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
8   -import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyDto;
  5 +import com.genersoft.iot.vmp.gb28181.bean.*;
  6 +import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
9 7 import com.genersoft.iot.vmp.vmanager.platform.bean.ChannelReduce;
10   -import com.genersoft.iot.vmp.gb28181.bean.MobilePosition;
11 8 import com.github.pagehelper.PageInfo;
12 9  
13 10 /**
... ... @@ -238,7 +235,7 @@ public interface IVideoManagerStorager {
238 235  
239 236 /**
240 237 * 添加Mobile Position设备移动位置
241   - * @param MobilePosition
  238 + * @param mobilePosition
242 239 * @return
243 240 */
244 241 public boolean insertMobilePosition(MobilePosition mobilePosition);
... ... @@ -268,14 +265,14 @@ public interface IVideoManagerStorager {
268 265 * @param streamProxyDto
269 266 * @return
270 267 */
271   - public int addStreamProxy(StreamProxyDto streamProxyDto);
  268 + public boolean addStreamProxy(StreamProxyItem streamProxyDto);
272 269  
273 270 /**
274 271 * 更新代理流
275 272 * @param streamProxyDto
276 273 * @return
277 274 */
278   - public int updateStreamProxy(StreamProxyDto streamProxyDto);
  275 + public boolean updateStreamProxy(StreamProxyItem streamProxyDto);
279 276  
280 277 /**
281 278 * 移除代理流
... ... @@ -290,7 +287,7 @@ public interface IVideoManagerStorager {
290 287 * @param enable
291 288 * @return
292 289 */
293   - public List<StreamProxyDto> getStreamProxyListForEnable(boolean enable);
  290 + public List<StreamProxyItem> getStreamProxyListForEnable(boolean enable);
294 291  
295 292 /**
296 293 * 按照是app和stream获取代理流
... ... @@ -298,7 +295,7 @@ public interface IVideoManagerStorager {
298 295 * @param stream
299 296 * @return
300 297 */
301   - public StreamProxyDto queryStreamProxy(String app, String stream);
  298 + public StreamProxyItem queryStreamProxy(String app, String stream);
302 299  
303 300 /**
304 301 * 获取代理流
... ... @@ -306,5 +303,20 @@ public interface IVideoManagerStorager {
306 303 * @param count
307 304 * @return
308 305 */
309   - PageInfo<StreamProxyDto> queryStreamProxyList(Integer page, Integer count);
  306 + PageInfo<StreamProxyItem> queryStreamProxyList(Integer page, Integer count);
  307 +
  308 + /**
  309 + * 根据国标ID获取平台关联的直播流
  310 + * @param platformId
  311 + * @param channelId
  312 + * @return
  313 + */
  314 + GbStream queryStreamInParentPlatform(String platformId, String channelId);
  315 +
  316 + /**
  317 + * 获取平台关联的直播流
  318 + * @param platformId
  319 + * @return
  320 + */
  321 + List<GbStream> queryGbStreamListInPlatform(String platformId);
310 322 }
... ...
src/main/java/com/genersoft/iot/vmp/storager/dao/GbStreamMapper.java 0 → 100644
  1 +package com.genersoft.iot.vmp.storager.dao;
  2 +
  3 +import com.genersoft.iot.vmp.gb28181.bean.GbStream;
  4 +import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
  5 +import org.apache.ibatis.annotations.*;
  6 +import org.springframework.stereotype.Repository;
  7 +
  8 +import java.util.List;
  9 +
  10 +@Mapper
  11 +@Repository
  12 +public interface GbStreamMapper {
  13 +
  14 + @Insert("INSERT INTO gb_stream (app, stream, gbId, name, " +
  15 + "longitude, latitude, streamType) VALUES" +
  16 + "('${app}', '${stream}', '${gbId}', '${name}', " +
  17 + "'${longitude}', '${latitude}', '${streamType}')")
  18 + int add(GbStream gbStream);
  19 +
  20 + @Update("UPDATE gb_stream " +
  21 + "SET app=#{app}," +
  22 + "stream=#{stream}," +
  23 + "gbId=#{gbId}," +
  24 + "name=#{name}," +
  25 + "streamType=#{streamType}," +
  26 + "longitude=#{longitude}, " +
  27 + "latitude=#{latitude}, " +
  28 + "WHERE app=#{app} AND stream=#{stream} AND gbId=#{gbId}")
  29 + int update(GbStream gbStream);
  30 +
  31 + @Delete("DELETE FROM gb_stream WHERE app=#{app} AND stream=#{stream}")
  32 + int del(String app, String stream);
  33 +
  34 + @Select("SELECT gs.*, pgs.platformId FROM gb_stream gs LEFT JOIN platform_gb_stream pgs ON gs.app = pgs.app AND gs.stream = pgs.stream")
  35 + List<GbStream> selectAll();
  36 +
  37 + @Select("SELECT * FROM gb_stream WHERE app=#{app} AND stream=#{stream}")
  38 + StreamProxyItem selectOne(String app, String stream);
  39 +
  40 + @Select("SELECT gs.*, pgs.platformId FROM gb_stream gs " +
  41 + "LEFT JOIN platform_gb_stream pgs ON gs.app = pgs.app AND gs.stream = pgs.stream " +
  42 + "WHERE gs.gbId = '${gbId}' AND pgs.platformId = '${platformId}'")
  43 + GbStream queryStreamInPlatform(String platformId, String gbId);
  44 +
  45 + @Select("SELECT gs.*, pgs.platformId FROM gb_stream gs " +
  46 + "LEFT JOIN platform_gb_stream pgs ON gs.app = pgs.app AND gs.stream = pgs.stream " +
  47 + "WHERE pgs.platformId = '${platformId}'")
  48 + List<GbStream> queryGbStreamListInPlatform(String platformId);
  49 +}
... ...
src/main/java/com/genersoft/iot/vmp/storager/dao/PlarfotmGbStreamMapper.java 0 → 100644
  1 +package com.genersoft.iot.vmp.storager.dao;
  2 +
  3 +import com.genersoft.iot.vmp.gb28181.bean.GbStream;
  4 +import com.genersoft.iot.vmp.gb28181.bean.PlatformGbStream;
  5 +import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
  6 +import org.apache.ibatis.annotations.*;
  7 +import org.springframework.stereotype.Repository;
  8 +
  9 +import java.util.List;
  10 +
  11 +
  12 +@Mapper
  13 +@Repository
  14 +public interface PlarfotmGbStreamMapper {
  15 +
  16 + @Insert("INSERT INTO platform_gb_stream (app, stream, platformId) VALUES" +
  17 + "('${app}', '${stream}', '${platformId}')")
  18 + int add(PlatformGbStream platformGbStream);
  19 +
  20 + @Delete("DELETE FROM platform_gb_stream WHERE app=#{app} AND stream=#{stream}")
  21 + int delByAppAndStream(String app, String stream);
  22 +
  23 + @Delete("DELETE FROM platform_gb_stream WHERE app=#{app} AND stream=#{stream}")
  24 + int delByPlatformId(String platformId);
  25 +
  26 + @Select("SELECT * FROM platform_gb_stream WHERE app=#{app} AND stream=#{stream} AND platformId=#{platformId}")
  27 + StreamProxyItem selectOne(String app, String stream, String platformId);
  28 +}
... ...
src/main/java/com/genersoft/iot/vmp/storager/dao/PatformChannelMapper.java renamed to src/main/java/com/genersoft/iot/vmp/storager/dao/PlatformChannelMapper.java
... ... @@ -13,7 +13,7 @@ import java.util.List;
13 13  
14 14 @Mapper
15 15 @Repository
16   -public interface PatformChannelMapper {
  16 +public interface PlatformChannelMapper {
17 17  
18 18 /**
19 19 * 查询列表里已经关联的
... ...
src/main/java/com/genersoft/iot/vmp/storager/dao/StreamProxyMapper.java
1 1 package com.genersoft.iot.vmp.storager.dao;
2 2  
3   -import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyDto;
  3 +import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
4 4 import org.apache.ibatis.annotations.*;
5 5 import org.springframework.stereotype.Repository;
6 6  
... ... @@ -14,7 +14,7 @@ public interface StreamProxyMapper {
14 14 "timeout_ms, ffmpeg_cmd_key, rtp_type, enable_hls, enable_mp4, enable) VALUES" +
15 15 "('${type}','${app}', '${stream}', '${url}', '${src_url}', '${dst_url}', " +
16 16 "'${timeout_ms}', '${ffmpeg_cmd_key}', '${rtp_type}', ${enable_hls}, ${enable_mp4}, ${enable} )")
17   - int add(StreamProxyDto streamProxyDto);
  17 + int add(StreamProxyItem streamProxyDto);
18 18  
19 19 @Update("UPDATE stream_proxy " +
20 20 "SET type=#{type}, " +
... ... @@ -30,17 +30,17 @@ public interface StreamProxyMapper {
30 30 "enable=#{enable}, " +
31 31 "enable_mp4=#{enable_mp4} " +
32 32 "WHERE app=#{app} AND stream=#{stream}")
33   - int update(StreamProxyDto streamProxyDto);
  33 + int update(StreamProxyItem streamProxyDto);
34 34  
35 35 @Delete("DELETE FROM stream_proxy WHERE app=#{app} AND stream=#{stream}")
36 36 int del(String app, String stream);
37 37  
38   - @Select("SELECT * FROM stream_proxy")
39   - List<StreamProxyDto> selectAll();
  38 + @Select("SELECT st.*, pgs.gbId, pgs.name, pgs.longitude, pgs.latitude FROM stream_proxy st LEFT JOIN gb_stream pgs on st.app = pgs.app AND st.stream = pgs.stream")
  39 + List<StreamProxyItem> selectAll();
40 40  
41   - @Select("SELECT * FROM stream_proxy WHERE enable=${enable}")
42   - List<StreamProxyDto> selectForEnable(boolean enable);
  41 + @Select("SELECT st.*, pgs.gbId, pgs.name, pgs.longitude, pgs.latitude FROM stream_proxy st LEFT JOIN gb_stream pgs on st.app = pgs.app AND st.stream = pgs.stream WHERE st.enable=${enable}")
  42 + List<StreamProxyItem> selectForEnable(boolean enable);
43 43  
44   - @Select("SELECT * FROM stream_proxy WHERE app=#{app} AND stream=#{stream}")
45   - StreamProxyDto selectOne(String app, String stream);
  44 + @Select("SELECT st.*, pgs.gbId, pgs.name, pgs.longitude, pgs.latitude FROM stream_proxy st LEFT JOIN gb_stream pgs on st.app = pgs.app AND st.stream = pgs.stream WHERE st.app=#{app} AND st.stream=#{stream}")
  45 + StreamProxyItem selectOne(String app, String stream);
46 46 }
... ...
src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java
... ... @@ -2,21 +2,20 @@ package com.genersoft.iot.vmp.storager.impl;
2 2  
3 3 import java.util.*;
4 4  
5   -import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
6   -import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
7   -import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch;
8   -import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyDto;
  5 +import com.genersoft.iot.vmp.gb28181.bean.*;
  6 +import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
9 7 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
10   -import com.genersoft.iot.vmp.gb28181.bean.MobilePosition;
11 8 import com.genersoft.iot.vmp.storager.dao.*;
12 9 import com.genersoft.iot.vmp.vmanager.platform.bean.ChannelReduce;
13 10 import com.github.pagehelper.PageHelper;
14 11 import com.github.pagehelper.PageInfo;
15 12 import org.springframework.beans.factory.annotation.Autowired;
  13 +import org.springframework.jdbc.datasource.DataSourceTransactionManager;
16 14 import org.springframework.stereotype.Component;
17 15  
18   -import com.genersoft.iot.vmp.gb28181.bean.Device;
19 16 import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
  17 +import org.springframework.transaction.TransactionDefinition;
  18 +import org.springframework.transaction.TransactionStatus;
20 19 import org.springframework.transaction.annotation.Transactional;
21 20  
22 21 /**
... ... @@ -27,6 +26,11 @@ import org.springframework.transaction.annotation.Transactional;
27 26 @SuppressWarnings("rawtypes")
28 27 @Component
29 28 public class VideoManagerStoragerImpl implements IVideoManagerStorager {
  29 + @Autowired
  30 + DataSourceTransactionManager dataSourceTransactionManager;
  31 +
  32 + @Autowired
  33 + TransactionDefinition transactionDefinition;
30 34  
31 35 @Autowired
32 36 private DeviceMapper deviceMapper;
... ... @@ -44,12 +48,13 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
44 48 private IRedisCatchStorage redisCatchStorage;
45 49  
46 50 @Autowired
47   - private PatformChannelMapper patformChannelMapper;
  51 + private PlatformChannelMapper platformChannelMapper;
48 52  
49 53 @Autowired
50 54 private StreamProxyMapper streamProxyMapper;
51 55  
52   -
  56 + @Autowired
  57 + private GbStreamMapper gbStreamMapper;
53 58  
54 59  
55 60 /**
... ... @@ -283,7 +288,7 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
283 288 public boolean deleteParentPlatform(ParentPlatform parentPlatform) {
284 289 int result = platformMapper.delParentPlatform(parentPlatform);
285 290 // 删除关联的通道
286   - patformChannelMapper.cleanChannelForGB(parentPlatform.getServerGBId());
  291 + platformChannelMapper.cleanChannelForGB(parentPlatform.getServerGBId());
287 292 return result > 0;
288 293 }
289 294  
... ... @@ -333,7 +338,7 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
333 338 }
334 339 List<String> deviceAndChannelList = new ArrayList<>(deviceAndChannels.keySet());
335 340 // 查询当前已经存在的
336   - List<String> relatedPlatformchannels = patformChannelMapper.findChannelRelatedPlatform(platformId, deviceAndChannelList);
  341 + List<String> relatedPlatformchannels = platformChannelMapper.findChannelRelatedPlatform(platformId, deviceAndChannelList);
337 342 if (relatedPlatformchannels != null) {
338 343 deviceAndChannelList.removeAll(relatedPlatformchannels);
339 344 }
... ... @@ -344,7 +349,7 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
344 349 // 对剩下的数据进行存储
345 350 int result = 0;
346 351 if (channelReducesToAdd.size() > 0) {
347   - result = patformChannelMapper.addChannels(platformId, channelReducesToAdd);
  352 + result = platformChannelMapper.addChannels(platformId, channelReducesToAdd);
348 353 }
349 354  
350 355 return result;
... ... @@ -354,20 +359,20 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
354 359 @Override
355 360 public int delChannelForGB(String platformId, List<ChannelReduce> channelReduces) {
356 361  
357   - int result = patformChannelMapper.delChannelForGB(platformId, channelReduces);
  362 + int result = platformChannelMapper.delChannelForGB(platformId, channelReduces);
358 363  
359 364 return result;
360 365 }
361 366  
362 367 @Override
363 368 public DeviceChannel queryChannelInParentPlatform(String platformId, String channelId) {
364   - DeviceChannel channel = patformChannelMapper.queryChannelInParentPlatform(platformId, channelId);
  369 + DeviceChannel channel = platformChannelMapper.queryChannelInParentPlatform(platformId, channelId);
365 370 return channel;
366 371 }
367 372  
368 373 @Override
369 374 public Device queryVideoDeviceByPlatformIdAndChannelId(String platformId, String channelId) {
370   - Device device = patformChannelMapper.queryVideoDeviceByPlatformIdAndChannelId(platformId, channelId);
  375 + Device device = platformChannelMapper.queryVideoDeviceByPlatformIdAndChannelId(platformId, channelId);
371 376 return device;
372 377 }
373 378  
... ... @@ -390,27 +395,54 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
390 395  
391 396 /**
392 397 * 新增代理流
393   - * @param streamProxyDto
  398 + * @param streamProxyItem
394 399 * @return
395 400 */
396 401 @Override
397   - public int addStreamProxy(StreamProxyDto streamProxyDto) {
398   - return streamProxyMapper.add(streamProxyDto);
  402 + public boolean addStreamProxy(StreamProxyItem streamProxyItem) {
  403 + TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
  404 + boolean result = false;
  405 + streamProxyItem.setStreamType("proxy");
  406 + try {
  407 + if (gbStreamMapper.add(streamProxyItem)<0 || streamProxyMapper.add(streamProxyItem) < 0) {
  408 + //事务回滚
  409 + dataSourceTransactionManager.rollback(transactionStatus);
  410 + }
  411 + result = true;
  412 + dataSourceTransactionManager.commit(transactionStatus); //手动提交
  413 + }catch (Exception e) {
  414 + dataSourceTransactionManager.rollback(transactionStatus);
  415 + }
  416 + return result;
399 417 }
400 418  
401 419 /**
402 420 * 更新代理流
403   - * @param streamProxyDto
  421 + * @param streamProxyItem
404 422 * @return
405 423 */
406 424 @Override
407   - public int updateStreamProxy(StreamProxyDto streamProxyDto) {
408   - return streamProxyMapper.update(streamProxyDto);
  425 + public boolean updateStreamProxy(StreamProxyItem streamProxyItem) {
  426 + TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
  427 + boolean result = false;
  428 + streamProxyItem.setStreamType("proxy");
  429 + try {
  430 + if (gbStreamMapper.update(streamProxyItem)<0 || streamProxyMapper.update(streamProxyItem) < 0) {
  431 + //事务回滚
  432 + dataSourceTransactionManager.rollback(transactionStatus);
  433 + }
  434 + dataSourceTransactionManager.commit(transactionStatus); //手动提交
  435 + result = true;
  436 + }catch (Exception e) {
  437 + dataSourceTransactionManager.rollback(transactionStatus);
  438 + }
  439 + return result;
409 440 }
410 441  
411 442 /**
412 443 * 移除代理流
413   - * @param id
  444 + * @param app
  445 + * @param stream
414 446 * @return
415 447 */
416 448 @Override
... ... @@ -424,7 +456,7 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
424 456 * @return
425 457 */
426 458 @Override
427   - public List<StreamProxyDto> getStreamProxyListForEnable(boolean enable) {
  459 + public List<StreamProxyItem> getStreamProxyListForEnable(boolean enable) {
428 460 return streamProxyMapper.selectForEnable(enable);
429 461 }
430 462  
... ... @@ -435,12 +467,32 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
435 467 * @return
436 468 */
437 469 @Override
438   - public PageInfo<StreamProxyDto> queryStreamProxyList(Integer page, Integer count) {
  470 + public PageInfo<StreamProxyItem> queryStreamProxyList(Integer page, Integer count) {
439 471 PageHelper.startPage(page, count);
440   - List<StreamProxyDto> all = streamProxyMapper.selectAll();
  472 + List<StreamProxyItem> all = streamProxyMapper.selectAll();
441 473 return new PageInfo<>(all);
442 474 }
443 475  
  476 + /**
  477 + * 根据国标ID获取平台关联的直播流
  478 + * @param platformId
  479 + * @param gbId
  480 + * @return
  481 + */
  482 + @Override
  483 + public GbStream queryStreamInParentPlatform(String platformId, String gbId) {
  484 + return gbStreamMapper.queryStreamInPlatform(platformId, gbId);
  485 + }
  486 +
  487 + /**
  488 + * 获取平台关联的直播流
  489 + * @param platformId
  490 + * @return
  491 + */
  492 + @Override
  493 + public List<GbStream> queryGbStreamListInPlatform(String platformId) {
  494 + return gbStreamMapper.queryGbStreamListInPlatform(platformId);
  495 + }
444 496  
445 497 /**
446 498 * 按照是app和stream获取代理流
... ... @@ -449,7 +501,7 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
449 501 * @return
450 502 */
451 503 @Override
452   - public StreamProxyDto queryStreamProxy(String app, String stream){
  504 + public StreamProxyItem queryStreamProxy(String app, String stream){
453 505 return streamProxyMapper.selectOne(app, stream);
454 506 }
455 507 }
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/gbStream/GbStreamController.java 0 → 100644
  1 +package com.genersoft.iot.vmp.vmanager.gbStream;
  2 +
  3 +import com.alibaba.fastjson.JSON;
  4 +import com.alibaba.fastjson.JSONArray;
  5 +import com.genersoft.iot.vmp.gb28181.bean.GbStream;
  6 +import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
  7 +import com.genersoft.iot.vmp.vmanager.gbStream.bean.GbStreamParam;
  8 +import com.genersoft.iot.vmp.vmanager.platform.bean.UpdateChannelParam;
  9 +import com.genersoft.iot.vmp.vmanager.service.IGbStreamService;
  10 +import com.github.pagehelper.PageInfo;
  11 +import org.slf4j.Logger;
  12 +import org.slf4j.LoggerFactory;
  13 +import org.springframework.beans.factory.annotation.Autowired;
  14 +import org.springframework.web.bind.annotation.*;
  15 +
  16 +import java.util.List;
  17 +
  18 +@CrossOrigin
  19 +@RestController
  20 +@RequestMapping("/api/gbStream")
  21 +public class GbStreamController {
  22 +
  23 + private final static Logger logger = LoggerFactory.getLogger(GbStreamController.class);
  24 +
  25 + @Autowired
  26 + private IGbStreamService gbStreamService;
  27 +
  28 + @Autowired
  29 + private IVideoManagerStorager storager;
  30 +
  31 +
  32 + @RequestMapping(value = "/list")
  33 + @ResponseBody
  34 + public PageInfo<GbStream> list(@RequestParam(required = false)Integer page,
  35 + @RequestParam(required = false)Integer count){
  36 +
  37 + return gbStreamService.getAll(page, count);
  38 + }
  39 +
  40 +
  41 + @RequestMapping(value = "/del")
  42 + @ResponseBody
  43 + public Object del(@RequestBody GbStreamParam gbStreamParam){
  44 + System.out.println(2222);
  45 + System.out.println(gbStreamParam.getGbStreams().size());
  46 + if (gbStreamService.delPlatformInfo(gbStreamParam.getGbStreams())) {
  47 + return "success";
  48 + }else {
  49 + return "fail";
  50 + }
  51 +
  52 + }
  53 +
  54 + @RequestMapping(value = "/add")
  55 + @ResponseBody
  56 + public Object add(@RequestBody GbStreamParam gbStreamParam){
  57 + System.out.println(3333);
  58 + System.out.println(gbStreamParam.getGbStreams().size());
  59 + if (gbStreamService.addPlatformInfo(gbStreamParam.getGbStreams(), gbStreamParam.getPlatformId())) {
  60 + return "success";
  61 + }else {
  62 + return "fail";
  63 + }
  64 + }
  65 +}
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/gbStream/bean/GbStreamParam.java 0 → 100644
  1 +package com.genersoft.iot.vmp.vmanager.gbStream.bean;
  2 +
  3 +import com.genersoft.iot.vmp.gb28181.bean.GbStream;
  4 +
  5 +import java.util.List;
  6 +
  7 +public class GbStreamParam {
  8 +
  9 + private String platformId;
  10 +
  11 + private List<GbStream> gbStreams;
  12 +
  13 + public String getPlatformId() {
  14 + return platformId;
  15 + }
  16 +
  17 + public void setPlatformId(String platformId) {
  18 + this.platformId = platformId;
  19 + }
  20 +
  21 + public List<GbStream> getGbStreams() {
  22 + return gbStreams;
  23 + }
  24 +
  25 + public void setGbStreams(List<GbStream> gbStreams) {
  26 + this.gbStreams = gbStreams;
  27 + }
  28 +}
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/media/MediaController.java
... ... @@ -46,7 +46,4 @@ public class MediaController {
46 46 return mediaService.getStreamInfoByAppAndStreamWithCheck(app, stream);
47 47 }
48 48  
49   -
50   -
51   -
52 49 }
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/platformGbStream/PlatformGbStreamController.java 0 → 100644
  1 +package com.genersoft.iot.vmp.vmanager.platformGbStream;
  2 +
  3 +import com.genersoft.iot.vmp.gb28181.bean.GbStream;
  4 +import com.genersoft.iot.vmp.gb28181.bean.PlatformGbStream;
  5 +import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
  6 +import com.genersoft.iot.vmp.vmanager.service.IGbStreamService;
  7 +import com.github.pagehelper.PageInfo;
  8 +import org.slf4j.Logger;
  9 +import org.slf4j.LoggerFactory;
  10 +import org.springframework.beans.factory.annotation.Autowired;
  11 +import org.springframework.web.bind.annotation.*;
  12 +
  13 +@CrossOrigin
  14 +@RestController
  15 +@RequestMapping("/api")
  16 +public class PlatformGbStreamController {
  17 +
  18 + private final static Logger logger = LoggerFactory.getLogger(PlatformGbStreamController.class);
  19 +
  20 + @Autowired
  21 + private IGbStreamService gbStreamService;
  22 +
  23 + @Autowired
  24 + private IVideoManagerStorager storager;
  25 +
  26 + @RequestMapping(value = "/list")
  27 + @ResponseBody
  28 + public PageInfo<GbStream> list(@RequestParam(required = false)Integer page,
  29 + @RequestParam(required = false)Integer count){
  30 +
  31 + return gbStreamService.getAll(page, count);
  32 + }
  33 +
  34 +
  35 +}
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java
... ... @@ -163,20 +163,7 @@ public class PlayController {
163 163 JSONObject data = jsonObject.getJSONObject("data");
164 164 if (data != null) {
165 165 result.put("key", data.getString("key"));
166   -// StreamInfo streamInfoResult = new StreamInfo();
167   -// streamInfoResult.setRtmp(dstUrl);
168   -// streamInfoResult.setRtsp(String.format("rtsp://%s:%s/convert/%s", mediaInfo.getWanIp(), mediaInfo.getRtspPort(), streamId));
169   -// streamInfoResult.setStreamId(streamId);
170   -// streamInfoResult.setFlv(String.format("http://%s:%s/convert/%s.flv", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), streamId));
171   -// streamInfoResult.setWs_flv(String.format("ws://%s:%s/convert/%s.flv", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), streamId));
172   -// streamInfoResult.setHls(String.format("http://%s:%s/convert/%s/hls.m3u8", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), streamId));
173   -// streamInfoResult.setWs_hls(String.format("ws://%s:%s/convert/%s/hls.m3u8", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), streamId));
174   -// streamInfoResult.setFmp4(String.format("http://%s:%s/convert/%s.live.mp4", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), streamId));
175   -// streamInfoResult.setWs_fmp4(String.format("ws://%s:%s/convert/%s.live.mp4", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), streamId));
176   -// streamInfoResult.setTs(String.format("http://%s:%s/convert/%s.live.ts", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), streamId));
177   -// streamInfoResult.setWs_ts(String.format("ws://%s:%s/convert/%s.live.ts", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), streamId));
178 166 StreamInfo streamInfoResult = mediaService.getStreamInfoByAppAndStream("convert", streamId);
179   - streamInfoResult.setStreamId(streamId);
180 167 result.put("data", streamInfoResult);
181 168 }
182 169 }else {
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/service/IGbStreamService.java 0 → 100644
  1 +package com.genersoft.iot.vmp.vmanager.service;
  2 +
  3 +import com.genersoft.iot.vmp.gb28181.bean.GbStream;
  4 +import com.genersoft.iot.vmp.gb28181.bean.PlatformGbStream;
  5 +import com.github.pagehelper.PageInfo;
  6 +
  7 +import java.util.List;
  8 +
  9 +/**
  10 + * 级联国标平台关联流业务接口
  11 + */
  12 +public interface IGbStreamService {
  13 +
  14 + /**
  15 + * 分页获取所有
  16 + * @param page
  17 + * @param count
  18 + * @return
  19 + */
  20 + PageInfo<GbStream> getAll(Integer page, Integer count);
  21 +
  22 +
  23 + /**
  24 + * 移除
  25 + * @param app
  26 + * @param stream
  27 + */
  28 + void del(String app, String stream);
  29 +
  30 + /**
  31 + * 保存国标关联
  32 + * @param gbStreams
  33 + */
  34 + boolean addPlatformInfo(List<GbStream> gbStreams, String platformId);
  35 +
  36 + /**
  37 + * 移除国标关联
  38 + * @param gbStreams
  39 + */
  40 + boolean delPlatformInfo(List<GbStream> gbStreams);
  41 +}
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/service/IStreamProxyService.java
1 1 package com.genersoft.iot.vmp.vmanager.service;
2 2  
3 3 import com.alibaba.fastjson.JSONObject;
4   -import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyDto;
5   -import com.genersoft.iot.vmp.vmanager.streamProxy.StreamProxyController;
  4 +import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
6 5 import com.github.pagehelper.PageInfo;
7 6  
8 7 public interface IStreamProxyService {
... ... @@ -11,21 +10,21 @@ public interface IStreamProxyService {
11 10 * 保存视频代理
12 11 * @param param
13 12 */
14   - void save(StreamProxyDto param);
  13 + void save(StreamProxyItem param);
15 14  
16 15 /**
17 16 * 添加视频代理到zlm
18 17 * @param param
19 18 * @return
20 19 */
21   - JSONObject addStreamProxyToZlm(StreamProxyDto param);
  20 + JSONObject addStreamProxyToZlm(StreamProxyItem param);
22 21  
23 22 /**
24 23 * 从zlm移除视频代理
25 24 * @param param
26 25 * @return
27 26 */
28   - JSONObject removeStreamProxyFromZlm(StreamProxyDto param);
  27 + JSONObject removeStreamProxyFromZlm(StreamProxyItem param);
29 28  
30 29 /**
31 30 * 分页查询
... ... @@ -33,7 +32,7 @@ public interface IStreamProxyService {
33 32 * @param count
34 33 * @return
35 34 */
36   - PageInfo<StreamProxyDto> getAll(Integer page, Integer count);
  35 + PageInfo<StreamProxyItem> getAll(Integer page, Integer count);
37 36  
38 37 /**
39 38 * 删除视频代理
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/service/impl/GbStreamServiceImpl.java 0 → 100644
  1 +package com.genersoft.iot.vmp.vmanager.service.impl;
  2 +
  3 +import com.genersoft.iot.vmp.gb28181.bean.GbStream;
  4 +import com.genersoft.iot.vmp.gb28181.bean.PlatformGbStream;
  5 +import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
  6 +import com.genersoft.iot.vmp.storager.dao.GbStreamMapper;
  7 +import com.genersoft.iot.vmp.storager.dao.PlarfotmGbStreamMapper;
  8 +import com.genersoft.iot.vmp.vmanager.platform.PlatformController;
  9 +import com.genersoft.iot.vmp.vmanager.service.IGbStreamService;
  10 +import com.github.pagehelper.PageHelper;
  11 +import com.github.pagehelper.PageInfo;
  12 +import org.slf4j.Logger;
  13 +import org.slf4j.LoggerFactory;
  14 +import org.springframework.beans.factory.annotation.Autowired;
  15 +import org.springframework.jdbc.datasource.DataSourceTransactionManager;
  16 +import org.springframework.stereotype.Service;
  17 +import org.springframework.transaction.TransactionDefinition;
  18 +import org.springframework.transaction.TransactionStatus;
  19 +
  20 +import java.util.List;
  21 +
  22 +@Service
  23 +public class GbStreamServiceImpl implements IGbStreamService {
  24 +
  25 + private final static Logger logger = LoggerFactory.getLogger(GbStreamServiceImpl.class);
  26 +
  27 + @Autowired
  28 + DataSourceTransactionManager dataSourceTransactionManager;
  29 +
  30 + @Autowired
  31 + TransactionDefinition transactionDefinition;
  32 +
  33 + @Autowired
  34 + private GbStreamMapper gbStreamMapper;
  35 +
  36 + @Autowired
  37 + private PlarfotmGbStreamMapper plarfotmGbStreamMapper;
  38 +
  39 + @Override
  40 + public PageInfo<GbStream> getAll(Integer page, Integer count) {
  41 + PageHelper.startPage(page, count);
  42 + List<GbStream> all = gbStreamMapper.selectAll();
  43 + return new PageInfo<>(all);
  44 + }
  45 +
  46 + @Override
  47 + public void del(String app, String stream) {
  48 + gbStreamMapper.del(app, stream);
  49 + }
  50 +
  51 +
  52 + @Override
  53 + public boolean addPlatformInfo(List<GbStream> gbStreams, String platformId) {
  54 + // 放在事务内执行
  55 + boolean result = false;
  56 + TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
  57 + try {
  58 + for (GbStream gbStream : gbStreams) {
  59 + gbStream.setPlatformId(platformId);
  60 + plarfotmGbStreamMapper.add(gbStream);
  61 + }
  62 + dataSourceTransactionManager.commit(transactionStatus); //手动提交
  63 + result = true;
  64 + }catch (Exception e) {
  65 + logger.error("批量保存流与平台的关系时错误", e);
  66 + dataSourceTransactionManager.rollback(transactionStatus);
  67 + }
  68 + return result;
  69 +
  70 + }
  71 +
  72 + @Override
  73 + public boolean delPlatformInfo(List<GbStream> gbStreams) {
  74 + // 放在事务内执行
  75 + boolean result = false;
  76 + TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
  77 + try {
  78 + for (GbStream gbStream : gbStreams) {
  79 + plarfotmGbStreamMapper.delByAppAndStream(gbStream.getApp(), gbStream.getStream());
  80 + }
  81 + dataSourceTransactionManager.commit(transactionStatus); //手动提交
  82 + result = true;
  83 + }catch (Exception e) {
  84 + logger.error("批量移除流与平台的关系时错误", e);
  85 + dataSourceTransactionManager.rollback(transactionStatus);
  86 + }
  87 + return result;
  88 + }
  89 +}
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/service/impl/MediaServiceImpl.java
... ... @@ -27,6 +27,8 @@ public class MediaServiceImpl implements IMediaService {
27 27 public StreamInfo getStreamInfoByAppAndStream(String app, String stream) {
28 28 MediaServerConfig mediaInfo = redisCatchStorage.getMediaInfo();
29 29 StreamInfo streamInfoResult = new StreamInfo();
  30 + streamInfoResult.setStreamId(stream);
  31 + streamInfoResult.setApp(app);
30 32 streamInfoResult.setRtmp(String.format("rtmp://%s:%s/%s/%s", mediaInfo.getWanIp(), mediaInfo.getRtmpPort(), app, stream));
31 33 streamInfoResult.setRtsp(String.format("rtsp://%s:%s/%s/%s", mediaInfo.getWanIp(), mediaInfo.getRtspPort(), app, stream));
32 34 streamInfoResult.setFlv(String.format("http://%s:%s/%s/%s.flv", mediaInfo.getWanIp(), mediaInfo.getHttpPort(), app, stream));
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/service/impl/PlayServiceImpl.java
... ... @@ -153,27 +153,8 @@ public class PlayServiceImpl implements IPlayService {
153 153 public StreamInfo onPublishHandler(JSONObject resonse, String deviceId, String channelId, String uuid) {
154 154 String streamId = resonse.getString("id");
155 155 StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream("rtp", streamId);
156   -// StreamInfo streamInfo = new StreamInfo();
157   - streamInfo.setStreamId(streamId);
158 156 streamInfo.setDeviceID(deviceId);
159 157 streamInfo.setChannelId(channelId);
160   -// MediaServerConfig mediaServerConfig = redisCatchStorage.getMediaInfo();
161   -
162   -// streamInfo.setFlv(String.format("http://%s:%s/rtp/%s.flv", mediaServerConfig.getWanIp(), mediaServerConfig.getHttpPort(), streamId));
163   -// streamInfo.setWs_flv(String.format("ws://%s:%s/rtp/%s.flv", mediaServerConfig.getWanIp(), mediaServerConfig.getHttpPort(), streamId));
164   -//
165   -// streamInfo.setFmp4(String.format("http://%s:%s/rtp/%s.live.mp4", mediaServerConfig.getWanIp(), mediaServerConfig.getHttpPort(), streamId));
166   -// streamInfo.setWs_fmp4(String.format("ws://%s:%s/rtp/%s.live.mp4", mediaServerConfig.getWanIp(), mediaServerConfig.getHttpPort(), streamId));
167   -//
168   -// streamInfo.setHls(String.format("http://%s:%s/rtp/%s/hls.m3u8", mediaServerConfig.getWanIp(), mediaServerConfig.getHttpPort(), streamId));
169   -// streamInfo.setWs_hls(String.format("ws://%s:%s/rtp/%s/hls.m3u8", mediaServerConfig.getWanIp(), mediaServerConfig.getHttpPort(), streamId));
170   -//
171   -// streamInfo.setTs(String.format("http://%s:%s/rtp/%s.live.ts", mediaServerConfig.getWanIp(), mediaServerConfig.getHttpPort(), streamId));
172   -// streamInfo.setWs_ts(String.format("ws://%s:%s/rtp/%s.live.ts", mediaServerConfig.getWanIp(), mediaServerConfig.getHttpPort(), streamId));
173   -//
174   -// streamInfo.setRtmp(String.format("rtmp://%s:%s/rtp/%s", mediaServerConfig.getWanIp(), mediaServerConfig.getRtmpPort(), streamId));
175   -// streamInfo.setRtsp(String.format("rtsp://%s:%s/rtp/%s", mediaServerConfig.getWanIp(), mediaServerConfig.getRtspPort(), streamId));
176   -
177 158 return streamInfo;
178 159 }
179 160  
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/service/impl/StreamProxyServiceImpl.java
... ... @@ -2,21 +2,18 @@ package com.genersoft.iot.vmp.vmanager.service.impl;
2 2  
3 3 import com.alibaba.fastjson.JSONObject;
4 4 import com.genersoft.iot.vmp.conf.MediaServerConfig;
5   -import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
6 5 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
7   -import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyDto;
  6 +import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
8 7 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
9 8 import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
  9 +import com.genersoft.iot.vmp.storager.dao.GbStreamMapper;
  10 +import com.genersoft.iot.vmp.storager.dao.PlarfotmGbStreamMapper;
10 11 import com.genersoft.iot.vmp.storager.dao.StreamProxyMapper;
11 12 import com.genersoft.iot.vmp.vmanager.service.IStreamProxyService;
12   -import com.genersoft.iot.vmp.vmanager.streamProxy.StreamProxyController;
13   -import com.github.pagehelper.PageHelper;
14 13 import com.github.pagehelper.PageInfo;
15 14 import org.springframework.beans.factory.annotation.Autowired;
16 15 import org.springframework.stereotype.Service;
17 16  
18   -import java.util.List;
19   -
20 17 /**
21 18 * 视频代理业务
22 19 */
... ... @@ -35,29 +32,35 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
35 32 @Autowired
36 33 private StreamProxyMapper streamProxyMapper;
37 34  
  35 + @Autowired
  36 + private GbStreamMapper gbStreamMapper;
  37 +
  38 + @Autowired
  39 + private PlarfotmGbStreamMapper plarfotmGbStreamMapper;
  40 +
38 41  
39 42 @Override
40   - public void save(StreamProxyDto param) {
  43 + public void save(StreamProxyItem param) {
41 44 MediaServerConfig mediaInfo = redisCatchStorage.getMediaInfo();
42 45 String dstUrl = String.format("rtmp://%s:%s/%s/%s", "127.0.0.1", mediaInfo.getRtmpPort(), param.getApp(),
43 46 param.getStream() );
44 47 param.setDst_url(dstUrl);
45 48 // 更新
46 49 if (videoManagerStorager.queryStreamProxy(param.getApp(), param.getStream()) != null) {
47   - int result = videoManagerStorager.updateStreamProxy(param);
48   - if (result > 0 && param.isEnable()) {
  50 + boolean result = videoManagerStorager.updateStreamProxy(param);
  51 + if (result && param.isEnable()) {
49 52 addStreamProxyToZlm(param);
50 53 }
51 54 }else { // 新增
52   - int result = videoManagerStorager.addStreamProxy(param);
53   - if (result > 0 && param.isEnable()) {
  55 + boolean result = videoManagerStorager.addStreamProxy(param);
  56 + if (result && param.isEnable()) {
54 57 addStreamProxyToZlm(param);
55 58 }
56 59 }
57 60 }
58 61  
59 62 @Override
60   - public JSONObject addStreamProxyToZlm(StreamProxyDto param) {
  63 + public JSONObject addStreamProxyToZlm(StreamProxyItem param) {
61 64 JSONObject result = null;
62 65 if ("default".equals(param.getType())){
63 66 result = zlmresTfulUtils.addStreamProxy(param.getApp(), param.getStream(), param.getUrl(),
... ... @@ -70,37 +73,42 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
70 73 }
71 74  
72 75 @Override
73   - public JSONObject removeStreamProxyFromZlm(StreamProxyDto param) {
  76 + public JSONObject removeStreamProxyFromZlm(StreamProxyItem param) {
74 77 JSONObject result = zlmresTfulUtils.closeStreams(param.getApp(), param.getStream());
  78 +
75 79 return result;
76 80 }
77 81  
78 82 @Override
79   - public PageInfo<StreamProxyDto> getAll(Integer page, Integer count) {
  83 + public PageInfo<StreamProxyItem> getAll(Integer page, Integer count) {
80 84 return videoManagerStorager.queryStreamProxyList(page, count);
81 85 }
82 86  
83 87 @Override
84 88 public void del(String app, String stream) {
85   - StreamProxyDto streamProxyDto = new StreamProxyDto();
86   - streamProxyDto.setApp(app);
87   - streamProxyDto.setStream(stream);
88   - JSONObject jsonObject = removeStreamProxyFromZlm(streamProxyDto);
  89 + StreamProxyItem streamProxyItem = new StreamProxyItem();
  90 + streamProxyItem.setApp(app);
  91 + streamProxyItem.setStream(stream);
  92 + JSONObject jsonObject = removeStreamProxyFromZlm(streamProxyItem);
89 93 if (jsonObject.getInteger("code") == 0) {
90 94 videoManagerStorager.deleteStreamProxy(app, stream);
  95 + // 如果关联了国标那么移除关联
  96 + gbStreamMapper.del(app, stream);
  97 + plarfotmGbStreamMapper.delByAppAndStream(app, stream);
  98 + // TODO 如果关联的推流, 那么状态设置为离线
91 99 }
92 100 }
93 101  
94 102 @Override
95 103 public boolean start(String app, String stream) {
96 104 boolean result = false;
97   - StreamProxyDto streamProxyDto = videoManagerStorager.queryStreamProxy(app, stream);
98   - if (!streamProxyDto.isEnable() && streamProxyDto != null) {
99   - JSONObject jsonObject = addStreamProxyToZlm(streamProxyDto);
  105 + StreamProxyItem streamProxy = videoManagerStorager.queryStreamProxy(app, stream);
  106 + if (!streamProxy.isEnable() && streamProxy != null) {
  107 + JSONObject jsonObject = addStreamProxyToZlm(streamProxy);
100 108 if (jsonObject.getInteger("code") == 0) {
101 109 result = true;
102   - streamProxyDto.setEnable(true);
103   - videoManagerStorager.updateStreamProxy(streamProxyDto);
  110 + streamProxy.setEnable(true);
  111 + videoManagerStorager.updateStreamProxy(streamProxy);
104 112 }
105 113 }
106 114 return result;
... ... @@ -109,7 +117,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
109 117 @Override
110 118 public boolean stop(String app, String stream) {
111 119 boolean result = false;
112   - StreamProxyDto streamProxyDto = videoManagerStorager.queryStreamProxy(app, stream);
  120 + StreamProxyItem streamProxyDto = videoManagerStorager.queryStreamProxy(app, stream);
113 121 if (streamProxyDto.isEnable() && streamProxyDto != null) {
114 122 JSONObject jsonObject = removeStreamProxyFromZlm(streamProxyDto);
115 123 if (jsonObject.getInteger("code") == 0) {
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java
1 1 package com.genersoft.iot.vmp.vmanager.streamProxy;
2 2  
3 3 import com.alibaba.fastjson.JSONObject;
4   -import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
5   -import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyDto;
  4 +import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
6 5 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
7 6 import com.genersoft.iot.vmp.vmanager.service.IStreamProxyService;
8 7 import com.github.pagehelper.PageInfo;
... ... @@ -31,17 +30,17 @@ public class StreamProxyController {
31 30  
32 31 @RequestMapping(value = "/list")
33 32 @ResponseBody
34   - public PageInfo<StreamProxyDto> list(@RequestParam(required = false)Integer page,
35   - @RequestParam(required = false)Integer count,
36   - @RequestParam(required = false)String q,
37   - @RequestParam(required = false)Boolean online ){
  33 + public PageInfo<StreamProxyItem> list(@RequestParam(required = false)Integer page,
  34 + @RequestParam(required = false)Integer count,
  35 + @RequestParam(required = false)String q,
  36 + @RequestParam(required = false)Boolean online ){
38 37  
39 38 return streamProxyService.getAll(page, count);
40 39 }
41 40  
42 41 @RequestMapping(value = "/save")
43 42 @ResponseBody
44   - public Object save(@RequestBody StreamProxyDto param){
  43 + public Object save(@RequestBody StreamProxyItem param){
45 44 logger.info("添加代理: " + JSONObject.toJSONString(param));
46 45 streamProxyService.save(param);
47 46 return "success";
... ...
src/main/resources/wvp.sqlite
No preview for this file type
web_src/src/components/PLatformStreamList.vue 0 → 100644
  1 +<template>
  2 + <div id="pLatformStreamList">
  3 + <el-container>
  4 + <el-header>
  5 + <uiHeader></uiHeader>
  6 + </el-header>
  7 + <el-main>
  8 + <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;">
  9 + <span style="font-size: 1rem; font-weight: bold;">直播级联列表</span>
  10 + </div>
  11 + <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;font-size: 14px;">
  12 + <el-button icon="el-icon-plus" size="mini" style="margin-right: 1rem;" type="primary" @click="addStreamProxy">添加代理</el-button>
  13 + </div>
  14 + <devicePlayer ref="devicePlayer"></devicePlayer>
  15 + <el-table :data="streamProxyList" border style="width: 100%" :height="winHeight">
  16 + <el-table-column prop="app" label="应用名" align="center" show-overflow-tooltip/>
  17 + <el-table-column prop="stream" label="流ID" align="center" show-overflow-tooltip/>
  18 + <el-table-column prop="gbId" label="国标平台" align="center" show-overflow-tooltip/>
  19 +
  20 + <el-table-column label="转HLS" width="120" align="center">
  21 + <template slot-scope="scope">
  22 + <div slot="reference" class="name-wrapper">
  23 + <el-tag size="medium" v-if="scope.row.enable_hls">已启用</el-tag>
  24 + <el-tag size="medium" type="info" v-if="!scope.row.enable_hls">未启用</el-tag>
  25 + </div>
  26 + </template>
  27 + </el-table-column>
  28 + <el-table-column label="MP4录制" width="120" align="center">
  29 + <template slot-scope="scope">
  30 + <div slot="reference" class="name-wrapper">
  31 + <el-tag size="medium" v-if="scope.row.enable_mp4">已启用</el-tag>
  32 + <el-tag size="medium" type="info" v-if="!scope.row.enable_mp4">未启用</el-tag>
  33 + </div>
  34 + </template>
  35 + </el-table-column>
  36 + <el-table-column label="启用" width="120" align="center">
  37 + <template slot-scope="scope">
  38 + <div slot="reference" class="name-wrapper">
  39 + <el-tag size="medium" v-if="scope.row.enable">已启用</el-tag>
  40 + <el-tag size="medium" type="info" v-if="!scope.row.enable">未启用</el-tag>
  41 + </div>
  42 + </template>
  43 + </el-table-column>
  44 +
  45 + <el-table-column label="操作" width="360" align="center" fixed="right">
  46 + <template slot-scope="scope">
  47 + <el-button-group>
  48 + <el-button size="mini" icon="el-icon-video-play" v-if="scope.row.enable" @click="play(scope.row)">播放</el-button>
  49 + <el-button size="mini" icon="el-icon-close" type="success" v-if="scope.row.enable" @click="stop(scope.row)">停用</el-button>
  50 + <el-button size="mini" icon="el-icon-check" type="primary" v-if="!scope.row.enable" @click="start(scope.row)">启用</el-button>
  51 + <el-button size="mini" icon="el-icon-delete" type="danger" @click="deleteStreamProxy(scope.row)">删除</el-button>
  52 + <!-- <el-button size="mini" icon="el-icon-position" type="primary" >加入国标</el-button> -->
  53 + </el-button-group>
  54 + </template>
  55 + </el-table-column>
  56 + </el-table>
  57 + <el-pagination
  58 + style="float: right"
  59 + @size-change="handleSizeChange"
  60 + @current-change="currentChange"
  61 + :current-page="currentPage"
  62 + :page-size="count"
  63 + :page-sizes="[15, 25, 35, 50]"
  64 + layout="total, sizes, prev, pager, next"
  65 + :total="total">
  66 + </el-pagination>
  67 + <streamProxyEdit ref="streamProxyEdit" ></streamProxyEdit>
  68 + </el-main>
  69 + </el-container>
  70 + </div>
  71 +</template>
  72 +
  73 +<script>
  74 + import streamProxyEdit from './dialog/StreamProxyEdit.vue'
  75 + import devicePlayer from './dialog/devicePlayer.vue'
  76 + import uiHeader from './UiHeader.vue'
  77 + export default {
  78 + name: 'pLatformStreamList',
  79 + components: {
  80 + devicePlayer,
  81 + streamProxyEdit,
  82 + uiHeader
  83 + },
  84 + data() {
  85 + return {
  86 + streamProxyList: [],
  87 + currentPusher: {}, //当前操作设备对象
  88 + updateLooper: 0, //数据刷新轮训标志
  89 + currentDeviceChannelsLenth:0,
  90 + winHeight: window.innerHeight - 200,
  91 + currentPage:1,
  92 + count:15,
  93 + total:0,
  94 + getListLoading: false
  95 + };
  96 + },
  97 + computed: {
  98 + },
  99 + mounted() {
  100 + this.initData();
  101 + // this.updateLooper = setInterval(this.initData, 10000);
  102 + },
  103 + destroyed() {
  104 + this.$destroy('videojs');
  105 + clearTimeout(this.updateLooper);
  106 + },
  107 + methods: {
  108 + initData: function() {
  109 + this.getStreamProxyList();
  110 + },
  111 + currentChange: function(val){
  112 + this.currentPage = val;
  113 + this.getStreamProxyList();
  114 + },
  115 + handleSizeChange: function(val){
  116 + this.count = val;
  117 + this.getStreamProxyList();
  118 + },
  119 + getStreamProxyList: function() {
  120 + let that = this;
  121 + this.getListLoading = true;
  122 + this.$axios.get(`/api/proxy/list`,{
  123 + params: {
  124 + page: that.currentPage,
  125 + count: that.count
  126 + }
  127 + } )
  128 + .then(function (res) {
  129 + console.log(res);
  130 + console.log(res.data.list);
  131 + that.total = res.data.total;
  132 + that.streamProxyList = res.data.list;
  133 + that.getListLoading = false;
  134 + })
  135 + .catch(function (error) {
  136 + console.log(error);
  137 + that.getListLoading = false;
  138 + });
  139 + },
  140 + addStreamProxy: function(){
  141 + this.$refs.streamProxyEdit.openDialog(null, this.initData)
  142 + },
  143 + saveStreamProxy: function(){
  144 + },
  145 + play: function(row){
  146 + let that = this;
  147 + this.getListLoading = true;
  148 + this.$axios.get(`/api/media/getStreamInfoByAppAndStream`,{
  149 + params: {
  150 + app: row.app,
  151 + stream: row.stream
  152 + }
  153 + })
  154 + .then(function (res) {
  155 + that.getListLoading = false;
  156 + that.$refs.devicePlayer.openDialog("streamPlay", null, null, {
  157 + streamInfo: res.data,
  158 + hasAudio: true
  159 + });
  160 + })
  161 + .catch(function (error) {
  162 + console.log(error);
  163 + that.getListLoading = false;
  164 + });
  165 +
  166 + },
  167 + deleteStreamProxy: function(row){
  168 + console.log(1111)
  169 + let that = this;
  170 + this.getListLoading = true;
  171 + this.$axios.get(`/api/proxy/del`,{
  172 + params: {
  173 + app: row.app,
  174 + stream: row.stream
  175 + }
  176 + })
  177 + .then(function (res) {
  178 + that.getListLoading = false;
  179 + that.initData()
  180 + })
  181 + .catch(function (error) {
  182 + console.log(error);
  183 + that.getListLoading = false;
  184 + });
  185 + },
  186 + start: function(row){
  187 + let that = this;
  188 + this.getListLoading = true;
  189 + this.$axios.get(`/api/proxy/start`,{
  190 + params: {
  191 + app: row.app,
  192 + stream: row.stream
  193 + }
  194 + })
  195 + .then(function (res) {
  196 + that.getListLoading = false;
  197 + that.initData()
  198 + })
  199 + .catch(function (error) {
  200 + console.log(error);
  201 + that.getListLoading = false;
  202 + });
  203 + },
  204 + stop: function(row){
  205 + let that = this;
  206 + this.getListLoading = true;
  207 + this.$axios.get(`/api/proxy/stop`,{
  208 + params: {
  209 + app: row.app,
  210 + stream: row.stream
  211 + }
  212 + })
  213 + .then(function (res) {
  214 + that.getListLoading = false;
  215 + that.initData()
  216 + })
  217 + .catch(function (error) {
  218 + console.log(error);
  219 + that.getListLoading = false;
  220 + });
  221 + }
  222 +
  223 + }
  224 + };
  225 +</script>
  226 +
  227 +<style>
  228 + .videoList {
  229 + display: flex;
  230 + flex-wrap: wrap;
  231 + align-content: flex-start;
  232 + }
  233 +
  234 + .video-item {
  235 + position: relative;
  236 + width: 15rem;
  237 + height: 10rem;
  238 + margin-right: 1rem;
  239 + background-color: #000000;
  240 + }
  241 +
  242 + .video-item-img {
  243 + position: absolute;
  244 + top: 0;
  245 + bottom: 0;
  246 + left: 0;
  247 + right: 0;
  248 + margin: auto;
  249 + width: 100%;
  250 + height: 100%;
  251 + }
  252 +
  253 + .video-item-img:after {
  254 + content: "";
  255 + display: inline-block;
  256 + position: absolute;
  257 + z-index: 2;
  258 + top: 0;
  259 + bottom: 0;
  260 + left: 0;
  261 + right: 0;
  262 + margin: auto;
  263 + width: 3rem;
  264 + height: 3rem;
  265 + background-image: url("../assets/loading.png");
  266 + background-size: cover;
  267 + background-color: #000000;
  268 + }
  269 +
  270 + .video-item-title {
  271 + position: absolute;
  272 + bottom: 0;
  273 + color: #000000;
  274 + background-color: #ffffff;
  275 + line-height: 1.5rem;
  276 + padding: 0.3rem;
  277 + width: 14.4rem;
  278 + }
  279 + .cpoy-btn {
  280 + cursor: pointer;
  281 + margin-right: 10px;
  282 + }
  283 +</style>
... ...
web_src/src/components/ParentPlatformList.vue
... ... @@ -19,7 +19,7 @@
19 19 <template slot-scope="scope">
20 20 <div slot="reference" class="name-wrapper">
21 21 <el-tag size="medium" v-if="scope.row.enable">已启用</el-tag>
22   - <el-tag size="medium" v-if="!scope.row.enable">未启用</el-tag>
  22 + <el-tag size="medium" type="info" v-if="!scope.row.enable">未启用</el-tag>
23 23 </div>
24 24 </template>
25 25 </el-table-column>
... ...
web_src/src/components/PushVideoList.vue
... ... @@ -19,10 +19,14 @@
19 19 </el-table-column>
20 20 <el-table-column prop="totalReaderCount" label="在线人数" width="240" align="center">
21 21 </el-table-column>
22   - <el-table-column prop="createStamp" label="开始时间" align="center">
  22 + <el-table-column label="开始时间" align="center" >
  23 + <template slot-scope="scope">
  24 + <el-button-group>
  25 + {{dateFormat(parseInt(scope.row.createStamp))}}
  26 + </el-button-group>
  27 + </template>
23 28 </el-table-column>
24 29  
25   -
26 30 <el-table-column label="操作" width="360" align="center" fixed="right">
27 31 <template slot-scope="scope">
28 32 <el-button-group>
... ... @@ -144,6 +148,19 @@
144 148 },
145 149 stopPuhsh: function(row){
146 150 console.log(row)
  151 + },
  152 + dateFormat: function(/** timestamp=0 **/) {
  153 + var ts = arguments[0] || 0;
  154 + var t,y,m,d,h,i,s;
  155 + t = ts ? new Date(ts*1000) : new Date();
  156 + y = t.getFullYear();
  157 + m = t.getMonth()+1;
  158 + d = t.getDate();
  159 + h = t.getHours();
  160 + i = t.getMinutes();
  161 + s = t.getSeconds();
  162 + // 可根据需要在这里定义时间格式
  163 + return y+'-'+(m<10?'0'+m:m)+'-'+(d<10?'0'+d:d)+' '+(h<10?'0'+h:h)+':'+(i<10?'0'+i:i)+':'+(s<10?'0'+s:s);
147 164 }
148 165  
149 166 }
... ...
web_src/src/components/StreamProxyList.vue
... ... @@ -13,7 +13,8 @@
13 13 </div>
14 14 <devicePlayer ref="devicePlayer"></devicePlayer>
15 15 <el-table :data="streamProxyList" border style="width: 100%" :height="winHeight">
16   - <el-table-column prop="app" label="应用名" align="center" show-overflow-tooltip/>
  16 + <el-table-column prop="name" label="名称" align="center" show-overflow-tooltip/>
  17 + <el-table-column prop="app" label="流应用名" align="center" show-overflow-tooltip/>
17 18 <el-table-column prop="stream" label="流ID" align="center" show-overflow-tooltip/>
18 19 <el-table-column label="流地址" width="400" align="center" show-overflow-tooltip >
19 20 <template slot-scope="scope">
... ... @@ -30,7 +31,7 @@
30 31 </div>
31 32 </template>
32 33 </el-table-column>
33   -
  34 + <el-table-column prop="gbId" label="国标编码" width="180" align="center" show-overflow-tooltip/>
34 35 <el-table-column label="转HLS" width="120" align="center">
35 36 <template slot-scope="scope">
36 37 <div slot="reference" class="name-wrapper">
... ... @@ -56,7 +57,6 @@
56 57 </template>
57 58 </el-table-column>
58 59  
59   -
60 60 <el-table-column label="操作" width="360" align="center" fixed="right">
61 61 <template slot-scope="scope">
62 62 <el-button-group>
... ... @@ -64,6 +64,7 @@
64 64 <el-button size="mini" icon="el-icon-close" type="success" v-if="scope.row.enable" @click="stop(scope.row)">停用</el-button>
65 65 <el-button size="mini" icon="el-icon-check" type="primary" v-if="!scope.row.enable" @click="start(scope.row)">启用</el-button>
66 66 <el-button size="mini" icon="el-icon-delete" type="danger" @click="deleteStreamProxy(scope.row)">删除</el-button>
  67 + <!-- <el-button size="mini" icon="el-icon-position" type="primary" >加入国标</el-button> -->
67 68 </el-button-group>
68 69 </template>
69 70 </el-table-column>
... ...
web_src/src/components/dialog/StreamProxyEdit.vue
... ... @@ -21,7 +21,10 @@
21 21 <el-option label="FFmpeg" value="ffmpeg"></el-option>
22 22 </el-select>
23 23 </el-form-item>
24   - <el-form-item label="应用名" prop="app">
  24 + <el-form-item label="名称" prop="name">
  25 + <el-input v-model="proxyParam.name" clearable></el-input>
  26 + </el-form-item>
  27 + <el-form-item label="流应用名" prop="app">
25 28 <el-input v-model="proxyParam.app" clearable></el-input>
26 29 </el-form-item>
27 30 <el-form-item label="流ID" prop="stream">
... ... @@ -39,6 +42,9 @@
39 42 <el-form-item label="FFmpeg命令模板" prop="ffmpeg_cmd_key" v-if="proxyParam.type=='ffmpeg'">
40 43 <el-input v-model="proxyParam.ffmpeg_cmd_key" clearable></el-input>
41 44 </el-form-item>
  45 + <el-form-item label="国标编码" prop="gbId">
  46 + <el-input v-model="proxyParam.gbId" placeholder="设置国标编码可推送到国标" clearable></el-input>
  47 + </el-form-item>
42 48 <el-form-item label="拉流方式" prop="rtp_type" v-if="proxyParam.type=='default'">
43 49 <el-select
44 50 v-model="proxyParam.rtp_type"
... ... @@ -100,6 +106,7 @@ export default {
100 106 isLoging: false,
101 107 onSubmit_text: "立即创建",
102 108 proxyParam: {
  109 + name: null,
103 110 type: "default",
104 111 app: null,
105 112 stream: null,
... ... @@ -107,6 +114,7 @@ export default {
107 114 src_url: null,
108 115 timeout_ms: null,
109 116 ffmpeg_cmd_key: null,
  117 + gbId: null,
110 118 rtp_type: null,
111 119 enable: true,
112 120 enable_hls: true,
... ... @@ -114,6 +122,7 @@ export default {
114 122 },
115 123  
116 124 rules: {
  125 + name: [{ required: true, message: "请输入名称", trigger: "blur" }],
117 126 app: [{ required: true, message: "请输入应用名", trigger: "blur" }],
118 127 stream: [{ required: true, message: "请输入流ID", trigger: "blur" }],
119 128 url: [{ required: true, message: "请输入要代理的流", trigger: "blur" }],
... ...
web_src/src/components/dialog/chooseChannel.vue
... ... @@ -13,7 +13,11 @@
13 13  
14 14 </el-tab-pane>
15 15 <el-tab-pane label="直播流通道" name="streamchannel">
16   - <!-- TODO -->
  16 + <el-container>
  17 + <el-main style="background-color: #FFF;">
  18 + <chooseChannelFoStream :platformId=platformId ></chooseChannelFoStream>
  19 + </el-main>
  20 + </el-container>
17 21 </el-tab-pane>
18 22 </el-tabs>
19 23 </el-dialog>
... ... @@ -22,11 +26,13 @@
22 26  
23 27 <script>
24 28 import chooseChannelForGb from '../dialog/chooseChannelForGb.vue'
  29 +import chooseChannelFoStream from '../dialog/chooseChannelForStream.vue'
25 30 export default {
26 31 name: 'chooseChannel',
27 32 props: {},
28 33 components: {
29 34 chooseChannelForGb,
  35 + chooseChannelFoStream,
30 36 },
31 37 computed: {
32 38 // getPlayerShared: function () {
... ...
web_src/src/components/dialog/chooseChannelForGb.vue
... ... @@ -27,7 +27,7 @@
27 27 <el-table-column type="selection" width="55" align="center" fixed > </el-table-column>
28 28 <el-table-column prop="channelId" label="通道编号" width="210">
29 29 </el-table-column>
30   - <el-table-column prop="name" label="通道名称">
  30 + <el-table-column prop="name" label="通道名称" show-overflow-tooltip>
31 31 </el-table-column>
32 32 <el-table-column prop="deviceId" label="设备编号" width="210" >
33 33 </el-table-column>
... ...
web_src/src/components/dialog/chooseChannelForStream.vue 0 → 100644
  1 +<template>
  2 +<div id="chooseChannelFoStream" >
  3 + <el-table ref="gbStreamsTable" :data="gbStreams" border style="width: 100%" @selection-change="checkedChanage" >
  4 + <el-table-column type="selection" width="55" align="center" fixed > </el-table-column>
  5 + <el-table-column prop="name" label="名称" show-overflow-tooltip>
  6 + </el-table-column>
  7 + <el-table-column prop="app" label="应用名" show-overflow-tooltip>
  8 + </el-table-column>
  9 + <el-table-column prop="stream" label="流ID" show-overflow-tooltip>
  10 + </el-table-column>
  11 + <el-table-column prop="gbId" label="国标编码" show-overflow-tooltip>
  12 + </el-table-column>
  13 + <el-table-column prop="streamType" label="流来源" align="center" show-overflow-tooltip>
  14 + </el-table-column>
  15 + <el-table-column label="流来源" width="100" align="center">
  16 + <template slot-scope="scope">
  17 + <div slot="reference" class="name-wrapper">
  18 + <el-tag size="medium" v-if="scope.row.streamType == 'proxy'">拉流代理</el-tag>
  19 + <el-tag size="medium" v-if="scope.row.streamType == 'push'">推流</el-tag>
  20 + </div>
  21 + </template>
  22 + </el-table-column>
  23 + </el-table>
  24 + <el-pagination style="float: right;margin-top: 1rem;" @size-change="handleSizeChange" @current-change="currentChange" :current-page="currentPage" :page-size="count" :page-sizes="[10, 20, 30, 50]" layout="total, sizes, prev, pager, next" :total="total">
  25 + </el-pagination>
  26 +</div>
  27 +</template>
  28 +
  29 +<script>
  30 +export default {
  31 + name: 'chooseChannelFoStream',
  32 + props: {},
  33 + computed: {
  34 + // getPlayerShared: function () {
  35 + // return {
  36 + // sharedUrl: window.location.host + '/' + this.videoUrl,
  37 + // sharedIframe: '<iframe src="' + window.location.host + '/' + this.videoUrl + '"></iframe>',
  38 + // sharedRtmp: this.videoUrl
  39 + // };
  40 + // }
  41 + },
  42 + props: ['platformId'],
  43 + created() {
  44 + this.initData();
  45 + },
  46 + data() {
  47 + return {
  48 + gbStreams: [],
  49 + gbChoosechannel:{},
  50 + searchSrt: "",
  51 + channelType: "",
  52 + online: "",
  53 + choosed: "",
  54 + currentPage: 0,
  55 + count: 10,
  56 + total: 0,
  57 + eventEnanle: false
  58 +
  59 + };
  60 + },
  61 + watch:{
  62 + platformId(newData, oldData){
  63 + console.log(newData)
  64 + this.initData()
  65 +
  66 + },
  67 + },
  68 + methods: {
  69 + initData: function() {
  70 + this.getChannelList();
  71 + },
  72 + currentChange: function (val) {
  73 + this.currentPage = val;
  74 + this.initData();
  75 + },
  76 + handleSizeChange: function (val) {
  77 + this.count = val;
  78 + console.log(val)
  79 + this.initData();
  80 +
  81 + },
  82 + rowcheckedChanage: function (val, row) {
  83 + console.log(val)
  84 + console.log(row)
  85 + },
  86 + checkedChanage: function (val) {
  87 + var that = this;
  88 + if (!that.eventEnanle) {
  89 + return;
  90 + }
  91 + var tabelData = JSON.parse(JSON.stringify(this.$refs.gbStreamsTable.data));
  92 + console.log("checkedChanage")
  93 + console.log(val)
  94 +
  95 + var newData = {};
  96 + var addData = [];
  97 + var delData = [];
  98 + if (val.length > 0) {
  99 + for (let i = 0; i < val.length; i++) {
  100 + const element = val[i];
  101 + var key = element.app + "_" + element.stream;
  102 + newData[key] = element;
  103 + if (!!!that.gbChoosechannel[key]){
  104 + addData.push(element)
  105 + }else{
  106 + delete that.gbChoosechannel[key]
  107 + }
  108 + }
  109 +
  110 + var oldKeys = Object.keys(that.gbChoosechannel);
  111 + if (oldKeys.length > 0) {
  112 + for (let i = 0; i < oldKeys.length; i++) {
  113 + const key = oldKeys[i];
  114 + delData.push(that.gbChoosechannel[key])
  115 + }
  116 + }
  117 +
  118 + }else{
  119 + var oldKeys = Object.keys(that.gbChoosechannel);
  120 + if (oldKeys.length > 0) {
  121 + for (let i = 0; i < oldKeys.length; i++) {
  122 + const key = oldKeys[i];
  123 + delData.push(that.gbChoosechannel[key])
  124 + }
  125 + }
  126 + }
  127 +
  128 + that.gbChoosechannel = newData;
  129 + if (Object.keys(addData).length >0) {
  130 + console.log(addData)
  131 + that.$axios({
  132 + method:"post",
  133 + url:"/api/gbStream/add",
  134 + data:{
  135 + platformId: that.platformId,
  136 + gbStreams: addData,
  137 + }
  138 + }).then((res)=>{
  139 + console.log("保存成功")
  140 + }).catch(function (error) {
  141 + console.log(error);
  142 + });
  143 + }
  144 + if (Object.keys(delData).length >0) {
  145 + console.log(delData)
  146 + that.$axios({
  147 + method:"post",
  148 + url:"/api/gbStream/del",
  149 + data:{
  150 + gbStreams: delData,
  151 + }
  152 + }).then((res)=>{
  153 + console.log("移除成功")
  154 + }).catch(function (error) {
  155 + console.log(error);
  156 + });
  157 + }
  158 +
  159 + },
  160 + shareAllCheckedChanage: function (val) {
  161 + this.chooseChanage(null, val)
  162 + },
  163 + getChannelList: function () {
  164 + let that = this;
  165 +
  166 + this.$axios.get(`/api/gbStream/list`, {
  167 + params: {
  168 + page: that.currentPage,
  169 + count: that.count,
  170 + query: that.searchSrt,
  171 + online: that.online,
  172 + choosed: that.choosed,
  173 + platformId: that.platformId,
  174 + channelType: that.channelType
  175 + }
  176 + })
  177 + .then(function (res) {
  178 + that.total = res.data.total;
  179 + that.gbStreams = res.data.list;
  180 + that.gbChoosechannel = {};
  181 + // 防止出现表格错位
  182 + that.$nextTick(() => {
  183 + that.$refs.gbStreamsTable.doLayout();
  184 + // 默认选中
  185 + var chooseGBS = [];
  186 + for (let i = 0; i < res.data.list.length; i++) {
  187 + const row = res.data.list[i];
  188 + console.log(row.platformId)
  189 + if (row.platformId == that.platformId) {
  190 + that.$refs.gbStreamsTable.toggleRowSelection(row, true);
  191 + chooseGBS.push(row)
  192 + that.gbChoosechannel[row.app+ "_" + row.stream] = row;
  193 +
  194 + }
  195 + }
  196 + that.eventEnanle = true;
  197 + // that.checkedChanage(chooseGBS)
  198 + })
  199 + console.log(that.gbChoosechannel)
  200 + })
  201 + .catch(function (error) {
  202 + console.log(error);
  203 + });
  204 +
  205 + },
  206 + handleGBSelectionChange: function() {
  207 + this.initData();
  208 + },
  209 + }
  210 +};
  211 +</script>
  212 +
  213 +<style>
  214 +
  215 +</style>
... ...
web_src/src/components/dialog/devicePlayer.vue
... ... @@ -163,6 +163,7 @@ export default {
163 163 },
164 164 showVideoDialog: false,
165 165 streamId: '',
  166 + app : '',
166 167 convertKey: '',
167 168 deviceId: '',
168 169 channelId: '',
... ... @@ -198,7 +199,7 @@ export default {
198 199 if (tab.name == "codec") {
199 200 this.$axios({
200 201 method: 'get',
201   - url: '/zlm/index/api/getMediaInfo?vhost=__defaultVhost__&schema=rtmp&app=rtp&stream='+ this.streamId
  202 + url: '/zlm/index/api/getMediaInfo?vhost=__defaultVhost__&schema=rtmp&app='+ this.app +'&stream='+ this.streamId
202 203 }).then(function (res) {
203 204 that.tracksLoading = false;
204 205 if (res.data.code == 0 && res.data.online) {
... ... @@ -218,6 +219,7 @@ export default {
218 219 this.channelId = channelId;
219 220 this.deviceId = deviceId;
220 221 this.streamId = "";
  222 + this.app = "";
221 223 this.videoUrl = ""
222 224 if (!!this.$refs.videoPlayer) {
223 225 this.$refs.videoPlayer.pause();
... ... @@ -228,11 +230,11 @@ export default {
228 230 break;
229 231 case "record":
230 232 this.showVideoDialog = true;
231   -
232 233 this.videoHistory.date = param.date;
233 234 this.queryRecords()
234 235 break;
235 236 case "streamPlay":
  237 + this.tabActiveName = "media";
236 238 this.showRrecord = false,
237 239 this.showPtz = false,
238 240 this.play(param.streamInfo, param.hasAudio)
... ... @@ -250,6 +252,7 @@ export default {
250 252 this.isLoging = false;
251 253 this.videoUrl = streamInfo.ws_flv;
252 254 this.streamId = streamInfo.streamId;
  255 + this.app = streamInfo.app;
253 256 this.playFromStreamInfo(false, streamInfo)
254 257 },
255 258 coverPlay: function () {
... ...
web_src/src/router/index.js
... ... @@ -6,6 +6,7 @@ import deviceList from &#39;../components/DeviceList.vue&#39;
6 6 import channelList from '../components/channelList.vue'
7 7 import pushVideoList from '../components/PushVideoList.vue'
8 8 import streamProxyList from '../components/StreamProxyList.vue'
  9 +import pLatformStreamList from '../components/PLatformStreamList.vue'
9 10 import devicePosition from '../components/devicePosition.vue'
10 11 import login from '../components/Login.vue'
11 12 import parentPlatformList from '../components/ParentPlatformList.vue'
... ... @@ -34,6 +35,10 @@ export default new VueRouter({
34 35 component: pushVideoList,
35 36 },
36 37 {
  38 + path: '/pLatformStreamList',
  39 + component: pLatformStreamList,
  40 + },
  41 + {
37 42 path: '/streamProxyList',
38 43 component: streamProxyList,
39 44 },
... ...