Update
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
// TODO: I moved the sample timeline data to a dedicated file, and delayed the loading to 1 sec with useEffect. as such, alot of the ogics are broken. I need to make sure the delayed timeline should work like normal
|
||||
// Updated video-editor.jsx to use selected meme and background
|
||||
|
||||
import { useMitt } from '@/plugins/MittContext';
|
||||
import useMediaStore from '@/stores/MediaStore'; // Add this import
|
||||
import useVideoEditorStore from '@/stores/VideoEditorStore';
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import sampleTimelineElements from './sample-timeline-data';
|
||||
import useVideoExport from './video-export';
|
||||
import VideoPreview from './video-preview';
|
||||
|
||||
@@ -23,6 +23,9 @@ const VideoEditor = ({ width, height }) => {
|
||||
const lastUpdateRef = useRef(0);
|
||||
const emitter = useMitt();
|
||||
|
||||
// Add MediaStore to get selected items
|
||||
const { selectedMeme, selectedBackground } = useMediaStore();
|
||||
|
||||
const [currentTime, setCurrentTime] = useState(0);
|
||||
const [isPlaying, setIsPlaying] = useState(false);
|
||||
const [videoElements, setVideoElements] = useState({});
|
||||
@@ -44,10 +47,56 @@ const VideoEditor = ({ width, height }) => {
|
||||
timelineElementsRef.current = timelineElements;
|
||||
}, [timelineElements]);
|
||||
|
||||
// ✅ FIX 1: Use useEffect to automatically setup videos when timeline loads
|
||||
useEffect(() => {
|
||||
initTimeline();
|
||||
}, []);
|
||||
// ✅ NEW: Create timeline from selected items
|
||||
const createTimelineFromSelections = useCallback(() => {
|
||||
const elements = [];
|
||||
|
||||
// If we have a selected meme, use its duration, otherwise default to 5 seconds
|
||||
const memeDuration = selectedMeme?.duration ? parseFloat(selectedMeme.duration) : 5;
|
||||
|
||||
// Add background video if selected (base layer)
|
||||
if (selectedBackground) {
|
||||
elements.push({
|
||||
id: `bg_${selectedBackground.ids}`,
|
||||
type: 'video',
|
||||
source_webm: selectedBackground.media_url, // Assuming it's webm
|
||||
source_mov: selectedBackground.media_url, // You might need different URLs
|
||||
poster: selectedBackground.media_url,
|
||||
name: 'Background',
|
||||
startTime: 0,
|
||||
layer: 0,
|
||||
inPoint: 0,
|
||||
duration: memeDuration, // Match meme duration
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: dimensions.width,
|
||||
height: dimensions.height,
|
||||
});
|
||||
}
|
||||
|
||||
// Add meme video if selected (overlay layer)
|
||||
if (selectedMeme) {
|
||||
elements.push({
|
||||
id: `meme_${selectedMeme.ids}`,
|
||||
type: 'video',
|
||||
source_webm: selectedMeme.webm_url,
|
||||
source_mov: selectedMeme.mov_url,
|
||||
poster: selectedMeme.webp_url,
|
||||
name: selectedMeme.name,
|
||||
startTime: 0,
|
||||
layer: 1,
|
||||
inPoint: 0,
|
||||
duration: memeDuration,
|
||||
x: 50, // Offset slightly for overlay effect
|
||||
y: 50,
|
||||
width: dimensions.width - 100,
|
||||
height: dimensions.height - 100,
|
||||
});
|
||||
}
|
||||
|
||||
showConsoleLogs && console.log('Created timeline from selections:', elements);
|
||||
return elements;
|
||||
}, [selectedMeme, selectedBackground, dimensions]);
|
||||
|
||||
const timelineUpdateResolverRef = useRef(null);
|
||||
|
||||
@@ -60,20 +109,29 @@ const VideoEditor = ({ width, height }) => {
|
||||
|
||||
// Add this useEffect to resolve the promise when timeline updates
|
||||
useEffect(() => {
|
||||
if (timelineUpdateResolverRef.current && timelineElements.length > 0) {
|
||||
if (timelineUpdateResolverRef.current && timelineElements.length >= 0) {
|
||||
// Changed from > 0 to >= 0
|
||||
timelineUpdateResolverRef.current();
|
||||
timelineUpdateResolverRef.current = null;
|
||||
}
|
||||
}, [timelineElements]);
|
||||
|
||||
const initTimeline = () => {
|
||||
// ✅ UPDATED: Use selections instead of sample data
|
||||
const initTimeline = useCallback(() => {
|
||||
cleanupVideos(videoElements);
|
||||
setTimelineElementsAsync(sampleTimelineElements).then(() => {
|
||||
showConsoleLogs && console.log('Loaded sample timeline');
|
||||
|
||||
const newElements = createTimelineFromSelections();
|
||||
setTimelineElementsAsync(newElements).then(() => {
|
||||
showConsoleLogs && console.log('Loaded timeline from selections');
|
||||
setupVideos();
|
||||
});
|
||||
};
|
||||
}, [createTimelineFromSelections, videoElements]);
|
||||
|
||||
// ✅ NEW: Watch for changes in selected items and update timeline
|
||||
useEffect(() => {
|
||||
initTimeline();
|
||||
}, [selectedMeme, selectedBackground]); // Re-run when selections change
|
||||
|
||||
// ✅ FIX 3: Auto-update status when videos load
|
||||
useEffect(() => {
|
||||
setupVideoStatus();
|
||||
@@ -83,7 +141,8 @@ const VideoEditor = ({ width, height }) => {
|
||||
setVideoIsPlaying(isPlaying);
|
||||
}, [isPlaying, setVideoIsPlaying]);
|
||||
|
||||
const totalDuration = Math.max(...timelineElements.map((el) => el.startTime + el.duration));
|
||||
// ✅ UPDATED: Calculate duration from actual timeline
|
||||
const totalDuration = timelineElements.length > 0 ? Math.max(...timelineElements.map((el) => el.startTime + el.duration)) : 5; // Default fallback
|
||||
|
||||
// Use the FFmpeg hook
|
||||
const { isExporting, exportProgress, exportStatus, ffmpegCommand, copyFFmpegCommand, exportVideo } = useVideoExport({
|
||||
@@ -155,8 +214,19 @@ const VideoEditor = ({ width, height }) => {
|
||||
scaledHeight = posterHeight * scale;
|
||||
}
|
||||
|
||||
const centeredX = (maxWidth - scaledWidth) / 2;
|
||||
const centeredY = (maxHeight - scaledHeight) / 2;
|
||||
// ✅ UPDATED: Different positioning for background vs meme
|
||||
let centeredX, centeredY;
|
||||
if (element.id.startsWith('bg_')) {
|
||||
// Background should fill the canvas
|
||||
centeredX = 0;
|
||||
centeredY = 0;
|
||||
scaledWidth = maxWidth;
|
||||
scaledHeight = maxHeight;
|
||||
} else {
|
||||
// Meme should be centered
|
||||
centeredX = (maxWidth - scaledWidth) / 2;
|
||||
centeredY = (maxHeight - scaledHeight) / 2;
|
||||
}
|
||||
|
||||
setTimelineElements((prev) =>
|
||||
prev.map((el) => {
|
||||
@@ -215,6 +285,7 @@ const VideoEditor = ({ width, height }) => {
|
||||
setVideoElements(videoEls);
|
||||
};
|
||||
|
||||
// Rest of the component remains the same...
|
||||
const cleanupVideos = (videosToCleanup) => {
|
||||
if (!videosToCleanup) return;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user