fix(voice-clone): source_audio_url 不做预签名转换,原样返回用户输入
source_audio_url 是用户传入的原始参考音频 URL(可能是外部地址), 不是系统内部 OSS storage key,不应该经过 storage.get_download_url 做预签名转换。之前的代码会把外部 URL 错误地当作 OSS key 处理, 导致返回无效的签名 URL。 - 删除 _to_response 中的 sign_url 调用和参数 - 清理 4 个端点中不再使用的 get_audio_url_signer 依赖注入 - 33 个 voice_clone 集成测试全绿
This commit is contained in:
Executable → Regular
+8
-14
@@ -6,7 +6,7 @@ import logging
|
||||
from typing import Optional
|
||||
|
||||
from app.auth import AuthenticatedUser, get_current_user
|
||||
from app.dependencies import get_audio_url_signer, get_cosyvoice_service, get_voice_clone_profile_repository
|
||||
from app.dependencies import get_cosyvoice_service, get_voice_clone_profile_repository
|
||||
from app.schemas.voice_clone import (
|
||||
CreateVoiceCloneRequest,
|
||||
ListVoiceCloneResponse,
|
||||
@@ -37,16 +37,14 @@ logger = logging.getLogger(__name__)
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
def _to_response(profile, sign_url=None) -> VoiceCloneProfileResponse:
|
||||
source_url = profile.source_audio_url
|
||||
if sign_url and source_url:
|
||||
source_url = sign_url(source_url)
|
||||
def _to_response(profile) -> VoiceCloneProfileResponse:
|
||||
# source_audio_url 是用户传入的原始 URL(可能是外部地址),不做预签名转换
|
||||
return VoiceCloneProfileResponse(
|
||||
id=profile.id,
|
||||
user_id=profile.user_id,
|
||||
name=profile.name,
|
||||
description=profile.description,
|
||||
source_audio_url=source_url,
|
||||
source_audio_url=profile.source_audio_url,
|
||||
voice_id=profile.voice_id,
|
||||
voice_model=profile.voice_model,
|
||||
language=profile.language,
|
||||
@@ -77,7 +75,6 @@ def create_voice_clone(
|
||||
request: CreateVoiceCloneRequest,
|
||||
authenticated_user: AuthenticatedUser = Depends(get_current_user),
|
||||
workflow: VoiceCloneWorkflowService = Depends(_get_workflow_service),
|
||||
sign_url=Depends(get_audio_url_signer),
|
||||
) -> VoiceCloneProfileResponse:
|
||||
"""创建音色克隆任务。
|
||||
|
||||
@@ -113,7 +110,7 @@ def create_voice_clone(
|
||||
except Exception as inner_e:
|
||||
logger.error(f"Failed to mark profile as failed after dispatch error: {inner_e}")
|
||||
|
||||
return _to_response(profile, sign_url)
|
||||
return _to_response(profile)
|
||||
|
||||
|
||||
@router.get("", response_model=ListVoiceCloneResponse)
|
||||
@@ -123,14 +120,13 @@ def list_voice_clones(
|
||||
limit: int = Query(50, ge=1, le=200),
|
||||
authenticated_user: AuthenticatedUser = Depends(get_current_user),
|
||||
repository: SQLAlchemyVoiceCloneProfileRepository = Depends(get_voice_clone_profile_repository),
|
||||
sign_url=Depends(get_audio_url_signer),
|
||||
) -> ListVoiceCloneResponse:
|
||||
"""获取用户的音色克隆列表。"""
|
||||
user_id = authenticated_user.user.id
|
||||
use_case = ListVoiceClonesUseCase(repository)
|
||||
items, total = use_case.execute(user_id, status=status_filter, skip=skip, limit=limit)
|
||||
return ListVoiceCloneResponse(
|
||||
items=[_to_response(p, sign_url) for p in items],
|
||||
items=[_to_response(p) for p in items],
|
||||
total=total,
|
||||
)
|
||||
|
||||
@@ -140,7 +136,6 @@ def get_voice_clone(
|
||||
clone_id: str,
|
||||
authenticated_user: AuthenticatedUser = Depends(get_current_user),
|
||||
repository: SQLAlchemyVoiceCloneProfileRepository = Depends(get_voice_clone_profile_repository),
|
||||
sign_url=Depends(get_audio_url_signer),
|
||||
) -> VoiceCloneProfileResponse:
|
||||
"""获取音色克隆详情。"""
|
||||
user_id = authenticated_user.user.id
|
||||
@@ -149,7 +144,7 @@ def get_voice_clone(
|
||||
profile = use_case.execute(clone_id, user_id)
|
||||
except VoiceCloneNotFoundError:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Voice clone not found")
|
||||
return _to_response(profile, sign_url)
|
||||
return _to_response(profile)
|
||||
|
||||
|
||||
@router.get("/{clone_id}/status", response_model=VoiceCloneStatusResponse)
|
||||
@@ -198,7 +193,6 @@ def retry_voice_clone(
|
||||
clone_id: str,
|
||||
authenticated_user: AuthenticatedUser = Depends(get_current_user),
|
||||
workflow: VoiceCloneWorkflowService = Depends(_get_workflow_service),
|
||||
sign_url=Depends(get_audio_url_signer),
|
||||
) -> VoiceCloneProfileResponse:
|
||||
"""重试失败的音色克隆。
|
||||
|
||||
@@ -231,4 +225,4 @@ def retry_voice_clone(
|
||||
except Exception as inner_e:
|
||||
logger.error(f"Failed to mark profile as failed after dispatch error: {inner_e}")
|
||||
|
||||
return _to_response(profile, sign_url)
|
||||
return _to_response(profile)
|
||||
|
||||
Reference in New Issue
Block a user