src/main/java/com/dji/sample/media/controller/FileController.java
@@ -3,17 +3,21 @@ import com.dji.sample.common.model.CustomClaim; import com.dji.sample.common.model.PaginationData; import com.dji.sample.common.model.ResponseResult; import com.dji.sample.media.model.FileUploadDTO; import com.dji.sample.media.model.MediaFileDTO; import com.dji.sample.media.model.MediaFileEntity; import com.dji.sample.media.model.MediaFileQueryParam; import com.dji.sample.media.service.IFileService; import org.apache.ibatis.annotations.Update; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.net.URL; import java.util.List; import static com.dji.sample.component.AuthInterceptor.TOKEN_CLAIM; @@ -32,6 +36,7 @@ /** * Get information about all the media files in this workspace based on the workspace id. * 根据工作空间id获取有关此工作空间中所有媒体文件的信息。 * * @param workspaceId * @return */ @@ -42,6 +47,23 @@ MediaFileQueryParam mediaFileQueryParam) { PaginationData<MediaFileEntity> filesList = fileService.getMediaFilesPaginationByWorkspaceId(workspaceId, page, pageSize,mediaFileQueryParam); return ResponseResult.success(filesList); } @GetMapping("/listAdded") public ResponseResult listIsadd() { List<MediaFileEntity> entityList = fileService.listByIsadd(); return ResponseResult.success(entityList); } @PutMapping("/examine") public ResponseResult examineData(@RequestParam String fileId) { int is = fileService.updateExamByFileId(fileId); if (is != 0) { return ResponseResult.success(); } else { return ResponseResult.error("更新状态失败"); } } @GetMapping("/{workspace_id}/files/{job_id}") @@ -55,6 +77,7 @@ mediaFileEntity.setUserId(claims.getId()); return ResponseResult.success(fileService.updateMediaFile(workspaceId, mediaFileEntity)); } @DeleteMapping("/{workspace_id}/deleteFile") public ResponseResult deleteFile(@PathVariable(name = "workspace_id") String workspaceId, @RequestParam String fileId) { @@ -69,6 +92,7 @@ /** * Query the download address of the file according to the media file id, * and redirect to this address directly for download. * * @param workspaceId * @param fileId * @param response @@ -84,16 +108,4 @@ e.printStackTrace(); } } // @PostMapping("/{workspace_id}/files/download") // public ResponseResult<String> waterMarkFile(){ // //获取media实体信息 // // //对mediaUrl进行下载 // // //对图片进行水印 // // //将带有水印的图片存入本地 // // //将链接返回 // } } src/main/java/com/dji/sample/media/controller/MediaController.java
@@ -35,6 +35,7 @@ /** * Check if the file has been uploaded by the fingerprint. * 检查文件是否已通过指纹上传。 * * @param workspaceId * @param file * @return @@ -50,6 +51,7 @@ /** * When the file is uploaded to the storage server by pilot, * the basic information of the file is reported through this interface. * * @param workspaceId * @param file * @return @@ -57,12 +59,12 @@ @PostMapping("/{workspace_id}/upload-callback") public ResponseResult<String> uploadCallback(@PathVariable(name = "workspace_id") String workspaceId, @RequestBody FileUploadDTO file) throws IOException, FontFormatException { mediaService.saveMediaFile(workspaceId, file); mediaService.saveMediaMarkFile(workspaceId, file); return ResponseResult.success(file.getObjectKey()); } /** * Query the files that already exist in this workspace based on the workspace id and the collection of tiny fingerprints. * * @param workspaceId * @param tinyFingerprints There is only one tiny_fingerprint parameter in the body. * But it is not recommended to use Map to receive the parameter. src/main/java/com/dji/sample/media/model/MediaFileEntity.java
@@ -78,6 +78,9 @@ @TableField("isadd") private Integer isadd; @TableField("examine") private Integer examine; } src/main/java/com/dji/sample/media/service/IFileService.java
@@ -20,6 +20,7 @@ /** * Query if the file already exists based on the workspace id and the fingerprint of the file. * * @param workspaceId * @param fingerprint * @return @@ -28,23 +29,32 @@ /** * Save the basic information of the file to the database. * * @param workspaceId * @param file * @return */ Integer saveFile(String workspaceId, FileUploadDTO file); Integer saveMarkFile(String workspaceId, FileUploadDTO file) throws IOException, FontFormatException; /** * Query information about all files in this workspace based on the workspace id. * * @param workspaceId * @return */ List<MediaFileDTO> getAllFilesByWorkspaceId(String workspaceId); List<MediaFileEntity> listByIsadd(); int updateExamByFileId(String fileId); List<MediaFileEntity> listMediaFileEntity(String workspaceId, String jobId); /** * Paginate through all media files in this workspace. * * @param workspaceId * @param page * @param pageSize @@ -54,6 +64,7 @@ /** * Get the download address of the file. * * @param workspaceId * @param fileId * @return @@ -62,6 +73,7 @@ /** * Query all media files of a job. * * @param workspaceId * @param jobId * @return @@ -70,6 +82,7 @@ /** * 更新文件 * * @param workspaceId 项目id * @param mediaFileEntity * @return src/main/java/com/dji/sample/media/service/IMediaService.java
@@ -20,6 +20,7 @@ /** * Check if the file has been uploaded by the fingerprint. * * @param workspaceId * @param fingerprint * @return @@ -28,16 +29,17 @@ /** * Save the basic information of the file to the database. * * @param workspaceId * @param file * @return */ Integer saveMediaFile(String workspaceId, FileUploadDTO file); Integer saveMediaMarkFile(String workspaceId, FileUploadDTO file) throws IOException, FontFormatException; /** * Query tiny fingerprints about all files in this workspace based on the workspace id. * * @param workspaceId * @return */ @@ -45,6 +47,7 @@ /** * Query the fingerprints that already exist in it based on the incoming tiny fingerprints data. * * @param workspaceId * @param tinyFingerprints * @return src/main/java/com/dji/sample/media/service/impl/FileServiceImpl.java
@@ -1,9 +1,5 @@ package com.dji.sample.media.service.impl; import com.aliyun.oss.OSS; import com.aliyun.oss.OSSClientBuilder; import com.aliyun.oss.model.PutObjectRequest; import com.aliyun.oss.model.PutObjectResult; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper; @@ -20,22 +16,24 @@ import com.dji.sample.media.model.*; import com.dji.sample.media.service.IFileService; import com.dji.sample.territory.service.impl.TbFjServiceImpl; import com.dji.sample.territory.utils.VideoZipUtil; import com.dji.sample.territory.utils.WaterMarkUtil; import io.minio.MinioClient; import io.minio.PutObjectArgs; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.awt.*; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.net.URL; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.Arrays; import java.util.*; import java.util.List; import java.util.Optional; import java.util.UUID; import java.util.stream.Collectors; /** @@ -83,21 +81,34 @@ fileEntity.setFileId(UUID.randomUUID().toString()); return mapper.insert(fileEntity); } public Integer saveMarkFile(String workspaceId, FileUploadDTO file) throws IOException, FontFormatException { File file2 = null; MediaFileMarkEntity mediaFileMarkEntity =this.fileUploadConvertToMarkEntity(file); String url = "http://dev.jxpskj.com:9000/cloud-bucket" + file.getObjectKey(); File file1=TbFjServiceImpl.downloadFile(url); File file2= new File(WaterMarkUtil.addWatermark(file1, Long.valueOf(file.getMetadata().getCreatedTime().toString()),file.getMetadata().getPhotoedPosition().getLat(), file.getMetadata().getPhotoedPosition().getLng(),file.getMetadata().getGimbalYawDegree()).toURI()); mediaFileMarkEntity.setObjectKey(file.getPath()); long timestamp = convertToTimestamp(file.getMetadata().getCreatedTime()); boolean endsWith = file.getObjectKey().endsWith(".mp4"); if (!endsWith) { file2 = new File(WaterMarkUtil.addWatermark(file1, timestamp, file.getMetadata().getShootPosition().getLat(), file.getMetadata().getShootPosition().getLng(), file.getMetadata().getGimbalYawDegree()).toURI()); } else { file2 = VideoZipUtil.compressVideo(file1, 1600000, 128000, 1280, 720); } mediaFileMarkEntity.setWorkspaceId(workspaceId); mediaFileMarkEntity.setFileId(UUID.randomUUID().toString()); mediaFileMarkEntity.setObjectKey("/mark"+file.getPath()+"/"+file.getName()); mediaFileMarkEntity.setFileName("mark"+file.getName()); mediaFileMarkEntity.setFilePath("mark"+file.getPath()); uploadFile(String.valueOf(file2), mediaFileMarkEntity.getObjectKey()); String endpoint = "http://dev.jxpskj.com:9000"; String accessKey = "pskj"; String secretKey = "pskj@2021"; String bucketName = "cloud-bucket"; String objectName = mediaFileMarkEntity.getObjectKey(); // 例如 "folder/file.txt" uploadFile(endpoint, accessKey, secretKey, bucketName, objectName, file2); return markMapper.insert(mediaFileMarkEntity); } @Override public List<MediaFileDTO> getAllFilesByWorkspaceId(String workspaceId) { return mapper.selectList(new LambdaQueryWrapper<MediaFileEntity>() @@ -111,6 +122,20 @@ public List<MediaFileEntity> listMediaFileEntity(String workspaceId, String jobId) { return mapper.selectList(new LambdaQueryWrapper<MediaFileEntity>() .eq(MediaFileEntity::getWorkspaceId, workspaceId).eq(MediaFileEntity::getJobId,jobId)); } public List<MediaFileEntity> listByIsadd() { return mapper.selectList(new LambdaQueryWrapper<MediaFileEntity>().eq(MediaFileEntity::getIsadd, 0) .like(MediaFileEntity::getFileName, "~")); } public int updateExamByFileId(String fileId) { // 创建并配置 LambdaUpdateWrapper LambdaUpdateWrapper<MediaFileEntity> updateWrapper = new LambdaUpdateWrapper<>(); updateWrapper.eq(MediaFileEntity::getFileId, fileId) .set(MediaFileEntity::getExamine, 0); // 执行更新操作并返回更新的行数 return mapper.update(null, updateWrapper); } @Override @@ -135,6 +160,7 @@ .eq(MediaFileEntity::getWorkspaceId, workspaceId)); return count; } @Override public URL getObjectUrl(String workspaceId, String fileId) { Optional<MediaFileEntity> mediaFileOpt = getMediaByFileId(workspaceId, fileId); @@ -171,6 +197,7 @@ /** * Convert the received file object into a database entity object. * * @param file * @return */ @@ -181,6 +208,7 @@ builder.fileName(file.getName()) .filePath(file.getPath()) .isadd(0) .examine(1) .fingerprint(file.getFingerprint()) .objectKey(file.getObjectKey()) .subFileType(file.getSubFileType()) @@ -200,6 +228,7 @@ } return builder.build(); } private MediaFileMarkEntity fileUploadConvertToMarkEntity(FileUploadDTO file) { MediaFileMarkEntity.MediaFileMarkEntityBuilder builder = MediaFileMarkEntity.builder(); @@ -230,6 +259,7 @@ /** * Convert database entity objects into file data transfer object. * * @param entity * @return */ @@ -255,16 +285,33 @@ return builder.build(); } public void uploadFile(String filePath, String key) { OSS ossClient = new OSSClientBuilder().build(OssConfiguration.endpoint, OssConfiguration.accessKey, OssConfiguration.secretKey); public static void uploadFile(String endpoint, String accessKey, String secretKey, String bucketName, String objectName, File file) { try { File file = new File(filePath); PutObjectRequest putObjectRequest = new PutObjectRequest(OssConfiguration.bucket, key, file); PutObjectResult putObjectResult = ossClient.putObject(putObjectRequest); // 创建MinIO客户端实例 MinioClient minioClient = MinioClient.builder() .endpoint(endpoint) .credentials(accessKey, secretKey) .build(); // 上传文件 FileInputStream fileInputStream = new FileInputStream(file); minioClient.putObject( PutObjectArgs.builder() .bucket(bucketName) .object(objectName) .stream(fileInputStream, file.length(), -1) .build() ); fileInputStream.close(); } catch (Exception e) { e.printStackTrace(); } finally { ossClient.shutdown(); throw new RuntimeException("上传文件至服务器失败" + e); } } public static long convertToTimestamp(Date date) { // 获取时间戳(毫秒级别) return date.getTime(); } } src/main/java/com/dji/sample/media/service/impl/MediaServiceImpl.java
@@ -15,6 +15,7 @@ import com.dji.sample.component.websocket.service.ISendMessageService; import com.dji.sample.manage.model.dto.DeviceDTO; import com.dji.sample.manage.model.enums.UserTypeEnum; import com.dji.sample.manage.model.receiver.OsdSubDeviceReceiver; import com.dji.sample.manage.service.IDeviceRedisService; import com.dji.sample.manage.service.IDeviceService; import com.dji.sample.media.dao.IFileMapper; @@ -39,6 +40,8 @@ import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.stream.Collectors; /** @@ -78,6 +81,7 @@ private String fileAddress; @Value("${oss.bucket}") private String bucket; @Override public Boolean fastUpload(String workspaceId, String fingerprint) { return fileService.checkExist(workspaceId, fingerprint); @@ -86,9 +90,6 @@ @Override public Integer saveMediaFile(String workspaceId, FileUploadDTO file) { return fileService.saveFile(workspaceId, file); } public Integer saveMediaMarkFile(String workspaceId, FileUploadDTO file) throws IOException, FontFormatException { return fileService.saveMarkFile(workspaceId, file); } @Override @@ -125,13 +126,13 @@ /** * Handle media files messages reported by dock. * 处理由dock报告的媒体文件消息。 * * @param receiver * @return */ @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_FILE_UPLOAD_CALLBACK, outputChannel = ChannelName.OUTBOUND_EVENTS) public CommonTopicReceiver handleFileUploadCallBack(CommonTopicReceiver receiver) { public CommonTopicReceiver handleFileUploadCallBack(CommonTopicReceiver receiver) throws IOException, FontFormatException { FileUploadCallback callback = objectMapper.convertValue(receiver.getData(), FileUploadCallback.class); if (callback.getResult() != ResponseResult.CODE_SUCCESS) { log.error("媒体文件上传失败;Media file upload failed!"); return null; @@ -175,6 +176,7 @@ /** * update the uploaded count and notify web side * 更新上传的计数并通知web端 * * @param mediaFileCount * @param receiver * @param jobId @@ -215,7 +217,7 @@ BizCodeEnum.FILE_UPLOAD_CALLBACK.getCode(), mediaFileCount); } private Boolean parseMediaFile(FileUploadCallback callback, WaylineJobDTO job) { private Boolean parseMediaFile(FileUploadCallback callback, WaylineJobDTO job) throws IOException, FontFormatException { // Set the drone sn that shoots the media Optional<DeviceDTO> dockDTO = deviceService.getDeviceBySn(job.getDockSn()); dockDTO.ifPresent(dock -> callback.getFile().getExt().setSn(dock.getChildDeviceSn())); @@ -223,12 +225,29 @@ // set path String objectKey = callback.getFile().getObjectKey(); callback.getFile().setPath(objectKey.substring(objectKey.indexOf("/") + 1, objectKey.lastIndexOf("/"))); try { System.out.println(callback.getFile().toString()); ExecutorService executor = Executors.newSingleThreadExecutor(); executor.execute(() -> { try { fileService.saveMarkFile(job.getWorkspaceId(), callback.getFile()); } catch (Exception e) { throw new RuntimeException(e); } }); executor.shutdown(); } catch (Exception e) { log.error("方法执行有误==============: ", e); throw e; } return fileService.saveFile(job.getWorkspaceId(), callback.getFile()) > 0; } /** * Handles the highest priority message about media uploads. * * @param receiver * @param headers * @return src/main/java/com/dji/sample/patches/controller/PatchesController.java
@@ -41,6 +41,7 @@ private TbDkjbxxServiceImpl tbDkjbxxService; @Autowired private TimerUtil timerUtil; /** * 根据workspaceId获取图斑列表信息 * @@ -74,16 +75,18 @@ getPatchesService.delPatches(); return ResponseResult.success(); } @GetMapping("/useMyTask") public ResponseResult useMyTask() throws Exception { try { timerUtil.myTask(); // timerUtil.myTask2(); // timerUtil.myTask(); timerUtil.myTask2(); return ResponseResult.success(); }catch (Exception e){ throw new RuntimeException("db存储发送出现异常"); } } /** * 根据图斑的地块编号获取相对应音视频 * src/main/java/com/dji/sample/patches/service/impl/GetPatchesServiceImpl.java
@@ -14,6 +14,7 @@ import com.dji.sample.wayline.model.entity.WaylineFileEntity; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; import java.util.stream.Collectors; @@ -26,6 +27,7 @@ /** * 分页获取数据的接口实现。 * * @param param 包含分页信息和查询条件的工作空间ID。 * @return 返回一个包含查询结果和分页信息的PaginationData对象。 */ @@ -44,6 +46,7 @@ public void delPatches() { mapper.delete(null); } /** * 根据条件获取照片的分页数据 * @@ -54,12 +57,13 @@ @Override public PaginationData<MediaFileEntity> getPhoto(PatchesParam param,String dkbh) { Page<MediaFileEntity> page=fileMapper.selectPage(new Page<MediaFileEntity>(param.getPage(), param.getPageSize()), new LambdaQueryWrapper<MediaFileEntity>().like(MediaFileEntity::getFileName, "%" + dkbh + "%") ); new LambdaQueryWrapper<MediaFileEntity>().like(MediaFileEntity::getFileName, "%" + dkbh + "~" + "%")); List<MediaFileEntity> records = page.getRecords() .stream() .collect(Collectors.toList()); return new PaginationData<MediaFileEntity>(records, new Pagination(page)); } /** * 根据条件获取照片的分页数据 * @@ -71,8 +75,10 @@ return fileMapper.selectList(new LambdaQueryWrapper<MediaFileEntity>().like(MediaFileEntity::getFileName, "%" + dkbh + "%") .eq(MediaFileEntity::getWorkspaceId,workspaceId)); } /** * 根据地块编号和工作空间ID获取地块信息。 * * @param dkbh 地块编号,用于查询特定定单的地块信息。 * @param workspaceId 工作空间ID,用于查询属于特定工作空间的地块信息。 * @return 返回匹配给定地块编号和工作空间ID的地块信息对象。如果找不到匹配的记录,则返回null。 @@ -81,9 +87,11 @@ return mapper.selectOne(new LambdaQueryWrapper<LotInfo>().eq(LotInfo::getDkbh, dkbh) .eq(LotInfo::getWorkspaceId, workspaceId)); } public LotInfo getLotinfoToDb(String dkbh) { return mapper.selectOne(new LambdaQueryWrapper<LotInfo>().eq(LotInfo::getDkbh, dkbh)); } public List<LotInfo>listLotinfo(){ return mapper.selectList(null); } src/main/java/com/dji/sample/patches/utils/TimerUtil.java
@@ -225,7 +225,9 @@ public List<List<MediaFileEntity>> getNoadd() { List<MediaFileEntity> list = fileMapper.selectList(new LambdaQueryWrapper<MediaFileEntity>() .eq(MediaFileEntity::getIsadd, 0).like(MediaFileEntity::getFileName, "~")); .eq(MediaFileEntity::getIsadd, 0) .eq(MediaFileEntity::getExamine, 1) .like(MediaFileEntity::getFileName, "~")); List<List<MediaFileEntity>> groupedFilenames = groupTasks(list); return groupedFilenames; } src/main/java/com/dji/sample/patches/xml/mode/share/action/utils/PayloadParamUtils.java
@@ -18,7 +18,8 @@ .samplingRate("240000") .scanningMode("repetitive") .payloadPositionIndex(0) .imageFormat("wide,ir") // .imageFormat("wide,ir") .imageFormat("wide") .build(); return pp; } src/main/java/com/dji/sample/territory/utils/WaterMarkUtil.java
@@ -61,7 +61,7 @@ g2d.drawString(watermarkText, x1, y1); alphaComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.7f); g2d.setComposite(alphaComposite); String extraInfo = String.format("Lon:%.9f Lat:%.6f\n%s 时间:%s", lng, lat,angel,sd); String extraInfo = String.format("Lon:%.7f Lat:%.7f\n%s %s", lng, lat,angel,sd); File fontFile = new File("/tmp/jave/MiSans-Normal.ttf"); // 替换为你的字体文件路径 Font customFont = Font.createFont(Font.TRUETYPE_FONT, fontFile).deriveFont(36.00F); @@ -81,14 +81,14 @@ int y2 = originalImage.getHeight() - textHeight - 30; // 最底部位置 y 坐标 int rectX = originalImage.getWidth() - textWidth +530; int rectX = originalImage.getWidth() - textWidth +490; int rectY = originalImage.getHeight() - textHeight -15; // 绘制半透明黑色背景矩形 Color semiTransparentColor = new Color(0, 0, 0, 156); // 0-255 的 alpha 值,0 表示完全透明,255 表示完全不透明 g2d.setColor(semiTransparentColor); g2d.fillRect(rectX, rectY, textWidth, textHeight-6); int rectXs = originalImage.getWidth() - textWidth +450 ; int rectXs = originalImage.getWidth() - textWidth +420 ; int rectYs = originalImage.getHeight() - textHeight -62; // 绘制半透明黑色背景矩形 g2d.setColor(semiTransparentColor); @@ -113,7 +113,8 @@ // 释放 Graphics2D 对象 g2d.dispose(); // 保存添加水印后的图片 File outputFile = new File("src/main/copy.jpeg"); File outputFile = File.createTempFile("mark", ".jpg"); try { ImageIO.write(originalImage, "jpg", outputFile); // 将图像写入临时文件 } catch (IOException e) { src/main/resources/template/wpmz/waylines.wpml
File was deleted