浏览代码

导览视频转换下载功能

dengsixing 2 年之前
父节点
当前提交
ba97781966

+ 21 - 0
4dkankan-center-scene/src/main/java/com/fdkankan/scene/controller/DownloadTourVideoController.java

@@ -0,0 +1,21 @@
+package com.fdkankan.scene.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ * 导览视频转换记录表 前端控制器
+ * </p>
+ *
+ * @author 
+ * @since 2022-10-12
+ */
+@RestController
+@RequestMapping("/scene/downloadTourVideo")
+public class DownloadTourVideoController {
+
+}
+

+ 12 - 3
4dkankan-center-scene/src/main/java/com/fdkankan/scene/controller/SceneEditController.java

@@ -6,6 +6,7 @@ import com.fdkankan.common.controller.BaseController;
 import com.fdkankan.common.exception.BusinessException;
 import com.fdkankan.common.response.ResultData;
 import com.fdkankan.scene.annotation.CheckCooperationPermit;
+import com.fdkankan.scene.service.IDownloadTourVideoService;
 import com.fdkankan.scene.service.ISceneEditInfoService;
 import com.fdkankan.scene.service.ISceneEditService;
 import com.fdkankan.scene.service.IScenePlusService;
@@ -79,6 +80,8 @@ public class SceneEditController extends BaseController {
     private ISurveillanceService surveillanceService;
     @Autowired
     private IScenePlusService scenePlusService;
+    @Autowired
+    private IDownloadTourVideoService downloadTourVideoService;
 
 
     /**
@@ -1026,9 +1029,15 @@ public class SceneEditController extends BaseController {
         return sceneEditService.saveTour(param);
     }
 
-    @PostMapping(value = "/downloadTourVideo")
-    public void tranferRoam(@RequestParam("file") MultipartFile file) throws Exception {
-        sceneUploadService.formatMp4(file, this.response);
+    @PostMapping(value = "/tour/video/upload")
+    public ResultData uploadTourVideo(@RequestParam("num") String num, @RequestParam("file") MultipartFile file) throws Exception {
+        downloadTourVideoService.uploadTourVideo(num, file);
+        return null;
+    }
+
+    @PostMapping(value = "/tour/video/download")
+    public ResultData downloadTourVideo(@RequestParam("num") String num) throws Exception {
+        return downloadTourVideoService.downloadTourVideo(num);
     }
 
     /**

+ 87 - 0
4dkankan-center-scene/src/main/java/com/fdkankan/scene/entity/DownloadTourVideo.java

@@ -0,0 +1,87 @@
+package com.fdkankan.scene.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import java.util.Date;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ * 导览视频转换记录表
+ * </p>
+ *
+ * @author 
+ * @since 2022-10-12
+ */
+@Getter
+@Setter
+@TableName("t_download_tour_video")
+public class DownloadTourVideo implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 场景码
+     */
+    @TableField("num")
+    private String num;
+
+    /**
+     * 视频转换状态(0-等待中,1-成功,2-失败)
+     */
+    @TableField("state")
+    private Integer state;
+
+    /**
+     * 转换失败原因
+     */
+    @TableField("reason")
+    private String reason;
+
+    /**
+     * 文件名称
+     */
+    @TableField("file_name")
+    private String fileName;
+
+    /**
+     * 本地临时文件地址
+     */
+    @TableField("local_path")
+    private String localPath;
+
+    /**
+     * 导览视频目录地址
+     */
+    @TableField("download_path")
+    private String downloadPath;
+
+    /**
+     * 创建时间
+     */
+    @TableField("create_time")
+    private Date createTime;
+
+    /**
+     * 修改时间
+     */
+    @TableField("update_time")
+    private Date updateTime;
+
+    /**
+     * A-有效,I-无效
+     */
+    @TableField("rec_status")
+    @TableLogic(value = "A", delval = "I")
+    private String recStatus;
+
+
+}

+ 1 - 1
4dkankan-center-scene/src/main/java/com/fdkankan/scene/generate/AutoGenerate.java

