- AudioParams.framing field: client declares "raw" or "adts"
- Client strips ADTS from audio before sending (strip_adts)
- Client does H.264 NAL inspection for keyframe detection (h264_is_keyframe)
- Server uses declared sample_rate/channels for ADTS synthesis instead of hardcoded 48kHz/stereo
- Server gates ADTS wrapping on framing field instead of per-packet sniffing
New backends only need to pipe output to demux_and_send() — server and Python unchanged.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>