| | |
| | | import com.genersoft.iot.vmp.service.IMediaServerService; |
| | | import com.genersoft.iot.vmp.service.bean.CloudRecordItem; |
| | | import com.genersoft.iot.vmp.service.bean.DownloadFileInfo; |
| | | import com.genersoft.iot.vmp.utils.DateUtil; |
| | | import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; |
| | | import com.genersoft.iot.vmp.vmanager.cloudRecord.bean.CloudRecordUrl; |
| | | import com.github.pagehelper.PageInfo; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.io.File; |
| | | import java.io.FileInputStream; |
| | | import java.io.IOException; |
| | | import java.util.ArrayList; |
| | | import java.util.Calendar; |
| | | import java.util.List; |
| | | import java.util.zip.ZipEntry; |
| | | import java.util.zip.ZipOutputStream; |
| | | |
| | | @SuppressWarnings("rawtypes") |
| | | @Tag(name = "云端录像接口") |
| | |
| | | @Parameter(name = "startTime", description = "开始时间(yyyy-MM-dd HH:mm:ss)", required = false) |
| | | @Parameter(name = "endTime", description = "结束时间(yyyy-MM-dd HH:mm:ss)", required = false) |
| | | @Parameter(name = "mediaServerId", description = "流媒体ID,置空则查询全部流媒体", required = false) |
| | | @Parameter(name = "callId", description = "每次录像的唯一标识,置空则查询全部流媒体", required = false) |
| | | public PageInfo<CloudRecordItem> openRtpServer( |
| | | @RequestParam(required = false) String query, |
| | | @RequestParam(required = false) String app, |
| | |
| | | @RequestParam int count, |
| | | @RequestParam(required = false) String startTime, |
| | | @RequestParam(required = false) String endTime, |
| | | @RequestParam(required = false) String mediaServerId |
| | | @RequestParam(required = false) String mediaServerId, |
| | | @RequestParam(required = false) String callId |
| | | |
| | | ) { |
| | | logger.info("[云端录像] 查询 app->{}, stream->{}, mediaServerId->{}, page->{}, count->{}, startTime->{}, endTime->{}", |
| | | app, stream, mediaServerId, page, count, startTime, endTime); |
| | | logger.info("[云端录像] 查询 app->{}, stream->{}, mediaServerId->{}, page->{}, count->{}, startTime->{}, endTime->{}, callId->{}", |
| | | app, stream, mediaServerId, page, count, startTime, endTime, callId); |
| | | |
| | | List<MediaServerItem> mediaServerItems; |
| | | if (!ObjectUtils.isEmpty(mediaServerId)) { |
| | |
| | | if (endTime != null && ObjectUtils.isEmpty(endTime.trim())) { |
| | | endTime = null; |
| | | } |
| | | return cloudRecordService.getList(page, count, query, app, stream, startTime, endTime, mediaServerItems); |
| | | if (callId != null && ObjectUtils.isEmpty(callId.trim())) { |
| | | callId = null; |
| | | } |
| | | return cloudRecordService.getList(page, count, query, app, stream, startTime, endTime, mediaServerItems, callId); |
| | | } |
| | | |
| | | @ResponseBody |
| | |
| | | ){ |
| | | return cloudRecordService.getPlayUrlPath(recordId); |
| | | } |
| | | |
| | | /************************* 以下这些接口只适合wvp和zlm部署在同一台服务器的情况,且wvp只有一个zlm节点的情况 ***************************************/ |
| | | |
| | | /** |
| | | * 下载指定录像文件的压缩包 |
| | | * @param query 检索内容 |
| | | * @param app 应用名 |
| | | * @param stream 流ID |
| | | * @param startTime 开始时间(yyyy-MM-dd HH:mm:ss) |
| | | * @param endTime 结束时间(yyyy-MM-dd HH:mm:ss) |
| | | * @param mediaServerId 流媒体ID,置空则查询全部流媒体 |
| | | * @param callId 每次录像的唯一标识,置空则查询全部流媒体 |
| | | * @param ids 指定的Id |
| | | */ |
| | | @ResponseBody |
| | | @GetMapping("/zip") |
| | | public void downloadZipFile( |
| | | HttpServletResponse response, |
| | | @RequestParam(required = false) String query, |
| | | @RequestParam(required = false) String app, |
| | | @RequestParam(required = false) String stream, |
| | | @RequestParam(required = false) String startTime, |
| | | @RequestParam(required = false) String endTime, |
| | | @RequestParam(required = false) String mediaServerId, |
| | | @RequestParam(required = false) String callId, |
| | | @RequestParam(required = false) List<Integer> ids |
| | | |
| | | ) { |
| | | logger.info("[下载指定录像文件的压缩包] 查询 app->{}, stream->{}, mediaServerId->{}, startTime->{}, endTime->{}, callId->{}", |
| | | app, stream, mediaServerId, startTime, endTime, callId); |
| | | |
| | | List<MediaServerItem> mediaServerItems; |
| | | if (!ObjectUtils.isEmpty(mediaServerId)) { |
| | | mediaServerItems = new ArrayList<>(); |
| | | MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId); |
| | | if (mediaServerItem == null) { |
| | | throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到流媒体: " + mediaServerId); |
| | | } |
| | | mediaServerItems.add(mediaServerItem); |
| | | } else { |
| | | mediaServerItems = mediaServerService.getAll(); |
| | | } |
| | | if (mediaServerItems.isEmpty()) { |
| | | throw new ControllerException(ErrorCode.ERROR100.getCode(), "当前无流媒体"); |
| | | } |
| | | if (query != null && ObjectUtils.isEmpty(query.trim())) { |
| | | query = null; |
| | | } |
| | | if (app != null && ObjectUtils.isEmpty(app.trim())) { |
| | | app = null; |
| | | } |
| | | if (stream != null && ObjectUtils.isEmpty(stream.trim())) { |
| | | stream = null; |
| | | } |
| | | if (startTime != null && ObjectUtils.isEmpty(startTime.trim())) { |
| | | startTime = null; |
| | | } |
| | | if (endTime != null && ObjectUtils.isEmpty(endTime.trim())) { |
| | | endTime = null; |
| | | } |
| | | if (callId != null && ObjectUtils.isEmpty(callId.trim())) { |
| | | callId = null; |
| | | } |
| | | if (stream != null && callId != null) { |
| | | response.addHeader( "Content-Disposition", "attachment;filename=" + stream + "_" + callId + ".zip" ); |
| | | } |
| | | List<CloudRecordItem> cloudRecordItemList = cloudRecordService.getAllList(query, app, stream, startTime, endTime, mediaServerItems, callId, ids); |
| | | if (ObjectUtils.isEmpty(cloudRecordItemList)) { |
| | | return; |
| | | } |
| | | try { |
| | | ZipOutputStream zos = new ZipOutputStream(response.getOutputStream()); |
| | | for (CloudRecordItem cloudRecordItem : cloudRecordItemList) { |
| | | zos.putNextEntry(new ZipEntry(DateUtil.timestampMsToUrlToyyyy_MM_dd_HH_mm_ss(cloudRecordItem.getStartTime()) + ".mp4")); |
| | | File file = new File(cloudRecordItem.getFilePath()); |
| | | if (!file.exists() || file.isDirectory()) { |
| | | continue; |
| | | } |
| | | FileInputStream fis = new FileInputStream(cloudRecordItem.getFilePath()); |
| | | byte[] buf = new byte[2*1024]; |
| | | int len; |
| | | while ((len = fis.read(buf)) != -1){ |
| | | zos.write(buf, 0, len); |
| | | } |
| | | zos.closeEntry(); |
| | | fis.close(); |
| | | } |
| | | zos.close(); |
| | | } catch (IOException e) { |
| | | logger.error("[下载指定录像文件的压缩包] 失败: 查询 app->{}, stream->{}, mediaServerId->{}, startTime->{}, endTime->{}, callId->{}", |
| | | app, stream, mediaServerId, startTime, endTime, callId, e); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * |
| | | * @param query 检索内容 |
| | | * @param app 应用名 |
| | | * @param stream 流ID |
| | | * @param startTime 开始时间(yyyy-MM-dd HH:mm:ss) |
| | | * @param endTime 结束时间(yyyy-MM-dd HH:mm:ss) |
| | | * @param mediaServerId 流媒体ID,置空则查询全部流媒体 |
| | | * @param callId 每次录像的唯一标识,置空则查询全部流媒体 |
| | | * @param remoteHost 拼接播放地址时使用的远程地址 |
| | | */ |
| | | @ResponseBody |
| | | @GetMapping("/list-url") |
| | | @Operation(summary = "分页查询云端录像", security = @SecurityRequirement(name = JwtUtils.HEADER)) |
| | | @Parameter(name = "query", description = "检索内容", required = false) |
| | | @Parameter(name = "app", description = "应用名", required = false) |
| | | @Parameter(name = "stream", description = "流ID", required = false) |
| | | @Parameter(name = "page", description = "当前页", required = true) |
| | | @Parameter(name = "count", description = "每页查询数量", required = true) |
| | | @Parameter(name = "startTime", description = "开始时间(yyyy-MM-dd HH:mm:ss)", required = false) |
| | | @Parameter(name = "endTime", description = "结束时间(yyyy-MM-dd HH:mm:ss)", required = false) |
| | | @Parameter(name = "mediaServerId", description = "流媒体ID,置空则查询全部流媒体", required = false) |
| | | @Parameter(name = "callId", description = "每次录像的唯一标识,置空则查询全部流媒体", required = false) |
| | | public PageInfo<CloudRecordUrl> getListWithUrl( |
| | | HttpServletRequest request, |
| | | @RequestParam(required = false) String query, |
| | | @RequestParam(required = false) String app, |
| | | @RequestParam(required = false) String stream, |
| | | @RequestParam int page, |
| | | @RequestParam int count, |
| | | @RequestParam(required = false) String startTime, |
| | | @RequestParam(required = false) String endTime, |
| | | @RequestParam(required = false) String mediaServerId, |
| | | @RequestParam(required = false) String callId, |
| | | @RequestParam(required = false) String remoteHost |
| | | |
| | | ) { |
| | | logger.info("[云端录像] 查询URL app->{}, stream->{}, mediaServerId->{}, page->{}, count->{}, startTime->{}, endTime->{}, callId->{}", |
| | | app, stream, mediaServerId, page, count, startTime, endTime, callId); |
| | | |
| | | List<MediaServerItem> mediaServerItems; |
| | | if (!ObjectUtils.isEmpty(mediaServerId)) { |
| | | mediaServerItems = new ArrayList<>(); |
| | | MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId); |
| | | if (mediaServerItem == null) { |
| | | throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到流媒体: " + mediaServerId); |
| | | } |
| | | mediaServerItems.add(mediaServerItem); |
| | | } else { |
| | | mediaServerItems = mediaServerService.getAll(); |
| | | } |
| | | if (mediaServerItems.isEmpty()) { |
| | | throw new ControllerException(ErrorCode.ERROR100.getCode(), "当前无流媒体"); |
| | | } |
| | | if (query != null && ObjectUtils.isEmpty(query.trim())) { |
| | | query = null; |
| | | } |
| | | if (app != null && ObjectUtils.isEmpty(app.trim())) { |
| | | app = null; |
| | | } |
| | | if (stream != null && ObjectUtils.isEmpty(stream.trim())) { |
| | | stream = null; |
| | | } |
| | | if (startTime != null && ObjectUtils.isEmpty(startTime.trim())) { |
| | | startTime = null; |
| | | } |
| | | if (endTime != null && ObjectUtils.isEmpty(endTime.trim())) { |
| | | endTime = null; |
| | | } |
| | | if (callId != null && ObjectUtils.isEmpty(callId.trim())) { |
| | | callId = null; |
| | | } |
| | | MediaServerItem mediaServerItem = mediaServerService.getDefaultMediaServer(); |
| | | if (mediaServerItem == null) { |
| | | throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到流媒体节点"); |
| | | } |
| | | if (remoteHost == null) { |
| | | remoteHost = request.getScheme() + "://" + request.getLocalAddr() + ":" + |
| | | (request.getScheme().equals("https")? mediaServerItem.getHttpSSlPort() : mediaServerItem.getHttpPort()); |
| | | } |
| | | PageInfo<CloudRecordItem> cloudRecordItemPageInfo = cloudRecordService.getList(page, count, query, app, stream, startTime, endTime, mediaServerItems, callId); |
| | | PageInfo<CloudRecordUrl> cloudRecordUrlPageInfo = new PageInfo<>(); |
| | | if (!ObjectUtils.isEmpty(cloudRecordItemPageInfo)) { |
| | | cloudRecordUrlPageInfo.setPageNum(cloudRecordItemPageInfo.getPageNum()); |
| | | cloudRecordUrlPageInfo.setPageSize(cloudRecordItemPageInfo.getPageSize()); |
| | | cloudRecordUrlPageInfo.setSize(cloudRecordItemPageInfo.getSize()); |
| | | cloudRecordUrlPageInfo.setEndRow(cloudRecordItemPageInfo.getEndRow()); |
| | | cloudRecordUrlPageInfo.setStartRow(cloudRecordItemPageInfo.getStartRow()); |
| | | cloudRecordUrlPageInfo.setPages(cloudRecordItemPageInfo.getPages()); |
| | | cloudRecordUrlPageInfo.setPrePage(cloudRecordItemPageInfo.getPrePage()); |
| | | cloudRecordUrlPageInfo.setNextPage(cloudRecordItemPageInfo.getNextPage()); |
| | | cloudRecordUrlPageInfo.setIsFirstPage(cloudRecordItemPageInfo.isIsFirstPage()); |
| | | cloudRecordUrlPageInfo.setIsLastPage(cloudRecordItemPageInfo.isIsLastPage()); |
| | | cloudRecordUrlPageInfo.setHasPreviousPage(cloudRecordItemPageInfo.isHasPreviousPage()); |
| | | cloudRecordUrlPageInfo.setHasNextPage(cloudRecordItemPageInfo.isHasNextPage()); |
| | | cloudRecordUrlPageInfo.setNavigatePages(cloudRecordItemPageInfo.getNavigatePages()); |
| | | cloudRecordUrlPageInfo.setNavigateFirstPage(cloudRecordItemPageInfo.getNavigateFirstPage()); |
| | | cloudRecordUrlPageInfo.setNavigateLastPage(cloudRecordItemPageInfo.getNavigateLastPage()); |
| | | cloudRecordUrlPageInfo.setNavigatepageNums(cloudRecordItemPageInfo.getNavigatepageNums()); |
| | | cloudRecordUrlPageInfo.setTotal(cloudRecordItemPageInfo.getTotal()); |
| | | List<CloudRecordUrl> cloudRecordUrlList = new ArrayList<>(cloudRecordItemPageInfo.getList().size()); |
| | | List<CloudRecordItem> cloudRecordItemList = cloudRecordItemPageInfo.getList(); |
| | | for (CloudRecordItem cloudRecordItem : cloudRecordItemList) { |
| | | CloudRecordUrl cloudRecordUrl = new CloudRecordUrl(); |
| | | cloudRecordUrl.setId(cloudRecordItem.getId()); |
| | | cloudRecordUrl.setDownloadUrl(remoteHost + "/index/api/downloadFile?file_path=" + cloudRecordItem.getFilePath() |
| | | + "&save_name=" + cloudRecordItem.getStream() + "_" + cloudRecordItem.getCallId() + "_" + DateUtil.timestampMsToUrlToyyyy_MM_dd_HH_mm_ss(cloudRecordItem.getStartTime()) ); |
| | | cloudRecordUrl.setPlayUrl(remoteHost + "/index/api/downloadFile?file_path=" + cloudRecordItem.getFilePath()); |
| | | cloudRecordUrlList.add(cloudRecordUrl); |
| | | } |
| | | cloudRecordUrlPageInfo.setList(cloudRecordUrlList); |
| | | } |
| | | return cloudRecordUrlPageInfo; |
| | | } |
| | | } |