fix: 移除配音选择时长过滤逻辑,所有配音素材完整显示 #1697
@@ -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
|
||||
}
|
||||
|
||||
/** 获取素材实际时长(优先顶层 duration,fallback 到 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>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user