Browse Source

增加设备删除接口,只允许删除离线设备;增加视频停止播放接口

pull/1/head
songww 5 years ago
parent
commit
6ecd801c23
  1. 8
      src/main/java/com/genersoft/iot/vmp/conf/SipConfig.java
  2. 4
      src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java
  3. 2
      src/main/java/com/genersoft/iot/vmp/gb28181/session/SsrcUtil.java
  4. 41
      src/main/java/com/genersoft/iot/vmp/gb28181/session/VideoStreamSessionManager.java
  5. 7
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java
  6. 57
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java
  7. 67
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
  8. 3
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/ISIPRequestProcessor.java
  9. 2
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/AckRequestProcessor.java
  10. 2
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/ByeRequestProcessor.java
  11. 2
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/CancelRequestProcessor.java
  12. 2
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java
  13. 4
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
  14. 2
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/OtherRequestProcessor.java
  15. 4
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/RegisterRequestProcessor.java
  16. 4
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/SubscribeRequestProcessor.java
  17. 44
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/InviteResponseProcessor.java
  18. 3
      src/main/java/com/genersoft/iot/vmp/storager/redis/VideoManagerRedisStoragerImpl.java
  19. 8
      src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java
  20. 26
      src/main/java/com/genersoft/iot/vmp/vmanager/device/DeviceController.java
  21. 20
      src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java
  22. 2
      src/main/resources/application.yml

8
src/main/java/com/genersoft/iot/vmp/conf/SipConfig.java

@ -12,6 +12,8 @@ public class SipConfig {
Integer sipPort;
@Value("${sip.domain}")
String sipDomain;
@Value("${sip.id}")
String sipId;
@Value("${sip.password}")
String sipPassword;
@Value("${media.ip}")
@ -78,5 +80,11 @@ public class SipConfig {
this.speed = speed;
}
public String getSipId() {
return sipId;
}
public void setSipId(String sipId) {
this.sipId = sipId;
}
}

4
src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java

