How to play mp3 from media browser folder?

This is the script I have and it works perfectly. I didn’t need to whitelist anything.

  - service: media_player.play_media
    target:
      entity_id: media_player.speaker
    data:
      media_content_id: '/media/local/file.mp3'
      media_content_type: audio/mp3

I had “music” as the media_content_type at first, but it wasn’t working with my setup. I found out using audio/mp3 has no issue.

8 Likes

Here is, what worked for me:

service: media_player.play_media
data:
  media_content_id: /media/music_party/Anastacia - Not that kind.mp3
  media_content_type: music
target:
  entity_id: media_player.fernseher

This is going to a Google Chrome Cast built into my Philips TV.

I had some trouble finding the correct URL for media_content_id. I finally found the right path by using the method described by @antimage in post #7.

When it finally worked, I had no idea where HA took that path segment “/music_party” from. The files are really stored in the /media partition of HA and the folder is called “/Party”. Later I found that the path is actually built using the media_dirs key from configuration yaml:

homeassistant:
  media_dirs:
    music_party: /media/Party

As you can see I did NOT have to put any host in front of the media_content_id, so no problem with host name vs. IP. Also all the authSig token generation and handling mechanics are done automatically in the background. No need to touch that. The param media_content_type works for me with both “music” and “audio/mp3”.

3 Likes

Thats weird.
Playing mp3 in /config/www in my home assistant with “music” works perfectely on old Sonos. However, on a new Sonos or Amazon Echo I got the error “sorry tts can only be called with notify.alexa_media service”. When I use “audio/mp3” or “audio” or “mp3” instead of music, I don’t get anything at all.

If anyone needs python code to generate a “signed” URL to an .mp3 (or some other asset), I wrote this:

from websocket import create_connection
import json
import sys

# Python code to get a "signed path" to a Home Assistant asset via the websocket API
# As per docs:
# https://developers.home-assistant.io/docs/api/websocket/
# https://developers.home-assistant.io/docs/auth_api/#signed-paths

# Make sure to substitute your server IP, desired path to sign, and long-lived access token
# You can generate your own in HA, click on your username (bottom left) then "Long-Lived Access Tokens" -> "CREATE TOKEN"

host = "192.168.0.158:8123"
path_to_sign = "/media/local/doorbell.mp3"
protocol = "http"
access_token = "XXXXXXXX"

ws = create_connection("ws://%s/api/websocket" % host)
ws.recv()
ws.send(json.dumps({
    "type": "auth",
    "access_token": access_token
}))
auth_resp = json.loads(ws.recv())
if auth_resp.get('type') != 'auth_ok':
    print('failed to login, check your auth token -- response: %s' % (auth_resp))
else:
    ws.send(json.dumps(
    {
      "type": "auth/sign_path",
      "path": path_to_sign,
      "id": 1,
      "expires": 300
    }))
    result = json.loads(ws.recv())
    if result.get('success') == True:
        signed_path = result.get('result').get('path')
        print('%s://%s%s' % (protocol, host, signed_path))
    else:
        print('ERROR: %s' % result)
ws.close()

The sample above return a URL like:
http://192.168.0.158:8123/media/local/doorbell.mp3?authSig=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJkZWU1MzFiNTlkZmY0OTAwYjkxZWMyYTkwZGNlZWEzNCIsInBhdGgiOiIvbWVkaWEvbG9jYWwvZG9vcmJlbGwubXAzIiwicGFyYW1zIjp7fSwiaWF0IjoxNjc2MDg4MTE5LCJleHAiOjE2NzYwODg0MTl9.Fml3y5_NjIwIcnCNq6SUk3s0xmwPXqGnrS7PbMyuryg

Note that the generated URL is only valid for 5 minutes

1 Like

Thanks!
How is it supposed to be used?
Do you have an example?

In my case, I am using at /config/www

So I can use http://IP:8123/local/myfile.mp3

Cons:

Pros:

  • It is in a public folder.
    I can make Alexa to reproduce it.
service: script.run_alexa_custom_skill_notification
data:
  speech: <audio src="https://ha.mydomain.com/local/myfile.mp3" />
  target: media_player.echo_dot_quarto
1 Like

Spent a good two hours pulling my hair out on this one. Soin case anyone else stumbles across this, Jpsy has the solution. There’s no token or auth needed. If you have the media folder set up properly in the config it will work.

2 Likes

Does this only work if you select 1 MP3 or can you also select a folder containing multiple MP3s?

Not sure if this will help you guys, but I just started using an Add-on called “Music assistant”. Works pretty well, and casts to all my Chromecast devices MUCH more reliably than Plex. Just thought I’d toss that out there. The interface is remarkably similar to Plex, but it displays right in HA, which is nice. No switching back and forth between apps. :slight_smile:

This deserves more credit. This is the solution that the docs don’t give you.

I did following and it worked for me. I can also play mp3 files from attached USB external HDD

  1. edit configuration.yaml and enter the following lines

homeassistant:
allowlist_external_dirs:
- /media
media_dirs:
local: /media

  1. I created an automation to play the file. you may be able to use button

action:

  • service: media_player.play_media
    target:
    entity_id: media_player.mpd
    data:
    media_content_type: audio/mp3
    media_content_id: media-source://media_source/local/Dumps/Songs/Bhajans/Hanuman Chalisa/Hanuman Chalisa - Mahendra Kapoor.mp3
    mode: single

You cannot play a folder or playlist without add-ons. This is because HomeAssist does not stream the media files, but only sends a link to the media file to the speaker, and does not process its contents in any way, so HA does not know the current status, i.e. playback duration. And in order to send the next file from a folder or playlist, you need to know that the previous file has finished playing. Something has to keep track of this, which is why media servers and other additional tools are installed for this purpose.

I use the Music Assistant add-on to serve this purpose. Works AWESOME.

solution is to update to version 2024.10.1
the issue is fixed in that version

Any idea what i might be doing wrong? google home speaker gets activated but no music plays… does the place where music file is has to be available on www public folder?

below is my flow

[
    {
        "id": "f95cdc2547c3b160",
        "type": "ha-api",
        "z": "970707c9e290e4c5",
        "name": "Get AuthSign",
        "server": "10d60cb7.4f5173",
        "version": 1,
        "debugenabled": false,
        "protocol": "websocket",
        "method": "get",
        "path": "",
        "data": "{\t   \"type\": \"auth/sign_path\",\t   \"path\": \"http://192.168.1.139:8123/media/local/Securityalarm.mp3\",\t   \"expires\": 300 \t}",
        "dataType": "jsonata",
        "responseType": "json",
        "outputProperties": [
            {
                "property": "payload",
                "propertyType": "msg",
                "value": "",
                "valueType": "results"
            }
        ],
        "x": 390,
        "y": 100,
        "wires": [
            [
                "4c4bfb4630ad677b"
            ]
        ]
    },
    {
        "id": "10d60cb7.4f5173",
        "type": "server",
        "name": "Home Assistant",
        "version": 5,
        "addon": true,
        "rejectUnauthorizedCerts": true,
        "ha_boolean": "y|yes|true|on|home|open",
        "connectionDelay": true,
        "cacheJson": true,
        "heartbeat": false,
        "heartbeatInterval": "30",
        "areaSelector": "friendlyName",
        "deviceSelector": "friendlyName",
        "entitySelector": "friendlyName",
        "statusSeparator": "at: ",
        "statusYear": "hidden",
        "statusMonth": "short",
        "statusDay": "numeric",
        "statusHourCycle": "h23",
        "statusTimeFormat": "h:m",
        "enableGlobalContextStore": true
    }
]