Commit 6ecd801c2365feb4e65f6684065aa97f11615797
1 parent
ca513992
增加设备删除接口,只允许删除离线设备;增加视频停止播放接口
Showing
22 changed files
with
266 additions
and
66 deletions
src/main/java/com/genersoft/iot/vmp/conf/SipConfig.java
| @@ -12,6 +12,8 @@ public class SipConfig { | @@ -12,6 +12,8 @@ public class SipConfig { | ||
| 12 | Integer sipPort; | 12 | Integer sipPort; |
| 13 | @Value("${sip.domain}") | 13 | @Value("${sip.domain}") |
| 14 | String sipDomain; | 14 | String sipDomain; |
| 15 | + @Value("${sip.id}") | ||
| 16 | + String sipId; | ||
| 15 | @Value("${sip.password}") | 17 | @Value("${sip.password}") |
| 16 | String sipPassword; | 18 | String sipPassword; |
| 17 | @Value("${media.ip}") | 19 | @Value("${media.ip}") |
| @@ -77,6 +79,12 @@ public class SipConfig { | @@ -77,6 +79,12 @@ public class SipConfig { | ||
| 77 | public void setSpeed(Integer speed) { | 79 | public void setSpeed(Integer speed) { |
| 78 | this.speed = speed; | 80 | this.speed = speed; |
| 79 | } | 81 | } |
| 80 | - | ||
| 81 | - | 82 | + |
| 83 | + public String getSipId() { | ||
| 84 | + return sipId; | ||
| 85 | + } | ||
| 86 | + | ||
| 87 | + public void setSipId(String sipId) { | ||
| 88 | + this.sipId = sipId; | ||
| 89 | + } | ||
| 82 | } | 90 | } |
src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java
| @@ -117,7 +117,7 @@ public class SipLayer implements SipListener, Runnable { | @@ -117,7 +117,7 @@ public class SipLayer implements SipListener, Runnable { | ||
| 117 | @Override | 117 | @Override |
| 118 | public void processRequest(RequestEvent evt) { | 118 | public void processRequest(RequestEvent evt) { |
| 119 | ISIPRequestProcessor processor = processorFactory.createRequestProcessor(evt); | 119 | ISIPRequestProcessor processor = processorFactory.createRequestProcessor(evt); |
| 120 | - processor.process(evt, this, getServerTransaction(evt)); | 120 | + processor.process(evt, this); |
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | @Override | 123 | @Override |
| @@ -200,7 +200,7 @@ public class SipLayer implements SipListener, Runnable { | @@ -200,7 +200,7 @@ public class SipLayer implements SipListener, Runnable { | ||
| 200 | 200 | ||
| 201 | } | 201 | } |
| 202 | 202 | ||
| 203 | - private ServerTransaction getServerTransaction(RequestEvent evt) { | 203 | + public ServerTransaction getServerTransaction(RequestEvent evt) { |
| 204 | Request request = evt.getRequest(); | 204 | Request request = evt.getRequest(); |
| 205 | ServerTransaction serverTransaction = evt.getServerTransaction(); | 205 | ServerTransaction serverTransaction = evt.getServerTransaction(); |
| 206 | // 判断TCP还是UDP | 206 | // 判断TCP还是UDP |
src/main/java/com/genersoft/iot/vmp/gb28181/utils/SsrcUtil.java renamed to src/main/java/com/genersoft/iot/vmp/gb28181/session/SsrcUtil.java
src/main/java/com/genersoft/iot/vmp/gb28181/session/VideoStreamSessionManager.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.gb28181.session; | ||
| 2 | + | ||
| 3 | +import java.util.concurrent.ConcurrentHashMap; | ||
| 4 | + | ||
| 5 | +import javax.sip.ClientTransaction; | ||
| 6 | + | ||
| 7 | +import org.springframework.stereotype.Component; | ||
| 8 | + | ||
| 9 | +/** | ||
| 10 | + * @Description:视频流session管理器,管理视频预览、预览回放的通信句柄 | ||
| 11 | + * @author: songww | ||
| 12 | + * @date: 2020年5月13日 下午4:03:02 | ||
| 13 | + */ | ||
| 14 | +@Component | ||
| 15 | +public class VideoStreamSessionManager { | ||
| 16 | + | ||
| 17 | + private ConcurrentHashMap<String, ClientTransaction> sessionMap = new ConcurrentHashMap<>(); | ||
| 18 | + | ||
| 19 | + public String createPlaySsrc(){ | ||
| 20 | + String ssrc = SsrcUtil.getPlaySsrc(); | ||
| 21 | + return ssrc; | ||
| 22 | + } | ||
| 23 | + | ||
| 24 | + public String createPlayBackSsrc(){ | ||
| 25 | + String ssrc = SsrcUtil.getPlayBackSsrc(); | ||
| 26 | + return ssrc; | ||
| 27 | + } | ||
| 28 | + | ||
| 29 | + public void put(String ssrc,ClientTransaction transaction){ | ||
| 30 | + sessionMap.put(ssrc, transaction); | ||
| 31 | + } | ||
| 32 | + | ||
| 33 | + public ClientTransaction get(String ssrc){ | ||
| 34 | + return sessionMap.get(ssrc); | ||
| 35 | + } | ||
| 36 | + | ||
| 37 | + public void remove(String ssrc) { | ||
| 38 | + sessionMap.remove(ssrc); | ||
| 39 | + SsrcUtil.releaseSsrc(ssrc); | ||
| 40 | + } | ||
| 41 | +} |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java
| @@ -82,6 +82,13 @@ public interface ISIPCommander { | @@ -82,6 +82,13 @@ public interface ISIPCommander { | ||
| 82 | public String playbackStreamCmd(Device device,String channelId, String startTime, String endTime); | 82 | public String playbackStreamCmd(Device device,String channelId, String startTime, String endTime); |
| 83 | 83 | ||
| 84 | /** | 84 | /** |
| 85 | + * 视频流停止 | ||
| 86 | + * | ||
| 87 | + * @param ssrc ssrc | ||
| 88 | + */ | ||
| 89 | + public void streamByeCmd(String ssrc); | ||
| 90 | + | ||
| 91 | + /** | ||
| 85 | * 语音广播 | 92 | * 语音广播 |
| 86 | * | 93 | * |
| 87 | * @param device 视频设备 | 94 | * @param device 视频设备 |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java
| @@ -46,14 +46,15 @@ public class SIPRequestHeaderProvider { | @@ -46,14 +46,15 @@ public class SIPRequestHeaderProvider { | ||
| 46 | ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>(); | 46 | ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>(); |
| 47 | ViaHeader viaHeader = layer.getHeaderFactory().createViaHeader(sipConfig.getSipIp(), sipConfig.getSipPort(), | 47 | ViaHeader viaHeader = layer.getHeaderFactory().createViaHeader(sipConfig.getSipIp(), sipConfig.getSipPort(), |
| 48 | device.getTransport(), viaTag); | 48 | device.getTransport(), viaTag); |
| 49 | + viaHeader.setRPort(); | ||
| 49 | viaHeaders.add(viaHeader); | 50 | viaHeaders.add(viaHeader); |
| 50 | // from | 51 | // from |
| 51 | - SipURI fromSipURI = layer.getAddressFactory().createSipURI(device.getDeviceId(), | 52 | + SipURI fromSipURI = layer.getAddressFactory().createSipURI(sipConfig.getSipId(), |
| 52 | sipConfig.getSipIp() + ":" + sipConfig.getSipPort()); | 53 | sipConfig.getSipIp() + ":" + sipConfig.getSipPort()); |
| 53 | Address fromAddress = layer.getAddressFactory().createAddress(fromSipURI); | 54 | Address fromAddress = layer.getAddressFactory().createAddress(fromSipURI); |
| 54 | FromHeader fromHeader = layer.getHeaderFactory().createFromHeader(fromAddress, fromTag); | 55 | FromHeader fromHeader = layer.getHeaderFactory().createFromHeader(fromAddress, fromTag); |
| 55 | // to | 56 | // to |
| 56 | - SipURI toSipURI = layer.getAddressFactory().createSipURI(device.getDeviceId(), host.getAddress()); | 57 | + SipURI toSipURI = layer.getAddressFactory().createSipURI(device.getDeviceId(), sipConfig.getSipDomain()); |
| 57 | Address toAddress = layer.getAddressFactory().createAddress(toSipURI); | 58 | Address toAddress = layer.getAddressFactory().createAddress(toSipURI); |
| 58 | ToHeader toHeader = layer.getHeaderFactory().createToHeader(toAddress, toTag); | 59 | ToHeader toHeader = layer.getHeaderFactory().createToHeader(toAddress, toTag); |
| 59 | // callid | 60 | // callid |
| @@ -71,6 +72,49 @@ public class SIPRequestHeaderProvider { | @@ -71,6 +72,49 @@ public class SIPRequestHeaderProvider { | ||
| 71 | return request; | 72 | return request; |
| 72 | } | 73 | } |
| 73 | 74 | ||
| 75 | +// public Request createInviteRequest(Device device, String content, String viaTag, String fromTag, String toTag) throws ParseException, InvalidArgumentException { | ||
| 76 | +// Request request = null; | ||
| 77 | +// Host host = device.getHost(); | ||
| 78 | +// //请求行 | ||
| 79 | +// SipURI requestLine = layer.getAddressFactory().createSipURI(device.getDeviceId(), host.getAddress()); | ||
| 80 | +// //via | ||
| 81 | +// ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>(); | ||
| 82 | +// ViaHeader viaHeader = layer.getHeaderFactory().createViaHeader(sipConfig.getSipIp(), sipConfig.getSipPort(), device.getTransport(), viaTag); | ||
| 83 | +// viaHeader.setRPort(); | ||
| 84 | +// viaHeaders.add(viaHeader); | ||
| 85 | +// //from | ||
| 86 | +// SipURI fromSipURI = layer.getAddressFactory().createSipURI(device.getDeviceId(),sipConfig.getSipIp()+":"+sipConfig.getSipPort()); | ||
| 87 | +// Address fromAddress = layer.getAddressFactory().createAddress(fromSipURI); | ||
| 88 | +// FromHeader fromHeader = layer.getHeaderFactory().createFromHeader(fromAddress, fromTag); //必须要有标记,否则无法创建会话,无法回应ack | ||
| 89 | +// //to | ||
| 90 | +// SipURI toSipURI = layer.getAddressFactory().createSipURI(device.getDeviceId(),host.getAddress()); | ||
| 91 | +// Address toAddress = layer.getAddressFactory().createAddress(toSipURI); | ||
| 92 | +// ToHeader toHeader = layer.getHeaderFactory().createToHeader(toAddress,null); | ||
| 93 | +// | ||
| 94 | +// //callid | ||
| 95 | +// CallIdHeader callIdHeader = null; | ||
| 96 | +// if(device.getTransport().equals("TCP")) { | ||
| 97 | +// callIdHeader = layer.getTcpSipProvider().getNewCallId(); | ||
| 98 | +// } | ||
| 99 | +// if(device.getTransport().equals("UDP")) { | ||
| 100 | +// callIdHeader = layer.getUdpSipProvider().getNewCallId(); | ||
| 101 | +// } | ||
| 102 | +// | ||
| 103 | +// //Forwards | ||
| 104 | +// MaxForwardsHeader maxForwards = layer.getHeaderFactory().createMaxForwardsHeader(70); | ||
| 105 | +// | ||
| 106 | +// //ceq | ||
| 107 | +// CSeqHeader cSeqHeader = layer.getHeaderFactory().createCSeqHeader(1L, Request.INVITE); | ||
| 108 | +// request = layer.getMessageFactory().createRequest(requestLine, Request.INVITE, callIdHeader, cSeqHeader,fromHeader, toHeader, viaHeaders, maxForwards); | ||
| 109 | +// | ||
| 110 | +// Address concatAddress = layer.getAddressFactory().createAddress(layer.getAddressFactory().createSipURI(sipConfig.getSipId(), sipConfig.getSipIp()+":"+sipConfig.getSipPort())); | ||
| 111 | +// request.addHeader(layer.getHeaderFactory().createContactHeader(concatAddress)); | ||
| 112 | +// | ||
| 113 | +// ContentTypeHeader contentTypeHeader = layer.getHeaderFactory().createContentTypeHeader("Application", "SDP"); | ||
| 114 | +// request.setContent(content, contentTypeHeader); | ||
| 115 | +// return request; | ||
| 116 | +// } | ||
| 117 | + | ||
| 74 | public Request createInviteRequest(Device device, String content, String viaTag, String fromTag, String toTag) throws ParseException, InvalidArgumentException { | 118 | public Request createInviteRequest(Device device, String content, String viaTag, String fromTag, String toTag) throws ParseException, InvalidArgumentException { |
| 75 | Request request = null; | 119 | Request request = null; |
| 76 | Host host = device.getHost(); | 120 | Host host = device.getHost(); |
| @@ -82,11 +126,11 @@ public class SIPRequestHeaderProvider { | @@ -82,11 +126,11 @@ public class SIPRequestHeaderProvider { | ||
| 82 | viaHeader.setRPort(); | 126 | viaHeader.setRPort(); |
| 83 | viaHeaders.add(viaHeader); | 127 | viaHeaders.add(viaHeader); |
| 84 | //from | 128 | //from |
| 85 | - SipURI fromSipURI = layer.getAddressFactory().createSipURI(device.getDeviceId(),sipConfig.getSipIp()+":"+sipConfig.getSipPort()); | 129 | + SipURI fromSipURI = layer.getAddressFactory().createSipURI(sipConfig.getSipId(),sipConfig.getSipDomain()); |
| 86 | Address fromAddress = layer.getAddressFactory().createAddress(fromSipURI); | 130 | Address fromAddress = layer.getAddressFactory().createAddress(fromSipURI); |
| 87 | FromHeader fromHeader = layer.getHeaderFactory().createFromHeader(fromAddress, fromTag); //必须要有标记,否则无法创建会话,无法回应ack | 131 | FromHeader fromHeader = layer.getHeaderFactory().createFromHeader(fromAddress, fromTag); //必须要有标记,否则无法创建会话,无法回应ack |
| 88 | //to | 132 | //to |
| 89 | - SipURI toSipURI = layer.getAddressFactory().createSipURI(device.getDeviceId(),host.getAddress()); | 133 | + SipURI toSipURI = layer.getAddressFactory().createSipURI(device.getDeviceId(),sipConfig.getSipDomain()); |
| 90 | Address toAddress = layer.getAddressFactory().createAddress(toSipURI); | 134 | Address toAddress = layer.getAddressFactory().createAddress(toSipURI); |
| 91 | ToHeader toHeader = layer.getHeaderFactory().createToHeader(toAddress,null); | 135 | ToHeader toHeader = layer.getHeaderFactory().createToHeader(toAddress,null); |
| 92 | 136 | ||
| @@ -101,9 +145,14 @@ public class SIPRequestHeaderProvider { | @@ -101,9 +145,14 @@ public class SIPRequestHeaderProvider { | ||
| 101 | 145 | ||
| 102 | //Forwards | 146 | //Forwards |
| 103 | MaxForwardsHeader maxForwards = layer.getHeaderFactory().createMaxForwardsHeader(70); | 147 | MaxForwardsHeader maxForwards = layer.getHeaderFactory().createMaxForwardsHeader(70); |
| 148 | + | ||
| 104 | //ceq | 149 | //ceq |
| 105 | CSeqHeader cSeqHeader = layer.getHeaderFactory().createCSeqHeader(1L, Request.INVITE); | 150 | CSeqHeader cSeqHeader = layer.getHeaderFactory().createCSeqHeader(1L, Request.INVITE); |
| 106 | request = layer.getMessageFactory().createRequest(requestLine, Request.INVITE, callIdHeader, cSeqHeader,fromHeader, toHeader, viaHeaders, maxForwards); | 151 | request = layer.getMessageFactory().createRequest(requestLine, Request.INVITE, callIdHeader, cSeqHeader,fromHeader, toHeader, viaHeaders, maxForwards); |
| 152 | + | ||
| 153 | + Address concatAddress = layer.getAddressFactory().createAddress(layer.getAddressFactory().createSipURI(sipConfig.getSipId(), sipConfig.getSipIp()+":"+sipConfig.getSipPort())); | ||
| 154 | + request.addHeader(layer.getHeaderFactory().createContactHeader(concatAddress)); | ||
| 155 | + | ||
| 107 | ContentTypeHeader contentTypeHeader = layer.getHeaderFactory().createContentTypeHeader("Application", "SDP"); | 156 | ContentTypeHeader contentTypeHeader = layer.getHeaderFactory().createContentTypeHeader("Application", "SDP"); |
| 108 | request.setContent(content, contentTypeHeader); | 157 | request.setContent(content, contentTypeHeader); |
| 109 | return request; | 158 | return request; |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
| @@ -3,8 +3,11 @@ package com.genersoft.iot.vmp.gb28181.transmit.cmd.impl; | @@ -3,8 +3,11 @@ package com.genersoft.iot.vmp.gb28181.transmit.cmd.impl; | ||
| 3 | import java.text.ParseException; | 3 | import java.text.ParseException; |
| 4 | 4 | ||
| 5 | import javax.sip.ClientTransaction; | 5 | import javax.sip.ClientTransaction; |
| 6 | +import javax.sip.Dialog; | ||
| 6 | import javax.sip.InvalidArgumentException; | 7 | import javax.sip.InvalidArgumentException; |
| 7 | import javax.sip.SipException; | 8 | import javax.sip.SipException; |
| 9 | +import javax.sip.TransactionDoesNotExistException; | ||
| 10 | +import javax.sip.header.ViaHeader; | ||
| 8 | import javax.sip.message.Request; | 11 | import javax.sip.message.Request; |
| 9 | 12 | ||
| 10 | import org.springframework.beans.factory.annotation.Autowired; | 13 | import org.springframework.beans.factory.annotation.Autowired; |
| @@ -13,10 +16,10 @@ import org.springframework.stereotype.Component; | @@ -13,10 +16,10 @@ import org.springframework.stereotype.Component; | ||
| 13 | import com.genersoft.iot.vmp.conf.SipConfig; | 16 | import com.genersoft.iot.vmp.conf.SipConfig; |
| 14 | import com.genersoft.iot.vmp.gb28181.SipLayer; | 17 | import com.genersoft.iot.vmp.gb28181.SipLayer; |
| 15 | import com.genersoft.iot.vmp.gb28181.bean.Device; | 18 | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| 19 | +import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; | ||
| 16 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; | 20 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; |
| 17 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider; | 21 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider; |
| 18 | import com.genersoft.iot.vmp.gb28181.utils.DateUtil; | 22 | import com.genersoft.iot.vmp.gb28181.utils.DateUtil; |
| 19 | -import com.genersoft.iot.vmp.gb28181.utils.SsrcUtil; | ||
| 20 | 23 | ||
| 21 | /** | 24 | /** |
| 22 | * @Description:设备能力接口,用于定义设备的控制、查询能力 | 25 | * @Description:设备能力接口,用于定义设备的控制、查询能力 |
| @@ -35,6 +38,9 @@ public class SIPCommander implements ISIPCommander { | @@ -35,6 +38,9 @@ public class SIPCommander implements ISIPCommander { | ||
| 35 | @Autowired | 38 | @Autowired |
| 36 | private SipLayer sipLayer; | 39 | private SipLayer sipLayer; |
| 37 | 40 | ||
| 41 | + @Autowired | ||
| 42 | + private VideoStreamSessionManager streamSession; | ||
| 43 | + | ||
| 38 | /** | 44 | /** |
| 39 | * 云台方向放控制,使用配置文件中的默认镜头移动速度 | 45 | * 云台方向放控制,使用配置文件中的默认镜头移动速度 |
| 40 | * | 46 | * |
| @@ -135,11 +141,11 @@ public class SIPCommander implements ISIPCommander { | @@ -135,11 +141,11 @@ public class SIPCommander implements ISIPCommander { | ||
| 135 | public String playStreamCmd(Device device, String channelId) { | 141 | public String playStreamCmd(Device device, String channelId) { |
| 136 | try { | 142 | try { |
| 137 | 143 | ||
| 138 | - String ssrc = SsrcUtil.getPlaySsrc(); | 144 | + String ssrc = streamSession.createPlaySsrc(); |
| 139 | // | 145 | // |
| 140 | StringBuffer content = new StringBuffer(200); | 146 | StringBuffer content = new StringBuffer(200); |
| 141 | content.append("v=0\r\n"); | 147 | content.append("v=0\r\n"); |
| 142 | - content.append("o="+channelId+" 0 0 IN IP4 "+sipConfig.getSipIp()+"\r\n"); | 148 | + content.append("o="+channelId+" 0 0 IN IP4 "+sipConfig.getMediaIp()+"\r\n"); |
| 143 | content.append("s=Play\r\n"); | 149 | content.append("s=Play\r\n"); |
| 144 | content.append("c=IN IP4 "+sipConfig.getMediaIp()+"\r\n"); | 150 | content.append("c=IN IP4 "+sipConfig.getMediaIp()+"\r\n"); |
| 145 | content.append("t=0 0\r\n"); | 151 | content.append("t=0 0\r\n"); |
| @@ -161,7 +167,8 @@ public class SIPCommander implements ISIPCommander { | @@ -161,7 +167,8 @@ public class SIPCommander implements ISIPCommander { | ||
| 161 | 167 | ||
| 162 | Request request = headerProvider.createInviteRequest(device, content.toString(), null, "live", null); | 168 | Request request = headerProvider.createInviteRequest(device, content.toString(), null, "live", null); |
| 163 | 169 | ||
| 164 | - transmitRequest(device, request); | 170 | + ClientTransaction transaction = transmitRequest(device, request); |
| 171 | + streamSession.put(ssrc, transaction); | ||
| 165 | return ssrc; | 172 | return ssrc; |
| 166 | } catch ( SipException | ParseException | InvalidArgumentException e) { | 173 | } catch ( SipException | ParseException | InvalidArgumentException e) { |
| 167 | e.printStackTrace(); | 174 | e.printStackTrace(); |
| @@ -181,11 +188,11 @@ public class SIPCommander implements ISIPCommander { | @@ -181,11 +188,11 @@ public class SIPCommander implements ISIPCommander { | ||
| 181 | public String playbackStreamCmd(Device device, String channelId, String startTime, String endTime) { | 188 | public String playbackStreamCmd(Device device, String channelId, String startTime, String endTime) { |
| 182 | try { | 189 | try { |
| 183 | 190 | ||
| 184 | - String ssrc = SsrcUtil.getPlayBackSsrc(); | 191 | + String ssrc = streamSession.createPlayBackSsrc(); |
| 185 | // | 192 | // |
| 186 | StringBuffer content = new StringBuffer(200); | 193 | StringBuffer content = new StringBuffer(200); |
| 187 | content.append("v=0\r\n"); | 194 | content.append("v=0\r\n"); |
| 188 | - content.append("o="+device.getDeviceId()+" 0 0 IN IP4 "+sipConfig.getSipIp()+"\r\n"); | 195 | + content.append("o="+device.getDeviceId()+" 0 0 IN IP4 "+sipConfig.getMediaIp()+"\r\n"); |
| 189 | content.append("s=Playback\r\n"); | 196 | content.append("s=Playback\r\n"); |
| 190 | content.append("u="+channelId+":3\r\n"); | 197 | content.append("u="+channelId+":3\r\n"); |
| 191 | content.append("c=IN IP4 "+sipConfig.getMediaIp()+"\r\n"); | 198 | content.append("c=IN IP4 "+sipConfig.getMediaIp()+"\r\n"); |
| @@ -208,13 +215,50 @@ public class SIPCommander implements ISIPCommander { | @@ -208,13 +215,50 @@ public class SIPCommander implements ISIPCommander { | ||
| 208 | 215 | ||
| 209 | Request request = headerProvider.createInviteRequest(device, content.toString(), null, "live", null); | 216 | Request request = headerProvider.createInviteRequest(device, content.toString(), null, "live", null); |
| 210 | 217 | ||
| 211 | - transmitRequest(device, request); | 218 | + ClientTransaction transaction = transmitRequest(device, request); |
| 219 | + streamSession.put(ssrc, transaction); | ||
| 212 | return ssrc; | 220 | return ssrc; |
| 213 | } catch ( SipException | ParseException | InvalidArgumentException e) { | 221 | } catch ( SipException | ParseException | InvalidArgumentException e) { |
| 214 | e.printStackTrace(); | 222 | e.printStackTrace(); |
| 215 | return null; | 223 | return null; |
| 216 | } | 224 | } |
| 217 | } | 225 | } |
| 226 | + | ||
| 227 | + /** | ||
| 228 | + * 视频流停止 | ||
| 229 | + * | ||
| 230 | + * @param device 视频设备 | ||
| 231 | + * @param channelId 预览通道 | ||
| 232 | + */ | ||
| 233 | + @Override | ||
| 234 | + public void streamByeCmd(String ssrc) { | ||
| 235 | + | ||
| 236 | + try { | ||
| 237 | + ClientTransaction transaction = streamSession.get(ssrc); | ||
| 238 | + if (transaction == null) { | ||
| 239 | + return; | ||
| 240 | + } | ||
| 241 | + | ||
| 242 | + Dialog dialog = transaction.getDialog(); | ||
| 243 | + if (dialog == null) { | ||
| 244 | + return; | ||
| 245 | + } | ||
| 246 | + Request byeRequest = dialog.createRequest(Request.BYE); | ||
| 247 | + ViaHeader viaHeader = (ViaHeader) byeRequest.getHeader(ViaHeader.NAME); | ||
| 248 | + String protocol = viaHeader.getTransport(); | ||
| 249 | + ClientTransaction clientTransaction = null; | ||
| 250 | + if("TCP".equals(protocol)) { | ||
| 251 | + clientTransaction = sipLayer.getTcpSipProvider().getNewClientTransaction(byeRequest); | ||
| 252 | + } else if("UDP".equals(protocol)) { | ||
| 253 | + clientTransaction = sipLayer.getUdpSipProvider().getNewClientTransaction(byeRequest); | ||
| 254 | + } | ||
| 255 | + dialog.sendRequest(clientTransaction); | ||
| 256 | + } catch (TransactionDoesNotExistException e) { | ||
| 257 | + e.printStackTrace(); | ||
| 258 | + } catch (SipException e) { | ||
| 259 | + e.printStackTrace(); | ||
| 260 | + } | ||
| 261 | + } | ||
| 218 | 262 | ||
| 219 | /** | 263 | /** |
| 220 | * 语音广播 | 264 | * 语音广播 |
| @@ -435,16 +479,15 @@ public class SIPCommander implements ISIPCommander { | @@ -435,16 +479,15 @@ public class SIPCommander implements ISIPCommander { | ||
| 435 | return false; | 479 | return false; |
| 436 | } | 480 | } |
| 437 | 481 | ||
| 438 | - private void transmitRequest(Device device, Request request) throws SipException { | 482 | + private ClientTransaction transmitRequest(Device device, Request request) throws SipException { |
| 439 | ClientTransaction clientTransaction = null; | 483 | ClientTransaction clientTransaction = null; |
| 440 | - if(device.getTransport().equals("TCP")) { | 484 | + if("TCP".equals(device.getTransport())) { |
| 441 | clientTransaction = sipLayer.getTcpSipProvider().getNewClientTransaction(request); | 485 | clientTransaction = sipLayer.getTcpSipProvider().getNewClientTransaction(request); |
| 442 | - //sipLayer.getTcpSipProvider().sendRequest(request); | ||
| 443 | - } else if(device.getTransport().equals("UDP")) { | 486 | + } else if("UDP".equals(device.getTransport())) { |
| 444 | clientTransaction = sipLayer.getUdpSipProvider().getNewClientTransaction(request); | 487 | clientTransaction = sipLayer.getUdpSipProvider().getNewClientTransaction(request); |
| 445 | - //sipLayer.getUdpSipProvider().sendRequest(request); | ||
| 446 | } | 488 | } |
| 447 | clientTransaction.sendRequest(); | 489 | clientTransaction.sendRequest(); |
| 490 | + return clientTransaction; | ||
| 448 | } | 491 | } |
| 449 | 492 | ||
| 450 | } | 493 | } |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/ISIPRequestProcessor.java
| 1 | package com.genersoft.iot.vmp.gb28181.transmit.request; | 1 | package com.genersoft.iot.vmp.gb28181.transmit.request; |
| 2 | 2 | ||
| 3 | import javax.sip.RequestEvent; | 3 | import javax.sip.RequestEvent; |
| 4 | -import javax.sip.ServerTransaction; | ||
| 5 | 4 | ||
| 6 | import com.genersoft.iot.vmp.gb28181.SipLayer; | 5 | import com.genersoft.iot.vmp.gb28181.SipLayer; |
| 7 | 6 | ||
| @@ -12,6 +11,6 @@ import com.genersoft.iot.vmp.gb28181.SipLayer; | @@ -12,6 +11,6 @@ import com.genersoft.iot.vmp.gb28181.SipLayer; | ||
| 12 | */ | 11 | */ |
| 13 | public interface ISIPRequestProcessor { | 12 | public interface ISIPRequestProcessor { |
| 14 | 13 | ||
| 15 | - public void process(RequestEvent evt, SipLayer layer, ServerTransaction transaction); | 14 | + public void process(RequestEvent evt, SipLayer layer); |
| 16 | 15 | ||
| 17 | } | 16 | } |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/AckRequestProcessor.java
| @@ -31,7 +31,7 @@ public class AckRequestProcessor implements ISIPRequestProcessor { | @@ -31,7 +31,7 @@ public class AckRequestProcessor implements ISIPRequestProcessor { | ||
| 31 | * @param config | 31 | * @param config |
| 32 | */ | 32 | */ |
| 33 | @Override | 33 | @Override |
| 34 | - public void process(RequestEvent evt, SipLayer layer, ServerTransaction transaction) { | 34 | + public void process(RequestEvent evt, SipLayer layer) { |
| 35 | Request request = evt.getRequest(); | 35 | Request request = evt.getRequest(); |
| 36 | Dialog dialog = evt.getDialog(); | 36 | Dialog dialog = evt.getDialog(); |
| 37 | try { | 37 | try { |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/ByeRequestProcessor.java
| @@ -25,7 +25,7 @@ public class ByeRequestProcessor implements ISIPRequestProcessor { | @@ -25,7 +25,7 @@ public class ByeRequestProcessor implements ISIPRequestProcessor { | ||
| 25 | * @param config | 25 | * @param config |
| 26 | */ | 26 | */ |
| 27 | @Override | 27 | @Override |
| 28 | - public void process(RequestEvent evt, SipLayer layer, ServerTransaction transaction) { | 28 | + public void process(RequestEvent evt, SipLayer layer) { |
| 29 | // TODO Auto-generated method stub | 29 | // TODO Auto-generated method stub |
| 30 | 30 | ||
| 31 | } | 31 | } |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/CancelRequestProcessor.java
| @@ -25,7 +25,7 @@ public class CancelRequestProcessor implements ISIPRequestProcessor { | @@ -25,7 +25,7 @@ public class CancelRequestProcessor implements ISIPRequestProcessor { | ||
| 25 | * @param config | 25 | * @param config |
| 26 | */ | 26 | */ |
| 27 | @Override | 27 | @Override |
| 28 | - public void process(RequestEvent evt, SipLayer layer, ServerTransaction transaction) { | 28 | + public void process(RequestEvent evt, SipLayer layer) { |
| 29 | // TODO Auto-generated method stub | 29 | // TODO Auto-generated method stub |
| 30 | 30 | ||
| 31 | } | 31 | } |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java
| @@ -23,7 +23,7 @@ public class InviteRequestProcessor implements ISIPRequestProcessor { | @@ -23,7 +23,7 @@ public class InviteRequestProcessor implements ISIPRequestProcessor { | ||
| 23 | * 请求消息 | 23 | * 请求消息 |
| 24 | */ | 24 | */ |
| 25 | @Override | 25 | @Override |
| 26 | - public void process(RequestEvent evt, SipLayer layer, ServerTransaction transaction) { | 26 | + public void process(RequestEvent evt, SipLayer layer) { |
| 27 | // TODO Auto-generated method stub | 27 | // TODO Auto-generated method stub |
| 28 | // Request request = requestEvent.getRequest(); | 28 | // Request request = requestEvent.getRequest(); |
| 29 | // | 29 | // |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
| @@ -93,10 +93,10 @@ public class MessageRequestProcessor implements ISIPRequestProcessor { | @@ -93,10 +93,10 @@ public class MessageRequestProcessor implements ISIPRequestProcessor { | ||
| 93 | * @param transaction | 93 | * @param transaction |
| 94 | */ | 94 | */ |
| 95 | @Override | 95 | @Override |
| 96 | - public void process(RequestEvent evt, SipLayer layer, ServerTransaction transaction) { | 96 | + public void process(RequestEvent evt, SipLayer layer) { |
| 97 | 97 | ||
| 98 | this.layer = layer; | 98 | this.layer = layer; |
| 99 | - this.transaction = transaction; | 99 | + this.transaction = layer.getServerTransaction(evt); |
| 100 | 100 | ||
| 101 | Request request = evt.getRequest(); | 101 | Request request = evt.getRequest(); |
| 102 | SAXReader reader = new SAXReader(); | 102 | SAXReader reader = new SAXReader(); |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/OtherRequestProcessor.java
| @@ -25,7 +25,7 @@ public class OtherRequestProcessor implements ISIPRequestProcessor { | @@ -25,7 +25,7 @@ public class OtherRequestProcessor implements ISIPRequestProcessor { | ||
| 25 | * @param config | 25 | * @param config |
| 26 | */ | 26 | */ |
| 27 | @Override | 27 | @Override |
| 28 | - public void process(RequestEvent evt, SipLayer layer, ServerTransaction transaction) { | 28 | + public void process(RequestEvent evt, SipLayer layer) { |
| 29 | System.out.println("no support the method! Method:" + evt.getRequest().getMethod()); | 29 | System.out.println("no support the method! Method:" + evt.getRequest().getMethod()); |
| 30 | } | 30 | } |
| 31 | 31 |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/RegisterRequestProcessor.java
| @@ -63,7 +63,7 @@ public class RegisterRequestProcessor implements ISIPRequestProcessor { | @@ -63,7 +63,7 @@ public class RegisterRequestProcessor implements ISIPRequestProcessor { | ||
| 63 | * 请求消息 | 63 | * 请求消息 |
| 64 | */ | 64 | */ |
| 65 | @Override | 65 | @Override |
| 66 | - public void process(RequestEvent evt, SipLayer layer, ServerTransaction transaction) { | 66 | + public void process(RequestEvent evt, SipLayer layer) { |
| 67 | try { | 67 | try { |
| 68 | System.out.println("收到注册请求,开始处理"); | 68 | System.out.println("收到注册请求,开始处理"); |
| 69 | Request request = evt.getRequest(); | 69 | Request request = evt.getRequest(); |
| @@ -141,7 +141,7 @@ public class RegisterRequestProcessor implements ISIPRequestProcessor { | @@ -141,7 +141,7 @@ public class RegisterRequestProcessor implements ISIPRequestProcessor { | ||
| 141 | device.setTransport(isTcp ? "TCP" : "UDP"); | 141 | device.setTransport(isTcp ? "TCP" : "UDP"); |
| 142 | } | 142 | } |
| 143 | } | 143 | } |
| 144 | - transaction.sendResponse(response); | 144 | + layer.getServerTransaction(evt).sendResponse(response); |
| 145 | // 注册成功 | 145 | // 注册成功 |
| 146 | // 保存到redis | 146 | // 保存到redis |
| 147 | // 下发catelog查询目录 | 147 | // 下发catelog查询目录 |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/SubscribeRequestProcessor.java
| @@ -32,7 +32,7 @@ public class SubscribeRequestProcessor implements ISIPRequestProcessor { | @@ -32,7 +32,7 @@ public class SubscribeRequestProcessor implements ISIPRequestProcessor { | ||
| 32 | * @param config | 32 | * @param config |
| 33 | */ | 33 | */ |
| 34 | @Override | 34 | @Override |
| 35 | - public void process(RequestEvent evt, SipLayer layer, ServerTransaction transaction) { | 35 | + public void process(RequestEvent evt, SipLayer layer) { |
| 36 | Request request = evt.getRequest(); | 36 | Request request = evt.getRequest(); |
| 37 | 37 | ||
| 38 | try { | 38 | try { |
| @@ -43,7 +43,7 @@ public class SubscribeRequestProcessor implements ISIPRequestProcessor { | @@ -43,7 +43,7 @@ public class SubscribeRequestProcessor implements ISIPRequestProcessor { | ||
| 43 | response.setExpires(expireHeader); | 43 | response.setExpires(expireHeader); |
| 44 | } | 44 | } |
| 45 | System.out.println("response : " + response.toString()); | 45 | System.out.println("response : " + response.toString()); |
| 46 | - | 46 | + ServerTransaction transaction = layer.getServerTransaction(evt); |
| 47 | if (transaction != null) { | 47 | if (transaction != null) { |
| 48 | transaction.sendResponse(response); | 48 | transaction.sendResponse(response); |
| 49 | transaction.terminate(); | 49 | transaction.terminate(); |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/InviteResponseProcessor.java
| @@ -50,31 +50,33 @@ public class InviteResponseProcessor implements ISIPResponseProcessor { | @@ -50,31 +50,33 @@ public class InviteResponseProcessor implements ISIPResponseProcessor { | ||
| 50 | //成功响应 | 50 | //成功响应 |
| 51 | //下发ack | 51 | //下发ack |
| 52 | if(statusCode == Response.OK){ | 52 | if(statusCode == Response.OK){ |
| 53 | - ClientTransaction clientTransaction = evt.getClientTransaction(); | ||
| 54 | - if(clientTransaction == null){ | ||
| 55 | - logger.error("回复ACK时,clientTransaction为null >>> {}",response); | ||
| 56 | - return; | ||
| 57 | - } | ||
| 58 | - Dialog clientDialog = clientTransaction.getDialog(); | ||
| 59 | - | ||
| 60 | - CSeqHeader clientCSeqHeader = (CSeqHeader) response.getHeader(CSeqHeader.NAME); | ||
| 61 | - long cseqId = clientCSeqHeader.getSeqNumber(); | ||
| 62 | - /* | ||
| 63 | - createAck函数,创建的ackRequest,会采用Invite响应的200OK,中的contact字段中的地址,作为目标地址。 | ||
| 64 | - 有的终端传上来的可能还是内网地址,会造成ack发送不出去。接受不到音视频流 | ||
| 65 | - 所以在此处统一替换地址。和响应消息的Via头中的地址保持一致。 | ||
| 66 | - */ | ||
| 67 | - Request ackRequest = clientDialog.createAck(cseqId); | ||
| 68 | - SipURI requestURI = (SipURI) ackRequest.getRequestURI(); | ||
| 69 | - ViaHeader viaHeader = (ViaHeader) response.getHeader(ViaHeader.NAME); | ||
| 70 | - requestURI.setHost(viaHeader.getHost()); | ||
| 71 | - requestURI.setPort(viaHeader.getPort()); | ||
| 72 | - clientDialog.sendAck(ackRequest); | 53 | +// ClientTransaction clientTransaction = evt.getClientTransaction(); |
| 54 | +// if(clientTransaction == null){ | ||
| 55 | +// logger.error("回复ACK时,clientTransaction为null >>> {}",response); | ||
| 56 | +// return; | ||
| 57 | +// } | ||
| 58 | +// Dialog clientDialog = clientTransaction.getDialog(); | ||
| 59 | +// | ||
| 60 | +// CSeqHeader clientCSeqHeader = (CSeqHeader) response.getHeader(CSeqHeader.NAME); | ||
| 61 | +// long cseqId = clientCSeqHeader.getSeqNumber(); | ||
| 62 | +// /* | ||
| 63 | +// createAck函数,创建的ackRequest,会采用Invite响应的200OK,中的contact字段中的地址,作为目标地址。 | ||
| 64 | +// 有的终端传上来的可能还是内网地址,会造成ack发送不出去。接受不到音视频流 | ||
| 65 | +// 所以在此处统一替换地址。和响应消息的Via头中的地址保持一致。 | ||
| 66 | +// */ | ||
| 67 | +// Request ackRequest = clientDialog.createAck(cseqId); | ||
| 68 | +// SipURI requestURI = (SipURI) ackRequest.getRequestURI(); | ||
| 69 | +// ViaHeader viaHeader = (ViaHeader) response.getHeader(ViaHeader.NAME); | ||
| 70 | +// requestURI.setHost(viaHeader.getHost()); | ||
| 71 | +// requestURI.setPort(viaHeader.getPort()); | ||
| 72 | +// clientDialog.sendAck(ackRequest); | ||
| 73 | + | ||
| 74 | + Dialog dialog = evt.getDialog(); | ||
| 75 | + Request reqAck =dialog.createAck(1L); | ||
| 76 | + dialog.sendAck(reqAck); | ||
| 73 | } | 77 | } |
| 74 | } catch (InvalidArgumentException | SipException e) { | 78 | } catch (InvalidArgumentException | SipException e) { |
| 75 | e.printStackTrace(); | 79 | e.printStackTrace(); |
| 76 | - } catch (ParseException e) { | ||
| 77 | - e.printStackTrace(); | ||
| 78 | } | 80 | } |
| 79 | } | 81 | } |
| 80 | 82 |
src/main/java/com/genersoft/iot/vmp/storager/redis/VideoManagerRedisStoragerImpl.java
| @@ -96,8 +96,7 @@ public class VideoManagerRedisStoragerImpl implements IVideoManagerStorager { | @@ -96,8 +96,7 @@ public class VideoManagerRedisStoragerImpl implements IVideoManagerStorager { | ||
| 96 | */ | 96 | */ |
| 97 | @Override | 97 | @Override |
| 98 | public boolean delete(String deviceId) { | 98 | public boolean delete(String deviceId) { |
| 99 | - redis.del(VideoManagerConstants.CACHEKEY_PREFIX+deviceId); | ||
| 100 | - return true; | 99 | + return redis.del(VideoManagerConstants.CACHEKEY_PREFIX+deviceId); |
| 101 | } | 100 | } |
| 102 | 101 | ||
| 103 | /** | 102 | /** |
src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java
| @@ -68,14 +68,20 @@ public class RedisUtil { | @@ -68,14 +68,20 @@ public class RedisUtil { | ||
| 68 | * @SuppressWarnings("unchecked") 忽略类型转换警告 | 68 | * @SuppressWarnings("unchecked") 忽略类型转换警告 |
| 69 | * @param key 键(一个或者多个) | 69 | * @param key 键(一个或者多个) |
| 70 | */ | 70 | */ |
| 71 | - public void del(String... key) { | ||
| 72 | - if (key != null && key.length > 0) { | ||
| 73 | - if (key.length == 1) { | ||
| 74 | - redisTemplate.delete(key[0]); | ||
| 75 | - } else { | ||
| 76 | -// 传入一个 Collection<String> 集合 | ||
| 77 | - redisTemplate.delete(CollectionUtils.arrayToList(key)); | 71 | + public boolean del(String... key) { |
| 72 | + try { | ||
| 73 | + if (key != null && key.length > 0) { | ||
| 74 | + if (key.length == 1) { | ||
| 75 | + redisTemplate.delete(key[0]); | ||
| 76 | + } else { | ||
| 77 | +// 传入一个 Collection<String> 集合 | ||
| 78 | + redisTemplate.delete(CollectionUtils.arrayToList(key)); | ||
| 79 | + } | ||
| 78 | } | 80 | } |
| 81 | + return true; | ||
| 82 | + } catch (Exception e) { | ||
| 83 | + e.printStackTrace(); | ||
| 84 | + return false; | ||
| 79 | } | 85 | } |
| 80 | } | 86 | } |
| 81 | 87 |
src/main/java/com/genersoft/iot/vmp/vmanager/device/DeviceController.java
| @@ -14,7 +14,9 @@ import org.springframework.web.bind.annotation.RequestMapping; | @@ -14,7 +14,9 @@ import org.springframework.web.bind.annotation.RequestMapping; | ||
| 14 | import org.springframework.web.bind.annotation.RestController; | 14 | import org.springframework.web.bind.annotation.RestController; |
| 15 | import org.springframework.web.context.request.async.DeferredResult; | 15 | import org.springframework.web.context.request.async.DeferredResult; |
| 16 | 16 | ||
| 17 | +import com.alibaba.fastjson.JSONObject; | ||
| 17 | import com.genersoft.iot.vmp.gb28181.bean.Device; | 18 | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| 19 | +import com.genersoft.iot.vmp.gb28181.event.DeviceOffLineDetector; | ||
| 18 | import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; | 20 | import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; |
| 19 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; | 21 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; |
| 20 | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; | 22 | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
| @@ -34,6 +36,9 @@ public class DeviceController { | @@ -34,6 +36,9 @@ public class DeviceController { | ||
| 34 | @Autowired | 36 | @Autowired |
| 35 | private DeferredResultHolder resultHolder; | 37 | private DeferredResultHolder resultHolder; |
| 36 | 38 | ||
| 39 | + @Autowired | ||
| 40 | + private DeviceOffLineDetector offLineDetector; | ||
| 41 | + | ||
| 37 | @GetMapping("/devices/{deviceId}") | 42 | @GetMapping("/devices/{deviceId}") |
| 38 | public ResponseEntity<Device> devices(@PathVariable String deviceId){ | 43 | public ResponseEntity<Device> devices(@PathVariable String deviceId){ |
| 39 | 44 | ||
| @@ -69,4 +74,25 @@ public class DeviceController { | @@ -69,4 +74,25 @@ public class DeviceController { | ||
| 69 | resultHolder.put(DeferredResultHolder.CALLBACK_CMD_CATALOG+deviceId, result); | 74 | resultHolder.put(DeferredResultHolder.CALLBACK_CMD_CATALOG+deviceId, result); |
| 70 | return result; | 75 | return result; |
| 71 | } | 76 | } |
| 77 | + | ||
| 78 | + @PostMapping("/devices/{deviceId}/delete") | ||
| 79 | + public ResponseEntity<String> delete(@PathVariable String deviceId){ | ||
| 80 | + | ||
| 81 | + if (logger.isDebugEnabled()) { | ||
| 82 | + logger.debug("设备信息删除API调用,deviceId:" + deviceId); | ||
| 83 | + } | ||
| 84 | + | ||
| 85 | + if (offLineDetector.isOnline(deviceId)) { | ||
| 86 | + return new ResponseEntity<String>("不允许删除在线设备!", HttpStatus.NOT_ACCEPTABLE); | ||
| 87 | + } | ||
| 88 | + boolean isSuccess = storager.delete(deviceId); | ||
| 89 | + if (isSuccess) { | ||
| 90 | + JSONObject json = new JSONObject(); | ||
| 91 | + json.put("deviceId", deviceId); | ||
| 92 | + return new ResponseEntity<>(json.toString(),HttpStatus.OK); | ||
| 93 | + } else { | ||
| 94 | + logger.warn("设备预览API调用失败!"); | ||
| 95 | + return new ResponseEntity<String>("设备预览API调用失败!", HttpStatus.INTERNAL_SERVER_ERROR); | ||
| 96 | + } | ||
| 97 | + } | ||
| 72 | } | 98 | } |
src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java
| @@ -7,6 +7,7 @@ import org.springframework.http.HttpStatus; | @@ -7,6 +7,7 @@ import org.springframework.http.HttpStatus; | ||
| 7 | import org.springframework.http.ResponseEntity; | 7 | import org.springframework.http.ResponseEntity; |
| 8 | import org.springframework.web.bind.annotation.GetMapping; | 8 | import org.springframework.web.bind.annotation.GetMapping; |
| 9 | import org.springframework.web.bind.annotation.PathVariable; | 9 | import org.springframework.web.bind.annotation.PathVariable; |
| 10 | +import org.springframework.web.bind.annotation.PostMapping; | ||
| 10 | import org.springframework.web.bind.annotation.RequestMapping; | 11 | import org.springframework.web.bind.annotation.RequestMapping; |
| 11 | import org.springframework.web.bind.annotation.RestController; | 12 | import org.springframework.web.bind.annotation.RestController; |
| 12 | 13 | ||
| @@ -47,4 +48,23 @@ public class PlayController { | @@ -47,4 +48,23 @@ public class PlayController { | ||
| 47 | return new ResponseEntity<String>(HttpStatus.INTERNAL_SERVER_ERROR); | 48 | return new ResponseEntity<String>(HttpStatus.INTERNAL_SERVER_ERROR); |
| 48 | } | 49 | } |
| 49 | } | 50 | } |
| 51 | + | ||
| 52 | + @PostMapping("/play/{ssrc}/stop") | ||
| 53 | + public ResponseEntity<String> playStop(@PathVariable String ssrc){ | ||
| 54 | + | ||
| 55 | + cmder.streamByeCmd(ssrc); | ||
| 56 | + | ||
| 57 | + if (logger.isDebugEnabled()) { | ||
| 58 | + logger.debug(String.format("设备预览停止API调用,ssrc:%s", ssrc)); | ||
| 59 | + } | ||
| 60 | + | ||
| 61 | + if(ssrc!=null) { | ||
| 62 | + JSONObject json = new JSONObject(); | ||
| 63 | + json.put("ssrc", ssrc); | ||
| 64 | + return new ResponseEntity<String>(json.toString(),HttpStatus.OK); | ||
| 65 | + } else { | ||
| 66 | + logger.warn("设备预览停止API调用失败!"); | ||
| 67 | + return new ResponseEntity<String>(HttpStatus.INTERNAL_SERVER_ERROR); | ||
| 68 | + } | ||
| 69 | + } | ||
| 50 | } | 70 | } |
src/main/resources/application.yml
| @@ -26,7 +26,7 @@ spring: | @@ -26,7 +26,7 @@ spring: | ||
| 26 | server: | 26 | server: |
| 27 | port: 8080 | 27 | port: 8080 |
| 28 | sip: | 28 | sip: |
| 29 | - ip: 127.0.0.1 | 29 | + ip: 10.200.64.63 |
| 30 | port: 5060 | 30 | port: 5060 |
| 31 | # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) | 31 | # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) |
| 32 | # 后两位为行业编码,定义参照附录D.3 | 32 | # 后两位为行业编码,定义参照附录D.3 |