Skip to content

Mediaplayer integration with Home Assistant

With dbus2mqtt as a bridge between MPRIS players and Home Assistant, it becomes possible to control Linux based media players via Home Assistant.

The Media Player Remote Interfacing Specification (MPRIS) is a standard for controlling Linux media players. It provides a mechanism for compliant media players discovery, basic playback and media player state control as well as a tracklist interface which is used to add context to the current item.

Pre-requisites:

Features

  • dbus subscription using org.mpris.MediaPlayer2.* wildcard to support multiple concurrent MRPIS players
  • Every 5 seconds, the state of the first known MPRIS player is published to MQTT topic dbus2mqtt/org.mpris.MediaPlayer2/state
  • Every MPRIS property update immediately publishes the state to MQTT topic dbus2mqtt/org.mpris.MediaPlayer2/state
  • Support for player commands (see below)

Setup activities

  • Configure dbus2mqtt using the supplied home_assistant_media_player.yaml
  • Configure the MQTT Sensor and player configuration in Home Assistant as described below

To run, execute the following commands

dbus2mqtt --config docs/examples/home_assistant_media_player.yaml

Tested configurations

The following MPRIS players are known to work with Home Assistant.

Application Play
Pause
Stop Next
Previous
Seek
SetPosition
Volume Quit Media Info Media Image Notes
Firefox Media length/position not always correct Bugzilla 1979495
VLC
Chromium ✔️ Images not working when Chromium is running as snap
Kodi Requires Kodi plugin MediaPlayerRemoteInterface
Spotify

Note

More players that support MPRIS (but have not been tested) can be found here: https://wiki.archlinux.org/title/MPRIS

Player commands

The following table lists player commands, their descriptions, and an example JSON payload for invoking them via MQTT.

Dbus methods can be invoked by sendig the JSON payload to MQTT topic dbus2mqtt/org.mpris.MediaPlayer2/command. Method calls will be done for all matching players. The same applies to property updates.

Method
Property
Description Example MQTT JSON Payload
Play Starts playback { "method": "Play" }
Pause Pauses playback { "method": "Pause" }
PlayPause Toggles between play and pause { "method": "PlayPause" }
Stop Stops playback { "method": "Stop" }
Next Next { "method": "Next" }
Previous Previous { "method": "Previous" }
Seek Seek forward or backward in micro seconds { "method": "Seek", "args": [60000000] }
Volume Set volume (double between 0 and 1) { "property": "Volume", "value": 1.0 }
SetPosition Set / seek to position in micro seconds. First arguments needs to be trackid which can be determined via Metadata.mpris:trackid { "method": "SetPosition", "args": ["/org/mpris/MediaPlayer2/firefox", 170692139] }
Quit Quits the media player { "method": "Quit" }

For an overview of MPRIS commands have a look at https://mpris2.readthedocs.io/en/latest/interfaces.html#mpris2.MediaPlayer2

Home Assistant configuration

Besides setting up dbus2mqtt, Home Assistant needs to be configured as well. The mqtt_mediaplayer.yaml example will publish a MQTT discovery payload for your Home Assistant installation, automatically creation the following sensors:

  • MQTT sensor listening on topic dbus2mqtt/org.mpris.MediaPlayer2/state
  • MQTT image listening on topic dbus2mqtt/org.mpris.MediaPlayer2/artUrlImage

The last part has to be configured by hand. Use the configuration below to create the Media Player component in Home Assistant.

config/packages/mqtt_mediaplayer.yaml
media_player:
  - platform: media_player_template
    media_players:
      mpris_media_player:
        device_class: receiver
        friendly_name: MPRIS Media Player
        value_template: >
          {% set s = states('sensor.mpris_media_player') %}
          {{ s if s not in ['unavailable', 'unknown'] else None }}

        current_volume_template: "{{ state_attr('sensor.mpris_media_player', 'Volume') }}"
        current_is_muted_template: "{{ state_attr('sensor.mpris_media_player', 'VolumeMuted') }}"
        current_position_template: "{{ state_attr('sensor.mpris_media_player', 'MediaPosition') }}"
        title_template: "{{ state_attr('sensor.mpris_media_player', 'MediaTitle') }}"

        media_content_type_template: music  # needed to show 'artist'
        media_duration_template: "{{ state_attr('sensor.mpris_media_player', 'MediaDuration') }}"
        album_template: "{{ state_attr('sensor.mpris_media_player', 'MediaAlbum') }}"
        artist_template: "{{ state_attr('sensor.mpris_media_player', 'MediaArtists') }}"

        # mpris:artUrl might contain a file:// schema. In these cases we rely on images published via MQTT
        media_image_url_template: >-
          {% set media_image_url = state_attr('sensor.mpris_media_player', 'MediaImageUrl') %}
          {% if media_image_url and media_image_url.startswith('file://') %}
            http://127.0.0.1:8123{{ state_attr('image.mpris_media_player_image', 'entity_picture') }}
          {% else %}
            {{ media_image_url }}
          {% endif %}

        turn_off:
          service: mqtt.publish
          data:
            topic: dbus2mqtt/org.mpris.MediaPlayer2/command
            payload: >
              {"method": "Quit"}
        play:
          service: mqtt.publish
          data:
            topic: dbus2mqtt/org.mpris.MediaPlayer2/command
            payload: >
              {"method": "Play"}
        pause:
          service: mqtt.publish
          data:
            topic: dbus2mqtt/org.mpris.MediaPlayer2/command
            payload: >
              {"method": "Pause"}
        stop:
          service: mqtt.publish
          data:
            topic: dbus2mqtt/org.mpris.MediaPlayer2/command
            payload: >
              {"method": "Stop"}
        next:
          service: mqtt.publish
          data:
            topic: dbus2mqtt/org.mpris.MediaPlayer2/command
            payload: >
              {"method": "Next"}
        previous:
          service: mqtt.publish
          data:
            topic: dbus2mqtt/org.mpris.MediaPlayer2/command
            payload: >
              {"method": "Previous"}
        seek:
          service: mqtt.publish
          data:
            topic: dbus2mqtt/org.mpris.MediaPlayer2/command
            payload: >
              { "method": "SetPosition", "args": ["{{ state_attr('sensor.mpris_media_player', 'Metadata')['mpris:trackid'] }}", {{ (position * 1000000) | int }}] }
        set_volume:
          service: mqtt.publish
          data:
            topic: dbus2mqtt/org.mpris.MediaPlayer2/command
            payload: >
              {"property": "Volume", "value": {{volume}} }
        volume_up:
          service: mqtt.publish
          data:
            topic: dbus2mqtt/org.mpris.MediaPlayer2/command
            payload: >
              {"property": "Volume", "value": {{ [1, (state_attr('sensor.mpris_media_player', 'Volume') + 0.1)] | min }} }
        volume_down:
          service: mqtt.publish
          data:
            topic: dbus2mqtt/org.mpris.MediaPlayer2/command
            payload: >
              {"property": "Volume", "value": {{ [0, (state_attr('sensor.mpris_media_player', 'Volume') - 0.1)] | max }} }

Source: mqtt_mediaplayer.yaml