648540858
2020-09-25 da14c7f24c61cf9027a02d8e566ab89116136f19
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
@@ -1,20 +1,31 @@
package com.genersoft.iot.vmp.gb28181.transmit.cmd.impl;
import java.text.ParseException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.sip.ClientTransaction;
import javax.sip.Dialog;
import javax.sip.InvalidArgumentException;
import javax.sip.SipException;
import javax.sip.SipFactory;
import javax.sip.SipProvider;
import javax.sip.TransactionDoesNotExistException;
import javax.sip.address.SipURI;
import javax.sip.header.ViaHeader;
import javax.sip.message.Request;
import com.alibaba.fastjson.JSONObject;
import com.genersoft.iot.vmp.common.StreamInfo;
import com.genersoft.iot.vmp.conf.MediaServerConfig;
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
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;
@@ -23,7 +34,7 @@
/**    
 * @Description:设备能力接口,用于定义设备的控制、查询能力   
 * @author: songww
 * @author: swwheihei
 * @date:   2020年5月3日 下午9:22:48     
 */
@Component
@@ -36,10 +47,21 @@
   private SIPRequestHeaderProvider headerProvider;
   
   @Autowired
   private SipLayer sipLayer;
   private VideoStreamSessionManager streamSession;
   @Autowired
   private IVideoManagerStorager storager;
   
   @Autowired
   private VideoStreamSessionManager streamSession;
   @Qualifier(value="tcpSipProvider")
   private SipProvider tcpSipProvider;
   @Autowired
   @Qualifier(value="udpSipProvider")
   private SipProvider udpSipProvider;
   @Value("${media.ip}")
   private String mediaIp;
   
   /**
    * 云台方向放控制,使用配置文件中的默认镜头移动速度
@@ -48,7 +70,6 @@
    * @param channelId  预览通道
    * @param leftRight  镜头左移右移 0:停止 1:左移 2:右移
     * @param upDown     镜头上移下移 0:停止 1:上移 2:下移
     * @param moveSpeed  镜头移动速度
    */
   @Override
   public boolean ptzdirectCmd(Device device, String channelId, int leftRight, int upDown) {
@@ -181,7 +202,7 @@
    * @param channelId  预览通道
    */  
   @Override
   public String playStreamCmd(Device device, String channelId) {
   public StreamInfo playStreamCmd(Device device, String channelId) {
      try {
         
         String ssrc = streamSession.createPlaySsrc();
@@ -213,7 +234,24 @@
   
           ClientTransaction transaction = transmitRequest(device, request);
           streamSession.put(ssrc, transaction);
         return ssrc;
         DeviceChannel deviceChannel = storager.queryChannel(device.getDeviceId(), channelId);
         if (deviceChannel != null) {
            deviceChannel.setSsrc(ssrc);
            storager.updateChannel(device.getDeviceId(), deviceChannel);
         }
         MediaServerConfig mediaInfo = storager.getMediaInfo();
         StreamInfo streamInfo = new StreamInfo();
         streamInfo.setSsrc(ssrc);
//         String streamId = Integer.toHexString(Integer.parseInt(streamInfo.getSsrc()));
         String streamId = String.format("%08x", Integer.parseInt(streamInfo.getSsrc())).toUpperCase(); // ZLM 要求大写且首位补零
         streamInfo.setFlv(String.format("http://%s:%s/rtp/%s.flv", mediaIp, mediaInfo.getHttpPort(), streamId));
         streamInfo.setWS_FLV(String.format("ws://%s:%s/rtp/%s.flv", mediaIp, mediaInfo.getHttpPort(), streamId));
         streamInfo.setRTMP(String.format("rtmp://%s:%s/rtp/%s", mediaIp, mediaInfo.getRtmpPort(), streamId));
         streamInfo.setHLS(String.format("http://%s:%s/rtp/%s/hls.m3u8", mediaIp, mediaInfo.getHttpPort(), streamId));
         streamInfo.setRTSP(String.format("rtsp://%s:%s/rtp/%s", mediaIp, mediaInfo.getRtspPort(), streamId));
         storager.startPlay(device.getDeviceId(), channelId, streamInfo);
         return streamInfo;
      } catch ( SipException | ParseException | InvalidArgumentException e) {
         e.printStackTrace();
         return null;
@@ -271,8 +309,6 @@
   /**
    * 视频流停止
    * 
    * @param device  视频设备
    * @param channelId  预览通道
    */
   @Override
   public void streamByeCmd(String ssrc) {
@@ -288,18 +324,27 @@
            return;
         }
         Request byeRequest = dialog.createRequest(Request.BYE);
         SipURI byeURI = (SipURI) byeRequest.getRequestURI();
         String vh = transaction.getRequest().getHeader(ViaHeader.NAME).toString();
         Pattern p = Pattern.compile("(\\d+\\.\\d+\\.\\d+\\.\\d+)\\:(\\d+)");
         Matcher matcher = p.matcher(vh);
         if (matcher.find()) {
            byeURI.setHost(matcher.group(1));
         }
         ViaHeader viaHeader = (ViaHeader) byeRequest.getHeader(ViaHeader.NAME);
         String protocol = viaHeader.getTransport().toUpperCase();
         ClientTransaction clientTransaction = null;
         if("TCP".equals(protocol)) {
            clientTransaction = sipLayer.getTcpSipProvider().getNewClientTransaction(byeRequest);
            clientTransaction = tcpSipProvider.getNewClientTransaction(byeRequest);
         } else if("UDP".equals(protocol)) {
            clientTransaction = sipLayer.getUdpSipProvider().getNewClientTransaction(byeRequest);
            clientTransaction = udpSipProvider.getNewClientTransaction(byeRequest);
         }
         dialog.sendRequest(clientTransaction);
      } catch (TransactionDoesNotExistException e) {
         e.printStackTrace();
      } catch (SipException e) {
         e.printStackTrace();
      } catch (ParseException e) {
         e.printStackTrace();
      }
   }
@@ -526,9 +571,9 @@
   private ClientTransaction transmitRequest(Device device, Request request) throws SipException {
      ClientTransaction clientTransaction = null;
      if("TCP".equals(device.getTransport())) {
         clientTransaction = sipLayer.getTcpSipProvider().getNewClientTransaction(request);
         clientTransaction = tcpSipProvider.getNewClientTransaction(request);
      } else if("UDP".equals(device.getTransport())) {
         clientTransaction = sipLayer.getUdpSipProvider().getNewClientTransaction(request);
         clientTransaction = udpSipProvider.getNewClientTransaction(request);
      }
      clientTransaction.sendRequest();
      return clientTransaction;