diff --git a/basic-properties/src/main/java/ink/wgink/properties/media/video/VideoProperties.java b/basic-properties/src/main/java/ink/wgink/properties/media/video/VideoProperties.java index a0fdcc6e..5dbc690b 100644 --- a/basic-properties/src/main/java/ink/wgink/properties/media/video/VideoProperties.java +++ b/basic-properties/src/main/java/ink/wgink/properties/media/video/VideoProperties.java @@ -17,22 +17,40 @@ import org.springframework.stereotype.Component; @ConfigurationProperties(prefix = "media.video") public class VideoProperties { - private Long backendDuration; - private Long appDuration; + private String types; + private Integer maxUploadCount; + private Long backendMaxDuration; + private Long appMaxDuration; - public Long getBackendDuration() { - return backendDuration; + public String getTypes() { + return types == null ? "mp4" : types; } - public void setBackendDuration(Long backendDuration) { - this.backendDuration = backendDuration; + public void setTypes(String types) { + this.types = types; } - public Long getAppDuration() { - return appDuration; + public Integer getMaxUploadCount() { + return maxUploadCount == null || maxUploadCount <= 1 ? 1 : maxUploadCount; } - public void setAppDuration(Long appDuration) { - this.appDuration = appDuration; + public void setMaxUploadCount(Integer maxUploadCount) { + this.maxUploadCount = maxUploadCount; + } + + public Long getBackendMaxDuration() { + return backendMaxDuration == null || backendMaxDuration <= 0 ? 0 : backendMaxDuration; + } + + public void setBackendMaxDuration(Long backendMaxDuration) { + this.backendMaxDuration = backendMaxDuration; + } + + public Long getAppMaxDuration() { + return appMaxDuration == null || appMaxDuration <= 0 ? 0 : appMaxDuration; + } + + public void setAppMaxDuration(Long appMaxDuration) { + this.appMaxDuration = appMaxDuration; } } diff --git a/module-file-media/src/main/java/ink/wgink/module/file/media/controller/api/video/VideoController.java b/module-file-media/src/main/java/ink/wgink/module/file/media/controller/api/video/VideoController.java index fa50cdd8..087e703b 100644 --- a/module-file-media/src/main/java/ink/wgink/module/file/media/controller/api/video/VideoController.java +++ b/module-file-media/src/main/java/ink/wgink/module/file/media/controller/api/video/VideoController.java @@ -3,19 +3,24 @@ package ink.wgink.module.file.media.controller.api.video; import ink.wgink.common.base.DefaultBaseController; import ink.wgink.exceptions.PropertiesException; import ink.wgink.interfaces.consts.ISystemConstant; +import ink.wgink.module.file.media.pojo.dtos.video.VideoDTO; import ink.wgink.module.file.media.service.video.IVideoService; +import ink.wgink.pojo.ListPage; import ink.wgink.pojo.result.ErrorResult; +import ink.wgink.pojo.result.SuccessResult; import ink.wgink.pojo.result.SuccessResultData; +import ink.wgink.pojo.result.SuccessResultList; import ink.wgink.properties.media.MediaProperties; import io.swagger.annotations.*; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; +import java.util.Arrays; +import java.util.List; +import java.util.Map; import java.util.concurrent.Callable; /** @@ -30,7 +35,7 @@ import java.util.concurrent.Callable; **/ @Api(tags = ISystemConstant.API_TAGS_SYSTEM_PREFIX + "视频接口") @RestController -@RequestMapping(ISystemConstant.API_PREFIX + "/video") +@RequestMapping(ISystemConstant.API_PREFIX + "/file/media/video") public class VideoController extends DefaultBaseController { @Autowired @@ -39,9 +44,6 @@ public class VideoController extends DefaultBaseController { private IVideoService videoService; @ApiOperation(value = "上传视频", notes = "上传视频接口") - @ApiImplicitParams({ - @ApiImplicitParam(name = "video", value = "文件video", paramType = "query") - }) @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)}) @PostMapping("upload") public Callable> upload(@RequestParam("video") MultipartFile video) { @@ -54,4 +56,53 @@ public class VideoController extends DefaultBaseController { return () -> new SuccessResultData<>(videoService.upload(video)); } + @ApiOperation(value = "删除文件类别(id列表)", notes = "删除文件类别(id列表)接口") + @ApiImplicitParams({ + @ApiImplicitParam(name = "ids", value = "ID列表,用下划线分隔", paramType = "path", example = "1_2_3") + }) + @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)}) + @DeleteMapping("remove/{isRemoveSource}/{ids}") + public synchronized SuccessResult remove(@PathVariable() Integer isRemoveSource, @PathVariable("ids") String ids) { + if (isRemoveSource == 0) { + videoService.remove(Arrays.asList(ids.split("\\_"))); + } + if (isRemoveSource == 1) { + videoService.delete(Arrays.asList(ids.split("\\_"))); + } + return new SuccessResult(); + } + + @ApiOperation(value = "视频转码", notes = "视频转码接口") + @ApiImplicitParams({ + @ApiImplicitParam(name = "ids", value = "ID列表,用下划线分隔", paramType = "path", example = "1_2_3") + }) + @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)}) + @PutMapping("convert/{fileId}") + public synchronized SuccessResult updateConvert(@PathVariable("fileId") String fileId) { + videoService.updateConvert(fileId); + return new SuccessResult(); + } + + @ApiOperation(value = "视频转换进度", notes = "视频转换进度接口") + @GetMapping(value = "get-convert-progress", produces = "text/event-stream") + public SseEmitter getConvertProgress() { + return videoService.getConvertProgress(); + } + + @ApiOperation(value = "视频分页列表", notes = "视频分页列表接口") + @ApiImplicitParams({ + @ApiImplicitParam(name = "page", value = "当前页码", paramType = "query", dataType = "int", defaultValue = "1"), + @ApiImplicitParam(name = "rows", value = "显示数量", paramType = "query", dataType = "int", defaultValue = "20"), + @ApiImplicitParam(name = "keywords", value = "关键字", paramType = "query", dataType = "String"), + @ApiImplicitParam(name = "startTime", value = "开始时间", paramType = "query", dataType = "String"), + @ApiImplicitParam(name = "endTime", value = "结束时间", paramType = "query", dataType = "String") + }) + @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)}) + @GetMapping("listpage") + public SuccessResultList> listPageInfo(ListPage page) { + Map params = requestParams(); + page.setParams(params); + return videoService.listPage(page); + } + } diff --git a/module-file-media/src/main/java/ink/wgink/module/file/media/controller/route/video/VideoRouteController.java b/module-file-media/src/main/java/ink/wgink/module/file/media/controller/route/video/VideoRouteController.java new file mode 100644 index 00000000..eb4ddc3c --- /dev/null +++ b/module-file-media/src/main/java/ink/wgink/module/file/media/controller/route/video/VideoRouteController.java @@ -0,0 +1,43 @@ +package ink.wgink.module.file.media.controller.route.video; + +import ink.wgink.interfaces.consts.ISystemConstant; +import ink.wgink.properties.media.video.VideoProperties; +import io.swagger.annotations.Api; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.servlet.ModelAndView; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: VideoRouteController + * @Description: 视频路由 + * @Author: wanggeng + * @Date: 2021/6/12 11:16 下午 + * @Version: 1.0 + */ +@Api(tags = ISystemConstant.API_TAGS_SYSTEM_PREFIX + "文件管理接口") +@Controller +@RequestMapping(ISystemConstant.ROUTE_PREFIX + "/file/media/video") +public class VideoRouteController { + + @Autowired + private VideoProperties videoProperties; + + @GetMapping("list") + public ModelAndView list() { + return new ModelAndView("file/media/video/list"); + } + + @GetMapping("upload") + public ModelAndView upload() { + ModelAndView modelAndView = new ModelAndView("file/media/video/upload"); + modelAndView.addObject("types", videoProperties.getTypes()); + modelAndView.addObject("maxUploadCount", videoProperties.getMaxUploadCount()); + return modelAndView; + } + +} diff --git a/module-file-media/src/main/java/ink/wgink/module/file/media/dao/video/IVideoDao.java b/module-file-media/src/main/java/ink/wgink/module/file/media/dao/video/IVideoDao.java new file mode 100644 index 00000000..a9dd7cf2 --- /dev/null +++ b/module-file-media/src/main/java/ink/wgink/module/file/media/dao/video/IVideoDao.java @@ -0,0 +1,91 @@ +package ink.wgink.module.file.media.dao.video; + +import ink.wgink.exceptions.RemoveException; +import ink.wgink.exceptions.SaveException; +import ink.wgink.exceptions.SearchException; +import ink.wgink.exceptions.UpdateException; +import ink.wgink.module.file.media.pojo.dtos.video.VideoDTO; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.Map; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: IVideoDao + * @Description: 视频 + * @Author: wanggeng + * @Date: 2021/6/12 10:25 下午 + * @Version: 1.0 + */ +@Repository +public interface IVideoDao { + + /** + * 建表 + * + * @throws UpdateException + */ + void createTable() throws UpdateException; + + /** + * 新增 + * + * @param params + * @throws SaveException + */ + void save(Map params) throws SaveException; + + /** + * 删除 + * + * @param params + * @throws RemoveException + */ + void remove(Map params) throws RemoveException; + + /** + * 删除(物理) + * + * @param params + * @throws RemoveException + */ + void delete(Map params) throws RemoveException; + + /** + * 更新 + * + * @param params + * @throws UpdateException + */ + void update(Map params) throws UpdateException; + + /** + * 更新(转码状态) + * + * @param params + * @throws UpdateException + */ + void updateConvert(Map params) throws UpdateException; + + /** + * 详情 + * + * @param params + * @return + * @throws SearchException + */ + VideoDTO get(Map params) throws SearchException; + + /** + * 列表 + * + * @param params + * @return + * @throws SearchException + */ + List list(Map params) throws SearchException; + +} diff --git a/module-file-media/src/main/java/ink/wgink/module/file/media/enums/ConvertStatusEnum.java b/module-file-media/src/main/java/ink/wgink/module/file/media/enums/ConvertStatusEnum.java new file mode 100644 index 00000000..eb1d90b1 --- /dev/null +++ b/module-file-media/src/main/java/ink/wgink/module/file/media/enums/ConvertStatusEnum.java @@ -0,0 +1,34 @@ +package ink.wgink.module.file.media.enums; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: ConvertStatusEnum + * @Description: 转码状态 + * @Author: wanggeng + * @Date: 2021/6/13 5:06 下午 + * @Version: 1.0 + */ +public enum ConvertStatusEnum { + + UN_CONVERTED("UN_CONVERTED", "未转码"), + CONVERTING("CONVERTING", "转码中"), + CONVERTED("CONVERTED", "已转码"); + + String value; + String summary; + + ConvertStatusEnum(String value, String summary) { + this.value = value; + this.summary = summary; + } + + public String getValue() { + return value == null ? "" : value; + } + + public String getSummary() { + return summary == null ? "" : summary; + } +} diff --git a/module-file-media/src/main/java/ink/wgink/module/file/media/pojo/dtos/ConvertProgressDTO.java b/module-file-media/src/main/java/ink/wgink/module/file/media/pojo/dtos/ConvertProgressDTO.java new file mode 100644 index 00000000..0107a15a --- /dev/null +++ b/module-file-media/src/main/java/ink/wgink/module/file/media/pojo/dtos/ConvertProgressDTO.java @@ -0,0 +1,33 @@ +package ink.wgink.module.file.media.pojo.dtos; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: ConvertProcessDTO + * @Description: 转换进度 + * @Author: wanggeng + * @Date: 2021/6/13 10:32 下午 + * @Version: 1.0 + */ +public class ConvertProgressDTO { + + private String fileId; + private Double percent; + + public String getFileId() { + return fileId == null ? "" : fileId; + } + + public void setFileId(String fileId) { + this.fileId = fileId; + } + + public Double getPercent() { + return percent == null ? 0 : percent; + } + + public void setPercent(Double percent) { + this.percent = percent; + } +} diff --git a/module-file-media/src/main/java/ink/wgink/module/file/media/pojo/dtos/MediaDTO.java b/module-file-media/src/main/java/ink/wgink/module/file/media/pojo/dtos/MediaDTO.java new file mode 100644 index 00000000..06514ff1 --- /dev/null +++ b/module-file-media/src/main/java/ink/wgink/module/file/media/pojo/dtos/MediaDTO.java @@ -0,0 +1,117 @@ +package ink.wgink.module.file.media.pojo.dtos; + +import java.io.Serializable; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: MediaDTO + * @Description: 媒体 + * @Author: wanggeng + * @Date: 2021/6/13 4:51 下午 + * @Version: 1.0 + */ +public class MediaDTO implements Serializable { + private static final long serialVersionUID = 4546445666757053123L; + + private String fileId; + private String fileName; + private String filePath; + private String fileFullPath; + private String fileUrl; + private String fileType; + private Long fileSize; + private String fileSummary; + private String fileMd5; + private Integer isBack; + private String staticUrl; + + public String getFileId() { + return fileId == null ? "" : fileId; + } + + public void setFileId(String fileId) { + this.fileId = fileId; + } + + public String getFileName() { + return fileName == null ? "" : fileName; + } + + public void setFileName(String fileName) { + this.fileName = fileName; + } + + public String getFilePath() { + return filePath == null ? "" : filePath; + } + + public void setFilePath(String filePath) { + this.filePath = filePath; + } + + public String getFileFullPath() { + return fileFullPath == null ? "" : fileFullPath; + } + + public void setFileFullPath(String fileFullPath) { + this.fileFullPath = fileFullPath; + } + + public String getFileUrl() { + return fileUrl == null ? "" : fileUrl; + } + + public void setFileUrl(String fileUrl) { + this.fileUrl = fileUrl; + } + + public String getFileType() { + return fileType == null ? "" : fileType; + } + + public void setFileType(String fileType) { + this.fileType = fileType; + } + + public Long getFileSize() { + return fileSize == null ? 0 : fileSize; + } + + public void setFileSize(Long fileSize) { + this.fileSize = fileSize; + } + + public String getFileSummary() { + return fileSummary == null ? "" : fileSummary; + } + + public void setFileSummary(String fileSummary) { + this.fileSummary = fileSummary; + } + + public String getFileMd5() { + return fileMd5 == null ? "" : fileMd5; + } + + public void setFileMd5(String fileMd5) { + this.fileMd5 = fileMd5; + } + + public Integer getIsBack() { + return isBack == null ? 0 : isBack; + } + + public void setIsBack(Integer isBack) { + this.isBack = isBack; + } + + public String getStaticUrl() { + return staticUrl == null ? "" : staticUrl; + } + + public void setStaticUrl(String staticUrl) { + this.staticUrl = staticUrl; + } +} diff --git a/module-file-media/src/main/java/ink/wgink/module/file/media/pojo/dtos/video/VideoDTO.java b/module-file-media/src/main/java/ink/wgink/module/file/media/pojo/dtos/video/VideoDTO.java new file mode 100644 index 00000000..d3c0ddb5 --- /dev/null +++ b/module-file-media/src/main/java/ink/wgink/module/file/media/pojo/dtos/video/VideoDTO.java @@ -0,0 +1,126 @@ +package ink.wgink.module.file.media.pojo.dtos.video; + +import ink.wgink.module.file.media.pojo.dtos.MediaDTO; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: VideoDTO + * @Description: 视频 + * @Author: wanggeng + * @Date: 2021/6/13 4:53 下午 + * @Version: 1.0 + */ +public class VideoDTO extends MediaDTO { + private static final long serialVersionUID = -7694278158868881064L; + + private String keyframe; + private Long videoDuration; + private Integer videoWidth; + private Integer videoHeight; + private Integer videoBitRate; + private String videoEncoder; + private Float videoFrameRate; + private Long audioDuration; + private Integer audioBitRate; + private Long audioSampleRate; + private String convertStatus; + private String gmtCreate; + + public String getKeyframe() { + return keyframe == null ? "" : keyframe; + } + + public void setKeyframe(String keyframe) { + this.keyframe = keyframe; + } + + public Long getVideoDuration() { + return videoDuration == null ? 0 : videoDuration; + } + + public void setVideoDuration(Long videoDuration) { + this.videoDuration = videoDuration; + } + + public Integer getVideoWidth() { + return videoWidth == null ? 0 : videoWidth; + } + + public void setVideoWidth(Integer videoWidth) { + this.videoWidth = videoWidth; + } + + public Integer getVideoHeight() { + return videoHeight == null ? 0 : videoHeight; + } + + public void setVideoHeight(Integer videoHeight) { + this.videoHeight = videoHeight; + } + + public Integer getVideoBitRate() { + return videoBitRate == null ? 0 : videoBitRate; + } + + public void setVideoBitRate(Integer videoBitRate) { + this.videoBitRate = videoBitRate; + } + + public String getVideoEncoder() { + return videoEncoder == null ? "" : videoEncoder; + } + + public void setVideoEncoder(String videoEncoder) { + this.videoEncoder = videoEncoder; + } + + public Float getVideoFrameRate() { + return videoFrameRate == null ? 0 : videoFrameRate; + } + + public void setVideoFrameRate(Float videoFrameRate) { + this.videoFrameRate = videoFrameRate; + } + + public Long getAudioDuration() { + return audioDuration == null ? 0 : audioDuration; + } + + public void setAudioDuration(Long audioDuration) { + this.audioDuration = audioDuration; + } + + public Integer getAudioBitRate() { + return audioBitRate == null ? 0 : audioBitRate; + } + + public void setAudioBitRate(Integer audioBitRate) { + this.audioBitRate = audioBitRate; + } + + public Long getAudioSampleRate() { + return audioSampleRate == null ? 0 : audioSampleRate; + } + + public void setAudioSampleRate(Long audioSampleRate) { + this.audioSampleRate = audioSampleRate; + } + + public String getConvertStatus() { + return convertStatus == null ? "" : convertStatus; + } + + public void setConvertStatus(String convertStatus) { + this.convertStatus = convertStatus; + } + + public String getGmtCreate() { + return gmtCreate == null ? "" : gmtCreate; + } + + public void setGmtCreate(String gmtCreate) { + this.gmtCreate = gmtCreate; + } +} diff --git a/module-file-media/src/main/java/ink/wgink/module/file/media/pojo/vos/MediaVO.java b/module-file-media/src/main/java/ink/wgink/module/file/media/pojo/vos/MediaVO.java index f944f753..3ac4eb67 100644 --- a/module-file-media/src/main/java/ink/wgink/module/file/media/pojo/vos/MediaVO.java +++ b/module-file-media/src/main/java/ink/wgink/module/file/media/pojo/vos/MediaVO.java @@ -1,5 +1,9 @@ package ink.wgink.module.file.media.pojo.vos; +import io.swagger.annotations.ApiModel; + +import java.io.Serializable; + /** * When you feel like quitting. Think about why you started * 当你想要放弃的时候,想想当初你为何开始 @@ -20,6 +24,8 @@ public class MediaVO { private Long fileSize; private String fileSummary; private String fileMd5; + private Integer isBack; + private String staticUrl; public String getFileName() { return fileName == null ? "" : fileName.trim(); @@ -84,4 +90,20 @@ public class MediaVO { public void setFileMd5(String fileMd5) { this.fileMd5 = fileMd5; } + + public Integer getIsBack() { + return isBack == null ? 0 : isBack; + } + + public void setIsBack(Integer isBack) { + this.isBack = isBack; + } + + public String getStaticUrl() { + return staticUrl == null ? "" : staticUrl; + } + + public void setStaticUrl(String staticUrl) { + this.staticUrl = staticUrl; + } } diff --git a/module-file-media/src/main/java/ink/wgink/module/file/media/pojo/vos/video/VideoVO.java b/module-file-media/src/main/java/ink/wgink/module/file/media/pojo/vos/video/VideoVO.java index dd742aab..beb54c24 100644 --- a/module-file-media/src/main/java/ink/wgink/module/file/media/pojo/vos/video/VideoVO.java +++ b/module-file-media/src/main/java/ink/wgink/module/file/media/pojo/vos/video/VideoVO.java @@ -15,74 +15,75 @@ import ink.wgink.module.file.media.pojo.vos.MediaVO; public class VideoVO extends MediaVO { private String keyframe; - private Long duration; - private Integer width; - private Integer height; - private Integer bitRate; - private String encoder; - private Float frameRate; + private Long videoDuration; + private Integer videoWidth; + private Integer videoHeight; + private Integer videoBitRate; + private String videoEncoder; + private Float videoFrameRate; private Long audioDuration; private Integer audioBitRate; private Long audioSampleRate; + private String convertStatus; public String getKeyframe() { - return keyframe == null ? "" : keyframe.trim(); + return keyframe == null ? "" : keyframe; } public void setKeyframe(String keyframe) { this.keyframe = keyframe; } - public Long getDuration() { - return duration; + public Long getVideoDuration() { + return videoDuration == null ? 0 : videoDuration; } - public void setDuration(Long duration) { - this.duration = duration; + public void setVideoDuration(Long videoDuration) { + this.videoDuration = videoDuration; } - public Integer getWidth() { - return width; + public Integer getVideoWidth() { + return videoWidth == null ? 0 : videoWidth; } - public void setWidth(Integer width) { - this.width = width; + public void setVideoWidth(Integer videoWidth) { + this.videoWidth = videoWidth; } - public Integer getHeight() { - return height; + public Integer getVideoHeight() { + return videoHeight == null ? 0 : videoHeight; } - public void setHeight(Integer height) { - this.height = height; + public void setVideoHeight(Integer videoHeight) { + this.videoHeight = videoHeight; } - public Integer getBitRate() { - return bitRate; + public Integer getVideoBitRate() { + return videoBitRate == null ? 0 : videoBitRate; } - public void setBitRate(Integer bitRate) { - this.bitRate = bitRate; + public void setVideoBitRate(Integer videoBitRate) { + this.videoBitRate = videoBitRate; } - public String getEncoder() { - return encoder == null ? "" : encoder.trim(); + public String getVideoEncoder() { + return videoEncoder == null ? "" : videoEncoder; } - public void setEncoder(String encoder) { - this.encoder = encoder; + public void setVideoEncoder(String videoEncoder) { + this.videoEncoder = videoEncoder; } - public Float getFrameRate() { - return frameRate; + public Float getVideoFrameRate() { + return videoFrameRate == null ? 0 : videoFrameRate; } - public void setFrameRate(Float frameRate) { - this.frameRate = frameRate; + public void setVideoFrameRate(Float videoFrameRate) { + this.videoFrameRate = videoFrameRate; } public Long getAudioDuration() { - return audioDuration; + return audioDuration == null ? 0 : audioDuration; } public void setAudioDuration(Long audioDuration) { @@ -90,7 +91,7 @@ public class VideoVO extends MediaVO { } public Integer getAudioBitRate() { - return audioBitRate; + return audioBitRate == null ? 0 : audioBitRate; } public void setAudioBitRate(Integer audioBitRate) { @@ -98,10 +99,18 @@ public class VideoVO extends MediaVO { } public Long getAudioSampleRate() { - return audioSampleRate; + return audioSampleRate == null ? 0 : audioSampleRate; } public void setAudioSampleRate(Long audioSampleRate) { this.audioSampleRate = audioSampleRate; } + + public String getConvertStatus() { + return convertStatus == null ? "" : convertStatus; + } + + public void setConvertStatus(String convertStatus) { + this.convertStatus = convertStatus; + } } diff --git a/module-file-media/src/main/java/ink/wgink/module/file/media/service/video/IVideoService.java b/module-file-media/src/main/java/ink/wgink/module/file/media/service/video/IVideoService.java index ab48d9d9..ca4ba583 100644 --- a/module-file-media/src/main/java/ink/wgink/module/file/media/service/video/IVideoService.java +++ b/module-file-media/src/main/java/ink/wgink/module/file/media/service/video/IVideoService.java @@ -1,7 +1,17 @@ package ink.wgink.module.file.media.service.video; +import ink.wgink.exceptions.SearchException; +import ink.wgink.module.file.media.pojo.dtos.ConvertProgressDTO; +import ink.wgink.module.file.media.pojo.dtos.video.VideoDTO; import ink.wgink.module.file.media.pojo.vos.video.VideoVO; +import ink.wgink.pojo.ListPage; +import ink.wgink.pojo.result.SuccessResultList; import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; + +import java.io.File; +import java.util.List; +import java.util.Map; /** * When you feel like quitting. Think about why you started @@ -34,6 +44,35 @@ public interface IVideoService { */ String save(String token, VideoVO videoVO); + /** + * 删除 + * + * @param ids + */ + void remove(List ids); + + /** + * 删除(物理) + * + * @param ids + */ + void delete(List ids); + + /** + * 更新转码信息 + * + * @param fileId + */ + void updateConvert(String fileId); + + /** + * 更新转码信息 + * + * @param fileId 文件ID + * @param convertFile 转码文件 + */ + void updateConvert(String fileId, File convertFile); + /** * 上传视频 * @@ -50,4 +89,52 @@ public interface IVideoService { * @return */ String upload(String token, MultipartFile video); + + /** + * 转换进度列表 + * + * @return + */ + SseEmitter getConvertProgress(); + + /** + * 详情 + * + * @param params + * @return + */ + VideoDTO get(Map params); + + /** + * 详情 + * + * @param fileId 文件ID + * @return + */ + VideoDTO get(String fileId); + + /** + * 详情 + * + * @param fileMd5 文件MD5值 + * @return + */ + VideoDTO getByMd5(String fileMd5); + + /** + * 列表 + * + * @param params + * @return + */ + List list(Map params); + + /** + * 分页 + * + * @param page + * @return + */ + SuccessResultList> listPage(ListPage page); + } diff --git a/module-file-media/src/main/java/ink/wgink/module/file/media/service/video/impl/VideoServiceImpl.java b/module-file-media/src/main/java/ink/wgink/module/file/media/service/video/impl/VideoServiceImpl.java index 129c846a..87a455cc 100644 --- a/module-file-media/src/main/java/ink/wgink/module/file/media/service/video/impl/VideoServiceImpl.java +++ b/module-file-media/src/main/java/ink/wgink/module/file/media/service/video/impl/VideoServiceImpl.java @@ -1,20 +1,39 @@ package ink.wgink.module.file.media.service.video.impl; +import com.github.pagehelper.PageHelper; +import com.github.pagehelper.PageInfo; import ink.wgink.common.base.DefaultBaseService; import ink.wgink.exceptions.FileException; +import ink.wgink.exceptions.SearchException; +import ink.wgink.module.file.media.dao.video.IVideoDao; +import ink.wgink.module.file.media.enums.ConvertStatusEnum; import ink.wgink.module.file.media.manager.MediaManager; import ink.wgink.module.file.media.manager.domain.MusicMetaInfo; import ink.wgink.module.file.media.manager.domain.VideoMetaInfo; +import ink.wgink.module.file.media.pojo.dtos.ConvertProgressDTO; +import ink.wgink.module.file.media.pojo.dtos.video.VideoDTO; import ink.wgink.module.file.media.pojo.vos.video.VideoVO; import ink.wgink.module.file.media.service.IMediaService; import ink.wgink.module.file.media.service.video.IVideoService; +import ink.wgink.module.file.media.task.transcoding.VideoConvertManager; +import ink.wgink.module.file.media.task.transcoding.runnable.VideoConvertRunnable; +import ink.wgink.pojo.ListPage; +import ink.wgink.pojo.result.SuccessResultList; import ink.wgink.properties.media.MediaProperties; import ink.wgink.util.UUIDUtil; +import ink.wgink.util.date.DateUtil; +import ink.wgink.util.map.HashMapUtil; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; /** * When you feel like quitting. Think about why you started @@ -33,17 +52,99 @@ public class VideoServiceImpl extends DefaultBaseService implements IVideoServic private IMediaService mediaService; @Autowired private MediaProperties mediaProperties; + @Autowired + private IVideoDao videoDao; @Override public String save(VideoVO videoVO) { - return null; + return save(null, videoVO); } @Override public String save(String token, VideoVO videoVO) { String fileId = UUIDUtil.getUUID(); + Map params = HashMapUtil.beanToMap(videoVO); + params.put("fileId", fileId); + if (StringUtils.isBlank(token)) { + setSaveInfo(params); + } else { + setAppSaveInfo(token, params); + } + videoDao.save(params); + return fileId; + } - return null; + @Override + public void remove(List ids) { + Map params = getHashMap(2); + params.put("fileIds", ids); + List videoDTOs = videoDao.list(params); + checkConverting(videoDTOs); + setUpdateInfo(params); + videoDao.remove(params); + } + + @Override + public void delete(List ids) { + Map params = getHashMap(2); + params.put("fileIds", ids); + List videoDTOs = videoDao.list(params); + checkConverting(videoDTOs); + // 删除文件 + for (VideoDTO videoDTO : videoDTOs) { + deleteSourceFile(videoDTO.getFileFullPath()); + } + // 删除记录 + videoDao.delete(params); + } + + @Override + public void updateConvert(String fileId) { + VideoDTO videoDTO = get(fileId); + if (videoDTO == null) { + throw new SearchException("视频不存在"); + } + VideoConvertManager.getInstance().convert(new VideoConvertRunnable(fileId, videoDTO.getFileFullPath(), this)); + // 更新状态 + Map params = getHashMap(8); + params.put("convertStatus", ConvertStatusEnum.CONVERTING.getValue()); + params.put("fileId", fileId); + setUpdateInfo(params); + videoDao.updateConvert(params); + } + + @Override + public void updateConvert(String fileId, File convertFile) { + VideoDTO videoDTO = get(fileId); + if (videoDTO == null) { + throw new SearchException("视频不存在"); + } + Map params = getHashMap(10); + params.put("fileSize", convertFile.length()); + params.put("fileType", "mp4"); + params.put("fileName", convertFile.getName()); + params.put("fileFullPath", convertFile.getAbsolutePath()); + + VideoMetaInfo videoMetaInfo = MediaManager.getInstance().getVideoMetaInfo(convertFile); + params.put("videoDuration", videoMetaInfo.getDuration()); + params.put("videoWidth", videoMetaInfo.getWidth()); + params.put("videoHeight", videoMetaInfo.getHeight()); + params.put("videoBitRate", videoMetaInfo.getBitRate()); + params.put("videoEncoder", videoMetaInfo.getEncoder()); + params.put("videoFrameRate", videoMetaInfo.getFrameRate()); + params.put("convertStatus", ConvertStatusEnum.CONVERTED.getValue()); + + MusicMetaInfo musicMetaInfo = videoMetaInfo.getMusicMetaInfo(); + if (musicMetaInfo != null) { + params.put("audioDuration", musicMetaInfo.getDuration()); + params.put("audioBitRate", musicMetaInfo.getBitRate()); + params.put("audioSampleRate", musicMetaInfo.getSampleRate()); + } + params.put("fileId", fileId); + setUpdateInfoByUserId(params, "1"); + videoDao.update(params); + // 删除源文件 + deleteSourceFile(videoDTO.getFileFullPath()); } @Override @@ -53,32 +154,44 @@ public class VideoServiceImpl extends DefaultBaseService implements IVideoServic @Override public String upload(String token, MultipartFile video) { - String filePath = mediaProperties.getUploadPath() + File.separator + VIDEO_PATH; + String filePath = VIDEO_PATH + File.separator + DateUtil.getDays(); + String uploadFolderPath = mediaProperties.getUploadPath() + File.separator + filePath; String fileName = video.getOriginalFilename(); long fileSize = video.getSize(); String fileType = mediaService.getFileType(fileName); - String fileMd5 = mediaService.upload(video, filePath, fileName); - String fileFullPath = filePath; + String uuidFileName = UUIDUtil.getUUID() + "." + fileType; + String fileMd5 = mediaService.upload(video, uploadFolderPath, uuidFileName); + // 判断文件是否存在,已经存在的不再新增,直接返回结果,删除临时文件 + VideoDTO videoDTO = getByMd5(fileMd5); + String fileFullPath = uploadFolderPath + File.separator + uuidFileName; + File uploadFile = new File(fileFullPath); + if (videoDTO != null) { + LOG.error("上传的【{}】视频已经存在,原文件为【{}】,返回原文件ID", videoDTO.getFileName(), videoDTO.getFileName()); + uploadFile.delete(); + return videoDTO.getFileId(); + } + // 构建视频内容 VideoVO videoVO = new VideoVO(); videoVO.setFileName(fileName); videoVO.setFileFullPath(fileFullPath); - videoVO.setFilePath(VIDEO_PATH); + videoVO.setFilePath(filePath); videoVO.setFileSize(fileSize); videoVO.setFileType(fileType); videoVO.setFileMd5(fileMd5); + videoVO.setIsBack(0); - File uploadFile = new File(fileFullPath + File.separator + fileName); VideoMetaInfo videoMetaInfo = MediaManager.getInstance().getVideoMetaInfo(uploadFile); if (videoMetaInfo == null) { throw new FileException("上传失败"); } - videoVO.setDuration(videoMetaInfo.getDuration()); - videoVO.setWidth(videoMetaInfo.getWidth()); - videoVO.setHeight(videoMetaInfo.getHeight()); - videoVO.setBitRate(videoMetaInfo.getBitRate()); - videoVO.setEncoder(videoMetaInfo.getEncoder()); - videoVO.setFrameRate(videoMetaInfo.getFrameRate()); + videoVO.setVideoDuration(videoMetaInfo.getDuration()); + videoVO.setVideoWidth(videoMetaInfo.getWidth()); + videoVO.setVideoHeight(videoMetaInfo.getHeight()); + videoVO.setVideoBitRate(videoMetaInfo.getBitRate()); + videoVO.setVideoEncoder(videoMetaInfo.getEncoder()); + videoVO.setVideoFrameRate(videoMetaInfo.getFrameRate()); + videoVO.setConvertStatus(ConvertStatusEnum.UN_CONVERTED.getValue()); MusicMetaInfo musicMetaInfo = videoMetaInfo.getMusicMetaInfo(); if (musicMetaInfo != null) { @@ -86,9 +199,84 @@ public class VideoServiceImpl extends DefaultBaseService implements IVideoServic videoVO.setAudioBitRate(musicMetaInfo.getBitRate()); videoVO.setAudioSampleRate(musicMetaInfo.getSampleRate()); } - String fileId = save(token, videoVO); - // 转码 - return fileId; + return save(token, videoVO); + } + + @Override + public SseEmitter getConvertProgress() { + String threadId = String.valueOf(Thread.currentThread().getId()); + // 30分钟超时 + SseEmitter sseEmitter = new SseEmitter(1800000L); + sseEmitter.onTimeout(() -> { + VideoConvertManager.getInstance().removeConvertProgressSseEmitter(threadId); + }); + sseEmitter.onCompletion(() -> { + }); + sseEmitter.onError(throwable -> { + throwable.printStackTrace(); + }); + VideoConvertManager.getInstance().addConvertProgressSseEmitter(threadId, sseEmitter); + return sseEmitter; + } + + @Override + public VideoDTO get(Map params) { + return videoDao.get(params); + } + + @Override + public VideoDTO get(String fileId) { + Map params = getHashMap(2); + params.put("fileId", fileId); + return get(params); + } + + @Override + public VideoDTO getByMd5(String fileMd5) { + Map params = getHashMap(2); + params.put("fileMd5", fileMd5); + return get(params); + } + + @Override + public List list(Map params) { + return videoDao.list(params); + } + + @Override + public SuccessResultList> listPage(ListPage page) { + PageHelper.startPage(page.getPage(), page.getRows()); + List videoDTOs = list(page.getParams()); + PageInfo pageInfo = new PageInfo<>(videoDTOs); + return new SuccessResultList<>(videoDTOs, pageInfo.getPageNum(), pageInfo.getTotal()); + } + + /** + * 检查转换中状态 + */ + private void checkConverting(List videoDTOs) { + for (VideoDTO videoDTO : videoDTOs) { + if (StringUtils.equals(ConvertStatusEnum.CONVERTING.getValue(), videoDTO.getConvertStatus())) { + throw new SearchException("存在转码中的视频,删除失败"); + } + } + } + + /** + * 删除源文件 + * + * @param sourceFilePath 源文件路径 + */ + private void deleteSourceFile(String sourceFilePath) { + File file = new File(sourceFilePath); + if (file.exists()) { + boolean isDelete = file.delete(); + if (isDelete) { + LOG.debug("源文件删除成功"); + } else { + LOG.debug("源文件删除失败"); + } + } } } diff --git a/module-file-media/src/main/java/ink/wgink/module/file/media/task/transcoding/VideoConvertManager.java b/module-file-media/src/main/java/ink/wgink/module/file/media/task/transcoding/VideoConvertManager.java new file mode 100644 index 00000000..fe2e2676 --- /dev/null +++ b/module-file-media/src/main/java/ink/wgink/module/file/media/task/transcoding/VideoConvertManager.java @@ -0,0 +1,62 @@ +package ink.wgink.module.file.media.task.transcoding; + +import ink.wgink.module.file.media.pojo.dtos.ConvertProgressDTO; +import ink.wgink.module.file.media.task.transcoding.runnable.VideoConvertRunnable; +import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; + +import java.util.Map; +import java.util.concurrent.*; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: VideoTransCodingManager + * @Description: 视频转码 + * @Author: wanggeng + * @Date: 2021/6/10 9:46 上午 + * @Version: 1.0 + */ +public class VideoConvertManager { + + private static VideoConvertManager VIDEO_TRANS_CODING_MANAGER = VideoTransCodingManagerBuilder.videoConvertManager; + private ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 10, 30L, TimeUnit.SECONDS, new LinkedBlockingDeque<>()); + private Map convertProgressSseEmitterMap = new ConcurrentHashMap<>(); + + private VideoConvertManager() { + } + + public static VideoConvertManager getInstance() { + return VIDEO_TRANS_CODING_MANAGER; + } + + public void convert(VideoConvertRunnable videoConvertRunnable) { + threadPoolExecutor.execute(videoConvertRunnable); + } + + public void addConvertProgressSseEmitter(String threadId, SseEmitter sseEmitter) { + convertProgressSseEmitterMap.put(threadId, sseEmitter); + } + + public void removeConvertProgressSseEmitter(String threadId) { + convertProgressSseEmitterMap.remove(threadId); + } + + public void convertProgressSseEmitterNotice(String fileId, Double percent) { + ConvertProgressDTO convertProgressDTO = new ConvertProgressDTO(); + convertProgressDTO.setFileId(fileId); + convertProgressDTO.setPercent(percent); + try { + for (Map.Entry kv : convertProgressSseEmitterMap.entrySet()) { + kv.getValue().send(convertProgressDTO); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + private static class VideoTransCodingManagerBuilder { + public static VideoConvertManager videoConvertManager = new VideoConvertManager(); + } + +} diff --git a/module-file-media/src/main/java/ink/wgink/module/file/media/task/transcoding/VideoTransCodingManager.java b/module-file-media/src/main/java/ink/wgink/module/file/media/task/transcoding/VideoTransCodingManager.java deleted file mode 100644 index 4cd3dbb0..00000000 --- a/module-file-media/src/main/java/ink/wgink/module/file/media/task/transcoding/VideoTransCodingManager.java +++ /dev/null @@ -1,31 +0,0 @@ -package ink.wgink.module.file.media.task.transcoding; - -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingDeque; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; - -/** - * When you feel like quitting. Think about why you started - * 当你想要放弃的时候,想想当初你为何开始 - * - * @ClassName: VideoTransCodingManager - * @Description: 视频转码 - * @Author: wanggeng - * @Date: 2021/6/10 9:46 上午 - * @Version: 1.0 - */ -public class VideoTransCodingManager { - - private static VideoTransCodingManager VIDEO_TRANS_CODING_MANAGER = VideoTransCodingManagerBuilder.videoTransCodingManager; - private ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 10, 30L, TimeUnit.SECONDS, new LinkedBlockingDeque<>()); - - private VideoTransCodingManager() {} - - - - private static class VideoTransCodingManagerBuilder { - public static VideoTransCodingManager videoTransCodingManager = new VideoTransCodingManager(); - } - -} diff --git a/module-file-media/src/main/java/ink/wgink/module/file/media/task/transcoding/runnable/VideoConvertRunnable.java b/module-file-media/src/main/java/ink/wgink/module/file/media/task/transcoding/runnable/VideoConvertRunnable.java new file mode 100644 index 00000000..5b86524c --- /dev/null +++ b/module-file-media/src/main/java/ink/wgink/module/file/media/task/transcoding/runnable/VideoConvertRunnable.java @@ -0,0 +1,126 @@ +package ink.wgink.module.file.media.task.transcoding.runnable; + +import ink.wgink.module.file.media.manager.MediaManager; +import ink.wgink.module.file.media.manager.domain.enums.CrfValueEnum; +import ink.wgink.module.file.media.manager.domain.enums.PresetVauleEnum; +import ink.wgink.module.file.media.manager.process.IMediaStream; +import ink.wgink.module.file.media.service.video.IVideoService; +import ink.wgink.module.file.media.task.transcoding.VideoConvertManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.BufferedReader; +import java.io.File; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * When you feel like quitting. Think about why you started + * 当你想要放弃的时候,想想当初你为何开始 + * + * @ClassName: VideoTransCodingRunnable + * @Description: 视频转码 + * @Author: wanggeng + * @Date: 2021/6/10 10:04 上午 + * @Version: 1.0 + */ +public class VideoConvertRunnable implements Runnable { + private static final Logger LOG = LoggerFactory.getLogger(VideoConvertRunnable.class); + private static Pattern durationPattern = Pattern.compile("Duration: \\d{2}:\\d{2}:\\d{2}"); + private static Pattern timePattern = Pattern.compile("time=\\d{2}:\\d{2}:\\d{2}"); + + private long fullTime = 0L; + private long currentTime = 0L; + private double convertPercent = 0D; + private boolean isUpdateConvertStatus = false; + private File outFile; + + private String fileId; + private String sourceFile; + private IVideoService videoService; + + public VideoConvertRunnable() { + } + + public VideoConvertRunnable(String fileId, String sourceFile, IVideoService videoService) { + this.fileId = fileId; + this.sourceFile = sourceFile; + this.videoService = videoService; + } + + @Override + public void run() { + File sourceFile = new File(this.sourceFile); + outFile = new File(this.sourceFile + ".mp4"); + MediaManager.getInstance().convertVideo(sourceFile, outFile, true, CrfValueEnum.HIGH_QUALITY.getCode(), PresetVauleEnum.MAX_FAST_ZIP_SPEED.getPresetValue(), null, null, new IMediaStream() { + @Override + public void input(InputStream inputStream) throws Exception { + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); + for (String line; (line = bufferedReader.readLine()) != null; ) { + LOG.debug(line); + } + } + + @Override + public void error(InputStream errorStream) throws Exception { + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(errorStream)); + for (String line; (line = bufferedReader.readLine()) != null; ) { + Matcher durationMatcher = durationPattern.matcher(line); + Matcher timeMatcher = timePattern.matcher(line); + if (durationMatcher.find()) { + String duration = durationMatcher.group(); + LOG.debug("开始转码,时长:{}", duration); + String durationTime = duration.replace("Duration: ", ""); + fullTime = durationToLongTime(durationTime); + } + if (timeMatcher.find()) { + String time = timeMatcher.group(); + String timeTime = time.replace("time=", ""); + currentTime = durationToLongTime(timeTime); + } + if (fullTime > 0L) { + convertPercent = new BigDecimal((currentTime / (fullTime * 1D) * 100D)).setScale(2, RoundingMode.HALF_UP).doubleValue(); + } + if (convertPercent > 0D && convertPercent < 100D && (int) convertPercent % 5 == 0) { + VideoConvertManager.getInstance().convertProgressSseEmitterNotice(fileId, convertPercent); + } + if (convertPercent >= 100D) { + updateConvertStatus(); + } + } + } + }); + } + + /** + * 更新转换状态 + */ + private void updateConvertStatus() { + if (isUpdateConvertStatus) { + return; + } + VideoConvertManager.getInstance().convertProgressSseEmitterNotice(fileId, convertPercent); + isUpdateConvertStatus = true; + LOG.debug("转码结束,更新状态"); + videoService.updateConvert(fileId, outFile); + } + + /** + * 视频时长 + * + * @param duration + * @return + */ + private long durationToLongTime(String duration) { + String[] durationArray = duration.split("\\:"); + int hour = Integer.parseInt(durationArray[0]); + int minute = Integer.parseInt(durationArray[1]); + int second = Integer.parseInt(durationArray[2]); + return (hour * 3600 + minute * 60 + second); + } + +} diff --git a/module-file-media/src/main/java/ink/wgink/module/file/media/task/transcoding/runnable/VideoTransCodingRunnable.java b/module-file-media/src/main/java/ink/wgink/module/file/media/task/transcoding/runnable/VideoTransCodingRunnable.java deleted file mode 100644 index 3efed090..00000000 --- a/module-file-media/src/main/java/ink/wgink/module/file/media/task/transcoding/runnable/VideoTransCodingRunnable.java +++ /dev/null @@ -1,53 +0,0 @@ -package ink.wgink.module.file.media.task.transcoding.runnable; - -import ink.wgink.module.file.media.manager.MediaManager; -import ink.wgink.module.file.media.manager.domain.enums.CrfValueEnum; -import ink.wgink.module.file.media.manager.domain.enums.PresetVauleEnum; -import ink.wgink.module.file.media.manager.process.IMediaStream; -import ink.wgink.module.file.media.service.video.IVideoService; - -import java.io.BufferedReader; -import java.io.File; -import java.io.InputStream; -import java.io.InputStreamReader; - -/** - * When you feel like quitting. Think about why you started - * 当你想要放弃的时候,想想当初你为何开始 - * - * @ClassName: VideoTransCodingRunnable - * @Description: 视频转码 - * @Author: wanggeng - * @Date: 2021/6/10 10:04 上午 - * @Version: 1.0 - */ -public class VideoTransCodingRunnable implements Runnable { - - private String sourcePath; - private String sourceName; - private IVideoService videoService; - - @Override - public void run() { - File sourceFile = new File(sourcePath + File.separator + sourceName); - File outFile = new File(sourcePath + File.separator + sourceName + ".mp4"); - MediaManager.getInstance().convertVideo(sourceFile, outFile, true, CrfValueEnum.HIGH_QUALITY.getCode(), PresetVauleEnum.MAX_FAST_ZIP_SPEED.getPresetValue(), null, null, new IMediaStream() { - @Override - public void input(InputStream inputStream) throws Exception { - BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); - for (String line; (line = bufferedReader.readLine()) != null; ) { - System.out.println("input-" + line); - } - } - - @Override - public void error(InputStream errorStream) throws Exception { - BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(errorStream)); - for (String line; (line = bufferedReader.readLine()) != null; ) { - System.out.println("error-" + line); - } - } - }); - } - -} diff --git a/module-file-media/src/main/resources/mybatis/mapper/media-video-mapper.xml b/module-file-media/src/main/resources/mybatis/mapper/media-video-mapper.xml new file mode 100644 index 00000000..eb12ea82 --- /dev/null +++ b/module-file-media/src/main/resources/mybatis/mapper/media-video-mapper.xml @@ -0,0 +1,298 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CREATE TABLE IF NOT EXISTS `media_video` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `file_id` char(36) NOT NULL COMMENT '主键', + `file_name` varchar(255) DEFAULT NULL COMMENT '名称', + `file_full_path` varchar(500) DEFAULT NULL COMMENT '全路径', + `file_path` varchar(255) DEFAULT NULL COMMENT '路径', + `file_size` varchar(100) DEFAULT NULL COMMENT '大小', + `file_type` varchar(255) DEFAULT NULL COMMENT '类型', + `file_md5` varchar(255) DEFAULT NULL COMMENT 'MD5', + `file_summary` varchar(255) DEFAULT NULL COMMENT '备注', + `video_duration` varchar(255) DEFAULT NULL COMMENT '时长', + `video_width` int(11) DEFAULT NULL COMMENT '宽度', + `video_height` int(11) DEFAULT NULL COMMENT '高度', + `video_bit_rate` int(11) DEFAULT NULL COMMENT '比特率', + `video_encoder` varchar(255) DEFAULT NULL COMMENT '编码', + `video_frame_rate` int(11) DEFAULT NULL COMMENT '帧率', + `audio_duration` varchar(255) DEFAULT NULL COMMENT '音频时长', + `audio_bit_rate` int(11) DEFAULT NULL COMMENT '音频比特率', + `audio_sample_rate` int(11) DEFAULT NULL COMMENT '音频采样率', + `convert_status` varchar(255) DEFAULT 'unConverted' COMMENT '转码状态', + `is_back` int(1) DEFAULT '0' COMMENT '是否备份', + `static_url` varchar(500) DEFAULT NULL COMMENT '静态url', + `creator` char(36) DEFAULT NULL COMMENT '创建人', + `gmt_create` datetime DEFAULT NULL COMMENT '创建时间', + `modifier` char(36) DEFAULT NULL COMMENT '修改人', + `gmt_modified` datetime DEFAULT NULL COMMENT '修改时间', + `is_delete` int(1) DEFAULT '0', + PRIMARY KEY (`id`,`file_id`) USING BTREE, + UNIQUE KEY `file_id` (`file_id`) USING BTREE + ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + + + + + INSERT INTO media_video( + file_id, + file_name, + file_full_path, + file_path, + file_size, + file_type, + file_md5, + file_summary, + video_duration, + video_width, + video_height, + video_bit_rate, + video_encoder, + video_frame_rate, + audio_duration, + audio_bit_rate, + audio_sample_rate, + convert_status, + is_back, + static_url, + creator, + gmt_create, + modifier, + gmt_modified, + is_delete + ) VALUES( + #{fileId}, + #{fileName}, + #{fileFullPath}, + #{filePath}, + #{fileSize}, + #{fileType}, + #{fileMd5}, + #{fileSummary}, + #{videoDuration}, + #{videoWidth}, + #{videoHeight}, + #{videoBitRate}, + #{videoEncoder}, + #{videoFrameRate}, + #{audioDuration}, + #{audioBitRate}, + #{audioSampleRate}, + #{convertStatus}, + #{isBack}, + #{staticUrl}, + #{creator}, + #{gmtCreate}, + #{modifier}, + #{gmtModified}, + #{isDelete} + ) + + + + + UPDATE + media_video + SET + is_delete = 1, + modifier = #{modifier}, + gmt_modified = #{gmtModified} + WHERE + file_id IN + + #{fileIds[${index}]} + + + + + + DELETE FROM + media_video + WHERE + file_id IN + + #{fileIds[${index}]} + + + + + + UPDATE + media_video + SET + + file_full_path = #{fileFullPath}, + + + file_path = #{filePath}, + + + file_size = #{fileSize}, + + + file_type = #{fileType}, + + + video_duration = #{videoDuration}, + + + video_width = #{videoWidth}, + + + video_height = #{videoHeight}, + + + video_bit_rate = #{videoBitRate}, + + + video_encoder = #{videoEncoder}, + + + video_frame_rate = #{videoFrameRate}, + + + audio_duration = #{audioDuration}, + + + audio_bit_rate = #{audioBitRate}, + + + audio_sample_rate = #{audioSampleRate}, + + + convert_status = #{convertStatus}, + + modifier = #{modifier}, + gmt_modified = #{gmtModified} + WHERE + file_id = #{fileId} + + + + + UPDATE + media_video + SET + convert_status = #{convertStatus}, + modifier = #{modifier}, + gmt_modified = #{gmtModified} + WHERE + file_id = #{fileId} + + + + + + + + + \ No newline at end of file diff --git a/module-file-media/src/main/resources/templates/file/media/video/list.html b/module-file-media/src/main/resources/templates/file/media/video/list.html new file mode 100644 index 00000000..1bcc4557 --- /dev/null +++ b/module-file-media/src/main/resources/templates/file/media/video/list.html @@ -0,0 +1,390 @@ + + + + + + + + + + + + + +
+
+
+
+
+
+
+ +
+
+ +
+
+ +
+ +
+
+ + +
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/module-file-media/src/main/resources/templates/file/media/video/upload.html b/module-file-media/src/main/resources/templates/file/media/video/upload.html new file mode 100644 index 00000000..898db1a3 --- /dev/null +++ b/module-file-media/src/main/resources/templates/file/media/video/upload.html @@ -0,0 +1,75 @@ + + + + + + + + + + + +
+
+
+ +
+
+
+ + + + + + + + + \ No newline at end of file