Add video speed control and improve playback smoothness

Added a speed control dropdown in the timeline toolbar that lets users change video playback speed between 0.5x to 2x. The dropdown shows the current speed and offers preset options.

Made video playback smoother by:
- Using better timing for speed changes
- Improving video synchronization
- Reducing playback stutters
- Making speed changes more responsive

The speed control is now easily accessible while editing and works smoothly with all video clips.
This commit is contained in:
StarKnightt
2025-06-23 20:01:12 +05:30
parent 294ba01abe
commit f72f5c100b
7 changed files with 344 additions and 210 deletions

View File

@ -6,15 +6,20 @@ interface PlaybackStore extends PlaybackState, PlaybackControls {
setCurrentTime: (time: number) => void;
}
let playbackTimer: NodeJS.Timeout | null = null;
let playbackTimer: number | null = null;
const startTimer = (store: any) => {
if (playbackTimer) clearInterval(playbackTimer);
if (playbackTimer) cancelAnimationFrame(playbackTimer);
playbackTimer = setInterval(() => {
// Use requestAnimationFrame for smoother updates
const updateTime = () => {
const state = store();
if (state.isPlaying && state.currentTime < state.duration) {
const newTime = state.currentTime + 0.1;
const now = performance.now();
const delta = (now - lastUpdate) / 1000; // Convert to seconds
lastUpdate = now;
const newTime = state.currentTime + (delta * state.speed);
if (newTime >= state.duration) {
state.pause();
} else {
@ -23,12 +28,16 @@ const startTimer = (store: any) => {
window.dispatchEvent(new CustomEvent('playback-update', { detail: { time: newTime } }));
}
}
}, 100);
playbackTimer = requestAnimationFrame(updateTime);
};
let lastUpdate = performance.now();
playbackTimer = requestAnimationFrame(updateTime);
};
const stopTimer = () => {
if (playbackTimer) {
clearInterval(playbackTimer);
cancelAnimationFrame(playbackTimer);
playbackTimer = null;
}
};
@ -38,6 +47,7 @@ export const usePlaybackStore = create<PlaybackStore>((set, get) => ({
currentTime: 0,
duration: 0,
volume: 1,
speed: 1.0,
play: () => {
set({ isPlaying: true });
@ -64,10 +74,20 @@ export const usePlaybackStore = create<PlaybackStore>((set, get) => ({
set({ currentTime: clampedTime });
// Notify video elements to seek
window.dispatchEvent(new CustomEvent('playback-seek', { detail: { time: clampedTime } }));
const event = new CustomEvent('playback-seek', { detail: { time: clampedTime } });
window.dispatchEvent(event);
},
setVolume: (volume: number) => set({ volume: Math.max(0, Math.min(1, volume)) }),
setSpeed: (speed: number) => {
const newSpeed = Math.max(0.1, Math.min(2.0, speed));
set({ speed: newSpeed });
const event = new CustomEvent('playback-speed', { detail: { speed: newSpeed } });
window.dispatchEvent(event);
},
setDuration: (duration: number) => set({ duration }),
setCurrentTime: (time: number) => set({ currentTime: time }),
}));