Changes
This commit is contained in:
@@ -95,42 +95,6 @@ export const useOfflineVideoExport = () => {
|
||||
throw new Error('No video codec supported');
|
||||
}
|
||||
|
||||
// Create audio context for recording
|
||||
const recordingAudioContext = new AudioContext();
|
||||
|
||||
// Resume audio context if suspended
|
||||
if (recordingAudioContext.state === 'suspended') {
|
||||
await recordingAudioContext.resume();
|
||||
}
|
||||
|
||||
// Create audio source and destination
|
||||
const recordingAudioSource = recordingAudioContext.createBufferSource();
|
||||
recordingAudioSource.buffer = audioBuffer;
|
||||
recordingAudioSource.loop = false;
|
||||
|
||||
const audioDestination = recordingAudioContext.createMediaStreamDestination();
|
||||
recordingAudioSource.connect(audioDestination);
|
||||
recordingAudioSource.connect(recordingAudioContext.destination);
|
||||
|
||||
// Combine video and audio streams
|
||||
const combinedStream = new MediaStream();
|
||||
canvas.captureStream(fps).getVideoTracks().forEach(track => combinedStream.addTrack(track));
|
||||
audioDestination.stream.getAudioTracks().forEach(track => combinedStream.addTrack(track));
|
||||
|
||||
console.log(`✅ Combined stream: ${combinedStream.getVideoTracks().length} video, ${combinedStream.getAudioTracks().length} audio tracks`);
|
||||
|
||||
const recorder = new MediaRecorder(combinedStream, {
|
||||
mimeType: selectedCodec,
|
||||
videoBitsPerSecond: videoBitsPerSecond,
|
||||
});
|
||||
|
||||
console.log('✅ MediaRecorder created with audio and video');
|
||||
recorder.start(1000); // 1 second chunks
|
||||
|
||||
// Start audio playback synchronized with recording
|
||||
recordingAudioSource.start(0);
|
||||
console.log('🔊 Audio playback started for recording');
|
||||
|
||||
// Use real audio data if available, otherwise generate mock data
|
||||
let audioBuffer: AudioBuffer;
|
||||
let sampleRate: number;
|
||||
@@ -171,6 +135,51 @@ export const useOfflineVideoExport = () => {
|
||||
console.log(`📊 Using mock audio: ${duration.toFixed(1)}s, ${totalSamples} samples`);
|
||||
}
|
||||
|
||||
// Create audio context for recording
|
||||
const recordingAudioContext = new AudioContext();
|
||||
|
||||
// Resume audio context if suspended
|
||||
if (recordingAudioContext.state === 'suspended') {
|
||||
await recordingAudioContext.resume();
|
||||
}
|
||||
|
||||
// Create audio source and destination
|
||||
const recordingAudioSource = recordingAudioContext.createBufferSource();
|
||||
recordingAudioSource.buffer = audioBuffer;
|
||||
recordingAudioSource.loop = false;
|
||||
|
||||
const audioDestination = recordingAudioContext.createMediaStreamDestination();
|
||||
recordingAudioSource.connect(audioDestination);
|
||||
recordingAudioSource.connect(recordingAudioContext.destination);
|
||||
|
||||
// Combine video and audio streams
|
||||
const combinedStream = new MediaStream();
|
||||
canvas.captureStream(fps).getVideoTracks().forEach(track => combinedStream.addTrack(track));
|
||||
audioDestination.stream.getAudioTracks().forEach(track => combinedStream.addTrack(track));
|
||||
|
||||
console.log(`✅ Combined stream: ${combinedStream.getVideoTracks().length} video, ${combinedStream.getAudioTracks().length} audio tracks`);
|
||||
|
||||
// Chunks array to collect recorded data
|
||||
const chunks: Blob[] = [];
|
||||
|
||||
const recorder = new MediaRecorder(combinedStream, {
|
||||
mimeType: selectedCodec,
|
||||
videoBitsPerSecond: videoBitsPerSecond,
|
||||
});
|
||||
|
||||
recorder.ondataavailable = (e) => {
|
||||
if (e.data.size > 0) {
|
||||
chunks.push(e.data);
|
||||
}
|
||||
};
|
||||
|
||||
console.log('✅ MediaRecorder created with audio and video');
|
||||
recorder.start(1000); // 1 second chunks
|
||||
|
||||
// Start audio playback synchronized with recording
|
||||
recordingAudioSource.start(0);
|
||||
console.log('🔊 Audio playback started for recording');
|
||||
|
||||
// Generate animation frames for full audio duration
|
||||
const totalFrames = Math.ceil(duration * fps);
|
||||
const samplesPerFrame = Math.min(qualityConfig.samplesPerFrame, Math.floor(totalSamples / totalFrames));
|
||||
|
||||
Reference in New Issue
Block a user