/** * Компонент управления пререндером */ import { Settings2, Sparkles } from "lucide-react" import { useCallback } from "react" import { toast } from "sonner" import { Button } from "@/components/ui/button" import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu" import { Label } from "@/components/ui/label" import { Slider } from "@/components/ui/slider" import { Switch } from "@/components/ui/switch" import { useTimeline } from "@/features/timeline/hooks/use-timeline" import { usePrerender, usePrerenderCache } from "@/features/video-compiler/hooks/use-prerender" import { usePlayer } from "../services/player-provider" export interface PrerenderSettings { enabled: boolean quality: number segmentDuration: number applyEffects: boolean autoPrerender: boolean } interface PrerenderControlsProps { currentTime: number duration: number onSettingsChange?: (settings: PrerenderSettings) => void } export function PrerenderControls({ currentTime, duration, onSettingsChange }: PrerenderControlsProps) { const { prerender, isRendering, currentResult } = usePrerender() const { clearCache, cacheSize, totalCacheSize } = usePrerenderCache() const { project } = useTimeline() const { prerenderSettings: { prerenderEnabled, prerenderQuality, prerenderSegmentDuration, prerenderApplyEffects, prerenderAutoPrerender, }, setPrerenderSettings, } = usePlayer() const settings: PrerenderSettings = { enabled: prerenderEnabled, quality: prerenderQuality, segmentDuration: prerenderSegmentDuration, applyEffects: prerenderApplyEffects, autoPrerender: prerenderAutoPrerender, } /** * Обновить настройку */ const updateSetting = useCallback( (key: K, value: PrerenderSettings[K]) => { const newSettings = { ...settings, [key]: value } // Обновляем глобальные настройки в плеере setPrerenderSettings({ prerenderEnabled: key === "enabled" ? (value as boolean) : undefined, prerenderQuality: key === "quality" ? (value as number) : undefined, prerenderSegmentDuration: key === "segmentDuration" ? (value as number) : undefined, prerenderApplyEffects: key === "applyEffects" ? (value as boolean) : undefined, prerenderAutoPrerender: key === "autoPrerender" ? (value as boolean) : undefined, }) onSettingsChange?.(newSettings) }, [settings, setPrerenderSettings, onSettingsChange], ) /** * Выполнить пререндер текущего сегмента */ const handlePrerenderCurrent = useCallback(async () => { const segmentStart = Math.floor(currentTime / settings.segmentDuration) * settings.segmentDuration const segmentEnd = Math.min(segmentStart + settings.segmentDuration, duration) const result = await prerender(segmentStart, segmentEnd, settings.applyEffects, settings.quality) if (result) { toast.success(`Пререндер завершен за ${result.renderTimeMs}мс`, { description: `Размер файла: ${(result.fileSize / 1024 / 1024).toFixed(2)} МБ`, }) } }, [currentTime, duration, settings, prerender]) /** * Проверить, есть ли эффекты в текущем моменте */ const hasEffectsAtCurrentTime = useCallback(() => { if (!project) return false // Проверяем, есть ли эффекты или фильтры в проекте // В реальной реализации здесь должна быть логика поиска клипов в указанное время const hasEffects = project.sections?.some((section) => section.tracks.some((track) => track.clips.some((clip) => (clip.effects?.length || 0) > 0 || (clip.filters?.length || 0) > 0), ), ) return hasEffects || false }, [currentTime, project]) return ( Настройки пререндера {/* Включение/выключение */}
updateSetting("enabled", checked)} />
{settings.enabled && ( <> {/* Качество */}
{settings.quality}%
updateSetting("quality", value)} min={10} max={100} step={5} className="w-full" />
{/* Длительность сегмента */}
{settings.segmentDuration}с
updateSetting("segmentDuration", value)} min={1} max={30} step={1} className="w-full" />
{/* Применять эффекты */}
updateSetting("applyEffects", checked)} />
{/* Автоматический пререндер */}
updateSetting("autoPrerender", checked)} />
{/* Действия */} {isRendering ? "Рендеринг..." : "Пререндер текущего сегмента"} {cacheSize > 0 && ( Очистить кеш ({cacheSize} файлов, {(totalCacheSize / 1024 / 1024).toFixed(1)} МБ) )} {/* Информация */} {currentResult && ( <>
Последний рендер: {currentResult.duration.toFixed(2)}с
Время: {currentResult.renderTimeMs}мс
Размер: {(currentResult.fileSize / 1024 / 1024).toFixed(2)} МБ
)} )}
) }