feat(material): remove video cover extraction and simplify upload API
- Remove extractVideoCoverOptional function and related video cover processing - Update MaterialService.uploadFile method signature to remove coverBase64 parameter - Simplify uploadAndIdentifyVideo function by removing cover generation logic - Remove loading indicator from VideoSelector component during video preview - Add presignGetUrlWithProcess method to FileClient interface for processed file URLs - Add logging support to S3FileClient implementation
This commit is contained in:
@@ -52,6 +52,19 @@ public interface FileApi {
|
||||
String presignGetUrl(@NotEmpty(message = "URL 不能为空") String url,
|
||||
Integer expirationSeconds);
|
||||
|
||||
/**
|
||||
* 生成文件预签名地址(带 OSS 处理参数),用于读取
|
||||
* 用于阿里云 OSS 视频截帧等图片处理场景
|
||||
*
|
||||
* @param url 完整的文件访问地址
|
||||
* @param expirationSeconds 访问有效期,单位秒
|
||||
* @param processParam OSS 处理参数,如 "video/snapshot,t_1000,f_jpg,w_300"
|
||||
* @return 文件预签名地址
|
||||
*/
|
||||
String presignGetUrlWithProcess(@NotEmpty(message = "URL 不能为空") String url,
|
||||
Integer expirationSeconds,
|
||||
String processParam);
|
||||
|
||||
/**
|
||||
* 获取主文件配置的自定义域名(CDN域名)
|
||||
*
|
||||
|
||||
@@ -34,6 +34,11 @@ public class FileApiImpl implements FileApi {
|
||||
return fileService.presignGetUrl(url, expirationSeconds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String presignGetUrlWithProcess(String url, Integer expirationSeconds, String processParam) {
|
||||
return fileService.presignGetUrlWithProcess(url, expirationSeconds, processParam);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMasterFileDomain() {
|
||||
FileClient client = fileConfigService.getMasterFileClient();
|
||||
|
||||
@@ -74,6 +74,24 @@ public interface FileClient {
|
||||
throw new UnsupportedOperationException("不支持的操作");
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成文件预签名地址(带 OSS 处理参数),用于读取
|
||||
*
|
||||
* <p>用于阿里云 OSS 视频截帧、图片处理等场景。
|
||||
* 将处理参数包含在签名中,避免私有桶访问时返回 403。
|
||||
*
|
||||
* <p><b>注意</b>:此方法仅阿里云 OSS 支持,其他云厂商会忽略 processParam 参数。
|
||||
*
|
||||
* @param url 完整的文件访问地址
|
||||
* @param expirationSeconds 访问有效期,单位秒
|
||||
* @param processParam OSS 处理参数,如 "video/snapshot,t_1000,f_jpg,w_300"
|
||||
* 参考:https://help.aliyun.com/document_detail/99285.html
|
||||
* @return 文件预签名地址(处理参数已包含在签名中)
|
||||
*/
|
||||
default String presignGetUrlWithProcess(String url, Integer expirationSeconds, String processParam) {
|
||||
throw new UnsupportedOperationException("不支持的操作");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件配置
|
||||
*
|
||||
|
||||
@@ -34,11 +34,14 @@ import java.util.Date;
|
||||
|
||||
import org.springframework.web.util.UriUtils;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* 基于 S3 协议的文件客户端,实现 MinIO、阿里云、腾讯云、七牛云、华为云等云服务
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Slf4j
|
||||
public class S3FileClient extends AbstractFileClient<S3FileClientConfig> {
|
||||
|
||||
private static final Duration EXPIRATION_DEFAULT = Duration.ofHours(24);
|
||||
@@ -198,24 +201,44 @@ public class S3FileClient extends AbstractFileClient<S3FileClientConfig> {
|
||||
|
||||
@Override
|
||||
public String presignGetUrl(String url, Integer expirationSeconds) {
|
||||
return presignGetUrlWithProcess(url, expirationSeconds, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String presignGetUrlWithProcess(String url, Integer expirationSeconds, String processParam) {
|
||||
// 1. 将 url 转换为 path(支持 CDN 域名和 OSS 原始域名)
|
||||
String path = extractPathFromUrl(url);
|
||||
String decodedPath = URLUtil.decode(path, StandardCharsets.UTF_8);
|
||||
|
||||
// 2. 公开访问:无需签名
|
||||
// 2. 公开访问:无需签名,直接拼接参数
|
||||
if (!BooleanUtil.isFalse(config.getEnablePublicAccess())) {
|
||||
String encodedPath = UriUtils.encodePath(decodedPath, StandardCharsets.UTF_8);
|
||||
return config.getDomain() + "/" + encodedPath;
|
||||
String resultUrl = config.getDomain() + "/" + encodedPath;
|
||||
if (StrUtil.isNotBlank(processParam)) {
|
||||
resultUrl = resultUrl + "?x-oss-process=" + processParam;
|
||||
}
|
||||
return resultUrl;
|
||||
}
|
||||
|
||||
// 3. 私有访问:生成预签名 URL
|
||||
// 3. 私有访问:生成预签名 URL(需要将处理参数包含在签名中)
|
||||
int expiration = expirationSeconds != null ? expirationSeconds : (int) EXPIRATION_DEFAULT.getSeconds();
|
||||
|
||||
String signedUrl;
|
||||
if (isAliyun) {
|
||||
Date expirationDate = new Date(System.currentTimeMillis() + expiration * 1000L);
|
||||
signedUrl = aliyunOssClient.generatePresignedUrl(config.getBucket(), decodedPath, expirationDate).toString();
|
||||
com.aliyun.oss.model.GeneratePresignedUrlRequest request =
|
||||
new com.aliyun.oss.model.GeneratePresignedUrlRequest(config.getBucket(), decodedPath, HttpMethod.GET);
|
||||
request.setExpiration(expirationDate);
|
||||
// 关键:将 x-oss-process 参数包含在签名中
|
||||
if (StrUtil.isNotBlank(processParam)) {
|
||||
request.addQueryParameter("x-oss-process", processParam);
|
||||
}
|
||||
signedUrl = aliyunOssClient.generatePresignedUrl(request).toString();
|
||||
} else {
|
||||
// 非阿里云不支持 OSS 处理参数,直接返回普通预签名 URL
|
||||
if (StrUtil.isNotBlank(processParam)) {
|
||||
log.warn("[presignGetUrlWithProcess] 非阿里云 OSS 不支持处理参数,已忽略。processParam={}", processParam);
|
||||
}
|
||||
Duration duration = Duration.ofSeconds(expiration);
|
||||
signedUrl = s3Presigner.presignGetObject(GetObjectPresignRequest.builder()
|
||||
.signatureDuration(duration)
|
||||
|
||||
@@ -54,6 +54,17 @@ public interface FileService {
|
||||
*/
|
||||
String presignGetUrl(String url, Integer expirationSeconds);
|
||||
|
||||
/**
|
||||
* 生成文件预签名地址(带 OSS 处理参数),用于读取
|
||||
* 用于阿里云 OSS 视频截帧等图片处理场景
|
||||
*
|
||||
* @param url 完整的文件访问地址
|
||||
* @param expirationSeconds 访问有效期,单位秒
|
||||
* @param processParam OSS 处理参数,如 "video/snapshot,t_1000,f_jpg,w_300"
|
||||
* @return 文件预签名地址
|
||||
*/
|
||||
String presignGetUrlWithProcess(String url, Integer expirationSeconds, String processParam);
|
||||
|
||||
/**
|
||||
* 创建文件
|
||||
*
|
||||
|
||||
@@ -146,6 +146,12 @@ public class FileServiceImpl implements FileService {
|
||||
return fileClient.presignGetUrl(url, expirationSeconds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String presignGetUrlWithProcess(String url, Integer expirationSeconds, String processParam) {
|
||||
FileClient fileClient = fileConfigService.getMasterFileClient();
|
||||
return fileClient.presignGetUrlWithProcess(url, expirationSeconds, processParam);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long createFile(FileCreateReqVO createReqVO) {
|
||||
createReqVO.setUrl(HttpUtils.removeUrlQuery(createReqVO.getUrl())); // 目的:移除私有桶情况下,URL 的签名参数
|
||||
|
||||
Reference in New Issue
Block a user