Youtube Music Multi Room Audio with Owntone (Supports both Airplay and chromecasts)

Recently, I stumbled upon a new self hosted music player which supported both Sonos(Airplay) and chromecast. I had previously looked into Snapcast. But I wanted to use the nice Nest Audio and Ikea Symfonisk Picture Frame Speakers I had and not have RPIs scattered around the house to run SnapCast Clients. This is where Owntone came up. This is a selfhosted music server which can stream local music from your server to one or many chromecast/Sonos speakers all at onces while maintaining sync across all the devices.

Setup Owntone

Owntone can be setup using docker and thats what I did.

    daapd:
      image: lscr.io/linuxserver/daapd:latest
      container_name: daapd
      network_mode: host
      environment:
        - PUID=1000
        - PGID=1000
        - TZ=America/Los_Angeles
      volumes:
        - ./owntone:/config
        - ~/media/music:/music
      restart: unless-stopped

This will setup the owntone running on your server. Note: Running owntone in network=host mode is critical for it to recognize cast and other wifi speakers in the WI-FI network. This will also run a UI and API on port 3689

Home Assistant Setup

Once you have Owntone server running: Next we will link it with HA
Homeassistant already has a built-in integration for Owntone. This can be setup by going into Settings -> Devices & Services -> Click on Add Integration and Search for Owntone. More Info can be found on the home assistant integration page.
![[Screenshot 2023-06-26 at 5.25.54 PM.png]]

Pipes

The HA owntone integration supports playing music using pipes similar to how MPD and snapcast supports it. So we can send any audio stream into Owntone from HA.
Currently, HA integration only supports a static pipe called librespot-java and a metadata pipe called librespot-java.metadata. These two pipes will be used to send audio stream contents and audio metadata to Owntone. More info here

The pipe needs to be created inside the music folder that we are sharing with owntone as our music library. In my case that path was ~/media/music. So I went ahead and logged into my server to create this pipe. Once you create the pipe, Homeassistant’s owntone integration will automatically detect it.

cd ~/media/music 
mkfifo librespot-java 
mkfifo librespot-java.metadata 

![[Screenshot 2023-06-26 at 5.34.00 PM.png]]
It will also expose all your cast and sonos speakers as its own media_player entities like this

![[Screenshot 2023-06-26 at 5.36.30 PM.png]]

At this point, you can use HA to stream any local music in sync throughout the house using owntone.

YT Music Integration

But I wanted to stream from YT-Music with multiroom-audio and wanted the music to follow me in my house as I move around. So I digged more to find the YT-Music Integration in HACS. This setup is very well explained in the guide, so I will just link it here

Once you have setup the YT Music Integration, all we have to do is take the stream from the media player entity which the YT Music integration creates, (in my case it is media_player.ytube_music_player) and pipe it to owntone.

Hence I created this automation which sets the owntone media player as source for the ytube music player integration.

automation 
- id: ytube_owntone
  alias: Youtube to Owntone
  trigger:
    - platform: state
      entity_id:
        - media_player.ytube_music_player
      to: playing
      id: playing
    - platform: state
      entity_id:
        - media_player.ytube_music_player
      to:
        - idle
        - 'off'
        - paused
      id: 'off'
  action:
    choose:
      - conditions:
          - condition: trigger
            id: playing
        sequence:
          - service: media_player.select_source
            data:
              source: media_player.owntone_server
              entity_id: media_player.ytube_music_player
      - conditions:
          - condition: trigger
            id: 'off'
        sequence:
          - service: media_player.turn_off
            entity_id: media_player.owntone_server

This automation will send the audio streaming from youtube music straight to the owntone server.

MultiRoom Audio

Once we have music streaming to media_player.owntone_speaker. Now I created an automation to make the music follow me around the house.

These are the speakers I have around my house.

  • Living Room
    • media_player.living_room_speaker
    • media_player.living_room_speaker_2
  • Bedroom
    • media_player.bedroom
      I also have presence sensors around my home, so I decided to use the presence to stream music to the dedicated speakers in the room.
      There are two automations which will cover two cases,
  • One will handle routing music to the speaker where there is presence when owntone speaker receives a new audio stream.
automation:
  - id: select_multiroom_audio
    alias: Select Multiroom Audio
    trigger:
      - platform: state
        entity_id:
          - media_player.owntone_server
        to: playing
    condition:
      - condition: state
        entity_id:
          - input_boolean.multiroom_audio
        state: 'on'
    action:
      choose:
        - conditions:
            - condition: state
              entity_id:
                - binary_sensor.bedroom_presence
              state: 'on'
          sequence:
            - service: media_player.turn_on
              entity_id:
                - media_player.owntone_output_bedroom
        - conditions:
            - condition: state
              entity_id:
                - binary_sensor.living_room_presence_presence
              state: 'on'
          sequence:
            - service: media_player.turn_on
              entity_id:
                - media_player.owntone_output_living_room_speaker
                - media_player.owntone_output_living_room_speaker_2