@@ -19,7 +19,7 @@ public class AutoGenerate {
         String path =System.getProperty("user.dir") + "\\4dkankan-center-scene";
 
         generate(path,"scene", getTables(new String[]{
-                "t_surveillance","t_surveillance_play","t_scene_surveillance_play"
+                "t_download_tour_video"
         }));
 
 //        generate(path,"goods", getTables(new String[]{

+ 66 - 131
4dkankan-center-scene/src/main/java/com/fdkankan/scene/listener/RabbitMqListener.java

@@ -1,131 +1,66 @@
-//package com.fdkankan.scene.listener;
-//
-//import com.alibaba.fastjson.JSONObject;
-//import com.fdkankan.rabbitmq.bean.BuildSceneCallMessage;
-//import com.fdkankan.rabbitmq.bean.BuildSceneFailDTMqMessage;
-//import com.fdkankan.rabbitmq.bean.BuildSceneResultMqMessage;
-//import com.fdkankan.scene.service.IBuildSceneDTService;
-//import com.fdkankan.scene.service.IBuildScenePostService;
-//import com.fdkankan.scene.service.IBuildScenePreService;
-//import com.fdkankan.scene.service.impl.BuildSceneDTServiceImpl;
-//import com.rabbitmq.client.Channel;
-//import java.nio.charset.StandardCharsets;
-//import lombok.extern.slf4j.Slf4j;
-//import org.springframework.amqp.core.Message;
-//import org.springframework.amqp.rabbit.annotation.Queue;
-//import org.springframework.amqp.rabbit.annotation.RabbitListener;
-//import org.springframework.beans.factory.annotation.Autowired;
-//import org.springframework.beans.factory.annotation.Value;
-//import org.springframework.stereotype.Component;
-//
-///**
-// * <p>
-// * TODO
-// * </p>
-// *
-// * @author dengsixing
-// * @since 2022/4/19
-// **/
-//@Slf4j
-//@Component
-//public class RabbitMqListener {
-//    @Value("${queue.modeling.modeling-pre}")
-//    private String queueModelingPre;
-//    @Value("${queue.modeling.modeling-post}")
-//    private String queueModelingPost;
-//    @Value("${queue.modeling.modeling-dt}")
-//    private String queueModelingDt;
-//
-//    @Autowired
-//    IBuildScenePreService buildScenePreService;
-//    @Autowired
-//    IBuildScenePostService buildScenePostService;
-//    @Autowired
-//    IBuildSceneDTService buildSceneDTService;
-//
-//
-//
-//    /**
-//     * 开启了手动确认模式,如果没有手动确认,消费者不会重试,当服务重启时会再次消费,因为rabbitmq认为你还没有处理完你的业务
-//     * queuesToDeclare = @Queue("${queue.modeling.modeling-test}"),  如果队列不不存在会自动创建队列
-//     * concurrency = "3"    设置消费线程数,每个线程每次只拉取一条消息消费
-//     */
-////    @RabbitListener(
-////        queuesToDeclare = @Queue("${queue.modeling.modeling-test}"),
-////        concurrency = "1"
-////    )
-////    public void receiveMessageDsx(Channel channel, Message message) throws Exception {
-////        channel.queueDeclare();
-////        String msg = new String(message.getBody(), StandardCharsets.UTF_8);
-////        log.info("开始消费消息-" + msg + "-" + Thread.currentThread().getId());
-////        Thread.sleep(5000L);
-////        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
-////        log.info("结束消息-" + Thread.currentThread().getId());
-////    }
-//
-//
-//    /**
-//     * 场景计算前置资源准备处理
-//     * @param channel
-//     * @param message
-//     * @throws Exception
-//     */
-//    @RabbitListener(
-//        queuesToDeclare = @Queue("${queue.modeling.modeling-pre}"),
-//        concurrency = "${maxThread.modeling.modeling-pre}"
-//    )
-//    public void buildScenePreHandler(Channel channel, Message message) throws Exception {
-//        Object correlation = message.getMessageProperties().getHeader("spring_returned_message_correlation");
-//        String correlationId = (String) correlation;
-//        String msg = new String(message.getBody(), StandardCharsets.UTF_8);
-//        log.info("场景计算资源准备开始,队列名:{},id:{},消息体:{}", queueModelingPre, correlationId, msg);
-//        BuildSceneCallMessage buildSceneMessage = JSONObject.parseObject(msg, BuildSceneCallMessage.class);
-//        Thread.sleep(2000L);
-//        buildScenePreService.buildScenePre(buildSceneMessage);
-//        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
-//    }
-//
-//    /**
-//     * 场景计算后置结果处理
-//     * @param channel
-//     * @param message
-//     * @throws Exception
-//     */
-//    @RabbitListener(
-//        queuesToDeclare = @Queue("${queue.modeling.modeling-post}"),
-//        concurrency = "${maxThread.modeling.modeling-post}"
-//    )
-//    public void buildScenePostHandler(Channel channel, Message message) throws Exception {
-//        Object correlation = message.getMessageProperties().getHeader("spring_returned_message_correlation");
-//        String correlationId = (String) correlation;
-//        String msg = new String(message.getBody(), StandardCharsets.UTF_8);
-//        log.info("场景计算结果处理开始,队列名:{},id:{},消息体:{}", queueModelingPost, correlationId, msg);
-//        BuildSceneResultMqMessage resultMessage = JSONObject.parseObject(msg, BuildSceneResultMqMessage.class);
-//        Thread.sleep(2000L);
-//        buildScenePostService.buildScenePost(resultMessage);
-//        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
-//    }
-//
-//    /**
-//     * 场景计算发送钉钉消息
-//     * @param channel
-//     * @param message
-//     * @throws Exception
-//     */
-//    @RabbitListener(
-//        queuesToDeclare = @Queue("${queue.modeling.modeling-dt}"),
-//        concurrency = "${maxThread.modeling.modeling-dt}"
-//    )
-//    public void buildSceneDTHandler(Channel channel, Message message) throws Exception {
-//        Object correlation = message.getMessageProperties().getHeader("spring_returned_message_correlation");
-//        String correlationId = (String) correlation;
-//        String msg = new String(message.getBody(), StandardCharsets.UTF_8);
-//        log.info("发送钉钉消息处理,队列名:{},id:{},消息体:{}", queueModelingDt, correlationId, msg);
-//        BuildSceneFailDTMqMessage dtMessage = JSONObject.parseObject(msg, BuildSceneFailDTMqMessage.class);
-//        buildSceneDTService.handFail(dtMessage.getReason(), dtMessage.getServerPath(),
-//            dtMessage.getNum(), dtMessage.getHostName(), BuildSceneDTServiceImpl.contentExt);
-//        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
-//    }
-//
-//
-//}
+package com.fdkankan.scene.listener;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.rabbitmq.bean.BuildSceneCallMessage;
+import com.fdkankan.rabbitmq.bean.BuildSceneFailDTMqMessage;
+import com.fdkankan.rabbitmq.bean.BuildSceneResultMqMessage;
+import com.fdkankan.scene.entity.DownloadTourVideo;
+import com.fdkankan.scene.service.IBuildSceneDTService;
+import com.fdkankan.scene.service.IBuildScenePostService;
+import com.fdkankan.scene.service.IBuildScenePreService;
+import com.fdkankan.scene.service.IDownloadTourVideoService;
+import com.fdkankan.scene.service.impl.BuildSceneDTServiceImpl;
+import com.rabbitmq.client.Channel;
+import java.nio.charset.StandardCharsets;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.amqp.core.Message;
+import org.springframework.amqp.rabbit.annotation.Queue;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/4/19
+ **/
+@Slf4j
+@Component
+public class RabbitMqListener {
+
+    @Value("${queue.scene.transfer-tour-video}")
+    private String downloadTourVideoQueue;
+
+    @Autowired
+    private IDownloadTourVideoService downloadTourVideoService;
+
+
+
+
+    /**
+     * 开启了手动确认模式,如果没有手动确认,消费者不会重试,当服务重启时会再次消费,因为rabbitmq认为你还没有处理完你的业务
+     * queuesToDeclare = @Queue("${queue.modeling.modeling-test}"),  如果队列不不存在会自动创建队列
+     * concurrency = "3"    设置消费线程数,每个线程每次只拉取一条消息消费
+     */
+    @RabbitListener(
+        queuesToDeclare = @Queue("${queue.scene.transfer-tour-video}")
+    )
+    public void transferTourVideo(Channel channel, Message message) throws Exception {
+        String correlation = (String)message.getMessageProperties().getHeader("spring_returned_message_correlation");
+        String msg = new String(message.getBody(), StandardCharsets.UTF_8);
+        log.info("开始消费消息,id:{},queue:{},content:{}", correlation, downloadTourVideoQueue, msg);
+        DownloadTourVideo downloadTourVideo = JSON.parseObject(msg, DownloadTourVideo.class);
+        downloadTourVideoService.transferTourVideo(downloadTourVideo);
+        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
+        log.info("结束消费消息,id:{}", correlation);
+    }
+
+
+
+
+}

+ 18 - 0
4dkankan-center-scene/src/main/java/com/fdkankan/scene/mapper/IDownloadTourVideoMapper.java

@@ -0,0 +1,18 @@
+package com.fdkankan.scene.mapper;
+
+import com.fdkankan.scene.entity.DownloadTourVideo;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ * 导览视频转换记录表 Mapper 接口
+ * </p>
+ *
+ * @author 
+ * @since 2022-10-12
+ */
+@Mapper
+public interface IDownloadTourVideoMapper extends BaseMapper<DownloadTourVideo> {
+
+}

+ 29 - 0
4dkankan-center-scene/src/main/java/com/fdkankan/scene/service/IDownloadTourVideoService.java

@@ -0,0 +1,29 @@
+package com.fdkankan.scene.service;
+
+import com.fdkankan.common.response.ResultData;
+import com.fdkankan.scene.entity.DownloadTourVideo;
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * <p>
+ * 导览视频转换记录表 服务类
+ * </p>
+ *
+ * @author 
+ * @since 2022-10-12
+ */
+public interface IDownloadTourVideoService extends IService<DownloadTourVideo> {
+
+    DownloadTourVideo getWaitingByNum(String num);
+
+    void removeByNum(String num);
+
+    ResultData uploadTourVideo(String num, MultipartFile file) throws Exception;
+
+    void transferTourVideo(DownloadTourVideo downloadTourVideo);
+
+    ResultData downloadTourVideo(String num);
+
+}

+ 131 - 0
4dkankan-center-scene/src/main/java/com/fdkankan/scene/service/impl/DownloadTourVideoServiceImpl.java

@@ -0,0 +1,131 @@
+package com.fdkankan.scene.service.impl;
+
+import cn.hutool.core.exceptions.ExceptionUtil;
+import cn.hutool.core.lang.UUID;
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.fdkankan.common.constant.ConstantFilePath;
+import com.fdkankan.common.constant.ErrorCode;
+import com.fdkankan.common.constant.UploadFilePath;
+import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.common.response.ResultData;
+import com.fdkankan.common.util.CreateObjUtil;
+import com.fdkankan.fyun.oss.UploadToOssUtil;
+import com.fdkankan.rabbitmq.util.RabbitMqProducer;
+import com.fdkankan.scene.entity.DownloadTourVideo;
+import com.fdkankan.scene.mapper.IDownloadTourVideoMapper;
+import com.fdkankan.scene.service.IDownloadTourVideoService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fdkankan.scene.vo.DownloadTourVideoVO;
+import java.io.File;
+import java.util.Date;
+import java.util.Objects;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * <p>
+ * 导览视频转换记录表 服务实现类
+ * </p>
+ *
+ * @author 
+ * @since 2022-10-12
+ */
+@Service
+public class DownloadTourVideoServiceImpl extends ServiceImpl<IDownloadTourVideoMapper, DownloadTourVideo> implements IDownloadTourVideoService {
+
+    @Value("${queue.scene.transfer-tour-video}")
+    private String downloadTourVideoQueue;
+    @Autowired
+    private RabbitMqProducer rabbitMqProducer;
+    @Autowired
+    private UploadToOssUtil uploadToOssUtil;
+
+    @Override
+    public DownloadTourVideo getWaitingByNum(String num) {
+        return this.getOne(
+            new LambdaQueryWrapper<DownloadTourVideo>().eq(DownloadTourVideo::getNum, num)
+                .eq(DownloadTourVideo::getState, 0));
+    }
+
+    @Override
+    public void removeByNum(String num) {
+        this.remove(new LambdaQueryWrapper<DownloadTourVideo>().eq(DownloadTourVideo::getNum, num));
+    }
+
+    @Override
+    public ResultData uploadTourVideo(String num, MultipartFile file) throws Exception {
+
+        //查询是否有任务正在执行,如果有,直接返回
+        DownloadTourVideo waiting = this.getWaitingByNum(num);
+        if(Objects.isNull(waiting)){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_5064);
+        }
+
+        String uuid = cn.hutool.core.lang.UUID.randomUUID().toString();
+        String fileName = file.getOriginalFilename();
+        String extName = cn.hutool.core.io.FileUtil.extName(fileName);
+        String tempFileName = uuid + "." + extName;
+        String srcPath = ConstantFilePath.SCENE_V4_PATH + num + "/tour/" + tempFileName;
+        File tempFile = new File(srcPath);
+        if(!tempFile.getParentFile().exists()){
+            tempFile.getParentFile().mkdir();
+        }
+        file.transferTo(tempFile);
+
+        //先将旧纪录置为无效
+        this.removeByNum(num);
+
+        //写入新记录
+        DownloadTourVideo downloadTourVideo = new DownloadTourVideo();
+        downloadTourVideo.setNum(num);
+        downloadTourVideo.setFileName(fileName);
+        downloadTourVideo.setLocalPath(srcPath);
+        this.save(downloadTourVideo);
+
+        //发送mq
+        rabbitMqProducer.sendByWorkQueue(downloadTourVideoQueue, downloadTourVideo);
+
+        return ResultData.ok();
+    }
+
+    @Override
+    public void transferTourVideo(DownloadTourVideo downloadTourVideo) {
+
+        String destPath = null;
+        try {
+            String destFileName = UUID.randomUUID().toString() + ".mp4";
+            destPath = ConstantFilePath.SCENE_V4_PATH + downloadTourVideo.getNum() + "tour/" + destFileName;
+            String srcPath = downloadTourVideo.getLocalPath();
+            CreateObjUtil.formatMp4(srcPath, destPath);
+        }catch (Exception e) {
+            log.error("导览视频转换失败,num:" + downloadTourVideo.getNum() + "源路径:" + downloadTourVideo.getLocalPath(), e);
+            downloadTourVideo.setReason(ExceptionUtil.stacktraceToString(e, 3000));
+            downloadTourVideo.setState(2);
+        }
+
+        //上传到oss
+        String ossPath = String.format(UploadFilePath.DOWNLOADS_TOUR_VIDEO, downloadTourVideo.getNum()) + downloadTourVideo.getFileName();
+        uploadToOssUtil.upload(destPath, ossPath);
+
+        downloadTourVideo.setDownloadPath(ossPath);
+        downloadTourVideo.setState(1);
+        this.updateById(downloadTourVideo);
+    }
+
+    @Override
+    public ResultData downloadTourVideo(String num) {
+        DownloadTourVideoVO result = new DownloadTourVideoVO();
+        DownloadTourVideo downloadTourVideo = this.getOne(new LambdaQueryWrapper<DownloadTourVideo>().eq(DownloadTourVideo::getNum, num));
+        if(Objects.isNull(downloadTourVideo)){
+            result.setStatus(0);
+        }else{
+            result.setStatus(1);
+            result.setTransferStatus(downloadTourVideo.getState());
+            result.setPath(downloadTourVideo.getDownloadPath());
+        }
+        return ResultData.ok(result);
+    }
+}

