Skip to content

Include AAC audio in the native HLS fallback writer - #669

Merged
matteius merged 2 commits into
mainfrom
feat/hls-fallback-audio-651
Oct 24, 2026
Merged

matteius merged 2 commits into
mainfrom
feat/hls-fallback-audio-651

Conversation

@matteius

Copy link
Copy Markdown
Contributor

Closes #651

Summary

When go2rtc native HLS isn't available, LightNVR's own FFmpeg HLS writer now muxes the camera's audio track, only when audio is enabled for the stream (record_audio && !audio_disabled, the same rule as the detection thread and MP4 recorder). With audio disabled, nothing changes: the thread never selects the audio track, the writer gets no audio stream, and any stray audio packets are dropped. The output is video only, as it is today.

Copy-only plus a clear skip (the acceptable first-PR option from the issue):

  • AAC with codec config (AudioSpecificConfig) is stream-copied into the MPEG-TS segments.
  • Other codecs (G.711 PCMU/PCMA, etc.) are skipped with one log_info per stream, and video is unaffected. AAC without extradata is also skipped, because it would make avformat_write_header() fail and take video down with it.
  • Transcoding isn't reused here: the existing transcoder in mp4_writer_utils.c is keyed by stream name and would collide with the MP4 recorder's instance for the same camera.

Details

  • hls_writer_initialize_av(writer, video, audio) is new. hls_writer_initialize() wraps it with no audio.
  • Packets are routed to output streams by media type instead of being forced to streams[0], so audio-before-video RTSP sources work.
  • Audio is rescaled from its own input timebase and has its own monotonic-DTS tracker. The video PTS/DTS fixups, keyframe-aligned cuts and segment settings are unchanged.
  • Only video packets refresh the thread's liveness timestamp, so flowing audio can't hide a video stall. max_interleave_delta is capped at 1s when audio is muxed, so a stalled audio track can't hold live video back.
  • A writer recreated after a reconnect is initialized with the audio stream before its header is written.

Testing

  • New tests in tests/unit/test_hls_cleanup.c use the fixture's H.264 video plus a sine-wave AAC track encoded in the test (listed before video):
    • AAC → output has video plus an AAC audio track, with first audio and first video timestamps within 0.2s
    • Audio disabled (no audio stream passed, audio packets still fed) → video only, zero audio packets
    • G.711 μ-law → video only
  • Full ctest: 156/158 pass. test_sod_unified and test_sod_voc fail on missing image/model arguments, which is unrelated.
  • Not yet done: the manual check with ENABLE_GO2RTC=OFF against a live RTSP source with audio, played in hls.js.

🤖 Generated with Claude Code

When go2rtc native HLS is unavailable, the FFmpeg HLS writer now muxes
the source's audio track alongside video, but only when audio is enabled
for the stream (record_audio && !audio_disabled). With audio disabled the
output stays video only, exactly as before.

- AAC with codec config is stream-copied; other codecs (G.711 etc.) are
  skipped with a single log_info and video output is unaffected.
- Packets are routed to output streams by media type rather than forced
  to stream 0, so audio-before-video RTSP sources work.
- Audio is rescaled from its own timebase and has its own monotonic DTS
  tracker; video PTS/DTS fixups are unchanged.
- Only video refreshes the thread's liveness timestamp, and
  max_interleave_delta is capped at 1s when audio is muxed.
- Writers recreated after reconnection are initialized with the audio
  stream before their header is written.

Closes #651

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@codecov

codecov Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.56067% with 13 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/video/hls_writer.c 85.71% 8 Missing ⚠️
src/video/hls/hls_unified_thread.c 75.00% 5 Missing ⚠️

📢 Thoughts on this report? Let us know!

The native HLS writer tests were built by ctest but not by the coverage
job, so codecov saw no hits for the HLS fallback audio changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@matteius
matteius merged commit 3187670 into main Oct 24, 2026
13 checks passed
@matteius
matteius deleted the feat/hls-fallback-audio-651 branch October 24, 2026 09:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Agent] Include audio in the native (non-go2rtc) HLS fallback

1 participant