From 1b44ba33671e27c3d206d875306b226c770b7980 Mon Sep 17 00:00:00 2001 From: panlinlin <648540858@qq.com> Date: 星期五, 15 一月 2021 18:22:57 +0800 Subject: [PATCH] 完成向上级联->点播--002 --- src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java | 2 src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java | 54 +--------- src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java | 80 ++++++++++++++- src/main/java/com/genersoft/iot/vmp/vmanager/service/impl/PlayServiceImpl.java | 75 +++++++++++++++ src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java | 6 + src/main/java/com/genersoft/iot/vmp/vmanager/service/IPlayService.java | 7 + src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java | 5 + src/main/java/com/genersoft/iot/vmp/vmanager/play/bean/PlayResult.java | 37 +++++++ 8 files changed, 210 insertions(+), 56 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java index 75db910..f4e4928 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java @@ -15,6 +15,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.response.impl.*; import com.genersoft.iot.vmp.gb28181.transmit.response.impl.*; import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; +import com.genersoft.iot.vmp.vmanager.service.IPlayService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -103,6 +104,9 @@ @Autowired private OtherResponseProcessor otherResponseProcessor; + @Autowired + private IPlayService playService; + // 娉細杩欓噷浣跨敤娉ㄨВ浼氬鑷村惊鐜緷璧栨敞鍏ワ紝鏆傜敤springBean private SipProvider tcpSipProvider; @@ -120,7 +124,9 @@ processor.setTcpSipProvider(getTcpSipProvider()); processor.setUdpSipProvider(getUdpSipProvider()); + processor.setCmder(cmder); processor.setCmderFroPlatform(cmderFroPlatform); + processor.setPlayService(playService); processor.setStorager(storager); return processor; } else if (Request.REGISTER.equals(method)) { diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java index 4dea5d4..58e11ad 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java @@ -10,19 +10,26 @@ import javax.sip.message.Request; import javax.sip.message.Response; +import com.alibaba.fastjson.JSONObject; +import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; import com.genersoft.iot.vmp.gb28181.sdp.Codec; import com.genersoft.iot.vmp.gb28181.sdp.MediaDescription; import com.genersoft.iot.vmp.gb28181.sdp.SdpParser; import com.genersoft.iot.vmp.gb28181.sdp.SessionDescription; +import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; +import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; 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.storager.IVideoManagerStorager; +import com.genersoft.iot.vmp.vmanager.play.bean.PlayResult; +import com.genersoft.iot.vmp.vmanager.service.IPlayService; import gov.nist.javax.sip.address.AddressImpl; import gov.nist.javax.sip.address.SipUri; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; import java.io.IOException; import java.text.ParseException; @@ -40,6 +47,10 @@ private SIPCommanderFroPlatform cmderFroPlatform; private IVideoManagerStorager storager; + + private SIPCommander cmder; + + private IPlayService playService; /** * 澶勭悊invite璇锋眰 @@ -119,7 +130,30 @@ String ssrc = sdp.getSsrc(); + + Device device = storager.queryVideoDeviceByPlatformIdAndChannelId(platformId, channelId); + if (device == null) { + logger.warn("鐐规挱骞冲彴{}鐨勯�氶亾{}鏃舵湭鎵惧埌璁惧淇℃伅", platformId, channel); + response500Ack(evt); + return; + } + // 閫氱煡涓嬬骇鎺ㄦ祦锛� + PlayResult playResult = playService.play(device.getDeviceId(), channelId, (response)->{ + // 鏀跺埌鎺ㄦ祦锛� 鍥炲200OK + + },(event -> { + // 鏈煡閿欒銆傜洿鎺ヨ浆鍙戣澶囩偣鎾殑閿欒 + Response response = null; + try { + response = getMessageFactory().createResponse(event.getResponse().getStatusCode(), evt.getRequest()); + getServerTransaction(evt).sendResponse(response); + + } catch (ParseException | SipException | InvalidArgumentException e) { + e.printStackTrace(); + } + })); + playResult.getResult(); // 鏌ユ壘鍚堥�傜殑绔彛鎺ㄦ祦锛� // 鍙戦�� 200ok // 鏀跺埌ack鍚庤皟鐢ㄦ帹娴佹帴鍙� @@ -149,14 +183,16 @@ } /*** - * 鍥炲404 + * 鍥炲200 OK * @param evt * @throws SipException * @throws InvalidArgumentException * @throws ParseException */ - private void response404Ack(RequestEvent evt) throws SipException, InvalidArgumentException, ParseException { - Response response = getMessageFactory().createResponse(Response.NOT_FOUND, evt.getRequest()); + private void responseAck(RequestEvent evt, String sdp) throws SipException, InvalidArgumentException, ParseException { + Response response = getMessageFactory().createResponse(Response.OK, evt.getRequest()); + ContentTypeHeader contentTypeHeader = getHeaderFactory().createContentTypeHeader("APPLICATION", "SDP"); + response.setContent(sdp, contentTypeHeader); getServerTransaction(evt).sendResponse(response); } @@ -173,6 +209,18 @@ } /*** + * 鍥炲404 + * @param evt + * @throws SipException + * @throws InvalidArgumentException + * @throws ParseException + */ + private void response404Ack(RequestEvent evt) throws SipException, InvalidArgumentException, ParseException { + Response response = getMessageFactory().createResponse(Response.NOT_FOUND, evt.getRequest()); + getServerTransaction(evt).sendResponse(response); + } + + /*** * 鍥炲488 * @param evt * @throws SipException @@ -185,18 +233,18 @@ } /*** - * 鍥炲200 OK + * 鍥炲500 * @param evt * @throws SipException * @throws InvalidArgumentException * @throws ParseException */ - private void responseAck(RequestEvent evt, String sdp) throws SipException, InvalidArgumentException, ParseException { - Response response = getMessageFactory().createResponse(Response.OK, evt.getRequest()); - ContentTypeHeader contentTypeHeader = getHeaderFactory().createContentTypeHeader("APPLICATION", "SDP"); - response.setContent(sdp, contentTypeHeader); + private void response500Ack(RequestEvent evt) throws SipException, InvalidArgumentException, ParseException { + Response response = getMessageFactory().createResponse(Response.SERVER_INTERNAL_ERROR, evt.getRequest()); getServerTransaction(evt).sendResponse(response); } + + @@ -222,4 +270,20 @@ public void setStorager(IVideoManagerStorager storager) { this.storager = storager; } + + public SIPCommander getCmder() { + return cmder; + } + + public void setCmder(SIPCommander cmder) { + this.cmder = cmder; + } + + public IPlayService getPlayService() { + return playService; + } + + public void setPlayService(IPlayService playService) { + this.playService = playService; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java b/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java index 7963109..7a2a76c 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java @@ -234,4 +234,6 @@ DeviceChannel queryChannelInParentPlatform(String platformId, String channelId); + + Device queryVideoDeviceByPlatformIdAndChannelId(String platformId, String channelId); } diff --git a/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java b/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java index aa83e3d..dac0aa2 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java @@ -335,4 +335,9 @@ DeviceChannel channel = patformChannelMapper.queryChannelInParentPlatform(platformId, channelId); return channel; } + + @Override + public Device queryVideoDeviceByPlatformIdAndChannelId(String platformId, String channelId) { + return null; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java index 3bd828a..9b9a69b 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java @@ -10,6 +10,7 @@ import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; +import com.genersoft.iot.vmp.vmanager.play.bean.PlayResult; import com.genersoft.iot.vmp.vmanager.service.IPlayService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -64,62 +65,19 @@ @PathVariable String channelId) { - Device device = storager.queryVideoDevice(deviceId); - StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId); - - UUID uuid = UUID.randomUUID(); - DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>(); - - // 褰曞儚鏌ヨ浠hannelId浣滀负deviceId鏌ヨ - resultHolder.put(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid, result); - - if (streamInfo == null) { - // 鍙戦�佺偣鎾秷鎭� - cmder.playStreamCmd(device, channelId, (JSONObject response) -> { - logger.info("鏀跺埌璁㈤槄娑堟伅锛� " + response.toJSONString()); - playService.onPublishHandlerForPlay(response, deviceId, channelId, uuid.toString()); - }, event -> { - RequestMessage msg = new RequestMessage(); - msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid); - Response response = event.getResponse(); - msg.setData(String.format("鐐规挱澶辫触锛� 閿欒鐮侊細 %s, %s", response.getStatusCode(), response.getReasonPhrase())); - resultHolder.invokeResult(msg); - }); - } else { - String streamId = streamInfo.getStreamId(); - JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(streamId); - if (rtpInfo.getBoolean("exist")) { - RequestMessage msg = new RequestMessage(); - msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid); - msg.setData(JSON.toJSONString(streamInfo)); - resultHolder.invokeResult(msg); - } else { - redisCatchStorage.stopPlay(streamInfo); - storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId()); - cmder.playStreamCmd(device, channelId, (JSONObject response) -> { - logger.info("鏀跺埌璁㈤槄娑堟伅锛� " + response.toJSONString()); - playService.onPublishHandlerForPlay(response, deviceId, channelId, uuid.toString()); - }, event -> { - RequestMessage msg = new RequestMessage(); - msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid); - Response response = event.getResponse(); - msg.setData(String.format("鐐规挱澶辫触锛� 閿欒鐮侊細 %s, %s", response.getStatusCode(), response.getReasonPhrase())); - resultHolder.invokeResult(msg); - }); - } - } + PlayResult playResult = playService.play(deviceId, channelId, null, null); // 瓒呮椂澶勭悊 - result.onTimeout(()->{ + playResult.getResult().onTimeout(()->{ logger.warn(String.format("璁惧鐐规挱瓒呮椂锛宒eviceId锛�%s 锛宑hannelId锛�%s", deviceId, channelId)); // 閲婃斁rtpserver - cmder.closeRTPServer(device, channelId); + cmder.closeRTPServer(playResult.getDevice(), channelId); RequestMessage msg = new RequestMessage(); - msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid); + msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + playResult.getUuid()); msg.setData("Timeout"); resultHolder.invokeResult(msg); }); - return result; + return playResult.getResult(); } @PostMapping("/play/{streamId}/stop") diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/play/bean/PlayResult.java b/src/main/java/com/genersoft/iot/vmp/vmanager/play/bean/PlayResult.java new file mode 100644 index 0000000..3d21349 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/play/bean/PlayResult.java @@ -0,0 +1,37 @@ +package com.genersoft.iot.vmp.vmanager.play.bean; + +import com.genersoft.iot.vmp.gb28181.bean.Device; +import org.springframework.http.ResponseEntity; +import org.springframework.web.context.request.async.DeferredResult; + +public class PlayResult { + + private DeferredResult<ResponseEntity<String>> result; + private String uuid; + + private Device device; + + public DeferredResult<ResponseEntity<String>> getResult() { + return result; + } + + public void setResult(DeferredResult<ResponseEntity<String>> result) { + this.result = result; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public Device getDevice() { + return device; + } + + public void setDevice(Device device) { + this.device = device; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/service/IPlayService.java b/src/main/java/com/genersoft/iot/vmp/vmanager/service/IPlayService.java index a80ab5d..898c014 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/service/IPlayService.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/service/IPlayService.java @@ -2,6 +2,11 @@ import com.alibaba.fastjson.JSONObject; import com.genersoft.iot.vmp.common.StreamInfo; +import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; +import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; +import com.genersoft.iot.vmp.vmanager.play.bean.PlayResult; +import org.springframework.http.ResponseEntity; +import org.springframework.web.context.request.async.DeferredResult; /** * 鐐规挱澶勭悊 @@ -10,4 +15,6 @@ void onPublishHandlerForPlayBack(JSONObject resonse, String deviceId, String channelId, String uuid); void onPublishHandlerForPlay(JSONObject resonse, String deviceId, String channelId, String uuid); + + PlayResult play(String deviceId, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent); } diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/vmanager/service/impl/PlayServiceImpl.java index 70ca1f3..e09541a 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/service/impl/PlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/service/impl/PlayServiceImpl.java @@ -4,19 +4,29 @@ 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.Device; import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; +import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; +import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; +import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; +import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorager; import com.genersoft.iot.vmp.vmanager.play.PlayController; +import com.genersoft.iot.vmp.vmanager.play.bean.PlayResult; import com.genersoft.iot.vmp.vmanager.service.IPlayService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; +import org.springframework.web.context.request.async.DeferredResult; +import javax.sip.message.Response; import java.text.DecimalFormat; +import java.util.UUID; @Service public class PlayServiceImpl implements IPlayService { @@ -27,11 +37,76 @@ private IVideoManagerStorager storager; @Autowired + private SIPCommander cmder; + + @Autowired private IRedisCatchStorage redisCatchStorage; @Autowired private DeferredResultHolder resultHolder; + @Autowired + private ZLMRESTfulUtils zlmresTfulUtils; + + + @Override + public PlayResult play(String deviceId, String channelId, ZLMHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent) { + PlayResult playResult = new PlayResult(); + Device device = storager.queryVideoDevice(deviceId); + StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId); + playResult.setDevice(device); + UUID uuid = UUID.randomUUID(); + playResult.setUuid(uuid.toString()); + DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>(); + playResult.setResult(result); + // 褰曞儚鏌ヨ浠hannelId浣滀负deviceId鏌ヨ + resultHolder.put(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid, result); + + if (streamInfo == null) { + // 鍙戦�佺偣鎾秷鎭� + cmder.playStreamCmd(device, channelId, (JSONObject response) -> { + logger.info("鏀跺埌璁㈤槄娑堟伅锛� " + response.toJSONString()); + onPublishHandlerForPlay(response, deviceId, channelId, uuid.toString()); + if (hookEvent != null) { + hookEvent.response(response); + } + }, event -> { + RequestMessage msg = new RequestMessage(); + msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid); + Response response = event.getResponse(); + msg.setData(String.format("鐐规挱澶辫触锛� 閿欒鐮侊細 %s, %s", response.getStatusCode(), response.getReasonPhrase())); + resultHolder.invokeResult(msg); + if (errorEvent != null) { + errorEvent.response(event); + } + }); + } else { + String streamId = streamInfo.getStreamId(); + JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(streamId); + if (rtpInfo.getBoolean("exist")) { + RequestMessage msg = new RequestMessage(); + msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid); + msg.setData(JSON.toJSONString(streamInfo)); + resultHolder.invokeResult(msg); + } else { + redisCatchStorage.stopPlay(streamInfo); + storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId()); + cmder.playStreamCmd(device, channelId, (JSONObject response) -> { + logger.info("鏀跺埌璁㈤槄娑堟伅锛� " + response.toJSONString()); + onPublishHandlerForPlay(response, deviceId, channelId, uuid.toString()); + }, event -> { + RequestMessage msg = new RequestMessage(); + msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid); + Response response = event.getResponse(); + msg.setData(String.format("鐐规挱澶辫触锛� 閿欒鐮侊細 %s, %s", response.getStatusCode(), response.getReasonPhrase())); + resultHolder.invokeResult(msg); + }); + } + } + + return playResult; + } + @Override public void onPublishHandlerForPlay(JSONObject resonse, String deviceId, String channelId, String uuid) { RequestMessage msg = new RequestMessage(); -- Gitblit v1.8.0