-
-
Notifications
You must be signed in to change notification settings - Fork 898
Description
When using setOnlyVideo(true) for SRT streaming, the MPEG-TS muxer still includes audio track information in PSI tables (PAT/PMT).
As a result, downstream servers (e.g. ZLMediaKit) detect and expect an audio track even though no audio packets are actually sent.
Impact
This behavior causes several issues on strict TS demuxers:
- ❌ Phantom audio track detected (e.g. mpeg4-generic)
- ❌ Potential TS demuxer crashes when audio packets never arrive
- ❌ Incorrect stream metadata reported by server APIs
Expected Behavior
When setOnlyVideo(true) is called before startStream():
- ✅ PSI tables (PAT/PMT) contain only video track
- ✅ No audio PID registered in PMT
- ✅ Server receives pure video-only metadata
- ✅ No audio packets sent (this already works correctly)
Actual Behavior
- ✅ SrtClient.setOnlyVideo(true) correctly sets commandsManager.audioDisabled = true
- ✅ SrtSender.getMpegTsPackets() correctly skips audio packets
- ❌ Audio track is still registered in PSI tables
Root Cause
In SrtSender.kt:
private fun setTrackConfig(videoEnabled: Boolean, audioEnabled: Boolean) {
Pid.reset()
service.clearTracks()
if (audioEnabled) service.addTrack(commandsManager.audioCodec.toCodec()) // ❌ Audio always added
if (videoEnabled) service.addTrack(commandsManager.videoCodec.toCodec())
service.generatePmt()
psiManager.updateService(service)
}
- audioEnabled is derived from !commandsManager.audioDisabled
- However, this method does not respect setOnlyVideo(true)
- As a result, audio track metadata is added even when audio is explicitly disabled
Server Detection Example (ZLMediaKit)
/index/api/getMediaList response:
{
"tracks": [
{
"codec_id": 2,
"codec_id_name": "mpeg4-generic", // ❌ Phantom audio track
"codec_type": 1,
"channels": 1,
"sample_rate": 8000
},
{
"codec_id": 1,
"codec_id_name": "H265",
"codec_type": 0,
"width": 1280,
"height": 720
}
]
}
Steps to Reproduce
- Prepare video encoder (H265) + audio encoder (AAC)
- Call srtClient.setOnlyVideo(true)
- Start streaming:
startStream("srt://server:9000?streamid=...") - Query server metadata (e.g. ZLMediaKit API)
- Observe: Both audio and video tracks detected
Proposed Fix
Modify SrtSender.setTrackConfig() to respect commandsManager.audioDisabled:
private fun setTrackConfig(videoEnabled: Boolean, audioEnabled: Boolean) {
Pid.reset()
service.clearTracks()
// Only add audio track if enabled AND not explicitly disabled
if (audioEnabled && !commandsManager.audioDisabled) {
service.addTrack(commandsManager.audioCodec.toCodec())
}
if (videoEnabled) {
service.addTrack(commandsManager.videoCodec.toCodec())
}
service.generatePmt()
psiManager.updateService(service)
Log.i(TAG, "Track config: video=$videoEnabled, audio=${audioEnabled && !commandsManager.audioDisabled}")
}
Workaround
Currently using a local patch to force video-only PSI tables:
private fun setTrackConfig(videoEnabled: Boolean, audioEnabled: Boolean) {
Pid.reset()
service.clearTracks()
if (videoEnabled) service.addTrack(commandsManager.videoCodec.toCodec())
service.generatePmt()
psiManager.updateService(service)
Log.i(TAG, "Track config: video=$videoEnabled, audio=false (forced)")
}
Environment
Library Version: rootProject-SNAPSHOT (latest master)
Android: 13 (API 33)
Video Codec: H265
Audio Codec: AAC
Protocol: SRT
Server: ZLMediaKit (2024)
Related Code
srt/src/main/java/com/pedro/srt/srt/SrtSender.kt (line 69–76, 113)
srt/src/main/java/com/pedro/srt/srt/SrtClient.kt (line 163)
srt/src/main/java/com/pedro/srt/srt/CommandsManager.kt (line 55)