Commit 7dc8fd4a1e8c5afb6fad53454935419c239838c0
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
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
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
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 '../components/DeviceList.vue' |
| 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 | }, | ... | ... |