Fix HDMI audio detection on Pi4 with dual HDMI ports#2811
Fix HDMI audio detection on Pi4 with dual HDMI ports#2811vpetersson wants to merge 3 commits intomasterfrom
Conversation
Pi4 has two HDMI ports (HDMI-A-1 and HDMI-A-2), but the existing code always hardcodes `default:CARD=vc4hdmi0` regardless of which port has a display connected. This causes no audio when using HDMI-A-2. Changes: - Add `_detect_hdmi_audio_device()` that reads `/sys/class/drm/cardN-HDMI-A-N/status` to find which HDMI port is connected and returns the correct ALSA device - Use `sysdefault:CARD=` instead of `default:CARD=` for more reliable audio output (avoids PulseAudio/dmix interference) - Apply detection for Pi4 and Pi5 HDMI output - Keep headphones and Pi1-3 paths unchanged Tested on Pi4 Model B with single HDMI connected to HDMI-A-1.
…ings Update existing tests for the default: -> sysdefault: switch and add coverage for _detect_hdmi_audio_device(): both port preferences, missing status files, and OSError fall-through. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Fixes HDMI audio device selection on Raspberry Pi 4/5 by auto-detecting which HDMI connector is physically connected and selecting the corresponding ALSA card, improving reliability when default: is affected by PulseAudio/dmix.
Changes:
- Add
_detect_hdmi_audio_device()that reads/sys/class/drm/*/statusfor HDMI connector connection state and returns a matchingsysdefault:CARD=...device string. - Update
get_alsa_audio_device()to use HDMI auto-detection on Pi4/Pi5 and switch several ALSA device strings fromdefault:tosysdefault:. - Update and extend unit tests to cover the new detection helper and the updated device selection behavior.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| viewer/media_player.py | Introduces HDMI connector detection helper and routes Pi4/Pi5 HDMI output through it; switches ALSA device strings to sysdefault:. |
| tests/test_media_player.py | Updates expectations for sysdefault: and adds direct tests for HDMI detection/fallback behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| """Auto-detect connected HDMI audio device on Pi4/Pi5. | ||
|
|
||
| Pi4 has two HDMI ports: | ||
| - HDMI-A-1 = card 1 = vc4hdmi0 | ||
| - HDMI-A-2 = card 2 = vc4hdmi1 | ||
|
|
||
| Checks /sys/class/drm/cardN-HDMI-A-N/status to find which port | ||
| is connected and returns the matching ALSA device. Uses | ||
| sysdefault instead of default to bypass PulseAudio/dmix. | ||
| """ | ||
| for port, card_name in [ | ||
| ('card1-HDMI-A-1', 'vc4hdmi0'), | ||
| ('card1-HDMI-A-2', 'vc4hdmi1'), | ||
| ]: |
There was a problem hiding this comment.
Fixed in 85fc3dd. The docstring now describes the two layers separately: the DRM connector paths (/sys/class/drm/card1-HDMI-A-{1,2}/) and the ALSA card names (vc4hdmi0/vc4hdmi1), and notes that the ALSA card name doesn't track the DRM card index.
| except OSError: | ||
| pass |
There was a problem hiding this comment.
Fixed in 85fc3dd. The except OSError branch now logs at debug level with the status_path and the exception, so field debugging has something to grep for. Behavior is unchanged — still falls back to sysdefault:CARD=vc4hdmi0.
…Error Address PR feedback: - Docstring previously conflated DRM card directories (/sys/class/drm/cardN-HDMI-A-N/) with ALSA card names (vc4hdmiN). Rewrite to describe the two layers separately and document the card1 / vc4hdmi0|1 mapping explicitly. - The except OSError branch silently swallowed read failures. Log them at debug level with the path and exception so field debugging has something to grep for; behavior (fallback to vc4hdmi0) is unchanged. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|



Summary
Supersedes #2667 by @Alex1981-tech, rebased onto current
masterwith conflicts resolved against the recentmedia_player.pyrefactor (top-levelget_alsa_audio_device()shared across MPV and VLC) and tests updated.Original work and the fix itself are by @Alex1981-tech; Alex's commit is preserved as-is.
Changes (from @Alex1981-tech)
default:CARD=vc4hdmi0regardless of which port had a display connected — no audio when using HDMI-A-2.default:CARD=ALSA device name is unreliable when PulseAudio or dmix is involved.The fix:
_detect_hdmi_audio_device()that reads/sys/class/drm/cardN-HDMI-A-N/statusto find which HDMI port is connected and returns the matching ALSA device.default:CARD=tosysdefault:CARD=for direct hardware access.get_alsa_audio_device()to a top-level helper used by both players.default:tosysdefault:for consistency.Conflict resolution notes
get_alsa_audio_deviceinto a top-level function shared byMPVMediaPlayerandVLCMediaPlayer. Alex's PR was based on a version where it lived as a method onVLCMediaPlayer. Alex's intent has been ported onto the current top-level helper.style: apply ruff format) was redundant on the resolved structure and was dropped during rebase; an equivalent format pass is already folded into his fix commit.Tests
tests/test_media_player.pycases updated fordefault:→sysdefault:._detect_hdmi_audio_deviceand asserts it's called._detect_hdmi_audio_deviceitself: first-port-connected, second-port-only-connected, no status files (fallback), and OSError on read (fallback).Test plan
uv run ruff check viewer/media_player.py tests/test_media_player.py— cleanuv run ruff format --check viewer/media_player.py tests/test_media_player.py— cleanuv run pytest -m "not integration"— 413 passed🤖 Generated with Claude Code