10dcc2b403
修复画布上传素材持久化回填和项目重进资源元数据恢复 修复图片、音频、视频图层的私有资源换签与视频裸路径回退 修复宣发素材切换模型后卡片尺寸变成1024x1024的问题 修复音视频预览、媒体导出格式、音频默认提示词和前端去背边界 修复角色动作生成在编辑器路径缺少ffprobe时的已知时长兜底 补充图片画布、资源换签、宣发尺寸、媒体导出和chromaKey回归测试 更新图片画布编辑器技术文档
101 lines
2.5 KiB
TypeScript
101 lines
2.5 KiB
TypeScript
import { useEffect, useState } from 'react';
|
|
|
|
import {
|
|
getSignedAssetReadUrl,
|
|
resolveAssetReadUrl,
|
|
shouldResolveAssetReadUrl,
|
|
} from '../services/assetReadUrlService';
|
|
|
|
type UseResolvedAssetReadUrlOptions = {
|
|
enabled?: boolean;
|
|
expireSeconds?: number;
|
|
objectKey?: string | null;
|
|
refreshKey?: string | number | null;
|
|
};
|
|
|
|
export function useResolvedAssetReadUrl(
|
|
source: string | null | undefined,
|
|
options: UseResolvedAssetReadUrlOptions = {},
|
|
) {
|
|
const enabled = options.enabled !== false;
|
|
const normalizedSource = source?.trim() ?? '';
|
|
const normalizedObjectKey = options.objectKey?.trim() ?? '';
|
|
const shouldResolve =
|
|
enabled &&
|
|
(Boolean(normalizedObjectKey) ||
|
|
shouldResolveAssetReadUrl(normalizedSource));
|
|
const [resolvedUrl, setResolvedUrl] = useState(
|
|
shouldResolve ? '' : normalizedSource,
|
|
);
|
|
const [isResolving, setIsResolving] = useState(shouldResolve);
|
|
|
|
useEffect(() => {
|
|
if (!normalizedSource && !normalizedObjectKey) {
|
|
setResolvedUrl('');
|
|
setIsResolving(false);
|
|
return;
|
|
}
|
|
|
|
if (!shouldResolve) {
|
|
setResolvedUrl(normalizedSource);
|
|
setIsResolving(false);
|
|
return;
|
|
}
|
|
|
|
let cancelled = false;
|
|
// 生成资源通常是 OSS 私有对象;签名 URL 未就绪前不能把裸 generated 路径交给 img 触发无鉴权 GET。
|
|
setResolvedUrl('');
|
|
setIsResolving(true);
|
|
|
|
const resolvePromise = normalizedObjectKey
|
|
? getSignedAssetReadUrl(
|
|
{
|
|
objectKey: normalizedObjectKey,
|
|
expireSeconds: options.expireSeconds,
|
|
},
|
|
undefined,
|
|
{
|
|
cacheVersion: options.refreshKey,
|
|
},
|
|
)
|
|
: resolveAssetReadUrl(normalizedSource, {
|
|
expireSeconds: options.expireSeconds,
|
|
refreshKey: options.refreshKey,
|
|
});
|
|
|
|
void resolvePromise
|
|
.then((nextUrl) => {
|
|
if (!cancelled) {
|
|
setResolvedUrl(nextUrl);
|
|
}
|
|
})
|
|
.catch(() => {
|
|
if (!cancelled) {
|
|
// 签名失败时保持空 src,避免继续请求无签名的私有对象兼容路径。
|
|
setResolvedUrl('');
|
|
}
|
|
})
|
|
.finally(() => {
|
|
if (!cancelled) {
|
|
setIsResolving(false);
|
|
}
|
|
});
|
|
|
|
return () => {
|
|
cancelled = true;
|
|
};
|
|
}, [
|
|
normalizedSource,
|
|
normalizedObjectKey,
|
|
options.expireSeconds,
|
|
options.refreshKey,
|
|
shouldResolve,
|
|
]);
|
|
|
|
return {
|
|
resolvedUrl,
|
|
isResolving,
|
|
shouldResolve,
|
|
};
|
|
}
|