Skip to content

Add MPRIS2 support on Linux#487

Open
CaioDamascenoAlves wants to merge 3 commits into
Stremio:masterfrom
CaioDamascenoAlves:feature/mpris2-linux-support
Open

Add MPRIS2 support on Linux#487
CaioDamascenoAlves wants to merge 3 commits into
Stremio:masterfrom
CaioDamascenoAlves:feature/mpris2-linux-support

Conversation

@CaioDamascenoAlves
Copy link
Copy Markdown

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.cpp

  • MprisRootAdaptor — implements org.mpris.MediaPlayer2 (Identity, CanRaise, Raise, etc.)
  • MprisPlayerAdaptor — implements org.mpris.MediaPlayer2.Player:
    • PlayPause, Play, Pause, Stop, Seek, SetPosition
    • Volume read/write with PropertiesChanged notification
    • Metadata (title, duration) via xesam:title and mpris:length
    • Real-time PlaybackStatus (Playing / Paused / Stopped) by observing mpv properties pause and core-idle through the existing mpvEvent signal
    • Seeked signal emitted after Seek/SetPosition

stremio.pro — adds mpris.cpp to SOURCES for unix:!mac only.

main.cpp — calls mprisSetup(mpv) after the QML engine loads, locating the MpvObject instance via findChild.

Testing

Tested on Debian 13 / KDE Plasma with KDE Connect:

  • Player appears in KDE Connect media controller automatically
  • Play / Pause works
  • Volume slider works (bidirectional — phone updates when changed in app)
  • Track title and duration show correctly
  • Status transitions (Playing → Paused → Stopped) are accurate

Also verified with playerctl:

playerctl -p stremio status   # Playing / Paused / Stopped
playerctl -p stremio metadata  # title, length
playerctl -p stremio volume 0.5

Notes

  • No changes to Windows or macOS builds — all new code is inside unix:!mac guards
  • QtDBus is already linked in stremio.pro; no new dependencies added
  • Builds with -Wall -Wextra without warnings

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()
Copilot AI review requested due to automatic review settings May 17, 2026 16:28
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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_title and m_duration without notifying that Metadata changed, so controllers can keep displaying stale metadata after a track stops or finishes. Include Metadata in this PropertiesChanged emission 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.

Comment thread main.cpp
if (root) {
MpvObject *mpv = root->findChild<MpvObject*>();
if (mpv) {
mprisSetup(mpv);
Comment thread mpris.cpp
Comment on lines +123 to +128
if (m_idle) {
m_title.clear();
m_duration = 0.0;
}
emitPropertiesChanged({{"PlaybackStatus", playbackStatus()}});
}
Comment thread mpris.cpp Outdated
Comment on lines +54 to +55
map["mpris:trackid"] = QVariant::fromValue(
QDBusObjectPath("/org/stremio/track/0")
Comment thread mpris.cpp Outdated
Comment on lines +106 to +107
void MprisPlayerAdaptor::SetPosition(const QDBusObjectPath &, qlonglong positionUs)
{
Comment thread main.cpp Outdated
if (mpv) {
mprisSetup(mpv);
} else {
qWarning("MPRIS: MpvObject não encontrado na árvore QML");
Comment thread mpris.cpp Outdated
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");
Comment thread mpris.h Outdated
bool canRaise() const { return true; }
bool hasTrackList() const { return false; }
QString identity() const { return "Stremio"; }
QString desktopEntry() const { return "stremio"; }
Comment thread mpris.cpp

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";
Comment thread mpris.cpp Outdated
: 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
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.

2 participants