Osciloscope integrated but video exported is broken

This commit is contained in:
2025-12-20 15:50:04 +01:00
parent 26584ea848
commit e227743728
4 changed files with 56 additions and 30 deletions
+2
View File
@@ -30,6 +30,7 @@ const Pacman = lazy(() => import("./pages/Pacman"));
const Snake = lazy(() => import("./pages/Snake"));
const Breakout = lazy(() => import("./pages/Breakout"));
const Music = lazy(() => import("./pages/Music"));
const Oscilloscope = lazy(() => import("./pages/Oscilloscope"));
const AIChat = lazy(() => import("./pages/AIChat"));
const Achievements = lazy(() => import("./pages/Achievements"));
const Credits = lazy(() => import("./pages/Credits"));
@@ -125,6 +126,7 @@ const AppContent = () => {
<Route path="games/breakout" element={<Breakout />} />
<Route path="faq" element={<FAQ />} />
<Route path="music" element={<Music />} />
<Route path="oscilloscope" element={<Oscilloscope />} />
<Route path="ai" element={<AIChat />} />
<Route path="achievements" element={<Achievements />} />
<Route path="credits" element={<Credits />} />
+27 -9
View File
@@ -351,7 +351,7 @@ export const useOfflineVideoExport = () => {
};
};
// Memory-efficient muxing using real-time playback
// Improved muxing with better synchronization
async function muxAudioVideo(
videoBlob: Blob,
audioFile: File,
@@ -367,9 +367,9 @@ async function muxAudioVideo(
video.src = videoUrl;
video.muted = true;
video.playbackRate = 4; // Speed up playback
video.playbackRate = 1; // Normal playback speed
audio.src = audioUrl;
audio.playbackRate = 4;
audio.playbackRate = 1;
const cleanup = () => {
URL.revokeObjectURL(videoUrl);
@@ -428,21 +428,39 @@ async function muxAudioVideo(
reject(new Error('Muxing failed'));
};
let lastVideoTime = 0;
const drawLoop = () => {
if (video.ended || audio.ended) {
setTimeout(() => recorder.stop(), 100);
if (video.paused || video.ended) {
if (video.ended || audio.ended) {
setTimeout(() => recorder.stop(), 100);
return;
}
requestAnimationFrame(drawLoop);
return;
}
ctx.drawImage(video, 0, 0);
// Only draw when video has progressed
if (video.currentTime !== lastVideoTime) {
lastVideoTime = video.currentTime;
ctx.drawImage(video, 0, 0);
}
requestAnimationFrame(drawLoop);
};
recorder.start(100);
// Ensure both start at the same time
video.currentTime = 0;
audio.currentTime = 0;
video.play();
audio.play();
drawLoop();
// Wait for both to be ready to play
Promise.all([video.play(), audio.play()]).then(() => {
drawLoop();
}).catch(err => {
console.error('Playback failed:', err);
cleanup();
reject(err);
});
}).catch(err => {
cleanup();
console.warn('Muxing failed, returning video only:', err);
+26
View File
@@ -0,0 +1,26 @@
import { motion } from 'framer-motion';
import { Oscilloscope } from '@/components/Oscilloscope';
const OscilloscopePage = () => {
return (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.5 }}
className="space-y-6"
>
<div className="text-center space-y-2">
<h1 className="font-minecraft text-3xl md:text-4xl text-primary text-glow-strong">
Audio Oscilloscope
</h1>
<p className="font-pixel text-foreground/80">
Visualize audio waveforms in real-time with microphone input or audio files.
</p>
</div>
<Oscilloscope />
</motion.div>
);
};
export default OscilloscopePage;