## Summary
This fixes RTMP playback audio corruption and VLC playback compatibility
when proxying some upstream RTMP streams through `addStreamProxy`. In
the reproduced case, HTTP-FLV playback was normal, while RTMP playback
had missing audio or occasional sharp noise in VLC.
## Root cause
- RTMP aggregate message parsing copied the 4-byte `PreviousTagSize`
field into the sub-message payload. This shifts the payload boundary and
can corrupt subsequent audio packets.
- `RtmpSession::onSendMedia` forwarded proxied audio/video packets with
the packet's original chunk stream id. This can make audio packets use
an unsuitable chunk id for RTMP playback.
- The RTMP play response emitted non-essential `MSG_DATA` notifications
(`|RtmpSampleAccess` and `NetStream.Data.Start`). FFmpeg tolerates
these, but VLC may expose them as an extra `Data: none` stream and
handle RTMP playback poorly.
## Changes
- Exclude `PreviousTagSize` from aggregate sub-message payloads while
still skipping it when advancing the parser cursor.
- Send audio packets on `CHUNK_AUDIO` and video packets on `CHUNK_VIDEO`
from `STREAM_MEDIA`; keep the original values for other packet types.
- Avoid sending the non-essential RTMP play data notifications before
metadata/config/media packets.
## Validation
- Built `MediaServer` locally in Debug mode.
- Proxied four live RTMP test streams via `addStreamProxy`.
- Verified local RTMP and HTTP-FLV playback expose AAC audio tracks.
- Decoded RTMP audio with `ffmpeg -xerror`; all tested streams completed
without AAC decode errors.
- Verified the VLC compatibility change removes the extra `Data: none`
stream from RTMP output while preserving Video + Audio streams.
- Built and deployed a Docker image locally with docker compose and
re-tested RTMP/FLV audio playback.
## Summary
This PR fixes GStreamer interoperability issues during WebRTC/WHEP
negotiation with ZLMediaServer.
GStreamer could fail to establish the connection for two separate
reasons:
1. ZLMediaServer generated a non-compliant ICE `ufrag`. The generated
value contained `_`, which is not a valid ICE character, so GStreamer
rejected the SDP.
2. ZLMediaServer did not correctly handle `bundle-only` offers and could
answer an accepted bundled m-line with `port=0`, which caused the later
WHEP negotiation to fail.
## Changes
- Generate ICE `ufrag` values using ICE-compliant characters only.
- Preserve and handle `a=bundle-only` correctly during SDP parsing and
answer generation.
- Return `port=9` instead of `port=0` for accepted bundled m-lines.
- Add regression coverage for `bundle-only` SDP handling.
- URL-encode `delete_webrtc` query parameters in the returned `Location`
header so ICE-safe identifiers remain round-trippable over HTTP.
## Validation
- Built with WebRTC and SCTP enabled.
- Added regression test: `test_webrtc_regression`
- Verified:
- ICE-safe identifier round-trip through `delete_webrtc`
- `bundle-only` SDP answer generation
解决在window mingw 5.3环境下编译出现如下报错信息
no known conversion from 'LONG (*)(EXCEPTION_POINTERS*) {aka long int
(*)(_EXCEPTION_POINTERS*)}' to 'LPTOP_LEVEL_EXCEPTION_FILTER {aka long
int (__attribute__((__stdcall__)) *)(_EXCEPTION_POINTERS*)}'
When performing a 302 redirect, if the server explicitly indicates that the connection is not a persistent connection, the current
connection should not be reused; this prevents potential failures caused
by certain servers actively closing the connection.
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>