From 22f306496b583d3c25f2d3354441b0e29d6840cf Mon Sep 17 00:00:00 2001
From: liusuyi <1951119284@qq.com>
Date: Fri, 26 Dec 2025 09:47:20 +0800
Subject: [PATCH] 飞行历史同步视频从新接口获取
---
ard-work/src/main/java/com/ard/work/service/impl/ArdFlightTaskServiceImpl.java | 294 +++++++++++++++++++++++++---------------------------------
1 files changed, 129 insertions(+), 165 deletions(-)
diff --git a/ard-work/src/main/java/com/ard/work/service/impl/ArdFlightTaskServiceImpl.java b/ard-work/src/main/java/com/ard/work/service/impl/ArdFlightTaskServiceImpl.java
index 4ab7d19..5d97e6a 100644
--- a/ard-work/src/main/java/com/ard/work/service/impl/ArdFlightTaskServiceImpl.java
+++ b/ard-work/src/main/java/com/ard/work/service/impl/ArdFlightTaskServiceImpl.java
@@ -10,10 +10,12 @@
import com.ard.work.component.forest.TyClient;
import com.ard.work.domain.dto.BoxHistoryDTO;
import com.ard.work.domain.dto.BoxPhotosDTO;
+import com.ard.work.domain.dto.BoxVideosDTO;
import com.ard.work.domain.entity.ArdFlightTask;
import com.ard.work.domain.entity.ArdMedia;
import com.ard.work.domain.receiver.BoxHistoryReceiver;
import com.ard.work.domain.receiver.BoxPhotosReceiver;
+import com.ard.work.domain.receiver.BoxVideosReceiver;
import com.ard.work.domain.receiver.TyHttpCommonReceiver;
import com.ard.work.mapper.ArdFlightTaskMapper;
import com.ard.work.mapper.ArdMediaMapper;
@@ -80,7 +82,7 @@
/**
* 同步所有服务的飞行历史
*/
- @Scheduled(fixedDelay = 10000)
+ @Scheduled(fixedDelay = 5000)
public void syncAllFlightHistory() {
List<String> serverIds = ardServerInfoService.getServerIdsList();
for (String serverId : serverIds) {
@@ -122,6 +124,10 @@
if (ardFlightTask == null) {
// 如果不存在,则插入新记录
log.debug("insert task {}", boxHistoryReceiver.getTaskId());
+ Date endTime = null;
+ if (boxHistoryReceiver.getEndTime() != null) {
+ endTime = DateUtils.dateTime(DateUtils.YYYY_MM_DD_HH_MM_SS, boxHistoryReceiver.getEndTime());
+ }
// 创建FlightTask实体对象并填充数据
ArdFlightTask flightTask = ArdFlightTask.builder()
.taskId(boxHistoryReceiver.getTaskId())
@@ -134,7 +140,7 @@
.videoPath(boxHistoryReceiver.getVideoPath())
.serverId(serverId)
.startTime(DateUtils.dateTime(DateUtils.YYYY_MM_DD_HH_MM_SS, boxHistoryReceiver.getStartTime()))
- .endTime(DateUtils.dateTime(DateUtils.YYYY_MM_DD_HH_MM_SS, boxHistoryReceiver.getEndTime()))
+ .endTime(endTime)
.flightMileage(boxHistoryReceiver.getFlightMileage())
.flightDuration(boxHistoryReceiver.getFlightDuration())
.aveSpeed(boxHistoryReceiver.getAveSpeed())
@@ -154,10 +160,8 @@
if (rows > 0) {
// 删除旧的媒体记录,防止重复插入
ardMediaMapper.deleteArdMediaByTaskId(flightTask.getTaskId());
-
// 插入视频
- insertVideoToDatabase(flightTask, boxHistoryReceiver.getVideoPathList());
-
+ insertVideoToDatabase(flightTask, serverId, boxHistoryReceiver.getBoxSn());
// 插入图片
insertPhotoToDatabase(flightTask, serverId, boxHistoryReceiver.getBoxSn());
}
@@ -165,8 +169,8 @@
// 如果存在,则更新记录
log.debug("Updating task {}", boxHistoryReceiver.getTaskId());
updateFlightTask(ardFlightTask, boxHistoryReceiver);
- // 增量更新
- updateVideoToDatabase(ardFlightTask, boxHistoryReceiver.getVideoPathList());
+ // 增量更新视频
+ updateVideoToDatabase(ardFlightTask, serverId, boxHistoryReceiver.getBoxSn());
// 增量更新图片
updatePhotoToDatabase(ardFlightTask, serverId, boxHistoryReceiver.getBoxSn());
@@ -177,10 +181,12 @@
boolean needUpdate = false;
// endTime 更新(重要!!!)
- Date newEnd = DateUtils.dateTime(DateUtils.YYYY_MM_DD_HH_MM_SS, remote.getEndTime());
- if (newEnd != null && (local.getEndTime() == null || !local.getEndTime().equals(newEnd))) {
- local.setEndTime(newEnd);
- needUpdate = true;
+ if (remote.getEndTime() != null) {
+ Date newEnd = DateUtils.dateTime(DateUtils.YYYY_MM_DD_HH_MM_SS, remote.getEndTime());
+ if (local.getEndTime() == null || !local.getEndTime().equals(newEnd)) {
+ local.setEndTime(newEnd);
+ needUpdate = true;
+ }
}
// photoCount 更新
@@ -208,171 +214,40 @@
TyHttpCommonReceiver<List<BoxHistoryReceiver>> boxHistory = tyClient.getBoxHistory(serverId, boxHistoryDTO);
return boxHistory.getContent();
}
-
- //调用接口获取架次图片
+ // 调用接口获取架次图片
private List<BoxPhotosReceiver> getBoxPhotos(String serverId, BoxPhotosDTO boxPhotosDTO) {
TyHttpCommonReceiver<List<BoxPhotosReceiver>> boxPhotos = tyClient.getBoxPhotos(serverId, boxPhotosDTO);
return boxPhotos.getContent();
}
-
-
- // 插入视频记录
- private void insertVideoToDatabase(ArdFlightTask flightTask, List<String> videoPathList) {
- if (videoPathList == null || videoPathList.isEmpty()) {
- return;
- }
- String boxSn = flightTask.getBoxSn();
- for (String videoPath : videoPathList) {
- //videoPath = "https://192.168.1.3:9001/record/DBM250974065008/8212fd8e89814d66b6c32f48d05f5101.mp4";
- ArdMedia media = ArdMedia.builder()
- .id(IdUtils.simpleUUID())
- .taskId(flightTask.getTaskId())
- .mediaType(1)
- .sourceUrl(videoPath)
- .fileSize(getFileSizeByUrl(videoPath))
- .build();
-
- // ---- 1. 视频上传(失败不抛异常,返回 null) ----
-
- CompletableFuture<String> videoFuture = CompletableFuture.supplyAsync(() -> {
- try (InputStream inputStream = openUrlInputStream(videoPath, 5000, 10000)) {
- if (inputStream != null) {
- return ossServiceContext.upload(
- "record",
- boxSn + "/" + media.getId() + ".mp4",
- inputStream,
- MimeTypeUtils.VIDEO_MP4
- );
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- return null;
- }, threadPoolTaskExecutor);
- // ---- 2. 缩略图上传(失败不抛异常,返回 null) ----
-
- CompletableFuture<String> thumbFuture = CompletableFuture.supplyAsync(() -> {
- try {
- try (ByteArrayInputStream thumbStream = generateThumbnail(videoPath, 1, 200)) {
- if (thumbStream != null) {
- return ossServiceContext.upload(
- "record",
- boxSn + "/" + media.getId() + ".jpg",
- thumbStream,
- MimeTypeUtils.IMAGE_JPEG
- );
- }
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- return null;
- }, threadPoolTaskExecutor);
-
- // 两个完成后写数据库(任意失败不阻断流程)
- videoFuture.thenCombine(thumbFuture, (vUrl, tUrl) -> {
- media.setMediaUrl(vUrl);
- media.setThumbnailUrl(tUrl);
- media.setCreateTime(new Date());
- return media;
- }).thenAcceptAsync(ardMediaMapper::insertArdMedia, threadPoolTaskExecutor);
- }
+ // 调用接口获取架次视频
+ private List<BoxVideosReceiver> getBoxVideos(String serverId, BoxVideosDTO boxVideosDTO) {
+ TyHttpCommonReceiver<List<BoxVideosReceiver>> boxVideos = tyClient.getBoxVideos(serverId, boxVideosDTO);
+ return boxVideos.getContent();
}
- private void updateVideoToDatabase(ArdFlightTask flightTask, List<String> videoPathList) {
- if (videoPathList == null) {
- return;
- }
- // 需要插入新的视频
- List<ArdMedia> existingVideos = ardMediaMapper.selectArdMediaByTaskIdAndType(flightTask.getTaskId(), 1);
- Integer count = existingVideos.size();//获取本地库视频数量
- int size = videoPathList.size();//获取接口返回的视频数量
- if (count != null && size > count) {
- log.info("任务【{}】录像数量不一致,需要更新数据库", flightTask.getTaskId());
-
- // 提取现有的视频路径
- List<String> existingVideoPaths = existingVideos.stream()
- .map(ArdMedia::getSourceUrl) // 获取每个视频的 URL
- .collect(Collectors.toList());
-
- // 从接口返回的视频路径中找出新的视频
- List<String> newVideos = videoPathList.stream()
- .filter(videoPath -> !existingVideoPaths.contains(videoPath)) // 过滤出新的视频
- .collect(Collectors.toList());
- if (!newVideos.isEmpty()) {
- String boxSn = flightTask.getBoxSn();
- // 插入新的视频记录
- for (String videoPath : newVideos) {
- ArdMedia ardMedia = ArdMedia.builder()
- .id(IdUtils.simpleUUID())
- .taskId(flightTask.getTaskId())
- .mediaType(1) // 1表示视频
- .fileSize(getFileSizeByUrl(videoPath))
- .sourceUrl(videoPath)
- .build();
- // ---- 1. 视频上传(失败不抛异常,返回 null) ----
- CompletableFuture<String> videoFuture = CompletableFuture.supplyAsync(() -> {
- try (InputStream inputStream = openUrlInputStream(videoPath, 5000, 10000)) {
- if (inputStream != null) {
- return ossServiceContext.upload(
- "record",
- boxSn + "/" + ardMedia.getId() + ".mp4",
- inputStream,
- MimeTypeUtils.VIDEO_MP4
- );
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- return null;
- }, threadPoolTaskExecutor);
- // ---- 2. 缩略图上传(失败不抛异常,返回 null) ----
- CompletableFuture<String> thumbFuture = CompletableFuture.supplyAsync(() -> {
- try {
- try (ByteArrayInputStream thumbStream = generateThumbnail(videoPath, 1, 200)) {
- if (thumbStream != null) {
- return ossServiceContext.upload(
- "record",
- boxSn + "/" + ardMedia.getId() + ".jpg",
- thumbStream,
- MimeTypeUtils.IMAGE_JPEG
- );
- }
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- return null;
- }, threadPoolTaskExecutor);
- // 两个完成后写数据库(任意失败不阻断流程)
- videoFuture.thenCombine(thumbFuture, (vUrl, tUrl) -> {
- ardMedia.setMediaUrl(vUrl);
- ardMedia.setThumbnailUrl(tUrl);
- ardMedia.setCreateTime(new Date());
- return ardMedia;
- }).thenAcceptAsync(ardMediaMapper::insertArdMedia, threadPoolTaskExecutor);
- }
- // 更新任务的视频数量
- flightTask.setVideoCount(flightTask.getVideoCount() + newVideos.size());
- ardFlightTaskMapper.updateArdFlightTask(flightTask);
- }
- }
- }
-
- // 插入图片记录
private void insertPhotoToDatabase(ArdFlightTask flightTask, String serverId, String boxSn) {
// 查询图片
BoxPhotosDTO boxPhotosDTO = new BoxPhotosDTO();
boxPhotosDTO.setTaskId(flightTask.getTaskId());
boxPhotosDTO.setBoxSn(boxSn);
boxPhotosDTO.setPageIndex(1);
- boxPhotosDTO.setPageSize(500);
+ boxPhotosDTO.setPageSize(100);
List<BoxPhotosReceiver> photoList = getBoxPhotos(serverId, boxPhotosDTO);
if (photoList != null && !photoList.isEmpty()) {
addPhotos(flightTask, photoList);
}
}
-
+ private void insertVideoToDatabase(ArdFlightTask flightTask, String serverId, String boxSn) {
+ BoxVideosDTO boxVideosDTO = new BoxVideosDTO();
+ boxVideosDTO.setTaskId(flightTask.getTaskId());
+ boxVideosDTO.setBoxSn(boxSn);
+ boxVideosDTO.setPageIndex(1);
+ boxVideosDTO.setPageSize(100);
+ List<BoxVideosReceiver> videoList = getBoxVideos(serverId, boxVideosDTO);
+ if (videoList != null && !videoList.isEmpty()) {
+ addVideos(flightTask, videoList);
+ }
+ }
private void updatePhotoToDatabase(ArdFlightTask flightTask, String serverId, String boxSn) {
// 获取本地数据库中已存在的图片记录(类型为 0 表示图片)
@@ -411,7 +286,44 @@
}
}
}
+ private void updateVideoToDatabase(ArdFlightTask flightTask, String serverId, String boxSn) {
+ // 获取本地数据库中已存在的图片记录(类型为 0 表示图片)
+ List<ArdMedia> existingVideos = ardMediaMapper.selectArdMediaByTaskIdAndType(flightTask.getTaskId(), 1);
+ int count = existingVideos.size(); //获取本地库视频数量
+ // 查询图片
+ BoxVideosDTO boxVideosDTO = BoxVideosDTO.builder()
+ .taskId(flightTask.getTaskId())
+ .boxSn(boxSn)
+ .pageIndex(1)
+ .pageSize(500)
+ .build();
+ TyHttpCommonReceiver<List<BoxVideosReceiver>> boxVideos = tyClient.getBoxVideos(serverId, boxVideosDTO);
+ List<BoxVideosReceiver> videoList = boxVideos.getContent();
+ int size = videoList.size();
+
+ if (size > count) {
+ log.info("任务【{}】视频数量不一致,需要更新数据库", flightTask.getTaskId());
+ // 需要插入新的视频
+ // 提取现有的图片路径(根据 imgUrl 来判断是否重复)
+ List<String> existingVideoUrls = existingVideos.stream()
+ .map(ArdMedia::getSourceUrl) // 提取 ArdMedia 中的图片 URL
+ .collect(Collectors.toList());
+
+ // 筛选出 photoList 中没有出现在 existingPhotos 中的新图片
+ List<BoxVideosReceiver> newVideos = videoList.stream()
+ .filter(photo -> !existingVideoUrls.contains(photo.getImgUrl())) // 过滤出新视频
+ .collect(Collectors.toList());
+ if (!newVideos.isEmpty()) {
+ // 插入新的视频记录
+ addVideos(flightTask, newVideos);
+
+ // 更新任务的视频数量
+ flightTask.setVideoCount(flightTask.getPhotoCount() + newVideos.size());
+ ardFlightTaskMapper.updateArdFlightTask(flightTask);
+ }
+ }
+ }
private void addPhotos(ArdFlightTask flightTask, List<BoxPhotosReceiver> photoList) {
String boxSn = flightTask.getBoxSn();
for (BoxPhotosReceiver photo : photoList) {
@@ -451,6 +363,63 @@
});
}
}
+ private void addVideos(ArdFlightTask flightTask, List<BoxVideosReceiver> videoList) {
+ String boxSn = flightTask.getBoxSn();
+ for (BoxVideosReceiver video : videoList) {
+ ArdMedia ardMedia = ArdMedia.builder()
+ .id(IdUtils.simpleUUID())
+ .taskId(flightTask.getTaskId())
+ .mediaType(1) // 1表示视频
+ .fileSize(getFileSizeByUrl(video.getImgUrl()))
+ .sourceUrl(video.getImgUrl())
+ .captureTime(DateUtils.parseDate(video.getStartTime()))
+ .build();
+ // 异步上传文件到OSS,并在上传完成后插入数据库
+ // ---- 1. 视频上传(失败不抛异常,返回 null) ----
+ CompletableFuture<String> videoFuture = CompletableFuture.supplyAsync(() -> {
+ try (InputStream inputStream = openUrlInputStream(ardMedia.getSourceUrl(), 5000, 10000)) {
+ if (inputStream != null) {
+ return ossServiceContext.upload(
+ "record",
+ boxSn + "/" + ardMedia.getId() + ".mp4",
+ inputStream,
+ MimeTypeUtils.VIDEO_MP4
+ );
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }, threadPoolTaskExecutor);
+ // ---- 2. 缩略图上传(失败不抛异常,返回 null) ----
+
+ CompletableFuture<String> thumbFuture = CompletableFuture.supplyAsync(() -> {
+ try {
+ try (ByteArrayInputStream thumbStream = generateThumbnail(ardMedia.getSourceUrl(), 1, 200)) {
+ if (thumbStream != null) {
+ return ossServiceContext.upload(
+ "record",
+ boxSn + "/" + ardMedia.getId() + ".jpg",
+ thumbStream,
+ MimeTypeUtils.IMAGE_JPEG
+ );
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }, threadPoolTaskExecutor);
+
+ // 两个完成后写数据库(任意失败不阻断流程)
+ videoFuture.thenCombine(thumbFuture, (vUrl, tUrl) -> {
+ ardMedia.setMediaUrl(vUrl);
+ ardMedia.setThumbnailUrl(tUrl);
+ ardMedia.setCreateTime(new Date());
+ return ardMedia;
+ }).thenAcceptAsync(ardMediaMapper::insertArdMedia, threadPoolTaskExecutor);
+ }
+ }
// 获取文件大小
private long getFileSizeByUrl(String fileUrl) {
@@ -464,12 +433,8 @@
return -1;
}
}
-
// 生成视频缩略图
- public ByteArrayInputStream generateThumbnail(
- String videoFile,
- int skipSeconds,
- int targetWidth) {
+ public ByteArrayInputStream generateThumbnail(String videoFile, int skipSeconds, int targetWidth) {
String ffmpegPath = "";
if (osSelect.isWindows()) {
ffmpegPath = "ffmpeg";
@@ -533,7 +498,6 @@
throw new RuntimeException("FFmpeg 生成缩略图失败", e);
}
}
-
/**
* 将 URL 转成 InputStream
*
--
Gitblit v1.9.3