diff --git a/pom.xml b/pom.xml index dba80cf3..86b4c176 100644 --- a/pom.xml +++ b/pom.xml @@ -169,8 +169,8 @@ + wvp-2.5.8 - org.springframework.boot spring-boot-maven-plugin @@ -184,18 +184,6 @@ 1.8 1.8 - diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/RegisterRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/RegisterRequestProcessor.java index 276127f2..be076bd8 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/RegisterRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/RegisterRequestProcessor.java @@ -16,6 +16,8 @@ import javax.sip.header.ViaHeader; import javax.sip.message.Request; import javax.sip.message.Response; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.util.StringUtils; import com.genersoft.iot.vmp.common.VideoManagerConstants; @@ -39,6 +41,8 @@ import gov.nist.javax.sip.header.Expires; */ public class RegisterRequestProcessor extends SIPRequestAbstractProcessor { + private Logger logger = LoggerFactory.getLogger(RegisterRequestProcessor.class); + private SipConfig sipConfig; private RegisterLogicHandler handler; @@ -46,17 +50,15 @@ public class RegisterRequestProcessor extends SIPRequestAbstractProcessor { private IVideoManagerStorager storager; private EventPublisher publisher; - - /*** + + /** * 收到注册请求 处理 - * - * @param request - * 请求消息 - */ + * @param evt + */ @Override public void process(RequestEvent evt) { try { - System.out.println("收到注册请求,开始处理"); + logger.info("收到注册请求,开始处理"); Request request = evt.getRequest(); Response response = null; @@ -75,9 +77,9 @@ public class RegisterRequestProcessor extends SIPRequestAbstractProcessor { if (authorhead == null || !passwordCorrect) { if (authorhead == null) { - System.out.println("未携带授权头 回复401"); + logger.info("未携带授权头 回复401"); } else if (!passwordCorrect) { - System.out.println("密码错误 回复401"); + logger.info("密码错误 回复401"); } response = getMessageFactory().createResponse(Response.UNAUTHORIZED, request); new DigestServerAuthenticationHelper().generateChallenge(getHeaderFactory(), response, sipConfig.getSipDomain()); @@ -138,12 +140,12 @@ public class RegisterRequestProcessor extends SIPRequestAbstractProcessor { // 保存到redis // 下发catelog查询目录 if (registerFlag == 1 && device != null) { - System.out.println("注册成功! deviceId:" + device.getDeviceId()); + logger.info("注册成功! deviceId:" + device.getDeviceId()); storager.updateDevice(device); publisher.onlineEventPublish(device.getDeviceId(), VideoManagerConstants.EVENT_ONLINE_REGISTER); handler.onRegister(device); } else if (registerFlag == 2) { - System.out.println("注销成功! deviceId:" + device.getDeviceId()); + logger.info("注销成功! deviceId:" + device.getDeviceId()); publisher.outlineEventPublish(device.getDeviceId(), VideoManagerConstants.EVENT_OUTLINE_UNREGISTER); } } catch (SipException | InvalidArgumentException | NoSuchAlgorithmException | ParseException e) { diff --git a/src/main/java/com/genersoft/iot/vmp/web/ApiStreamController.java b/src/main/java/com/genersoft/iot/vmp/web/ApiStreamController.java index 8d845b1c..76df0d2d 100644 --- a/src/main/java/com/genersoft/iot/vmp/web/ApiStreamController.java +++ b/src/main/java/com/genersoft/iot/vmp/web/ApiStreamController.java @@ -1,16 +1,19 @@ package com.genersoft.iot.vmp.web; import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; +import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; import com.genersoft.iot.vmp.storager.IVideoManagerStorager; import com.genersoft.iot.vmp.vmanager.play.PlayController; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @@ -31,6 +34,13 @@ public class ApiStreamController { @Autowired private IVideoManagerStorager storager; + @Value("${media.closeWaitRTPInfo}") + private boolean closeWaitRTPInfo; + + + @Autowired + private ZLMRESTfulUtils zlmresTfulUtils; + /** * 实时直播 - 开始直播 * @param serial 设备编号 @@ -56,28 +66,112 @@ public class ApiStreamController { @RequestParam(required = false)String timeout ){ - + int getEncoding = closeWaitRTPInfo? 1: 0; Device device = storager.queryVideoDevice(serial); + if (device == null ) { JSONObject result = new JSONObject(); result.put("error","device[ " + serial + " ]未找到"); return result; + }else if (device.getOnline() == 0) { + JSONObject result = new JSONObject(); + result.put("error","device[ " + code + " ]offline"); + return result; } + DeviceChannel deviceChannel = storager.queryChannel(serial, code); if (deviceChannel == null) { JSONObject result = new JSONObject(); result.put("error","channel[ " + code + " ]未找到"); return result; + }else if (deviceChannel.getStatus() == 0) { + JSONObject result = new JSONObject(); + result.put("error","channel[ " + code + " ]offline"); + return result; } + // 查询是否已经在播放 StreamInfo streamInfo = storager.queryPlayByDevice(device.getDeviceId(), code); - if (streamInfo == null) streamInfo = cmder.playStreamCmd(device, code); + if (streamInfo == null) { + logger.debug("streamInfo 等于null, 重新点播"); + streamInfo = cmder.playStreamCmd(device, code); + }else { + logger.debug("streamInfo 不等于null, 向流媒体查询是否正在推流"); + String streamId = String.format("%08x", Integer.parseInt(streamInfo.getSsrc())).toUpperCase(); + JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(streamId); + if (rtpInfo.getBoolean("exist")) { + logger.debug("向流媒体查询正在推流, 直接返回: " + streamInfo.getRtsp()); + JSONObject result = new JSONObject(); + result.put("StreamID", streamInfo.getSsrc()); + result.put("DeviceID", device.getDeviceId()); + result.put("ChannelID", code); + result.put("ChannelName", deviceChannel.getName()); + result.put("ChannelCustomName ", ""); + result.put("FLV ", streamInfo.getFlv()); + result.put("WS_FLV ", streamInfo.getWs_flv()); + result.put("RTMP", streamInfo.getRtmp()); + result.put("HLS", streamInfo.getHls()); + result.put("RTSP", streamInfo.getRtsp()); + result.put("CDN", ""); + result.put("SnapURL", ""); + result.put("Transport", device.getTransport()); + result.put("StartAt", ""); + result.put("Duration", ""); + result.put("SourceVideoCodecName", ""); + result.put("SourceVideoWidth", ""); + result.put("SourceVideoHeight", ""); + result.put("SourceVideoFrameRate", ""); + result.put("SourceAudioCodecName", ""); + result.put("SourceAudioSampleRate", ""); + result.put("AudioEnable", ""); + result.put("Ondemand", ""); + result.put("InBytes", ""); + result.put("InBitRate", ""); + result.put("OutBytes", ""); + result.put("NumOutputs", ""); + result.put("CascadeSize", ""); + result.put("RelaySize", ""); + result.put("ChannelPTZType", 0); + return result; + } else { + logger.debug("向流媒体查询没有推流, 重新点播"); + storager.stopPlay(streamInfo); + streamInfo = cmder.playStreamCmd(device, code); + } + } if (logger.isDebugEnabled()) { logger.debug(String.format("设备预览 API调用,deviceId:%s ,channelId:%s",serial, code)); logger.debug("设备预览 API调用,ssrc:"+streamInfo.getSsrc()+",ZLMedia streamId:"+Integer.toHexString(Integer.parseInt(streamInfo.getSsrc()))); } + boolean lockFlag = true; + long startTime = System.currentTimeMillis(); + while (lockFlag) { + try { + if (System.currentTimeMillis() - startTime > 10 * 1000) { + storager.stopPlay(streamInfo); + logger.info("播放等待超时"); + JSONObject result = new JSONObject(); + result.put("error","timeout"); + return result; + } else { + StreamInfo streamInfoNow = storager.queryPlayByDevice(serial, code); + logger.debug("正在向流媒体查询"); + if (streamInfoNow != null && streamInfoNow.getFlv() != null) { + streamInfo = streamInfoNow; + logger.debug("向流媒体查询到: " + streamInfoNow.getRtsp()); + lockFlag = false; + continue; + } else { + Thread.sleep(2000); + continue; + } + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + } if(streamInfo!=null) { JSONObject result = new JSONObject(); result.put("StreamID", streamInfo.getSsrc()); diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 5a752e5c..5e6c1fc2 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -49,5 +49,13 @@ media: #zlm服务器的ip与http端口, 重点: 这是http端口 rtp: # 启用udp多端口模式 enable: true udpPortRange: 30000,30500 # 端口范围 - - +logging: + file: + name: logs/wvp.log + max-history: 30 + max-size: 10MB + total-size-cap:300MB + level: + com: + genersoft: + iot: debug \ No newline at end of file