This commit is contained in:
ct
2025-06-21 09:13:23 +08:00
parent db10fc3f1c
commit 8e58f85860
39 changed files with 684 additions and 181 deletions

View File

@@ -4,10 +4,13 @@ import useVideoEditorStore from '@/stores/VideoEditorStore';
import { useCallback, useEffect, useRef, useState } from 'react';
import SINGLE_CAPTION_TEMPLATE from '../../templates/single_caption_meme_background.json';
import { generateTimelineFromTemplate } from '../../utils/timeline-template-processor';
import VideoDownloadModal from './video-download/video-download-modal';
import useVideoExport from './video-export';
import VideoPreview from './video-preview';
const VideoEditor = ({ width, height, onOpenTextSidebar }) => {
const [isDownloadModalOpen, setIsDownloadModalOpen] = useState(false);
const [showConsoleLogs] = useState(true);
const [dimensions] = useState({
@@ -34,7 +37,7 @@ const VideoEditor = ({ width, height, onOpenTextSidebar }) => {
const pausedTimeRef = useRef(0);
const { setVideoIsPlaying } = useVideoEditorStore();
const { selectedMeme, selectedBackground, currentCaption } = useMediaStore();
const { selectedMeme, selectedBackground, currentCaption, watermarked } = useMediaStore();
const FPS_INTERVAL = 1000 / 30; // 30 FPS
@@ -544,9 +547,19 @@ const VideoEditor = ({ width, height, onOpenTextSidebar }) => {
});
}, [handlePause, handleSeek, videoElements]);
const handleExport = useCallback(() => {
exportVideo();
}, [exportVideo]);
const handleOpenDownloadModal = () => {
setIsDownloadModalOpen(true);
};
const activeElements = getActiveElements(currentTime);
useEffect(() => {
emitter.on('video-open-download-modal', handleOpenDownloadModal);
emitter.on('video-export', handleExport);
emitter.on('video-play', handlePlay);
emitter.on('video-reset', handleReset);
emitter.on('video-seek', handleSeek);
@@ -555,6 +568,8 @@ const VideoEditor = ({ width, height, onOpenTextSidebar }) => {
});
return () => {
emitter.off('video-open-download-modal', handleOpenDownloadModal);
emitter.off('video-export', handleExport);
emitter.off('video-play', handlePlay);
emitter.off('video-reset', handleReset);
emitter.off('video-seek', handleSeek);
@@ -563,33 +578,45 @@ const VideoEditor = ({ width, height, onOpenTextSidebar }) => {
}, [emitter, handlePlay, handleReset, handleSeek, handleElementUpdate]);
return (
<div style={{ width: dimensions.width, height: dimensions.height }} className="rounded-3xl">
<VideoPreview
dimensions={dimensions}
currentTime={currentTime}
totalDuration={totalDuration}
isPlaying={isPlaying}
status={status}
<>
<div style={{ width: dimensions.width, height: dimensions.height }} className="rounded-3xl">
<VideoPreview
watermarked={watermarked}
dimensions={dimensions}
currentTime={currentTime}
totalDuration={totalDuration}
isPlaying={isPlaying}
status={status}
isExporting={isExporting}
exportProgress={exportProgress}
exportStatus={exportStatus}
timelineElements={timelineElements}
activeElements={activeElements}
videoElements={videoElements}
loadedVideos={loadedVideos}
videoStates={videoStates}
ffmpegCommand={ffmpegCommand}
handlePlay={handlePlay}
handlePause={handlePause}
handleReset={handleReset}
handleSeek={handleSeek}
copyFFmpegCommand={copyFFmpegCommand}
exportVideo={exportVideo}
onElementUpdate={handleElementUpdate}
onOpenTextSidebar={onOpenTextSidebar}
layerRef={layerRef}
/>
</div>
<VideoDownloadModal
isOpen={isDownloadModalOpen}
onClose={() => setIsDownloadModalOpen(false)}
ffmpegCommand={ffmpegCommand}
handleDownloadButton={handleExport}
isExporting={isExporting}
exportProgress={exportProgress}
exportStatus={exportStatus}
timelineElements={timelineElements}
activeElements={activeElements}
videoElements={videoElements}
loadedVideos={loadedVideos}
videoStates={videoStates}
ffmpegCommand={ffmpegCommand}
handlePlay={handlePlay}
handlePause={handlePause}
handleReset={handleReset}
handleSeek={handleSeek}
copyFFmpegCommand={copyFFmpegCommand}
exportVideo={exportVideo}
onElementUpdate={handleElementUpdate}
onOpenTextSidebar={onOpenTextSidebar}
layerRef={layerRef}
/>
</div>
</>
);
};