+ 5 - 0
4dkankan-center-scene/src/main/java/com/fdkankan/scene/service/impl/SceneUploadServiceImpl.java

@@ -1,4 +1,6 @@
 package com.fdkankan.scene.service.impl;
+import com.fdkankan.scene.service.IDownloadTourVideoService;
+import java.util.Date;
 
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.io.IoUtil;
@@ -19,6 +21,7 @@ import com.fdkankan.common.util.BASE64DecodedMultipartFile;
 import com.fdkankan.common.util.CreateObjUtil;
 import com.fdkankan.common.util.FileUtil;
 import com.fdkankan.fyun.oss.UploadToOssUtil;
+import com.fdkankan.scene.entity.DownloadTourVideo;
 import com.fdkankan.scene.entity.ScenePro;
 import com.fdkankan.scene.entity.SceneUpload;
 import com.fdkankan.scene.mapper.ISceneUploadMapper;
@@ -35,7 +38,9 @@ import java.io.OutputStream;
 import java.net.URLEncoder;
 import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
+import java.util.Calendar;
 import java.util.HashSet;
+import java.util.Objects;
 import java.util.Set;
 import javax.servlet.http.HttpServletResponse;
 import org.apache.commons.lang3.StringUtils;

+ 21 - 0
4dkankan-center-scene/src/main/java/com/fdkankan/scene/vo/DownloadTourVideoVO.java

@@ -0,0 +1,21 @@
+package com.fdkankan.scene.vo;
+
+import lombok.Data;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/10/13
+ **/
+@Data
+public class DownloadTourVideoVO {
+
+    private Integer status;
+    private Integer transferStatus;
+    private String path;
+
+
+}

+ 5 - 0
4dkankan-center-scene/src/main/resources/mapper/scene/DownloadTourVideoMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fdkankan.scene.mapper.IDownloadTourVideoMapper">
+
+</mapper>