Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3e3f7175d8 | |||
| 4750e67c55 | |||
| aa36e7ae62 |
@@ -0,0 +1,70 @@
|
||||
import { useCallback } from "react"
|
||||
import type { VoiceClone } from "@/api/voice-clone"
|
||||
|
||||
interface UseVoiceModeSelectionOptions {
|
||||
selectedVoice: string
|
||||
onSelectedVoiceChange: (voiceId: string) => void
|
||||
voiceMode: "preset" | "custom" | "clone"
|
||||
onVoiceModeChange: (mode: "preset" | "custom" | "clone") => void
|
||||
selectedClonedVoice: string
|
||||
onSelectedClonedVoiceChange: (voiceId: string) => void
|
||||
addClone: (voice: VoiceClone) => void
|
||||
cloneModalOpen: boolean
|
||||
onCloneModalOpenChange: (open: boolean) => void
|
||||
}
|
||||
|
||||
export function useVoiceModeSelection({
|
||||
onSelectedVoiceChange,
|
||||
onVoiceModeChange,
|
||||
onSelectedClonedVoiceChange,
|
||||
addClone,
|
||||
onCloneModalOpenChange,
|
||||
}: UseVoiceModeSelectionOptions) {
|
||||
const handleSelectRecommendedVoice = useCallback(
|
||||
(voiceId: string) => {
|
||||
onVoiceModeChange("preset")
|
||||
onSelectedVoiceChange(voiceId)
|
||||
},
|
||||
[onVoiceModeChange, onSelectedVoiceChange],
|
||||
)
|
||||
|
||||
const handleSelectPresetVoice = useCallback(
|
||||
(voiceId: string) => {
|
||||
onVoiceModeChange("preset")
|
||||
onSelectedVoiceChange(voiceId)
|
||||
},
|
||||
[onVoiceModeChange, onSelectedVoiceChange],
|
||||
)
|
||||
|
||||
const handleSelectCloneVoice = useCallback(() => {
|
||||
onVoiceModeChange("clone")
|
||||
}, [onVoiceModeChange])
|
||||
|
||||
const handleSelectClonedVoice = useCallback(
|
||||
(voiceId: string) => {
|
||||
onSelectedClonedVoiceChange(voiceId)
|
||||
},
|
||||
[onSelectedClonedVoiceChange],
|
||||
)
|
||||
|
||||
const handleOpenCloneModal = useCallback(() => {
|
||||
onCloneModalOpenChange(true)
|
||||
}, [onCloneModalOpenChange])
|
||||
|
||||
const handleCloneSuccess = useCallback(
|
||||
(voice: VoiceClone) => {
|
||||
addClone(voice)
|
||||
onCloneModalOpenChange(false)
|
||||
},
|
||||
[addClone, onCloneModalOpenChange],
|
||||
)
|
||||
|
||||
return {
|
||||
handleSelectRecommendedVoice,
|
||||
handleSelectPresetVoice,
|
||||
handleSelectCloneVoice,
|
||||
handleSelectClonedVoice,
|
||||
handleOpenCloneModal,
|
||||
handleCloneSuccess,
|
||||
}
|
||||
}
|
||||
Regular → Executable
+24
-43
@@ -2,15 +2,15 @@
|
||||
* Step 5 配音选择 Hook
|
||||
* 封装 AI 推荐、预设音色试听、TTS 自定义合成、存为素材等逻辑
|
||||
*/
|
||||
import { useCallback } from "react"
|
||||
import type { VoiceClone } from "@/api/voice-clone"
|
||||
import { message } from "antd"
|
||||
import type { VoiceClone } from "@/api/voice-clone"
|
||||
import { VOICE_GENDER_ICON, CLONE_STATUS_CONFIG } from "../constants"
|
||||
import { formatDuration } from "../utils/formatDuration"
|
||||
import { useVoiceAudio } from "./step5-voice/useVoiceAudio"
|
||||
import { useVoiceRecommend } from "./step5-voice/useVoiceRecommend"
|
||||
import { useTtsSynthesis } from "./step5-voice/useTtsSynthesis"
|
||||
import { useSaveToLibrary } from "./step5-voice/useSaveToLibrary"
|
||||
import { useVoiceModeSelection } from "./step5-voice/useVoiceModeSelection"
|
||||
|
||||
interface UseStep5VoiceProps {
|
||||
selectedVoice: string
|
||||
@@ -81,48 +81,29 @@ export function useStep5Voice({
|
||||
handleAddTagInModal,
|
||||
} = useSaveToLibrary(completedTtsJobId, resetTtsState)
|
||||
|
||||
/* ── 推荐音色选择 ── */
|
||||
const handleSelectRecommendedVoice = useCallback(
|
||||
(voiceId: string) => {
|
||||
onVoiceModeChange("preset")
|
||||
onSelectedVoiceChange(voiceId)
|
||||
},
|
||||
[onVoiceModeChange, onSelectedVoiceChange],
|
||||
)
|
||||
const {
|
||||
handleSelectRecommendedVoice,
|
||||
handleSelectPresetVoice,
|
||||
handleSelectCloneVoice,
|
||||
handleSelectClonedVoice,
|
||||
handleOpenCloneModal,
|
||||
handleCloneSuccess: rawCloneSuccess,
|
||||
} = useVoiceModeSelection({
|
||||
selectedVoice,
|
||||
onSelectedVoiceChange,
|
||||
voiceMode,
|
||||
onVoiceModeChange,
|
||||
selectedClonedVoice,
|
||||
onSelectedClonedVoiceChange,
|
||||
addClone,
|
||||
cloneModalOpen,
|
||||
onCloneModalOpenChange,
|
||||
})
|
||||
|
||||
/* ── 克隆成功回调 ── */
|
||||
const handleCloneSuccess = useCallback(
|
||||
(voice: VoiceClone) => {
|
||||
addClone(voice)
|
||||
onCloneModalOpenChange(false)
|
||||
message.success("音色克隆成功!")
|
||||
},
|
||||
[addClone, onCloneModalOpenChange],
|
||||
)
|
||||
|
||||
/* ── 预设音色选择操作 ── */
|
||||
const handleSelectPresetVoice = useCallback(
|
||||
(voiceId: string) => {
|
||||
onVoiceModeChange("preset")
|
||||
onSelectedVoiceChange(voiceId)
|
||||
},
|
||||
[onVoiceModeChange, onSelectedVoiceChange],
|
||||
)
|
||||
|
||||
const handleSelectCloneVoice = useCallback(() => {
|
||||
onVoiceModeChange("clone")
|
||||
}, [onVoiceModeChange])
|
||||
|
||||
const handleSelectClonedVoice = useCallback(
|
||||
(voiceId: string) => {
|
||||
onSelectedClonedVoiceChange(voiceId)
|
||||
},
|
||||
[onSelectedClonedVoiceChange],
|
||||
)
|
||||
|
||||
const handleOpenCloneModal = useCallback(() => {
|
||||
onCloneModalOpenChange(true)
|
||||
}, [onCloneModalOpenChange])
|
||||
const handleCloneSuccess = (voice: VoiceClone) => {
|
||||
rawCloneSuccess(voice)
|
||||
message.success("音色克隆成功!")
|
||||
}
|
||||
|
||||
return {
|
||||
// 数据
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
# ── 单轨时间计算 ──────────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
from packages.domain.speed_config import (
|
||||
DEFAULT_SPEED,
|
||||
SpeedConfig,
|
||||
|
||||
@@ -6,7 +6,6 @@ domain 层纯逻辑模块,0 FFmpeg 依赖,快速轻量。
|
||||
from __future__ import annotations
|
||||
|
||||
import dataclasses
|
||||
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
import pytest
|
||||
|
||||
@@ -4,7 +4,6 @@ from __future__ import annotations
|
||||
|
||||
import dataclasses
|
||||
|
||||
|
||||
import pytest
|
||||
|
||||
from packages.domain.transition_presets import (
|
||||
|
||||
Reference in New Issue
Block a user