Skip to content

[Bug]: Media keys and tray Play/Pause do nothing while a radio station is loaded #2303

Description

@yepeekai

I have already checked through the existing (both open AND closed) bug reports and found no duplicates

  • Yes

App Version

1.15.1

Music Server and Version

Navidrome 0.63.2

What local environments are you seeing the problem on?

No response

What happened?

Play/pause commands coming from the main process — media keys, the tray menu's Play/Pause entry, MPRIS — do nothing while an internet radio station is loaded. It fails even with the window focused, and even when the station is only loaded and paused.

Cause — in the renderer's main-process listener hook, every media command is short-circuited as soon as a station is loaded, and nothing forwards it to the radio player:

const isRadioLoaded = useIsRadioLoaded();   // !!currentStreamUrl

mpvPlayerListener.rendererPlayPause(() => { isRadioLoaded || mediaTogglePlayPause() });
mpvPlayerListener.rendererPlay(() => { isRadioLoaded || mediaPlay() });
mpvPlayerListener.rendererPause(() => { isRadioLoaded || mediaPause() });

(Identifiers recovered from the 1.15.1 bundle: Ds.rendererPlayPause(()=>{e||h()}), where e comes from the selector t => !!t.currentStreamUrl on the radio store.)

The guard correctly keeps the queue player from fighting the radio player — I assume it came from #1490 — but the command is then simply lost, because the radio player is a separate player with its own store actions. The result is that a radio station can only be paused from inside the window, with the mouse.

The UI button handles both cases properly:

const { currentStreamUrl } = useRadioStore();
const isPlaying = useRadioIsPlaying();
const { pause, play } = useRadioActions();

const onClick = () => { isPlaying ? pause() : currentStreamUrl && play() };

Suggested fix — route the listeners to the radio actions when a station is loaded, reusing that same logic:

mpvPlayerListener.rendererPlayPause(() => {
    if (isRadioLoaded) {
        const radio = useRadioStore.getState();
        radio.isPlaying ? radio.actions.pause() : radio.actions.play();
    } else {
        mediaTogglePlayPause();
    }
});

with the matching one-sided variants for rendererPlay and rendererPause.

I applied this to my local build (1.15.1, Ubuntu 26.04, GNOME/Wayland, mpv backend) together with the companion MPRIS fix, and the media keys now pause and resume a radio stream correctly.

rendererNext / rendererPrevious are gated the same way. I left them alone since skipping has no obvious meaning on a continuous stream, but they might be worth routing to "previous/next station" or left as explicit no-ops.

Steps to reproduce

  1. On a Linux desktop, play any internet radio station.
  2. Focus the Feishin window, then press the play/pause media key. Nothing happens.
  3. Same with the Play/Pause entry of the tray menu.
  4. The play/pause button inside the window works — only commands coming from the main process are lost.

Relevant log output

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions