lawrencehj
2021-08-26 45969a00b74b5a240c0dc6e2c37f5381cd0cb65f
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java
@@ -1,22 +1,20 @@
package com.genersoft.iot.vmp.gb28181.transmit.request.impl;
import javax.sdp.*;
import javax.sip.InvalidArgumentException;
import javax.sip.RequestEvent;
import javax.sip.SipException;
import javax.sip.SipFactory;
import javax.sip.*;
import javax.sip.address.Address;
import javax.sip.address.SipURI;
import javax.sip.header.*;
import javax.sip.message.Request;
import javax.sip.message.Response;
import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig;
import com.genersoft.iot.vmp.gb28181.bean.*;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor;
import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
import com.genersoft.iot.vmp.service.IMediaServerService;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult;
@@ -50,6 +48,8 @@
   private IPlayService playService;
   private ZLMRTPServerFactory zlmrtpServerFactory;
   private IMediaServerService mediaServerService;
   public ZLMRTPServerFactory getZlmrtpServerFactory() {
      return zlmrtpServerFactory;
@@ -91,11 +91,27 @@
            // 查询平台下是否有该通道
            DeviceChannel channel = storager.queryChannelInParentPlatform(requesterId, channelId);
            GbStream gbStream = storager.queryStreamInParentPlatform(requesterId, channelId);
            MediaServerItem mediaServerItem = null;
            // 不是通道可能是直播流
            if (channel != null || gbStream != null ) {
            if (channel != null && gbStream == null ) {
               if (channel.getStatus() == 0) {
                  logger.info("通道离线,返回400");
                  responseAck(evt, Response.BAD_REQUEST, "channel [" + channel.getChannelId() + "] offline");
                  return;
               }
               responseAck(evt, Response.CALL_IS_BEING_FORWARDED); // 通道存在,发181,呼叫转接中
            }else if(channel == null && gbStream != null){
               String mediaServerId = gbStream.getMediaServerId();
               mediaServerItem = mediaServerService.getOne(mediaServerId);
               if (mediaServerItem == null) {
                  logger.info("[ app={}, stream={} ]zlm找不到,返回410",gbStream.getApp(), gbStream.getStream());
                  responseAck(evt, Response.GONE, "media server not found");
                  return;
               }
               Boolean streamReady = zlmrtpServerFactory.isStreamReady(mediaServerItem, gbStream.getApp(), gbStream.getStream());
               if (!streamReady ) {
                  logger.info("[ app={}, stream={} ]通道离线,返回400",gbStream.getApp(), gbStream.getStream());
                  responseAck(evt, Response.BAD_REQUEST, "channel [" + gbStream.getGbId() + "] offline");
                  return;
               }
               responseAck(evt, Response.CALL_IS_BEING_FORWARDED); // 通道存在,发181,呼叫转接中
@@ -122,8 +138,8 @@
            //boolean recvonly = false;
            boolean mediaTransmissionTCP = false;
            Boolean tcpActive = null;
            for (int i = 0; i < mediaDescriptions.size(); i++) {
               MediaDescription mediaDescription = (MediaDescription)mediaDescriptions.get(i);
            for (Object description : mediaDescriptions) {
               MediaDescription mediaDescription = (MediaDescription) description;
               Media media = mediaDescription.getMedia();
               Vector mediaFormats = media.getMediaFormats(false);
@@ -139,7 +155,7 @@
                        mediaTransmissionTCP = true;
                        if ("active".equals(setup)) {
                           tcpActive = true;
                        }else if ("passive".equals(setup)) {
                        } else if ("passive".equals(setup)) {
                           tcpActive = false;
                        }
                     }
@@ -166,7 +182,13 @@
                  responseAck(evt, Response.SERVER_INTERNAL_ERROR);
                  return;
               }
               SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(addressStr, port, ssrc, requesterId,
               mediaServerItem = playService.getNewMediaServerItem(device);
               if (mediaServerItem == null) {
                  logger.warn("未找到可用的zlm");
                  responseAck(evt, Response.BUSY_HERE);
                  return;
               }
               SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId,
                     device.getDeviceId(), channelId,
                     mediaTransmissionTCP);
               if (tcpActive != null) {
@@ -181,18 +203,18 @@
               // 写入redis, 超时时回复
               redisCatchStorage.updateSendRTPSever(sendRtpItem);
               // 通知下级推流,
               PlayResult playResult = playService.play(device.getDeviceId(), channelId, (responseJSON)->{
               PlayResult playResult = playService.play(mediaServerItem,device.getDeviceId(), channelId, (mediaServerItemInUSe, responseJSON)->{
                  // 收到推流, 回复200OK, 等待ack
                  // if (sendRtpItem == null) return;
                  sendRtpItem.setStatus(1);
                  redisCatchStorage.updateSendRTPSever(sendRtpItem);
                  // TODO 添加对tcp的支持
                  ZLMServerConfig mediaInfo = redisCatchStorage.getMediaInfo();
                  StringBuffer content = new StringBuffer(200);
                  content.append("v=0\r\n");
                  content.append("o="+"00000"+" 0 0 IN IP4 "+mediaInfo.getWanIp()+"\r\n");
                  content.append("o="+"00000"+" 0 0 IN IP4 "+mediaServerItemInUSe.getSdpIp()+"\r\n");
                  content.append("s=Play\r\n");
                  content.append("c=IN IP4 "+mediaInfo.getWanIp()+"\r\n");
                  content.append("c=IN IP4 "+mediaServerItemInUSe.getSdpIp()+"\r\n");
                  content.append("t=0 0\r\n");
                  content.append("m=video "+ sendRtpItem.getLocalPort()+" RTP/AVP 96\r\n");
                  content.append("a=sendonly\r\n");
@@ -209,12 +231,14 @@
                  } catch (ParseException e) {
                     e.printStackTrace();
                  }
               } ,(event -> {
               } ,((event) -> {
                  // 未知错误。直接转发设备点播的错误
                  Response response = null;
                  try {
                     response = getMessageFactory().createResponse(event.getResponse().getStatusCode(), evt.getRequest());
                     getServerTransaction(evt).sendResponse(response);
                     ServerTransaction serverTransaction = getServerTransaction(evt);
                     serverTransaction.sendResponse(response);
                     if (serverTransaction.getDialog() != null) serverTransaction.getDialog().delete();
                  } catch (ParseException | SipException | InvalidArgumentException e) {
                     e.printStackTrace();
                  }
@@ -224,7 +248,7 @@
               }
            }else if (gbStream != null) {
               SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(addressStr, port, ssrc, requesterId,
               SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId,
                     gbStream.getApp(), gbStream.getStream(), channelId,
                     mediaTransmissionTCP);
@@ -240,34 +264,29 @@
               // 写入redis, 超时时回复
               redisCatchStorage.updateSendRTPSever(sendRtpItem);
               // 检测直播流是否在线
               Boolean streamReady = zlmrtpServerFactory.isStreamReady(gbStream.getApp(), gbStream.getStream());
               if (streamReady) {
                  sendRtpItem.setStatus(1);
                  redisCatchStorage.updateSendRTPSever(sendRtpItem);
                  // TODO 添加对tcp的支持
                  ZLMServerConfig mediaInfo = redisCatchStorage.getMediaInfo();
                  StringBuffer content = new StringBuffer(200);
                  content.append("v=0\r\n");
                  content.append("o="+"00000"+" 0 0 IN IP4 "+mediaInfo.getWanIp()+"\r\n");
                  content.append("s=Play\r\n");
                  content.append("c=IN IP4 "+mediaInfo.getWanIp()+"\r\n");
                  content.append("t=0 0\r\n");
                  content.append("m=video "+ sendRtpItem.getLocalPort()+" RTP/AVP 96\r\n");
                  content.append("a=sendonly\r\n");
                  content.append("a=rtpmap:96 PS/90000\r\n");
                  content.append("y="+ ssrc + "\r\n");
                  content.append("f=\r\n");
               sendRtpItem.setStatus(1);
               redisCatchStorage.updateSendRTPSever(sendRtpItem);
               // TODO 添加对tcp的支持
               StringBuffer content = new StringBuffer(200);
               content.append("v=0\r\n");
               content.append("o="+"00000"+" 0 0 IN IP4 "+mediaServerItem.getSdpIp()+"\r\n");
               content.append("s=Play\r\n");
               content.append("c=IN IP4 "+mediaServerItem.getSdpIp()+"\r\n");
               content.append("t=0 0\r\n");
               content.append("m=video "+ sendRtpItem.getLocalPort()+" RTP/AVP 96\r\n");
               content.append("a=sendonly\r\n");
               content.append("a=rtpmap:96 PS/90000\r\n");
               content.append("y="+ ssrc + "\r\n");
               content.append("f=\r\n");
                  try {
                     responseAck(evt, content.toString());
                  } catch (SipException e) {
                     e.printStackTrace();
                  } catch (InvalidArgumentException e) {
                     e.printStackTrace();
                  } catch (ParseException e) {
                     e.printStackTrace();
                  }
               try {
                  responseAck(evt, content.toString());
               } catch (SipException e) {
                  e.printStackTrace();
               } catch (InvalidArgumentException e) {
                  e.printStackTrace();
               } catch (ParseException e) {
                  e.printStackTrace();
               }
            }
@@ -332,11 +351,6 @@
               String username = sdp.getOrigin().getUsername();
               String addressStr = sdp.getOrigin().getAddress();
               logger.info("设备{}请求语音流,地址:{}:{},ssrc:{}", username, addressStr, port, ssrc);
            } else {
               logger.warn("来自无效设备/平台的请求");
@@ -369,13 +383,17 @@
    */
   private void responseAck(RequestEvent evt, int statusCode) throws SipException, InvalidArgumentException, ParseException {
      Response response = getMessageFactory().createResponse(statusCode, evt.getRequest());
      getServerTransaction(evt).sendResponse(response);
      ServerTransaction serverTransaction = getServerTransaction(evt);
      serverTransaction.sendResponse(response);
      if (serverTransaction.getDialog() != null) serverTransaction.getDialog().delete();
   }
   private void responseAck(RequestEvent evt, int statusCode, String msg) throws SipException, InvalidArgumentException, ParseException {
      Response response = getMessageFactory().createResponse(statusCode, evt.getRequest());
      response.setReasonPhrase(msg);
      getServerTransaction(evt).sendResponse(response);
      ServerTransaction serverTransaction = getServerTransaction(evt);
      serverTransaction.sendResponse(response);
      if (serverTransaction.getDialog() != null) serverTransaction.getDialog().delete();
   }
   /**
@@ -445,4 +463,12 @@
   public void setRedisCatchStorage(IRedisCatchStorage redisCatchStorage) {
      this.redisCatchStorage = redisCatchStorage;
   }
   public IMediaServerService getMediaServerService() {
      return mediaServerService;
   }
   public void setMediaServerService(IMediaServerService mediaServerService) {
      this.mediaServerService = mediaServerService;
   }
}