Add MPRIS2 support on Linux#487
Open
CaioDamascenoAlves wants to merge 3 commits into
Open
Conversation
Registers org.mpris.MediaPlayer2.stremio on the session D-Bus, allowing KDE Connect and other MPRIS2 clients to control playback. - mpris.h / mpris.cpp: MprisRootAdaptor (org.mpris.MediaPlayer2) and MprisPlayerAdaptor (org.mpris.MediaPlayer2.Player) using Qt D-Bus adaptors. Observes mpv properties (pause, core-idle, media-title, duration, volume) via mpvEvent signal for real-time PropertiesChanged notifications. Supports PlayPause, Play, Pause, Stop, Seek, SetPosition and Volume read/write. - stremio.pro: compile mpris.cpp on unix/Linux only. - main.cpp: call mprisSetup() after QML engine loads, finding the MpvObject instance via findChild. Closes the long-standing issue where KDE Connect could not control Stremio on Linux (Flatpak or native build) due to missing MPRIS2.
- Replace #pragma once with #ifndef include guard to match project style - Remove <QWindow> from header (only needed in .cpp) - Use QQuickWindow* directly in Raise() instead of casting to QWindow* - Add null check for QQuickWindow in Raise()
There was a problem hiding this comment.
Pull request overview
Adds Linux MPRIS2 integration so desktop media controllers can discover Stremio and control playback through D-Bus.
Changes:
- Adds MPRIS root/player D-Bus adaptors for playback, volume, metadata, seeking, and status updates.
- Wires MPRIS setup into Linux startup after QML loads the
MpvObject. - Adds qmake build entries for the new MPRIS files on Unix non-macOS builds.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 9 comments.
| File | Description |
|---|---|
stremio.pro |
Adds MPRIS source/header to the qmake Linux/Unix build. |
mpris.h |
Declares MPRIS root and player adaptor interfaces. |
mpris.cpp |
Implements MPRIS D-Bus registration, properties, controls, metadata, and mpv event handling. |
main.cpp |
Locates the QML mpv player and initializes MPRIS on Linux. |
Comments suppressed due to low confidence (1)
mpris.cpp:148
- The end-of-file path also clears
m_titleandm_durationwithout notifying thatMetadatachanged, so controllers can keep displaying stale metadata after a track stops or finishes. IncludeMetadatain thisPropertiesChangedemission when clearing the cached fields.
m_idle = true;
m_title.clear();
m_duration = 0.0;
emitPropertiesChanged({{"PlaybackStatus", QString("Stopped")}});
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (root) { | ||
| MpvObject *mpv = root->findChild<MpvObject*>(); | ||
| if (mpv) { | ||
| mprisSetup(mpv); |
Comment on lines
+123
to
+128
| if (m_idle) { | ||
| m_title.clear(); | ||
| m_duration = 0.0; | ||
| } | ||
| emitPropertiesChanged({{"PlaybackStatus", playbackStatus()}}); | ||
| } |
Comment on lines
+54
to
+55
| map["mpris:trackid"] = QVariant::fromValue( | ||
| QDBusObjectPath("/org/stremio/track/0") |
Comment on lines
+106
to
+107
| void MprisPlayerAdaptor::SetPosition(const QDBusObjectPath &, qlonglong positionUs) | ||
| { |
| if (mpv) { | ||
| mprisSetup(mpv); | ||
| } else { | ||
| qWarning("MPRIS: MpvObject não encontrado na árvore QML"); |
Comment on lines
+172
to
+179
| qWarning("MPRIS: falha ao registrar objeto D-Bus em %s", MPRIS_OBJECT_PATH); | ||
| return; | ||
| } | ||
| if (!bus.registerService(SERVICE_NAME)) { | ||
| qWarning("MPRIS: falha ao registrar serviço %s", SERVICE_NAME); | ||
| return; | ||
| } | ||
| qDebug("MPRIS: registrado com sucesso — KDE Connect pode controlar o Stremio"); |
| bool canRaise() const { return true; } | ||
| bool hasTrackList() const { return false; } | ||
| QString identity() const { return "Stremio"; } | ||
| QString desktopEntry() const { return "stremio"; } |
|
|
||
| static const char *MPRIS_OBJECT_PATH = "/org/mpris/MediaPlayer2"; | ||
| static const char *PLAYER_IFACE = "org.mpris.MediaPlayer2.Player"; | ||
| static const char *SERVICE_NAME = "org.mpris.MediaPlayer2.stremio"; |
| : QDBusAbstractAdaptor(player), m_player(player) | ||
| { | ||
| // Observa as propriedades mpv relevantes para MPRIS | ||
| player->observeProperty("core-idle"); |
- Use idle-active instead of core-idle (core-idle is true while paused) - Track ID is now unique per media item using an incrementing sequence counter - SetPosition validates the track ID to ignore stale seek requests - Emit Metadata alongside PlaybackStatus when clearing state on stop/idle - CMakeLists.txt: include mpris.cpp for UNIX non-Apple builds - DesktopEntry matches the installed .desktop filename (smartcode-stremio) - Translate log messages to English for consistency with the codebase
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
On Linux, Stremio does not expose an MPRIS2 D-Bus interface (
org.mpris.MediaPlayer2). This means media controller clients — KDE Connect, GNOME Shell media panel, playerctl, and similar tools — cannot discover or control Stremio playback.This has been a long-standing request (see #391, and the earlier stremio-linux-shell#15). A previous attempt (PR #464) was left unmerged.
Solution
Implement the full MPRIS2 interface using Qt's D-Bus adaptor system (
QDBusAbstractAdaptor), which is already a build dependency (QT += dbus).Two new files, compiled on Linux only:
mpris.h/mpris.cppMprisRootAdaptor— implementsorg.mpris.MediaPlayer2(Identity, CanRaise, Raise, etc.)MprisPlayerAdaptor— implementsorg.mpris.MediaPlayer2.Player:PropertiesChangednotificationxesam:titleandmpris:lengthPlaybackStatus(Playing / Paused / Stopped) by observing mpv propertiespauseandcore-idlethrough the existingmpvEventsignalSeekedsignal emitted after Seek/SetPositionstremio.pro— addsmpris.cpptoSOURCESforunix:!maconly.main.cpp— callsmprisSetup(mpv)after the QML engine loads, locating theMpvObjectinstance viafindChild.Testing
Tested on Debian 13 / KDE Plasma with KDE Connect:
Also verified with
playerctl:Notes
unix:!macguardsstremio.pro; no new dependencies added-Wall -Wextrawithout warnings