package com.dji.sample.media.service.impl; import com.dji.sample.component.oss.model.OssConfiguration; import com.dji.sample.component.websocket.model.BizCodeEnum; import com.dji.sample.component.websocket.service.IWebSocketMessageService; import com.dji.sample.component.websocketWmm.WebSocketServerPlayBack; import com.dji.sample.manage.model.dto.DeviceDTO; import com.dji.sample.manage.model.enums.UserTypeEnum; import com.dji.sample.manage.service.IDeviceRedisService; import com.dji.sample.manage.service.IDeviceService; import com.dji.sample.media.model.MediaFileCountDTO; import com.dji.sample.media.model.MediaFileDTO; import com.dji.sample.media.model.param.UploadFlighttaskMediaPrioritizeParam; import com.dji.sample.media.service.IFileService; import com.dji.sample.media.service.IMediaRedisService; import com.dji.sample.media.service.IMediaService; import com.dji.sample.wayline.service.IWaylineJobService; import com.dji.sdk.cloudapi.media.*; import com.dji.sdk.cloudapi.media.api.AbstractMediaService; import com.dji.sdk.common.HttpResultResponse; import com.dji.sdk.common.SDKManager; import com.dji.sdk.mqtt.MqttReply; import com.dji.sdk.mqtt.events.TopicEventsRequest; import com.dji.sdk.mqtt.events.TopicEventsResponse; import com.dji.sdk.mqtt.services.ServicesReplyData; import com.dji.sdk.mqtt.services.TopicServicesResponse; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.messaging.MessageHeaders; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; import java.util.List; import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; //import static com.dji.sample.manage.model.common.HmsJsonUtil.mapper; /** * @author sean * @version 0.2 * @date 2021/12/9 */ @Service @Slf4j public class MediaServiceImpl extends AbstractMediaService implements IMediaService { @Autowired private IFileService fileService; @Autowired private IWaylineJobService waylineJobService; @Autowired private ObjectMapper objectMapper; @Autowired private IDeviceService deviceService; @Autowired private IWebSocketMessageService webSocketMessageService; @Autowired private IDeviceRedisService deviceRedisService; @Autowired private IMediaRedisService mediaRedisService; @Autowired private AbstractMediaService mediaService; @Autowired private ObjectMapper mapper; @Override public Boolean fastUpload(String workspaceId, String fingerprint) { return fileService.checkExist(workspaceId, fingerprint); } @Override public Integer saveMediaFile(String workspaceId, MediaUploadCallbackRequest file) { return fileService.saveFile(workspaceId, file); } @Override public List getAllTinyFingerprintsByWorkspaceId(String workspaceId) { return fileService.getAllFilesByWorkspaceId(workspaceId) .stream() .map(MediaFileDTO::getTinnyFingerprint) .collect(Collectors.toList()); } @Override public List getExistTinyFingerprints(String workspaceId, List tinyFingerprints) { List tinyFingerprintList = this.getAllTinyFingerprintsByWorkspaceId(workspaceId); return tinyFingerprints .stream() .filter(tinyFingerprintList::contains) .collect(Collectors.toList()); } @Override public TopicEventsResponse fileUploadCallback(TopicEventsRequest request, MessageHeaders headers) { FileUploadCallback callback = request.getData(); if (MqttReply.CODE_SUCCESS != callback.getResult()) { log.error("Media file upload failed!"); return null; } String jobId = callback.getFile().getExt().getFlightId(); Optional deviceOpt = deviceRedisService.getDeviceOnline(request.getGateway()); MediaFileCountDTO mediaFileCount = mediaRedisService.getMediaCount(request.getGateway(), jobId); // duplicate data if (deviceOpt.isEmpty() || (Objects.nonNull(mediaFileCount) && request.getBid().equals(mediaFileCount.getBid()) && request.getTid().equals(mediaFileCount.getTid()))) { return new TopicEventsResponse().setData(MqttReply.success()); } DeviceDTO device = deviceOpt.get(); boolean isSave = parseMediaFile(callback, device); if (!isSave) { log.error("Failed to save the file to the database, please check the data manually."); return null; } notifyUploadedCount(mediaFileCount, request, jobId, device); ObjectMapper mapper = new ObjectMapper(); String fileUploadCallback = ""; // try { // fileUploadCallback = mapper.writeValueAsString(request.getData()); // } catch (JsonProcessingException e) { // throw new RuntimeException("trans json failed."); // } WebSocketServerPlayBack.sendInfo(BizCodeEnum.FILE_UPLOAD_CALLBACK, fileUploadCallback); return new TopicEventsResponse().setData(MqttReply.success()); } @Override public TopicEventsResponse highestPriorityUploadFlightTaskMedia( TopicEventsRequest request, MessageHeaders headers) { WebSocketServerPlayBack.sendInfo(request.toString()); String jobId = request.getData().getFlightId(); if (!StringUtils.hasText(jobId)) { return null; } MediaFileCountDTO countDTO = mediaRedisService.getMediaHighestPriority(request.getGateway()); if (Objects.nonNull(countDTO)) { if (jobId.equals(countDTO.getJobId())) { mediaRedisService.setMediaHighestPriority(request.getGateway(), countDTO); return new TopicEventsResponse().setData(MqttReply.success()); } countDTO.setPreJobId(countDTO.getJobId()); } countDTO.setJobId(jobId); mediaRedisService.setMediaHighestPriority(request.getGateway(), countDTO); Optional deviceOpt = deviceRedisService.getDeviceOnline(request.getGateway()); if (deviceOpt.isEmpty()) { return null; } webSocketMessageService.sendBatch(deviceOpt.get().getWorkspaceId(), UserTypeEnum.WEB.getVal(), BizCodeEnum.HIGHEST_PRIORITY_UPLOAD_FLIGHT_TASK_MEDIA.getCode(), countDTO); return new TopicEventsResponse().setData(MqttReply.success()); } private Boolean parseMediaFile(FileUploadCallback callback, DeviceDTO device) { MediaUploadCallbackRequest file = convert2callbackRequest(callback.getFile()); // Set the drone sn that shoots the media file.getExt().setSn(device.getChildDeviceSn()); // set path String objectKey = file.getObjectKey(); file.setPath(objectKey.substring(Optional.of(objectKey.indexOf(OssConfiguration.objectDirPrefix)) .filter(index -> index > 0).map(index -> index++).orElse(0), objectKey.lastIndexOf("/"))); return fileService.saveFile(device.getWorkspaceId(), file) > 0; } private void notifyUploadedCount(MediaFileCountDTO mediaFileCount, TopicEventsRequest request, String jobId, DeviceDTO dock) { // Do not notify when files that do not belong to the route are uploaded. if (Objects.isNull(mediaFileCount)) { return; } mediaFileCount.setBid(request.getBid()); mediaFileCount.setTid(request.getTid()); mediaFileCount.setUploadedCount(mediaFileCount.getUploadedCount() + 1); // After all the files of the job are uploaded, delete the media file key. if (mediaFileCount.getUploadedCount() >= mediaFileCount.getMediaCount()) { mediaRedisService.delMediaCount(request.getGateway(), jobId); // After uploading, delete the key with the highest priority. MediaFileCountDTO fileCount = mediaRedisService.getMediaHighestPriority(request.getGateway()); if (Objects.nonNull(fileCount) && jobId.equals(fileCount.getJobId())) { mediaRedisService.delMediaHighestPriority(request.getGateway()); } } else { mediaRedisService.setMediaCount(request.getGateway(), jobId, mediaFileCount); } webSocketMessageService.sendBatch(dock.getWorkspaceId(), UserTypeEnum.WEB.getVal(), BizCodeEnum.FILE_UPLOAD_CALLBACK.getCode(), mediaFileCount); } private MediaUploadCallbackRequest convert2callbackRequest(FileUploadCallbackFile file) { if (Objects.isNull(file)) { return null; } return new MediaUploadCallbackRequest() .setExt(Optional.ofNullable(file.getExt()) .map(ext -> new MediaFileExtension() .setDroneModelKey(ext.getDroneModelKey()) .setFileGroupId(ext.getFlightId()) .setOriginal(ext.getOriginal()) .setPayloadModelKey(ext.getPayloadModelKey())) .orElse(new MediaFileExtension())) .setMetadata(Optional.ofNullable(file.getMetadata()) .map(data -> new MediaFileMetadata() .setAbsoluteAltitude(data.getAbsoluteAltitude()) .setGimbalYawDegree(data.getGimbalYawDegree()) .setRelativeAltitude(data.getRelativeAltitude()) .setShootPosition(data.getShootPosition()) .setCreatedTime(data.getCreatedTime())) .get()) .setName(file.getName()) .setObjectKey(file.getObjectKey()) .setPath(file.getPath()); } @Override public HttpResultResponse uploadFlighttaskMediaPrioritize(String sn, UploadFlighttaskMediaPrioritizeParam param) { TopicServicesResponse response = mediaService.uploadFlighttaskMediaPrioritize(SDKManager.getDeviceSDK(sn),mapper.convertValue(param, UploadFlighttaskMediaPrioritize.class)); ServicesReplyData reply = response.getData(); return reply.getResult().isSuccess() ? HttpResultResponse.success() : HttpResultResponse.error("The flight task media prioritize failed to upload. " + reply.getResult()); } }