@ -117,7 +117,7 @@ public class SipLayer implements SipListener, Runnable {
@Override
public void processRequest(RequestEvent evt) {
ISIPRequestProcessor processor = processorFactory.createRequestProcessor(evt);
processor.process(evt, this, getServerTransaction(evt));
processor.process(evt, this);
}
@Override
@ -200,7 +200,7 @@ public class SipLayer implements SipListener, Runnable {
}
private ServerTransaction getServerTransaction(RequestEvent evt) {
public ServerTransaction getServerTransaction(RequestEvent evt) {
Request request = evt.getRequest();
ServerTransaction serverTransaction = evt.getServerTransaction();
// 判断TCP还是UDP

2
src/main/java/com/genersoft/iot/vmp/gb28181/utils/SsrcUtil.java → src/main/java/com/genersoft/iot/vmp/gb28181/session/SsrcUtil.java

@ -1,4 +1,4 @@
package com.genersoft.iot.vmp.gb28181.utils;
package com.genersoft.iot.vmp.gb28181.session;
import java.util.ArrayList;
import java.util.List;

41
src/main/java/com/genersoft/iot/vmp/gb28181/session/VideoStreamSessionManager.java

@ -0,0 +1,41 @@
package com.genersoft.iot.vmp.gb28181.session;
import java.util.concurrent.ConcurrentHashMap;
import javax.sip.ClientTransaction;
import org.springframework.stereotype.Component;
/**
* @Description:视频流session管理器管理视频预览预览回放的通信句柄
* @author: songww
* @date: 2020年5月13日 下午4:03:02
*/
@Component
public class VideoStreamSessionManager {
private ConcurrentHashMap<String, ClientTransaction> sessionMap = new ConcurrentHashMap<>();
public String createPlaySsrc(){
String ssrc = SsrcUtil.getPlaySsrc();
return ssrc;
}
public String createPlayBackSsrc(){
String ssrc = SsrcUtil.getPlayBackSsrc();
return ssrc;
}
public void put(String ssrc,ClientTransaction transaction){
sessionMap.put(ssrc, transaction);
}
public ClientTransaction get(String ssrc){
return sessionMap.get(ssrc);
}
public void remove(String ssrc) {
sessionMap.remove(ssrc);
SsrcUtil.releaseSsrc(ssrc);
}
}

7
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java

@ -81,6 +81,13 @@ public interface ISIPCommander {
*/
public String playbackStreamCmd(Device device,String channelId, String startTime, String endTime);
/**
* 视频流停止
*
* @param ssrc ssrc
*/
public void streamByeCmd(String ssrc);
/**
* 语音广播
*

57
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java

@ -46,14 +46,15 @@ public class SIPRequestHeaderProvider {
ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>();
ViaHeader viaHeader = layer.getHeaderFactory().createViaHeader(sipConfig.getSipIp(), sipConfig.getSipPort(),
device.getTransport(), viaTag);
viaHeader.setRPort();
viaHeaders.add(viaHeader);
// from
SipURI fromSipURI = layer.getAddressFactory().createSipURI(device.getDeviceId(),
SipURI fromSipURI = layer.getAddressFactory().createSipURI(sipConfig.getSipId(),
sipConfig.getSipIp() + ":" + sipConfig.getSipPort());
Address fromAddress = layer.getAddressFactory().createAddress(fromSipURI);
FromHeader fromHeader = layer.getHeaderFactory().createFromHeader(fromAddress, fromTag);
// to
SipURI toSipURI = layer.getAddressFactory().createSipURI(device.getDeviceId(), host.getAddress());
SipURI toSipURI = layer.getAddressFactory().createSipURI(device.getDeviceId(), sipConfig.getSipDomain());
Address toAddress = layer.getAddressFactory().createAddress(toSipURI);
ToHeader toHeader = layer.getHeaderFactory().createToHeader(toAddress, toTag);
// callid
@ -71,6 +72,49 @@ public class SIPRequestHeaderProvider {
return request;
}
// public Request createInviteRequest(Device device, String content, String viaTag, String fromTag, String toTag) throws ParseException, InvalidArgumentException {
// Request request = null;
// Host host = device.getHost();
// //请求行
// SipURI requestLine = layer.getAddressFactory().createSipURI(device.getDeviceId(), host.getAddress());
// //via
// ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>();
// ViaHeader viaHeader = layer.getHeaderFactory().createViaHeader(sipConfig.getSipIp(), sipConfig.getSipPort(), device.getTransport(), viaTag);
// viaHeader.setRPort();
// viaHeaders.add(viaHeader);
// //from
// SipURI fromSipURI = layer.getAddressFactory().createSipURI(device.getDeviceId(),sipConfig.getSipIp()+":"+sipConfig.getSipPort());
// Address fromAddress = layer.getAddressFactory().createAddress(fromSipURI);
// FromHeader fromHeader = layer.getHeaderFactory().createFromHeader(fromAddress, fromTag); //必须要有标记,否则无法创建会话,无法回应ack
// //to
// SipURI toSipURI = layer.getAddressFactory().createSipURI(device.getDeviceId(),host.getAddress());
// Address toAddress = layer.getAddressFactory().createAddress(toSipURI);
// ToHeader toHeader = layer.getHeaderFactory().createToHeader(toAddress,null);
//
// //callid
// CallIdHeader callIdHeader = null;
// if(device.getTransport().equals("TCP")) {
// callIdHeader = layer.getTcpSipProvider().getNewCallId();
// }
// if(device.getTransport().equals("UDP")) {
// callIdHeader = layer.getUdpSipProvider().getNewCallId();
// }
//
// //Forwards
// MaxForwardsHeader maxForwards = layer.getHeaderFactory().createMaxForwardsHeader(70);
//
// //ceq
// CSeqHeader cSeqHeader = layer.getHeaderFactory().createCSeqHeader(1L, Request.INVITE);
// request = layer.getMessageFactory().createRequest(requestLine, Request.INVITE, callIdHeader, cSeqHeader,fromHeader, toHeader, viaHeaders, maxForwards);
//
// Address concatAddress = layer.getAddressFactory().createAddress(layer.getAddressFactory().createSipURI(sipConfig.getSipId(), sipConfig.getSipIp()+":"+sipConfig.getSipPort()));
// request.addHeader(layer.getHeaderFactory().createContactHeader(concatAddress));
//
// ContentTypeHeader contentTypeHeader = layer.getHeaderFactory().createContentTypeHeader("Application", "SDP");
// request.setContent(content, contentTypeHeader);
// return request;
// }
public Request createInviteRequest(Device device, String content, String viaTag, String fromTag, String toTag) throws ParseException, InvalidArgumentException {
Request request = null;
Host host = device.getHost();
@ -82,11 +126,11 @@ public class SIPRequestHeaderProvider {
viaHeader.setRPort();
viaHeaders.add(viaHeader);
//from
SipURI fromSipURI = layer.getAddressFactory().createSipURI(device.getDeviceId(),sipConfig.getSipIp()+":"+sipConfig.getSipPort());
SipURI fromSipURI = layer.getAddressFactory().createSipURI(sipConfig.getSipId(),sipConfig.getSipDomain());
Address fromAddress = layer.getAddressFactory().createAddress(fromSipURI);
FromHeader fromHeader = layer.getHeaderFactory().createFromHeader(fromAddress, fromTag); //必须要有标记,否则无法创建会话,无法回应ack
//to
SipURI toSipURI = layer.getAddressFactory().createSipURI(device.getDeviceId(),host.getAddress());
SipURI toSipURI = layer.getAddressFactory().createSipURI(device.getDeviceId(),sipConfig.getSipDomain());
Address toAddress = layer.getAddressFactory().createAddress(toSipURI);
ToHeader toHeader = layer.getHeaderFactory().createToHeader(toAddress,null);
@ -101,9 +145,14 @@ public class SIPRequestHeaderProvider {
//Forwards
MaxForwardsHeader maxForwards = layer.getHeaderFactory().createMaxForwardsHeader(70);
//ceq
CSeqHeader cSeqHeader = layer.getHeaderFactory().createCSeqHeader(1L, Request.INVITE);
request = layer.getMessageFactory().createRequest(requestLine, Request.INVITE, callIdHeader, cSeqHeader,fromHeader, toHeader, viaHeaders, maxForwards);
Address concatAddress = layer.getAddressFactory().createAddress(layer.getAddressFactory().createSipURI(sipConfig.getSipId(), sipConfig.getSipIp()+":"+sipConfig.getSipPort()));
request.addHeader(layer.getHeaderFactory().createContactHeader(concatAddress));
ContentTypeHeader contentTypeHeader = layer.getHeaderFactory().createContentTypeHeader("Application", "SDP");
request.setContent(content, contentTypeHeader);
return request;

67
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;
import java.text.ParseException;
import javax.sip.ClientTransaction;
import javax.sip.Dialog;
import javax.sip.InvalidArgumentException;
import javax.sip.SipException;
import javax.sip.TransactionDoesNotExistException;
import javax.sip.header.ViaHeader;
import javax.sip.message.Request;
import org.springframework.beans.factory.annotation.Autowired;
@ -13,10 +16,10 @@ import org.springframework.stereotype.Component;
import com.genersoft.iot.vmp.conf.SipConfig;
import com.genersoft.iot.vmp.gb28181.SipLayer;
import com.genersoft.iot.vmp.gb28181.bean.Device;
import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider;
import com.genersoft.iot.vmp.gb28181.utils.DateUtil;
import com.genersoft.iot.vmp.gb28181.utils.SsrcUtil;
/**
* @Description:设备能力接口用于定义设备的控制查询能力
@ -35,6 +38,9 @@ public class SIPCommander implements ISIPCommander {
@Autowired
private SipLayer sipLayer;
@Autowired
private VideoStreamSessionManager streamSession;
/**
* 云台方向放控制使用配置文件中的默认镜头移动速度
*
@ -135,11 +141,11 @@ public class SIPCommander implements ISIPCommander {
public String playStreamCmd(Device device, String channelId) {
try {
String ssrc = SsrcUtil.getPlaySsrc();
String ssrc = streamSession.createPlaySsrc();
//
StringBuffer content = new StringBuffer(200);
content.append("v=0\r\n");
content.append("o="+channelId+" 0 0 IN IP4 "+sipConfig.getSipIp()+"\r\n");
content.append("o="+channelId+" 0 0 IN IP4 "+sipConfig.getMediaIp()+"\r\n");
content.append("s=Play\r\n");
content.append("c=IN IP4 "+sipConfig.getMediaIp()+"\r\n");
content.append("t=0 0\r\n");
@ -161,7 +167,8 @@ public class SIPCommander implements ISIPCommander {
Request request = headerProvider.createInviteRequest(device, content.toString(), null, "live", null);
transmitRequest(device, request);
ClientTransaction transaction = transmitRequest(device, request);
streamSession.put(ssrc, transaction);
return ssrc;
} catch ( SipException | ParseException | InvalidArgumentException e) {
e.printStackTrace();
@ -181,11 +188,11 @@ public class SIPCommander implements ISIPCommander {
public String playbackStreamCmd(Device device, String channelId, String startTime, String endTime) {
try {
String ssrc = SsrcUtil.getPlayBackSsrc();
String ssrc = streamSession.createPlayBackSsrc();
//
StringBuffer content = new StringBuffer(200);
content.append("v=0\r\n");
content.append("o="+device.getDeviceId()+" 0 0 IN IP4 "+sipConfig.getSipIp()+"\r\n");
content.append("o="+device.getDeviceId()+" 0 0 IN IP4 "+sipConfig.getMediaIp()+"\r\n");
content.append("s=Playback\r\n");
content.append("u="+channelId+":3\r\n");
content.append("c=IN IP4 "+sipConfig.getMediaIp()+"\r\n");
@ -208,7 +215,8 @@ public class SIPCommander implements ISIPCommander {
Request request = headerProvider.createInviteRequest(device, content.toString(), null, "live", null);
transmitRequest(device, request);
ClientTransaction transaction = transmitRequest(device, request);
streamSession.put(ssrc, transaction);
return ssrc;
} catch ( SipException | ParseException | InvalidArgumentException e) {
e.printStackTrace();
@ -216,6 +224,42 @@ public class SIPCommander implements ISIPCommander {
}
}
/**
* 视频流停止
*
* @param device 视频设备
* @param channelId 预览通道
*/
@Override
public void streamByeCmd(String ssrc) {
try {
ClientTransaction transaction = streamSession.get(ssrc);
if (transaction == null) {
return;
}
Dialog dialog = transaction.getDialog();
if (dialog == null) {
return;
}
Request byeRequest = dialog.createRequest(Request.BYE);
ViaHeader viaHeader = (ViaHeader) byeRequest.getHeader(ViaHeader.NAME);
String protocol = viaHeader.getTransport();
ClientTransaction clientTransaction = null;
if("TCP".equals(protocol)) {
clientTransaction = sipLayer.getTcpSipProvider().getNewClientTransaction(byeRequest);
} else if("UDP".equals(protocol)) {
clientTransaction = sipLayer.getUdpSipProvider().getNewClientTransaction(byeRequest);
}
dialog.sendRequest(clientTransaction);
} catch (TransactionDoesNotExistException e) {
e.printStackTrace();
} catch (SipException e) {
e.printStackTrace();
}
}
/**
* 语音广播
*
@ -435,16 +479,15 @@ public class SIPCommander implements ISIPCommander {
return false;
}
private void transmitRequest(Device device, Request request) throws SipException {
private ClientTransaction transmitRequest(Device device, Request request) throws SipException {
ClientTransaction clientTransaction = null;
if(device.getTransport().equals("TCP")) {
if("TCP".equals(device.getTransport())) {
clientTransaction = sipLayer.getTcpSipProvider().getNewClientTransaction(request);
//sipLayer.getTcpSipProvider().sendRequest(request);
} else if(device.getTransport().equals("UDP")) {
} else if("UDP".equals(device.getTransport())) {
clientTransaction = sipLayer.getUdpSipProvider().getNewClientTransaction(request);
//sipLayer.getUdpSipProvider().sendRequest(request);
}
clientTransaction.sendRequest();
return clientTransaction;
}
}

3
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/ISIPRequestProcessor.java

@ -1,7 +1,6 @@
package com.genersoft.iot.vmp.gb28181.transmit.request;
import javax.sip.RequestEvent;
import javax.sip.ServerTransaction;
import com.genersoft.iot.vmp.gb28181.SipLayer;
@ -12,6 +11,6 @@ import com.genersoft.iot.vmp.gb28181.SipLayer;
*/
public interface ISIPRequestProcessor {
public void process(RequestEvent evt, SipLayer layer, ServerTransaction transaction);
public void process(RequestEvent evt, SipLayer layer);
}

2
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/AckRequestProcessor.java

@ -31,7 +31,7 @@ public class AckRequestProcessor implements ISIPRequestProcessor {
* @param config
*/
@Override
public void process(RequestEvent evt, SipLayer layer, ServerTransaction transaction) {
public void process(RequestEvent evt, SipLayer layer) {
Request request = evt.getRequest();
Dialog dialog = evt.getDialog();
try {

2
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/ByeRequestProcessor.java

@ -25,7 +25,7 @@ public class ByeRequestProcessor implements ISIPRequestProcessor {
* @param config
*/
@Override
public void process(RequestEvent evt, SipLayer layer, ServerTransaction transaction) {
public void process(RequestEvent evt, SipLayer layer) {
// TODO Auto-generated method stub
}

2
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/CancelRequestProcessor.java

@ -25,7 +25,7 @@ public class CancelRequestProcessor implements ISIPRequestProcessor {
* @param config
*/
@Override
public void process(RequestEvent evt, SipLayer layer, ServerTransaction transaction) {
public void process(RequestEvent evt, SipLayer layer) {
// TODO Auto-generated method stub
}

2
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java

@ -23,7 +23,7 @@ public class InviteRequestProcessor implements ISIPRequestProcessor {
* 请求消息
*/
@Override
public void process(RequestEvent evt, SipLayer layer, ServerTransaction transaction) {
public void process(RequestEvent evt, SipLayer layer) {
// TODO Auto-generated method stub
// Request request = requestEvent.getRequest();
//

4
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java

@ -93,10 +93,10 @@ public class MessageRequestProcessor implements ISIPRequestProcessor {
* @param transaction
*/
@Override
public void process(RequestEvent evt, SipLayer layer, ServerTransaction transaction) {
public void process(RequestEvent evt, SipLayer layer) {
this.layer = layer;
this.transaction = transaction;
this.transaction = layer.getServerTransaction(evt);
Request request = evt.getRequest();
SAXReader reader = new SAXReader();

2
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/OtherRequestProcessor.java

@ -25,7 +25,7 @@ public class OtherRequestProcessor implements ISIPRequestProcessor {
* @param config
*/
@Override
public void process(RequestEvent evt, SipLayer layer, ServerTransaction transaction) {
public void process(RequestEvent evt, SipLayer layer) {
System.out.println("no support the method! Method:" + evt.getRequest().getMethod());
}

4
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/RegisterRequestProcessor.java

@ -63,7 +63,7 @@ public class RegisterRequestProcessor implements ISIPRequestProcessor {
* 请求消息
*/
@Override
public void process(RequestEvent evt, SipLayer layer, ServerTransaction transaction) {
public void process(RequestEvent evt, SipLayer layer) {
try {
System.out.println("收到注册请求,开始处理");
Request request = evt.getRequest();
@ -141,7 +141,7 @@ public class RegisterRequestProcessor implements ISIPRequestProcessor {
device.setTransport(isTcp ? "TCP" : "UDP");
}
}
transaction.sendResponse(response);
layer.getServerTransaction(evt).sendResponse(response);
// 注册成功
// 保存到redis
// 下发catelog查询目录

4
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/SubscribeRequestProcessor.java

@ -32,7 +32,7 @@ public class SubscribeRequestProcessor implements ISIPRequestProcessor {
* @param config
*/
@Override
public void process(RequestEvent evt, SipLayer layer, ServerTransaction transaction) {
public void process(RequestEvent evt, SipLayer layer) {
Request request = evt.getRequest();
try {
@ -43,7 +43,7 @@ public class SubscribeRequestProcessor implements ISIPRequestProcessor {
response.setExpires(expireHeader);
}
System.out.println("response : " + response.toString());
ServerTransaction transaction = layer.getServerTransaction(evt);
if (transaction != null) {
transaction.sendResponse(response);
transaction.terminate();

44
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/InviteResponseProcessor.java

@ -50,31 +50,33 @@ public class InviteResponseProcessor implements ISIPResponseProcessor {
//成功响应
//下发ack
if(statusCode == Response.OK){
ClientTransaction clientTransaction = evt.getClientTransaction();
if(clientTransaction == null){
logger.error("回复ACK时,clientTransaction为null >>> {}",response);
return;
}
Dialog clientDialog = clientTransaction.getDialog();
// ClientTransaction clientTransaction = evt.getClientTransaction();
// if(clientTransaction == null){
// logger.error("回复ACK时,clientTransaction为null >>> {}",response);
// return;
// }
// Dialog clientDialog = clientTransaction.getDialog();
//
// CSeqHeader clientCSeqHeader = (CSeqHeader) response.getHeader(CSeqHeader.NAME);
// long cseqId = clientCSeqHeader.getSeqNumber();
// /*
// createAck函数,创建的ackRequest,会采用Invite响应的200OK,中的contact字段中的地址,作为目标地址。
// 有的终端传上来的可能还是内网地址,会造成ack发送不出去。接受不到音视频流
// 所以在此处统一替换地址。和响应消息的Via头中的地址保持一致。
// */
// Request ackRequest = clientDialog.createAck(cseqId);
// SipURI requestURI = (SipURI) ackRequest.getRequestURI();
// ViaHeader viaHeader = (ViaHeader) response.getHeader(ViaHeader.NAME);
// requestURI.setHost(viaHeader.getHost());
// requestURI.setPort(viaHeader.getPort());
// clientDialog.sendAck(ackRequest);
CSeqHeader clientCSeqHeader = (CSeqHeader) response.getHeader(CSeqHeader.NAME);
long cseqId = clientCSeqHeader.getSeqNumber();
/*
createAck函数创建的ackRequest会采用Invite响应的200OK中的contact字段中的地址作为目标地址
有的终端传上来的可能还是内网地址会造成ack发送不出去接受不到音视频流
所以在此处统一替换地址和响应消息的Via头中的地址保持一致
*/
Request ackRequest = clientDialog.createAck(cseqId);
SipURI requestURI = (SipURI) ackRequest.getRequestURI();
ViaHeader viaHeader = (ViaHeader) response.getHeader(ViaHeader.NAME);
requestURI.setHost(viaHeader.getHost());
requestURI.setPort(viaHeader.getPort());
clientDialog.sendAck(ackRequest);
Dialog dialog = evt.getDialog();
Request reqAck =dialog.createAck(1L);
dialog.sendAck(reqAck);
}
} catch (InvalidArgumentException | SipException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}
}

3
src/main/java/com/genersoft/iot/vmp/storager/redis/VideoManagerRedisStoragerImpl.java

@ -96,8 +96,7 @@ public class VideoManagerRedisStoragerImpl implements IVideoManagerStorager {
*/
@Override
public boolean delete(String deviceId) {
redis.del(VideoManagerConstants.CACHEKEY_PREFIX+deviceId);
return true;
return redis.del(VideoManagerConstants.CACHEKEY_PREFIX+deviceId);
}
/**

8
src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java

@ -68,7 +68,8 @@ public class RedisUtil {
* @SuppressWarnings("unchecked") 忽略类型转换警告
* @param key 一个或者多个
*/
public void del(String... key) {
public boolean del(String... key) {
try {
if (key != null && key.length > 0) {
if (key.length == 1) {
redisTemplate.delete(key[0]);
@ -77,6 +78,11 @@ public class RedisUtil {
redisTemplate.delete(CollectionUtils.arrayToList(key));
}
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
// ============================== String ==============================

26
src/main/java/com/genersoft/iot/vmp/vmanager/device/DeviceController.java

@ -14,7 +14,9 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult;
import com.alibaba.fastjson.JSONObject;
import com.genersoft.iot.vmp.gb28181.bean.Device;
import com.genersoft.iot.vmp.gb28181.event.DeviceOffLineDetector;
import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
@ -34,6 +36,9 @@ public class DeviceController {
@Autowired
private DeferredResultHolder resultHolder;
@Autowired
private DeviceOffLineDetector offLineDetector;
@GetMapping("/devices/{deviceId}")
public ResponseEntity<Device> devices(@PathVariable String deviceId){
@ -69,4 +74,25 @@ public class DeviceController {
resultHolder.put(DeferredResultHolder.CALLBACK_CMD_CATALOG+deviceId, result);
return result;
}
@PostMapping("/devices/{deviceId}/delete")
public ResponseEntity<String> delete(@PathVariable String deviceId){
if (logger.isDebugEnabled()) {
logger.debug("设备信息删除API调用,deviceId:" + deviceId);
}
if (offLineDetector.isOnline(deviceId)) {
return new ResponseEntity<String>("不允许删除在线设备!", HttpStatus.NOT_ACCEPTABLE);
}
boolean isSuccess = storager.delete(deviceId);
if (isSuccess) {
JSONObject json = new JSONObject();
json.put("deviceId", deviceId);
return new ResponseEntity<>(json.toString(),HttpStatus.OK);
} else {
logger.warn("设备预览API调用失败!");
return new ResponseEntity<String>("设备预览API调用失败!", HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}

20
src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java

@ -7,6 +7,7 @@ import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@ -47,4 +48,23 @@ public class PlayController {
return new ResponseEntity<String>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@PostMapping("/play/{ssrc}/stop")
public ResponseEntity<String> playStop(@PathVariable String ssrc){
cmder.streamByeCmd(ssrc);
if (logger.isDebugEnabled()) {
logger.debug(String.format("设备预览停止API调用,ssrc:%s", ssrc));
}
if(ssrc!=null) {
JSONObject json = new JSONObject();
json.put("ssrc", ssrc);
return new ResponseEntity<String>(json.toString(),HttpStatus.OK);
} else {
logger.warn("设备预览停止API调用失败!");
return new ResponseEntity<String>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}

2
src/main/resources/application.yml

@ -26,7 +26,7 @@ spring:
server:
port: 8080
sip:
ip: 127.0.0.1
ip: 10.200.64.63
port: 5060
# 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007)
# 后两位为行业编码,定义参照附录D.3

Loading…
Cancel
Save