648540858
2024-04-01 33b75be71a7b7b324e652d3a4be62b0f03b5d46b
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java
@@ -9,28 +9,27 @@
import com.genersoft.iot.vmp.conf.UserSetting;
import com.genersoft.iot.vmp.conf.exception.ControllerException;
import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException;
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.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.ZLMRESTfulUtils;
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
import com.genersoft.iot.vmp.media.service.IMediaServerService;
import com.genersoft.iot.vmp.media.bean.MediaServer;
import com.genersoft.iot.vmp.service.IInviteStreamService;
import com.genersoft.iot.vmp.service.IMediaServerService;
import com.genersoft.iot.vmp.service.IMediaService;
import com.genersoft.iot.vmp.service.IPlayService;
import com.genersoft.iot.vmp.service.bean.InviteErrorCode;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
import com.genersoft.iot.vmp.utils.DateUtil;
import com.genersoft.iot.vmp.vmanager.bean.*;
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 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;
@@ -69,13 +68,7 @@
   private IVideoManagerStorage storager;
   @Autowired
   private IRedisCatchStorage redisCatchStorage;
   @Autowired
   private IInviteStreamService inviteStreamService;
   @Autowired
   private ZLMRESTfulUtils zlmresTfulUtils;
   @Autowired
   private DeferredResultHolder resultHolder;
@@ -84,15 +77,12 @@
   private IPlayService playService;
   @Autowired
   private IMediaService mediaService;
   @Autowired
   private IMediaServerService mediaServerService;
   @Autowired
   private UserSetting userSetting;
   @Operation(summary = "开始点播")
   @Operation(summary = "开始点播", security = @SecurityRequirement(name = JwtUtils.HEADER))
   @Parameter(name = "deviceId", description = "设备国标编号", required = true)
   @Parameter(name = "channelId", description = "通道国标编号", required = true)
   @GetMapping("/start/{deviceId}/{channelId}")
@@ -102,7 +92,7 @@
      logger.info("[开始点播] deviceId:{}, channelId:{}, ", deviceId, channelId);
      // 获取可用的zlm
      Device device = storager.queryVideoDevice(deviceId);
      MediaServerItem newMediaServerItem = playService.getNewMediaServerItem(device);
      MediaServer newMediaServerItem = playService.getNewMediaServerItem(device);
      RequestMessage requestMessage = new RequestMessage();
      String key = DeferredResultHolder.CALLBACK_CMD_PLAY + deviceId + channelId;
@@ -146,6 +136,9 @@
                  streamInfo.channgeStreamIp(host);
               }
               wvpResult.setData(new StreamContent(streamInfo));
            }else {
               wvpResult.setCode(code);
               wvpResult.setMsg(msg);
            }
         }else {
            wvpResult.setCode(code);
@@ -157,7 +150,7 @@
      return result;
   }
   @Operation(summary = "停止点播")
   @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)
@@ -197,54 +190,10 @@
      json.put("isSubStream", isSubStream);
      return json;
   }
   /**
    * 将不是h264的视频通过ffmpeg 转码为h264 + aac
    * @param streamId 流ID
    */
   @Operation(summary = "将不是h264的视频通过ffmpeg 转码为h264 + aac")
   @Parameter(name = "streamId", description = "视频流ID", required = true)
   @PostMapping("/convert/{streamId}")
   public JSONObject playConvert(@PathVariable String streamId) {
//      StreamInfo streamInfo = redisCatchStorage.queryPlayByStreamId(streamId);
      InviteInfo inviteInfo = inviteStreamService.getInviteInfoByStream(null, streamId);
      if (inviteInfo == null || inviteInfo.getStreamInfo() == null) {
         logger.warn("视频转码API调用失败!, 视频流已经停止!");
         throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到视频流信息, 视频流可能已经停止");
      }
      MediaServerItem mediaInfo = mediaServerService.getOne(inviteInfo.getStreamInfo().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 = "视频流key", required = true)
   @Parameter(name = "mediaServerId", description = "流媒体服务ID", required = true)
   @PostMapping("/convertStop/{key}")
@@ -252,24 +201,18 @@
      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)
@@ -309,7 +252,7 @@
      playService.stopAudioBroadcast(deviceId, channelId);
   }
   @Operation(summary = "获取所有的ssrc")
   @Operation(summary = "获取所有的ssrc", security = @SecurityRequirement(name = JwtUtils.HEADER))
   @GetMapping("/ssrc")
   public JSONObject getSSRC() {
      if (logger.isDebugEnabled()) {
@@ -332,7 +275,7 @@
      return jsonObject;
   }
   @Operation(summary = "获取截图")
   @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)