From 764d04b497356ba6bcbb75fd42b51eca750f7223 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: 星期三, 29 五月 2024 15:02:51 +0800 Subject: [PATCH] 调整上级观看消息的发送 --- src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java | 301 ++++++++++++++++++++++++------------------------- 1 files changed, 146 insertions(+), 155 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java old mode 100644 new mode 100755 index 2fcc9c2..780f536 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java @@ -1,42 +1,43 @@ package com.genersoft.iot.vmp.vmanager.gb28181.play; -import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson2.JSONArray; +import com.alibaba.fastjson2.JSONObject; +import com.genersoft.iot.vmp.common.InviteSessionType; import com.genersoft.iot.vmp.common.StreamInfo; +import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.conf.exception.ControllerException; +import com.genersoft.iot.vmp.conf.security.JwtUtils; +import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction; import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; -import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; -import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; -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.gb28181.transmit.cmd.impl.SIPCommander; +import com.genersoft.iot.vmp.media.bean.MediaServer; +import com.genersoft.iot.vmp.media.service.IMediaServerService; +import com.genersoft.iot.vmp.service.IInviteStreamService; +import com.genersoft.iot.vmp.service.IPlayService; +import com.genersoft.iot.vmp.service.bean.InviteErrorCode; +import com.genersoft.iot.vmp.storager.IVideoManagerStorage; +import com.genersoft.iot.vmp.utils.DateUtil; import com.genersoft.iot.vmp.vmanager.bean.AudioBroadcastResult; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; +import com.genersoft.iot.vmp.vmanager.bean.StreamContent; import com.genersoft.iot.vmp.vmanager.bean.WVPResult; -import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult; -import com.genersoft.iot.vmp.service.IMediaService; -import com.genersoft.iot.vmp.service.IPlayService; - import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.CrossOrigin; -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; - -import com.alibaba.fastjson.JSONObject; -import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; -import com.genersoft.iot.vmp.storager.IVideoManagerStorage; +import org.springframework.util.ObjectUtils; +import org.springframework.web.bind.annotation.*; import org.springframework.web.context.request.async.DeferredResult; +import javax.servlet.http.HttpServletRequest; +import java.net.MalformedURLException; +import java.net.URL; import java.util.List; import java.util.UUID; @@ -45,7 +46,7 @@ * @author lin */ @Tag(name = "鍥芥爣璁惧鐐规挱") -@CrossOrigin + @RestController @RequestMapping("/api/play") public class PlayController { @@ -62,10 +63,7 @@ private IVideoManagerStorage storager; @Autowired - private IRedisCatchStorage redisCatchStorage; - - @Autowired - private ZLMRESTfulUtils zlmresTfulUtils; + private IInviteStreamService inviteStreamService; @Autowired private DeferredResultHolder resultHolder; @@ -74,28 +72,84 @@ private IPlayService playService; @Autowired - private IMediaService mediaService; - - @Autowired private IMediaServerService mediaServerService; - @Operation(summary = "寮�濮嬬偣鎾�") + @Autowired + private UserSetting userSetting; + + @Operation(summary = "寮�濮嬬偣鎾�", security = @SecurityRequirement(name = JwtUtils.HEADER)) @Parameter(name = "deviceId", description = "璁惧鍥芥爣缂栧彿", required = true) @Parameter(name = "channelId", description = "閫氶亾鍥芥爣缂栧彿", required = true) @GetMapping("/start/{deviceId}/{channelId}") - public DeferredResult<WVPResult<String>> play(@PathVariable String deviceId, - @PathVariable String channelId) { + public DeferredResult<WVPResult<StreamContent>> play(HttpServletRequest request, @PathVariable String deviceId, + @PathVariable String channelId) { + logger.info("[寮�濮嬬偣鎾璢 deviceId锛歿}, channelId锛歿}, ", deviceId, channelId); // 鑾峰彇鍙敤鐨剒lm Device device = storager.queryVideoDevice(deviceId); - MediaServerItem newMediaServerItem = playService.getNewMediaServerItem(device); - PlayResult playResult = playService.play(newMediaServerItem, deviceId, channelId, null, null, null); + MediaServer newMediaServerItem = playService.getNewMediaServerItem(device); - return playResult.getResult(); + RequestMessage requestMessage = new RequestMessage(); + String key = DeferredResultHolder.CALLBACK_CMD_PLAY + deviceId + channelId; + requestMessage.setKey(key); + String uuid = UUID.randomUUID().toString(); + requestMessage.setId(uuid); + DeferredResult<WVPResult<StreamContent>> result = new DeferredResult<>(userSetting.getPlayTimeout().longValue()); + + result.onTimeout(()->{ + logger.info("[鐐规挱绛夊緟瓒呮椂] deviceId锛歿}, channelId锛歿}, ", deviceId, channelId); + // 閲婃斁rtpserver + WVPResult<StreamInfo> wvpResult = new WVPResult<>(); + wvpResult.setCode(ErrorCode.ERROR100.getCode()); + wvpResult.setMsg("鐐规挱瓒呮椂"); + requestMessage.setData(wvpResult); + resultHolder.invokeAllResult(requestMessage); + inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId); + storager.stopPlay(deviceId, channelId); + }); + + // 褰曞儚鏌ヨ浠hannelId浣滀负deviceId鏌ヨ + resultHolder.put(key, uuid, result); + + playService.play(newMediaServerItem, deviceId, channelId, null, (code, msg, data) -> { + WVPResult<StreamContent> wvpResult = new WVPResult<>(); + if (code == InviteErrorCode.SUCCESS.getCode()) { + wvpResult.setCode(ErrorCode.SUCCESS.getCode()); + wvpResult.setMsg(ErrorCode.SUCCESS.getMsg()); + + if (data != null) { + StreamInfo streamInfo = (StreamInfo)data; + if (userSetting.getUseSourceIpAsStreamIp()) { + streamInfo=streamInfo.clone();//娣辨嫹璐� + String host; + try { + URL url=new URL(request.getRequestURL().toString()); + host=url.getHost(); + } catch (MalformedURLException e) { + host=request.getLocalAddr(); + } + streamInfo.channgeStreamIp(host); + } + if (!ObjectUtils.isEmpty(newMediaServerItem.getTranscodeSuffix()) && !"null".equalsIgnoreCase(newMediaServerItem.getTranscodeSuffix())) { + streamInfo.setStream(streamInfo.getStream() + "_" + newMediaServerItem.getTranscodeSuffix()); + } + wvpResult.setData(new StreamContent(streamInfo)); + }else { + wvpResult.setCode(code); + wvpResult.setMsg(msg); + } + }else { + wvpResult.setCode(code); + wvpResult.setMsg(msg); + } + requestMessage.setData(wvpResult); + // 姝ゅ蹇呴』閲婃斁鎵�鏈夎姹� + resultHolder.invokeAllResult(requestMessage); + }); + return result; } - - @Operation(summary = "鍋滄鐐规挱") + @Operation(summary = "鍋滄鐐规挱", security = @SecurityRequirement(name = JwtUtils.HEADER)) @Parameter(name = "deviceId", description = "璁惧鍥芥爣缂栧彿", required = true) @Parameter(name = "channelId", description = "閫氶亾鍥芥爣缂栧彿", required = true) @GetMapping("/stop/{deviceId}/{channelId}") @@ -107,70 +161,21 @@ throw new ControllerException(ErrorCode.ERROR400); } - StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId); - if (streamInfo == null) { - throw new ControllerException(ErrorCode.ERROR100.getCode(), "鐐规挱鏈壘鍒�"); + Device device = storager.queryVideoDevice(deviceId); + if (device == null) { + throw new ControllerException(ErrorCode.ERROR100.getCode(), "璁惧[" + deviceId + "]涓嶅瓨鍦�"); } - cmder.streamByeCmd(deviceId, channelId, streamInfo.getStream(), null, null); - redisCatchStorage.stopPlay(streamInfo); - - storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId()); + playService.stopPlay(device, channelId); JSONObject json = new JSONObject(); json.put("deviceId", deviceId); json.put("channelId", channelId); return json; - } - - /** - * 灏嗕笉鏄痟264鐨勮棰戦�氳繃ffmpeg 杞爜涓篽264 + aac - * @param streamId 娴両D - */ - @Operation(summary = "灏嗕笉鏄痟264鐨勮棰戦�氳繃ffmpeg 杞爜涓篽264 + aac") - @Parameter(name = "streamId", description = "瑙嗛娴両D", required = true) - @PostMapping("/convert/{streamId}") - public JSONObject playConvert(@PathVariable String streamId) { - StreamInfo streamInfo = redisCatchStorage.queryPlayByStreamId(streamId); - if (streamInfo == null) { - streamInfo = redisCatchStorage.queryPlayback(null, null, streamId, null); - } - if (streamInfo == null) { - logger.warn("瑙嗛杞爜API璋冪敤澶辫触锛�, 瑙嗛娴佸凡缁忓仠姝�!"); - throw new ControllerException(ErrorCode.ERROR100.getCode(), "鏈壘鍒拌棰戞祦淇℃伅, 瑙嗛娴佸彲鑳藉凡缁忓仠姝�"); - } - MediaServerItem mediaInfo = mediaServerService.getOne(streamInfo.getMediaServerId()); - JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(mediaInfo, streamId); - if (!rtpInfo.getBoolean("exist")) { - logger.warn("瑙嗛杞爜API璋冪敤澶辫触锛�, 瑙嗛娴佸凡鍋滄鎺ㄦ祦!"); - throw new ControllerException(ErrorCode.ERROR100.getCode(), "鏈壘鍒拌棰戞祦淇℃伅, 瑙嗛娴佸彲鑳藉凡鍋滄鎺ㄦ祦"); - } else { - String dstUrl = String.format("rtmp://%s:%s/convert/%s", "127.0.0.1", mediaInfo.getRtmpPort(), - streamId ); - String srcUrl = String.format("rtsp://%s:%s/rtp/%s", "127.0.0.1", mediaInfo.getRtspPort(), streamId); - JSONObject jsonObject = zlmresTfulUtils.addFFmpegSource(mediaInfo, srcUrl, dstUrl, "1000000", true, false, null); - logger.info(jsonObject.toJSONString()); - if (jsonObject != null && jsonObject.getInteger("code") == 0) { - JSONObject data = jsonObject.getJSONObject("data"); - if (data != null) { - JSONObject result = new JSONObject(); - result.put("key", data.getString("key")); - StreamInfo streamInfoResult = mediaService.getStreamInfoByAppAndStreamWithCheck("convert", streamId, mediaInfo.getId(), false); - result.put("StreamInfo", streamInfoResult); - return result; - }else { - throw new ControllerException(ErrorCode.ERROR100.getCode(), "杞爜澶辫触"); - } - }else { - throw new ControllerException(ErrorCode.ERROR100.getCode(), "杞爜澶辫触"); - } - } - } - /** * 缁撴潫杞爜 */ - @Operation(summary = "缁撴潫杞爜") + @Operation(summary = "缁撴潫杞爜", security = @SecurityRequirement(name = JwtUtils.HEADER)) @Parameter(name = "key", description = "瑙嗛娴乲ey", required = true) @Parameter(name = "mediaServerId", description = "娴佸獟浣撴湇鍔D", required = true) @PostMapping("/convertStop/{key}") @@ -178,103 +183,58 @@ if (mediaServerId == null) { throw new ControllerException(ErrorCode.ERROR400.getCode(), "娴佸獟浣擄細" + mediaServerId + "涓嶅瓨鍦�" ); } - MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); + MediaServer mediaInfo = mediaServerService.getOne(mediaServerId); if (mediaInfo == null) { throw new ControllerException(ErrorCode.ERROR100.getCode(), "浣跨敤鐨勬祦濯掍綋宸茬粡鍋滄杩愯" ); }else { - JSONObject jsonObject = zlmresTfulUtils.delFFmpegSource(mediaInfo, key); - logger.info(jsonObject.toJSONString()); - if (jsonObject != null && jsonObject.getInteger("code") == 0) { - JSONObject data = jsonObject.getJSONObject("data"); - if (data == null || data.getBoolean("flag") == null || !data.getBoolean("flag")) { - throw new ControllerException(ErrorCode.ERROR100 ); - } - }else { + Boolean deleted = mediaServerService.delFFmpegSource(mediaInfo, key); + if (!deleted) { throw new ControllerException(ErrorCode.ERROR100 ); } } } - @Operation(summary = "璇煶骞挎挱鍛戒护") + @Operation(summary = "璇煶骞挎挱鍛戒护", security = @SecurityRequirement(name = JwtUtils.HEADER)) @Parameter(name = "deviceId", description = "璁惧鍥芥爣缂栧彿", required = true) @Parameter(name = "deviceId", description = "閫氶亾鍥芥爣缂栧彿", required = true) @Parameter(name = "timeout", description = "鎺ㄦ祦瓒呮椂鏃堕棿(绉�)", required = true) @GetMapping("/broadcast/{deviceId}/{channelId}") @PostMapping("/broadcast/{deviceId}/{channelId}") - public DeferredResult<WVPResult<AudioBroadcastResult>> broadcastApi(@PathVariable String deviceId, @PathVariable String channelId, Integer timeout) { - if (logger.isDebugEnabled()) { - logger.debug("璇煶骞挎挱API璋冪敤"); - } - Device device = storager.queryVideoDevice(deviceId); + public AudioBroadcastResult broadcastApi(@PathVariable String deviceId, @PathVariable String channelId, Integer timeout, Boolean broadcastMode) { + if (logger.isDebugEnabled()) { + logger.debug("璇煶骞挎挱API璋冪敤"); + } + Device device = storager.queryVideoDevice(deviceId); if (device == null) { - WVPResult<AudioBroadcastResult> result = new WVPResult<>(); - result.setCode(-1); - result.setMsg("鏈壘鍒拌澶囷細 " + deviceId); - DeferredResult<WVPResult<AudioBroadcastResult>> deferredResult = new DeferredResult<>(); - deferredResult.setResult(result); - return deferredResult; + throw new ControllerException(ErrorCode.ERROR400.getCode(), "鏈壘鍒拌澶囷細 " + deviceId); } if (channelId == null) { - WVPResult<AudioBroadcastResult> result = new WVPResult<>(); - result.setCode(-1); - result.setMsg("鏈壘鍒伴�氶亾锛� " + channelId); - DeferredResult<WVPResult<AudioBroadcastResult>> deferredResult = new DeferredResult<>(); - deferredResult.setResult(result); - return deferredResult; + throw new ControllerException(ErrorCode.ERROR400.getCode(), "鏈壘鍒伴�氶亾锛� " + channelId); } - String key = DeferredResultHolder.CALLBACK_CMD_BROADCAST + deviceId; - if (resultHolder.exist(key, null)) { - WVPResult<AudioBroadcastResult> wvpResult = new WVPResult<>(); - wvpResult.setCode(-1); - wvpResult.setMsg("璁惧浣跨敤涓�"); - DeferredResult<WVPResult<AudioBroadcastResult>> deferredResult = new DeferredResult<>(); - deferredResult.setResult(wvpResult); - return deferredResult; - } - if (timeout == null){ - timeout = 30; - } - DeferredResult<WVPResult<AudioBroadcastResult>> result = new DeferredResult<>(timeout.longValue()*1000 + 2000); - String uuid = UUID.randomUUID().toString(); - result.onTimeout(()->{ - WVPResult<AudioBroadcastResult> wvpResult = new WVPResult<>(); - wvpResult.setCode(-1); - wvpResult.setMsg("璇锋眰瓒呮椂"); - RequestMessage requestMessage = new RequestMessage(); - requestMessage.setKey(key); - requestMessage.setData(wvpResult); - resultHolder.invokeAllResult(requestMessage); - }); - playService.audioBroadcast(device, channelId, timeout, (msg)->{ - WVPResult<AudioBroadcastResult> wvpResult = new WVPResult<>(); - wvpResult.setCode(-1); - wvpResult.setMsg(msg); - RequestMessage requestMessage = new RequestMessage(); - requestMessage.setKey(key); - requestMessage.setData(wvpResult); - resultHolder.invokeAllResult(requestMessage); - }); - resultHolder.put(key, uuid, result); + return playService.audioBroadcast(device, channelId, broadcastMode); - return result; } - @Operation(summary = "鍋滄璇煶骞挎挱") @Parameter(name = "deviceId", description = "璁惧Id", required = true) @Parameter(name = "channelId", description = "閫氶亾Id", required = true) @GetMapping("/broadcast/stop/{deviceId}/{channelId}") @PostMapping("/broadcast/stop/{deviceId}/{channelId}") - public WVPResult<String> stopBroadcastA(@PathVariable String deviceId, @PathVariable String channelId) { + public void stopBroadcast(@PathVariable String deviceId, @PathVariable String channelId) { if (logger.isDebugEnabled()) { logger.debug("鍋滄璇煶骞挎挱API璋冪敤"); } +// try { +// playService.stopAudioBroadcast(deviceId, channelId); +// } catch (InvalidArgumentException | ParseException | SipException e) { +// logger.error("[鍛戒护鍙戦�佸け璐 鍋滄璇煶: {}", e.getMessage()); +// throw new ControllerException(ErrorCode.ERROR100.getCode(), "鍛戒护鍙戦�佸け璐�: " + e.getMessage()); +// } playService.stopAudioBroadcast(deviceId, channelId); - return new WVPResult<>(0, "success", null); } - @Operation(summary = "鑾峰彇鎵�鏈夌殑ssrc") + @Operation(summary = "鑾峰彇鎵�鏈夌殑ssrc", security = @SecurityRequirement(name = JwtUtils.HEADER)) @GetMapping("/ssrc") public JSONObject getSSRC() { if (logger.isDebugEnabled()) { @@ -297,5 +257,36 @@ return jsonObject; } + @Operation(summary = "鑾峰彇鎴浘", security = @SecurityRequirement(name = JwtUtils.HEADER)) + @Parameter(name = "deviceId", description = "璁惧鍥芥爣缂栧彿", required = true) + @Parameter(name = "channelId", description = "閫氶亾鍥芥爣缂栧彿", required = true) + @Parameter(name = "isSubStream", description = "鏄惁瀛愮爜娴侊紙true-瀛愮爜娴侊紝false-涓荤爜娴侊級锛岄粯璁や负false", required = true) + @GetMapping("/snap") + public DeferredResult<String> getSnap(String deviceId, String channelId,boolean isSubStream) { + if (logger.isDebugEnabled()) { + logger.debug("鑾峰彇鎴浘: {}/{}", deviceId, channelId); + } + + DeferredResult<String> result = new DeferredResult<>(3 * 1000L); + String key = DeferredResultHolder.CALLBACK_CMD_SNAP + deviceId; + String uuid = UUID.randomUUID().toString(); + resultHolder.put(key, uuid, result); + + RequestMessage message = new RequestMessage(); + message.setKey(key); + message.setId(uuid); + + String fileName = deviceId + "_" + channelId + "_" + DateUtil.getNowForUrl() + ".jpg"; + playService.getSnap(deviceId, channelId, fileName, (code, msg, data) -> { + if (code == InviteErrorCode.SUCCESS.getCode()) { + message.setData(data); + }else { + message.setData(WVPResult.fail(code, msg)); + } + resultHolder.invokeResult(message); + }); + return result; + } + } -- Gitblit v1.8.0