Skip to content

EAC3 5.1 on the remote-HLS bypass is silent on a Bluetooth route (AirPods Pro), video fine #671

Description

@JorisM

What happened?

An EAC3 5.1 JOC track plays as complete silence on AirPods Pro while the video renders normally. The same file plays with sound through wired speakers on the same machine, an AAC 5.1 file plays fine on the same AirPods, and mpv-based clients play the same file on the same Mac and the same output.

The session takes the native remote-HLS bypass, so audio is AVPlayer's to manage:

[AetherEngine] AE#246: the loopback session's own open classified the source as HLS; taking the AE#154 reroute onto the native remote-HLS bypass
[AetherEngine] #321: effective video route = remoteBypass
[AetherEngine] AE#462: audio delivery = playerManaged

AVPlayer accepts the track and reports it enabled and playing:

[NativeAVPlayerHost] #1 item.audioTrack codec='ec-3' enabled=true sr=48000 ch=6 bits=0 fmt=ec-3 layoutTag=<missing> (readyToPlay)
[NativeAVPlayerHost] #1 item.videoTrack codec='hvc1' enabled=true dim=3840x1702 ... (readyToPlay)
[NativeAVPlayerHost] #1 timeControlStatus=playing reason=- t+4.81s

Video presents, timeControlStatus=playing, and there is no audio. Note layoutTag=<missing> on a 6-channel ec-3 track.

Worth stating explicitly, because it was my own first guess and it was wrong: this is not the HLSVideoEngine+AudioRoute stream-copy path. EAC3+JOC Atmos: stream-copy engaged does not appear in the session at all — the source was classified as HLS and rerouted to the bypass before that decision.

Possibly related: #395 (Live TS silent on AirPlay speakers, VOD and HDMI fine) looks like the same class, silence confined to one output route.

Steps to reproduce

  1. Jellyfin 12.1.0 source: HEVC Dolby Vision video plus a single EAC3 5.1 JOC audio track.
  2. Play it on macOS with AirPods Pro as the output. The server transcodes video (TranscodeReasons=VideoRangeTypeNotSupported) and passes audio through (AudioCodec=copy), so every HLS variant carries CODECS="hvc1.2.4.L150.B0,ec-3".
  3. Video plays, audio is silent.
  4. Switch output to wired speakers and replay. Audio plays.

AetherEngine version or commit SHA

6.89.1 (72b0cec)

Host app

Custom / my own integration — Moonfin, built from Moonfin-Core main 647087a3

Platform

macOS

OS version

macOS 26

Device / chip

MacBook Pro, M4 Pro (Mac16,7)

Playback path

Native AVPlayer

Source media

hvc1.2.4.L150.B0 Dolby Vision (DOVIWithHDR10Plus), 3840x1702, 23.976 fps. Audio ec-3, 6 channels, 48 kHz, Dolby Digital Plus + Dolby Atmos, single audio track.

Error codes / log lines

Trimmed to the playback session, identifiers redacted:

Moonfin diagnostic report (trimmed to the playback session; identifiers redacted)
App: Moonfin for macOS 2.6.100 (built from Moonfin-Core main 647087a3)
Platform: macOS 26, MacBook Pro M4 Pro (Mac16,7)
Output: AirPods Pro (Bluetooth)

--- server playback decision (host app) ---
INFO  [media] Playback decision for "<title>": transcode - HEVC/EAC3 MKV @ 120000000bps
{"backend":"AetherBackend","playMethod":"transcode","transcodingReasons":[],
 "directPlayVerdict":{"requestedByClient":true,"offeredByServer":false,"sourceBitrate":14793991},
 "selectedAudioStreamIndex":2,"container":"MKV","videoCodec":"HEVC","videoProfile":"Main 10",
 "videoRange":"DOVIWithHDR10Plus","audioCodec":"EAC3",
 "audioProfile":"Dolby Digital Plus + Dolby Atmos","audioChannels":"6",
 "allowedAudioCodecs":["AAC","AAC_LATM","AC3","ALAC","DCA","DTS","EAC3","FLAC","MLP","MP2","MP3",
   "OPUS","PCM_ALAW","PCM_MULAW","PCM_S16LE","PCM_S20LE","PCM_S24LE","TRUEHD","VORBIS"],
 "hlsFmp4AudioCodecs":["AAC","AC3","ALAC","EAC3","FLAC","OPUS"],
 "advertisedMaxAudioChannels":"8","passthroughMode":"auto","passthroughCodecs":[],
 "downmixToStereo":false,"prefMaxAudioChannels":0,"audioSpdifCodecs":[],
 "audioCapabilities":{"canDecodeAc3":true,"canDecodeEac3":true,"canPassthroughEac3":false,
   "maxPcmChannels":8,"activeRouteType":"other","routeSupportsHdAudio":false},
 "activeRouteType":"other"}

