Audio from generateAudio was being silently dropped during video
stitching. Add [VideoStitch] checkpoint logs at each stage where
audio can be discarded: getConnectedInputs, prepareAudioAsync,
and codec detection. Surface codec failure as a visible progress
warning instead of only console.warn.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace RegExp constructor with replaceAll() for @variable substitution
in promptConstructor to prevent regex injection via variable names
- Wrap annotation, prompt, and promptConstructor execution cases in
try/catch to gracefully handle errors (log + set node error, continue)
- Fix MediaBunny resource cleanup type safety with closeable type guard
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- AudioInputNode: use named event handlers with removeEventListener in cleanup
- deduplicatedFetch: track setTimeout IDs and clear them in clearFetchCache()
- waitForPendingImageSyncs: clear timeout in finally block after Promise.race
- decodeWithMediaBunny: wrap in try/finally to close sink, input, blobSource
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When videoDuration is 0 (unknown at call time), prepareAudioAsync was
computing targetDuration as max(0.1, 0) = 0.1 seconds, truncating the
audio to 100ms. Now computes the actual decoded audio duration from
buffers and uses that when videoDuration <= 0.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Use MediaBunny as the primary decoder following the documented pattern:
getPrimaryAudioTrack() + canDecode() check + AudioBufferSink.buffers().
Falls back to Web Audio API's decodeAudioData if MediaBunny cannot parse
the format (e.g. unusual codecs). This ensures MediaBunny handles
container formats it supports while Web Audio API catches the rest.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
MediaBunny's Input/BlobSource is designed for video containers and cannot
parse standalone audio files (MP3, WAV, etc.), causing "unsupported format"
errors at getAudioTracks(). Replace with Web Audio API's decodeAudioData
which natively handles all browser-supported audio formats.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Port useAudioVisualization.ts with waveform peak extraction
- Port useAudioMixing.ts with prepareAudioAsync standalone function
- Port useStitchVideos.ts with stitchVideosAsync and checkEncoderSupport
- Export applyFades from useAudioMixing for shared use
- Remove preview mode logic from useStitchVideos (always full quality)
- Inline constants (DEFAULT_BITRATE, MAX_OUTPUT_FPS) in useStitchVideos
- All hooks use MediaBunny for audio/video processing
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>