增加设备删除接口,只允许删除离线设备;增加视频停止播放接口
This commit is contained in:
parent
ca5139929b
commit
6ecd801c23
@ -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}")
|
||||
@ -77,6 +79,12 @@ public class SipConfig {
|
||||
public void setSpeed(Integer speed) {
|
||||
this.speed = speed;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public String getSipId() {
|
||||
return sipId;
|
||||
}
|
||||
|
||||
public void setSipId(String sipId) {
|
||||
this.sipId = sipId;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
||||
/**
|
||||
* 语音广播
|
||||
*
|
||||
|
@ -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;
|
||||
|
@ -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,13 +215,50 @@ 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();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 视频流停止
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
}
|
||||
|
@ -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();
|
||||
//
|
||||
|
@ -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();
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -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查询目录
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
||||
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);
|
||||
// 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);
|
||||
|
||||
Dialog dialog = evt.getDialog();
|
||||
Request reqAck =dialog.createAck(1L);
|
||||
dialog.sendAck(reqAck);
|
||||
}
|
||||
} catch (InvalidArgumentException | SipException e) {
|
||||
e.printStackTrace();
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -68,14 +68,20 @@ public class RedisUtil {
|
||||
* @SuppressWarnings("unchecked") 忽略类型转换警告
|
||||
* @param key 键(一个或者多个)
|
||||
*/
|
||||
public void del(String... key) {
|
||||
if (key != null && key.length > 0) {
|
||||
if (key.length == 1) {
|
||||
redisTemplate.delete(key[0]);
|
||||
} else {
|
||||
// 传入一个 Collection<String> 集合
|
||||
redisTemplate.delete(CollectionUtils.arrayToList(key));
|
||||
public boolean del(String... key) {
|
||||
try {
|
||||
if (key != null && key.length > 0) {
|
||||
if (key.length == 1) {
|
||||
redisTemplate.delete(key[0]);
|
||||
} else {
|
||||
// 传入一个 Collection<String> 集合
|
||||
redisTemplate.delete(CollectionUtils.arrayToList(key));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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…
Reference in New Issue
Block a user