Secondly, once I start moving around the house, I wanted the music to stop playing in the room that I left and start playing in the room that I entered.

automation:
- id: move_music_bw_rooms
    alias: Move Music between rooms
    trigger:
      - platform: state
        to: 'on'
        entity_id:
          - binary_sensor.bedroom_presence
        id: bedroom_presence_on
      - platform: state
        to: 'off'
        entity_id:
          - binary_sensor.bedroom_presence
        id: bedroom_presence_off
      - platform: state
        to: 'on'
        entity_id:
          - binary_sensor.living_room_presence_presence
        id: living_room_presence_on
      - platform: state
        to: 'off'
        entity_id:
          - binary_sensor.living_room_presence_presence
        id: living_room_presence_off
    condition:
      - condition: and
        conditions:
          - condition: state
            entity_id:
              - input_boolean.multiroom_audio
            state: 'on'
          - condition: state
            entity_id:
              - media_player.owntone_server
            state: playing
    action:
      choose:
        - conditions:
            - condition: trigger
              id: bedroom_presence_on
          sequence:
            - service: media_player.turn_on
              entity_id:
                - media_player.owntone_output_bedroom
        - conditions:
            - condition: trigger
              id: bedroom_presence_off
          sequence:
            - service: media_player.turn_off
              entity_id:
                - media_player.owntone_output_bedroom
        - conditions:
            - condition: trigger
              id: living_room_presence_on
          sequence:
            - service: media_player.turn_on
              entity_id:
                - media_player.owntone_output_living_room_speaker
                - media_player.owntone_output_living_room_speaker_2
        - conditions:
            - condition: trigger
              id: living_room_presence_off
          sequence:
            - service: media_player.turn_off
              entity_id:
                - media_player.owntone_output_living_room_speaker
                - media_player.owntone_output_living_room_speaker_2

Now voila!, we have multiroom-audio following presence in each room.
Let me know if there is any questions/need more info on getting this setup.
Sorry for any mistakes in this write up.

5 Likes

This looks awesome. With a quick search I found what appears to be an Owntone HA add-on, but there is no documentation for it.

There is a forum thread but not much said in there


That’s not the server though.

Oh, I am running HA core in a docker container, so I didn’t use the HA addon, but used owntone as a standalone docker container.

Can you update screenshots please?

@sriramsv Can you confirm if this is still working well for you? I saw that may owntone container got updated recently, and I can no longer connect to any of my chromecasts (or nest speakers) from the owntone server. This is the error I get
Request failed (status: 500 Internal Server Error http://owntone.home.lan:3689/api/outputs/721620172/toggle)

@sriramsv : thanks for your tutorial! I installed the owntone docker container in my
 unraid system and I could add the addon in HA. I can also stream a radio stream 
to the owntone_server and it get played on the homepods. What I tried now is to 
use the media stream of one of my homepod mini (`media_player.kuche`) and 
send this to my `owntone_server`. Therefore I made a automation similiar to 
your youtube ones, but instead of `media_player.ytube_music_player` i am 
using `media_player.kuche`.

The automation get triggered correctly, but the `owntone_server` does 
nothing. What could be the problem? Thanks in advance!

EDIT: I have the same issue as described [here](https://community.home-assistant.io/t/error-in-forum-unformatted-code-modale-dialog-not-closing/638829). 
That's why I had to select the whole text as 'preformated text'. Why is this happening?

Thanks for the Example on the Multiroom Audio following you :slight_smile:

I had this working quite flawlessly for a while. But lately when starting the playback, the ytube component might “play” for 5 seconds but then skip to the next song and keep going the same way. At some point It might play some song for a second but then skip to the next one. I might get it working by pausing ytubemusic for a couple of seconds right after a track change and then after a few seconds it starts playing itself correctly? This, after I disabled the automation mentioned in this thread.

I keep getting these errors in log:
13:53:54.613 ERROR (MainThread) [custom_components.ytube_music_player.media_player] signature not found, decoding

and also ERROR (MainThread) [custom_components.ytube_music_player.media_player] chromecast in pause should be playings, <state media_player.owntone_server=idle; source_list=[‘Clear queue’, ‘Default (no pipe)’, ‘librespot-java (pipe)’, (plus list of all my playlists available in owntone)


Edit: for now it seems I got it adequately working by triggering ytubemusic to PAUSE whenever owntone goes IDLE. I did this in Node-RED but I think it’s simple enough to do in HA itself.