Playback Debugging
Targeted workflow for preview stalls, scrub freezes, decode drift, and render-path mismatches.
What To Use First
Section titled “What To Use First”Playback bugs in MasterSelects usually span three layers at once:
- media readiness and browser decode state
- render-loop and target scheduling state
- timeline-to-preview sync and cache behavior
Use the browser monitors and AI bridge tools together instead of guessing from the UI.
Browser Surfaces
Section titled “Browser Surfaces”These globals are the fastest way to inspect the live playback path:
window.__WC_PIPELINE__for WebCodecs events, seeks, stalls, and aggregate counterswindow.__VF_PIPELINE__for HTML video / VideoFrame fallback eventswindow.__PLAYBACK_HEALTH__for health state, anomalies, active video status, and recovery helperswindow.__FRAME_PHASES__for per-frame phase timelines and summarieswindow.Loggerfor buffered module logs and redacted summaries
Useful console setup:
Logger.enable('WebCodecsPlayer,PlaybackHealth,LayerCollector')Logger.enable('VideoSyncManager,ParallelDecode,RenderLoop')Logger.setLevel('DEBUG')Additional shortcuts:
Logger.search('device')Logger.errors()Logger.dump(50)Logger.summary()AI Bridge Tools
Section titled “AI Bridge Tools”When the development bridge is available, prefer the structured tools:
getStatsgetStatsHistorygetAudioDiagnosticsgetLogsgetPlaybackTracegetRuntimeDiagnosticspurgePlaybackPathsamplePlaybackFramePacingsimulateScrubsimulatePlaybacksimulatePlaybackPathgetClipDetailsreloadApp
The most useful payload for real playback bugs is usually:
getStatsgetPlaybackTracegetLogsfiltered to playback modules
For crackling, pops, or dropouts during audible playback, capture getAudioDiagnostics during the noise. It reports per-element ready/buffer state, approximate source-time drift, Web Audio context latency/state, routing graph state, and recent audio_drift / audio_drift_correct events.
Signals To Watch
Section titled “Signals To Watch”These fields are the highest-signal indicators across trace, stats, and simulation results:
stalePreviewWhileTargetMoveddecoderResetspreviewFreezeEventspreviewPathCountsentries such asempty-hold,paused-empty-hold, andtarget-empty-holddriftSecondsgetAudioDiagnostics.events.correctionMsgetAudioDiagnostics.mediaElements[].buffered.bufferedAheadSecondsgetAudioDiagnostics.routing.context.baseLatencyMsfirstPreviewUpdateMsFRAME_STALLSEEK_STUCKHIGH_DROP_RATEGPU_SURFACE_COLD
If the preview is black after reload, also confirm the browser media element is actually ready. A valid render path with a cold or unready surface still produces empty frames.
Common Failure Patterns
Section titled “Common Failure Patterns”Black Preview Or Black Source Monitor
Section titled “Black Preview Or Black Source Monitor”- Check browser media
readyStatefirst. - Check
getStats.decoderandplayback.pipeline: the active path can be full WebCodecs, HTML video / VideoFrame (including cache variants), Native Helper, or ParallelDecode. - If external texture import fails, inspect the media readiness and the recorded GPU/runtime diagnostics before assuming a browser-specific fallback.
Scrub Freezes Or Delayed Updates
Section titled “Scrub Freezes Or Delayed Updates”- Inspect
previewFreezeEventsandfirstPreviewUpdateMs. - Check whether RAM preview is stale while the target moved.
- Confirm whether the render loop is idle and requires restarting.
Drift During Playback
Section titled “Drift During Playback”- Check
driftSeconds, handoff events, and active anomaly flags. - Compare the active decoder/pipeline with the WebCodecs and VF event streams to see where sync diverged.
- Verify whether the issue is clip-specific with
getClipDetails.
Source FPS Higher Than Composition FPS
Section titled “Source FPS Higher Than Composition FPS”- Playback preview is visually locked to the active composition frame rate. A 60 fps video in a 30 fps composition should show about 30 render/preview updates per second, not every decoded source frame.
samplePlaybackFramePacingmay still report the browser media element advancing at the source cadence throughvideoQuality/ video frame callbacks. UserenderLoop.renderCountDelta,stats.fps,stats.targetFps,playback.previewUpdateFps, andvisualTargetFpsto confirm the visible composition cadence.- During playback, the HTML media clock stays continuous to avoid per-frame seeking; visual layer target times are quantized to composition frames for cache/provider selection and deterministic preview presentation.
- Full WebCodecs playback is disabled by the default feature flag, but can be enabled through the persisted settings toggle; it disables the HTML preview fallback.
Export Looks Fine But Preview Is Wrong
Section titled “Export Looks Fine But Preview Is Wrong”- Compare target routing and render-target state in
getStats. - Confirm the issue is not limited to a popup output or independent preview target.
- Check whether cached hold frames or fallback frames are masking a decode problem.
Minimal Repro Routine
Section titled “Minimal Repro Routine”- Reload the app.
- Reproduce once without changing settings.
- Capture
getStats. - Capture
getPlaybackTrace. - Enable targeted logger modules and reproduce again.
- Compare whether the issue happens on the main preview, source monitor, and popup output.
This isolates whether the problem is in decode, render scheduling, target routing, or overlay state.
Source Map
Section titled “Source Map”src/services/playbackHealthMonitor.tssrc/services/playbackDebugStats.tssrc/services/framePhaseMonitor.tssrc/services/wcPipelineMonitor.tssrc/services/vfPipelineMonitor.tssrc/components/preview/Preview.tsxsrc/components/preview/SourceMonitor.tsxsrc/services/aiTools/bridge.tssrc/services/nativeHelper/NativeHelperClient.ts