fix: 移除配音选择时长过滤逻辑,所有配音素材完整显示 #1697

Merged
auto-approve-bot merged 3 commits from fix/remove-voice-duration-filter into develop 2026-09-04 21:08:41 +08:00
3 changed files with 1 additions and 38 deletions
@@ -16,10 +16,6 @@ import { useQuery } from "@tanstack/react-query"
import { useCloneProgress } from "@/hooks/useCloneProgress"
import CloneModal from "@/components/voice/CloneModal"
import GenerateHeader from "./components/GenerateHeader"
import {
calculateTotalVideoDuration,
estimateTotalVideoDuration,
} from "./utils/calculateTotalVideoDuration"
import FrontendPreviewPlayer from "./components/FrontendPreviewPlayer"
import GenerateStepsBar from "./components/GenerateStepsBar"
import GenerateStepContent from "./components/GenerateStepContent"
@@ -128,7 +124,6 @@ const GeneratePage: React.FC = () => {
cancelled = true
controller.abort()
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [selectedVoice, selectedClonedVoice, titleSettings.title, voiceMaterials])
/* ── 克隆声音 ── */
@@ -174,13 +169,6 @@ const GeneratePage: React.FC = () => {
[previewAssetsReady, currentTemplate],
)
/* ── 视频总时长计算 ── */
const totalVideoDuration = useMemo(() => {
const exact = calculateTotalVideoDuration(previewAssets, currentTemplate ?? undefined)
if (exact > 0) return exact
return estimateTotalVideoDuration(currentTemplate ?? undefined)
}, [previewAssets, currentTemplate])
/* ── 视频生成核心逻辑 ── */
const {
generating,
@@ -291,7 +279,6 @@ const GeneratePage: React.FC = () => {
onCoverSettingsChange={setCoverSettings}
selectedVoice={selectedVoice}
onSelectedVoiceChange={setSelectedVoice}
totalVideoDuration={totalVideoDuration}
onServerClipsChange={setServerClips}
voiceMode={voiceMode}
onVoiceModeChange={setVoiceMode}
@@ -49,7 +49,6 @@ export interface GenerateStepContentProps {
/* 配音 */
selectedVoice: string
onSelectedVoiceChange: (id: string) => void
totalVideoDuration?: number
onServerClipsChange: (clips: EditPlanClip[]) => void
voiceMode: "preset" | "custom" | "clone"
onVoiceModeChange: (mode: "preset" | "custom" | "clone") => void
@@ -104,7 +103,6 @@ export const GenerateStepContent: React.FC<GenerateStepContentProps> = (props) =
onCoverSettingsChange,
selectedVoice,
onSelectedVoiceChange,
totalVideoDuration,
onServerClipsChange,
voiceMode,
selectedClonedVoice,
@@ -151,7 +149,6 @@ export const GenerateStepContent: React.FC<GenerateStepContentProps> = (props) =
<Step3VoiceSelect
selectedVoice={selectedVoice}
onSelectedVoiceChange={onSelectedVoiceChange}
totalVideoDuration={totalVideoDuration}
/>
)
case 4:
@@ -1,7 +1,6 @@
/**
* Step 5 配音选择组件
* 展示用户已上传的配音素材,支持选中、预览播放
* 根据视频总时长自动过滤时长差异过大的配音(±10%以内)
*/
import React, { useState, useRef, useCallback } from "react"
import { useNavigate } from "react-router-dom"
@@ -13,7 +12,6 @@ import type { AssetItem } from "@/api/assets"
interface Step5VoiceSelectProps {
selectedVoice: string
onSelectedVoiceChange: (id: string) => void
totalVideoDuration?: number
}
/** 获取素材实际时长(优先顶层 durationfallback 到 metadata.duration */
@@ -45,7 +43,6 @@ const formatFileSize = (bytes?: number): string => {
const Step5VoiceSelect: React.FC<Step5VoiceSelectProps> = ({
selectedVoice,
onSelectedVoiceChange,
totalVideoDuration = 0,
}) => {
const navigate = useNavigate()
const [playingId, setPlayingId] = useState<string | null>(null)
@@ -57,19 +54,6 @@ const Step5VoiceSelect: React.FC<Step5VoiceSelectProps> = ({
queryFn: () => getAssetsByKind("voice", { limit: 50 }),
})
// 根据视频总时长过滤配音:只保留时长在 ±10% 以内的素材,AI 音色始终展示
const filteredMaterials = React.useMemo(() => {
if (totalVideoDuration <= 0) return materials
return materials.filter((item) => {
// AI 音色没有固定时长,始终保留
if (isAiVoice(item)) return true
const duration = getDuration(item)
if (duration <= 0) return true
const ratio = duration / totalVideoDuration
return ratio >= 0.9 && ratio <= 1.1
})
}, [materials, totalVideoDuration])
/** 切换播放/暂停 */
const togglePlay = useCallback(
(material: AssetItem) => {
@@ -175,7 +159,7 @@ const Step5VoiceSelect: React.FC<Step5VoiceSelectProps> = ({
gap: 12,
}}
>
{filteredMaterials.map((item) => {
{materials.map((item) => {
const isSelected = selectedVoice === item.id
const isPlaying = playingId === item.id
@@ -275,11 +259,6 @@ const Step5VoiceSelect: React.FC<Step5VoiceSelectProps> = ({
)
})}
</div>
{totalVideoDuration > 0 && filteredMaterials.length < materials.length && (
<p style={{ color: "#999", fontSize: 12, marginTop: 8 }}>
{Math.round(totalVideoDuration)}s
</p>
)}
</div>
)
}