--- engine route selection ---
[AetherEngine] probe failed (Demuxer: open failed (Invalid data found when processing input (-1094995529))); proceeding without criteria
[AetherEngine] probe failed; falling through to the native video path (HLSVideoEngine will reopen and discover the stream) rather than degrading to audio-only
[AetherEngine] dispatch: codec=0 -> native
[AVIOReader] HLS playlist body on the VOD loopback path (AE#154); rerouting to the native remote-HLS bypass.
[HLSVODIngest] carriage probe inconclusive: unsupportedSegmentFormat
[AetherEngine] AE#246: the loopback session's own open classified the source as HLS; taking the AE#154 reroute onto the native remote-HLS bypass
[AetherEngine] #321: effective video route = remoteBypass
[AetherEngine] AE#462: audio delivery = playerManaged

--- master playlist handed to AVPlayer (one variant shown; all three carry ec-3) ---
#EXT-X-STREAM-INF:BANDWIDTH=14663818,VIDEO-RANGE=PQ,CODECS="hvc1.2.4.L150.B0,ec-3",SUPPLEMENTAL-CODECS="dvh1.08.06/db1p",RESOLUTION=3840x1702,FRAME-RATE=23.976,SUBTITLES="subs"
https://<server>/videos/<item-id>/main.m3u8?...&VideoCodec=hevc,h264&AudioCodec=copy&AudioBitrate=768000&AudioSampleRate=48000&SegmentContainer=mp4&...&eac3-profile=dolbydigitalplus%20dolbyatmos&eac3-audiochannels=8&TranscodeReasons=VideoRangeTypeNotSupported&AudioStreamIndex=2

--- AVPlayer state: video renders, audio track present and enabled, no sound ---
[NativeAVPlayerHost] #1 load url=<redacted> startPos=769.30s headers=2
[NativeAVPlayerHost] #1 asset.load(isPlayable) ok value=true
[NativeAVPlayerHost] #1 asset.load(duration) ok seconds=9271.2
[NativeAVPlayerHost] #1 errorLog code=-12889 domain=CoreMediaErrorDomain 'No response for map in 3.003s'
[NativeAVPlayerHost] #1 layer.isReadyForDisplay=true t+4.35s
[AetherEngine] #361 startup 8/8 presenting (gen 1)
[NativeAVPlayerHost] #1 item.status=readyToPlay
[NativeAVPlayerHost] #1 timeControlStatus=playing reason=- t+4.81s
[NativeAVPlayerHost] #1 item.videoTrack codec='hvc1' enabled=true dim=3840x1702 primaries=ITU_R_709_2 transfer=ITU_R_709_2 matrix=ITU_R_709_2 fullRange=false (readyToPlay)
[NativeAVPlayerHost] #1 item.audioTrack codec='ec-3' enabled=true sr=48000 ch=6 bits=0 fmt=ec-3 layoutTag=<missing> (readyToPlay)
[NativeAVPlayerHost] #1 item videoFormat=sdr subType='hvc1' transfer=ITU_R_709_2 rate=0.000

--- engine memprobe during playback (engine owns no audio on this path) ---
[AetherEngine] memprobe t=60s ... packetsWritten=0 audioFifo=0 abFifoKB=0 abSwrKB=0 abTotKB=0 ... audioTracks=0 subTracks=2 avBufAhead=51.3s avBufBehind=31.2s seams=0

(no "EAC3+JOC Atmos: stream-copy engaged" line appears anywhere in the session)

Anything else

Reproduced on a second Mac (MacBook Air M4) with its own AirPods, so it is not one machine's audio configuration.

On the host-app side the workaround is to ask the server for stereo, which costs surround on every other file.

One observation that may matter for route-aware decisions: the host reported activeRouteType: "other" for this session, because that app has no audio-route probe on macOS — so nothing in the chain knew the output was Bluetooth at the point the decision was made.

Host-app context, for anyone arriving from the other side: Moonfin-Client/Moonfin-Core#1696 — that thread has the Jellyfin-side traces for the same sessions, and the Moonfin maintainer asked for this report after ruling the host app's own audio path out.

Happy to test a patch against this file and setup.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions