|
|
@@ -1,10 +1,14 @@
|
|
|
package com.fs.course.service.impl;
|
|
|
|
|
|
+import java.io.File;
|
|
|
import java.io.IOException;
|
|
|
import java.io.InputStream;
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
import java.util.*;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
import com.fs.common.core.domain.R;
|
|
|
import com.fs.common.utils.DateUtils;
|
|
|
import com.fs.common.utils.StringUtils;
|
|
|
@@ -20,11 +24,20 @@ import com.fs.course.vo.FsUserVideoPVO;
|
|
|
import com.fs.course.param.FsUserVideoParam;
|
|
|
import com.fs.course.vo.FsUserVideoListUVO;
|
|
|
|
|
|
+import com.volcengine.helper.VodUploadProgressListener;
|
|
|
+import com.volcengine.model.beans.Functions;
|
|
|
+import com.volcengine.service.vod.IVodService;
|
|
|
+import com.volcengine.service.vod.model.request.VodGetMediaInfosRequest;
|
|
|
+import com.volcengine.service.vod.model.request.VodUploadMediaRequest;
|
|
|
+import com.volcengine.service.vod.model.response.VodCommitUploadInfoResponse;
|
|
|
+import com.volcengine.service.vod.model.response.VodGetMediaInfosResponse;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.data.redis.core.RedisTemplate;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import com.fs.course.domain.FsUserVideo;
|
|
|
import com.fs.course.service.IFsUserVideoService;
|
|
|
+import org.springframework.web.multipart.MultipartFile;
|
|
|
|
|
|
/**
|
|
|
* 课堂视频Service业务层处理
|
|
|
@@ -32,6 +45,7 @@ import com.fs.course.service.IFsUserVideoService;
|
|
|
* @author fs
|
|
|
* @date 2024-05-15
|
|
|
*/
|
|
|
+@Slf4j
|
|
|
@Service
|
|
|
public class FsUserVideoServiceImpl implements IFsUserVideoService {
|
|
|
@Autowired
|
|
|
@@ -46,6 +60,9 @@ public class FsUserVideoServiceImpl implements IFsUserVideoService {
|
|
|
private IRecommendationService recommendationService;
|
|
|
@Autowired
|
|
|
private RedisTemplate redisTemplate;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IVodService vodService;
|
|
|
private static final String LIKE_KEY_PREFIX = "like:video:";
|
|
|
private static final String FAVORITE_KEY_PREFIX = "favorite:video:";
|
|
|
|
|
|
@@ -444,5 +461,110 @@ public class FsUserVideoServiceImpl implements IFsUserVideoService {
|
|
|
return url;
|
|
|
}
|
|
|
|
|
|
+ //本地文件视频上传
|
|
|
+ @Override
|
|
|
+ public String uploadVideo(MultipartFile file, String uploadId) {
|
|
|
+ log.info("上传视频开始",uploadId);
|
|
|
+ File tempFile = null;
|
|
|
+ try {
|
|
|
+ // 将 MultipartFile 转换为临时文件
|
|
|
+ String originalFilename = file.getOriginalFilename();
|
|
|
+ String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
|
|
|
+ tempFile = File.createTempFile("upload_", suffix);
|
|
|
+ file.transferTo(tempFile);
|
|
|
+
|
|
|
+ // 点播空间名称
|
|
|
+ String space = "rt-huoshan";
|
|
|
+ // 本地临时文件路径(用于上传)
|
|
|
+ String localFilePath = tempFile.getAbsolutePath();
|
|
|
+
|
|
|
+ // 火山云存储路径(文件上传后在火山云的路径)
|
|
|
+ String datePath = new SimpleDateFormat("yyyyMMdd").format(new Date());
|
|
|
+ String fileName = System.currentTimeMillis() + ".mp4";
|
|
|
+ String remoteFileName = "course/" + datePath + "/" + fileName;
|
|
|
+
|
|
|
+ // 上传功能函数,可用于实现截图、设置媒资信息、触发工作流进行转码等功能。详见[上传功能函数说明](https://www.volcengine.com/docs/4/1185644)
|
|
|
+ List<Functions> functionsList = new ArrayList<>();
|
|
|
+ Functions getMetaFunc = Functions.GetMetaFunction();
|
|
|
+ functionsList.add(getMetaFunc);
|
|
|
+ Functions snapShotFunc = Functions.SnapShotFunction(2.3);
|
|
|
+ functionsList.add(snapShotFunc);
|
|
|
+ Functions addOptionInfo = Functions.AddOptionInfoFunction(fileName, "test", "用户上传视频", 0, true);
|
|
|
+ functionsList.add(addOptionInfo);
|
|
|
+
|
|
|
+ // 使用工作流进行转码
|
|
|
+
|
|
|
+ List<String> impTemplateIds = new ArrayList<>();
|
|
|
+// impTemplateIds.add("a4a7066c968344e9bf7a56ec0891fbb8");
|
|
|
+// FunctionsWorkflowTemplate impTemplate = new FunctionsWorkflowTemplate(impTemplateIds, "imp");
|
|
|
+//
|
|
|
+// List<String> transcodeTemplateIds = new ArrayList<>();
|
|
|
+// transcodeTemplateIds.add("a4a7066c968344e9bf7a56ec0891fbb8");
|
|
|
+// FunctionsWorkflowTemplate transcodeTemplate = new FunctionsWorkflowTemplate(transcodeTemplateIds,
|
|
|
+// "transcode");
|
|
|
+
|
|
|
+// List<FunctionsWorkflowTemplate> templates = new ArrayList<>();
|
|
|
+// templates.add(impTemplate);
|
|
|
+// templates.add(transcodeTemplate);
|
|
|
+
|
|
|
+// Functions workflowFunc = Functions.StartWorkFlowFunction(templates);
|
|
|
+// functionsList.add(workflowFunc);
|
|
|
+
|
|
|
+ VodUploadMediaRequest vodUploadMediaRequest = VodUploadMediaRequest.newBuilder()
|
|
|
+ .setSpaceName(space)
|
|
|
+ .setFilePath(localFilePath) // 使用本地临时文件路径
|
|
|
+ .setFileName(remoteFileName) // 火山云存储路径
|
|
|
+ .setFunctions(JSON.toJSONString(functionsList))
|
|
|
+ .setStorageClass(1)
|
|
|
+ .build();
|
|
|
+
|
|
|
+ // 需要进度条功能时添加相应 listener,如无需求,传 null 值即可
|
|
|
+ VodUploadProgressListener listener = new VodUploadMediaProcessListener(uploadId, redisTemplate);
|
|
|
+
|
|
|
+ VodCommitUploadInfoResponse vodCommitUploadInfoResponse = vodService.uploadMedia(vodUploadMediaRequest, listener);
|
|
|
+
|
|
|
+ redisTemplate.opsForValue()
|
|
|
+ .set("vod:upload:" + uploadId, 100, 10, TimeUnit.MINUTES);
|
|
|
+
|
|
|
+ if (vodCommitUploadInfoResponse.getResponseMetadata().hasError()) {
|
|
|
+ throw new RuntimeException("火山云上传失败: " + vodCommitUploadInfoResponse.getResponseMetadata().getError());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 返回视频 VID
|
|
|
+ String vid = vodCommitUploadInfoResponse.getResult().getData().getVid();
|
|
|
+ System.out.println("视频上传成功,VID: " + vid);
|
|
|
+ System.out.println("RequestId: " + vodCommitUploadInfoResponse.getResponseMetadata().getRequestId());
|
|
|
+
|
|
|
+ return vid;
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new RuntimeException("视频上传失败: " + e.getMessage(), e);
|
|
|
+ } finally {
|
|
|
+ // 删除临时文件
|
|
|
+ if (tempFile != null && tempFile.exists()) {
|
|
|
+ tempFile.delete();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //根据vid查询视频信息
|
|
|
+ @Override
|
|
|
+ public String getVideoInfoByVid(String vid) {
|
|
|
+ try {
|
|
|
+ VodGetMediaInfosRequest.Builder reqBuilder = VodGetMediaInfosRequest.newBuilder();
|
|
|
+ reqBuilder.setVids("vid");
|
|
|
+
|
|
|
+ VodGetMediaInfosResponse resp = vodService.getMediaInfos20230701(reqBuilder.build());
|
|
|
+ if (resp.getResponseMetadata().hasError()) {
|
|
|
+ System.out.println(resp.getResponseMetadata().getError());
|
|
|
+ System.exit(-1);
|
|
|
+ }else {
|
|
|
+ return resp.getResult().getMediaInfoList(0).getSourceInfo().getStoreUri();
|
|
|
+ }
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
|
|
|
}
|