Music Assistant - Play n random tracks from Spotify Playlist

I’m trying to write a script that will randomize a spotify playlist and play a configurable number of tracks then stop.

Looking at the docs on the Music Assistant add-on, it seems pretty limited.

The examples show a way to Play a Random Item but it appears that’s only possible when searching tracks in your library.

What I think I need to do is have a way somehow to break a playlist down to its component tracks, then shuffle them, etc.

I thought I had a way to do that by playing the playlist, pausing/stopping the player, then examining the player queue - however, that doesn’t give very much information. Here’s a queue, which shows that there are 16 tracks, but it only shows the current and next track.

media_player.lounge_airplay:
  queue_id: ap00226c01be2e
  active: true
  name: Lounge Speaker
  items: 16
  shuffle_enabled: false
  repeat_mode: "off"
  current_index: 2
  elapsed_time: 110
  current_item:
    queue_item_id: 58ff3efde14349049ded0797cf6bcc8b
    name: Mount Shrine - Winter Restlessness
    duration: 609
    media_item:
      media_type: track
      uri: spotify://track/21Ici4ahxmkC3S73agYGL5
      name: Winter Restlessness
      version: ""
      image: https://i.scdn.co/image/ab67616d0000b27339ac2350560d7a92dbfb6b58
      artists:
        - media_type: artist
          uri: spotify://artist/6Md52GXgJjLniff4TEgHJr
          name: Mount Shrine
          version: ""
          image: null
      album:
        media_type: album
        uri: spotify://album/41XDP8MfJW2hVieF62J0Rl
        name: Winter Restlessness
        version: ""
        image: https://i.scdn.co/image/ab67616d0000b27339ac2350560d7a92dbfb6b58
    stream_title: null
    stream_details:
      content_type: ogg
      sample_rate: 44100
      bit_depth: 16
      provider: spotify--Eh8DNsbw
      item_id: 21Ici4ahxmkC3S73agYGL5
  next_item:
    queue_item_id: 792558e56b7b4a78bf5f73a7eee5d198
    name: Lesa Listvy - Evening by the Lake
    duration: 416
    media_item:
      media_type: track
      uri: spotify://track/6rTX8QNrp1XJc02BIwWHcg
      name: Evening by the Lake
      version: ""
      image: https://i.scdn.co/image/ab67616d0000b2730df488d3a31e410a75034e7e
      artists:
        - media_type: artist
          uri: spotify://artist/6HpbySgoX3F1Qi7NCa1fQe
          name: Lesa Listvy
          version: ""
          image: null
      album:
        media_type: album
        uri: spotify://album/3N2tnOD0qjl2EYIoXds23u
        name: Way Home
        version: ""
        image: https://i.scdn.co/image/ab67616d0000b2730df488d3a31e410a75034e7e
    stream_title: null

I suppose I could:

  1. Add the playlist to the player
  2. Shuffle it
  3. Get the current track
  4. Advance to the next track
  5. Repeat 3-4 n-times to build a new playlist

Not sure if that’s possible, but it’s such a hacky way of doing it that I am holding out hope there’s a better way. Any advice?

Here’s my script so far:

alias: Play Songs From Playlist
description: >-
  Plays a specified number of songs from a playlist, either randomly or in
  original order
fields:
  playlist_uri:
    name: Playlist URI
    description: The playlist URI
    required: true
    selector:
      text: null
  song_count:
    name: Number of Songs
    description: Number of songs to play
    required: true
    selector:
      number:
        min: 1
        mode: box
        unit_of_measurement: songs
    default: 1
  media_player:
    name: Media Player
    description: Media player to play on
    required: true
    selector:
      entity:
        domain: media_player
        multiple: true
  random:
    name: Random Order
    description: Play songs in random order if true, playlist order if false
    required: false
    default: true
    selector:
      boolean: null
sequence:
  - action: music_assistant.play_media
    metadata: {}
    data:
      media_type: playlist
      enqueue: add
      media_id: "{{ playlist_uri }}"
    target:
      entity_id: "{{ media_player }}"
  - action: media_player.media_stop
    metadata: {}
    data: {}
    target:
      entity_id: "{{ media_player }}"
  - action: music_assistant.get_queue
    metadata: {}
    data: {}
    response_variable: tracks
    target:
      entity_id: "{{ media_player }}"

< DO SOMETHING HERE >
      
  - repeat:
      count: "{{ song_count }}"
      sequence:
        - action: music_assistant.play_media
          data:
            media_id: "{{ random_tracks.tracks[repeat.index - 1].uri }}"
            media_type: track
            enqueue: "{{ 'play' if repeat.index == 1 else 'add' }}"
          target:
            entity_id: "{{ media_player }}"

You could utilize SpotifyPlus Integration Services to do some of this (see below). The Spotify Web API Get Users Queue endpoint will only return 20 queue items max, so that option will probably not work for your needs.

SpotifyPlus Services

Get Playlist Items will return a list of all items defined in the playlist; you can also limit the number of total items returned. Note that this will return a TON of data, so be aware if trying to update a sensor with the information (16k max limits); it’s easy to trim the data with a template though if need be (see Queue Info List Dashboard for example on template sensors).

Once you have the tracks, it’s then a matter of shuffling them, or you can simply turn shuffle on and let Spotify do the shuffling for you.

Then you pass the list to something that can play them, like the Player Media Play Tracks service.

Example:

# get playlist items (first 200 max).
service: spotifyplus.get_playlist_items
data:
  entity_id: media_player.spotifyplus_john_s
  playlist_id: 5v5ETK9WFXAnGQ3MRubKuE
  limit_total: 200

# turn shuffle on.
service: spotifyplus.player_set_shuffle_mode
data:
  entity_id: media_player.spotifyplus_john_s
  state: true

# play the list of tracks.
service: spotifyplus.player_media_play_tracks
data:
  entity_id: media_player.spotifyplus_john_s
  uris: spotify:track:6zd8T1PBe9JFHmuVnurdRp,spotify:track:1kWUud3vY5ij5r62zxpTRy, ... etc

If you wanted to, you could take the track list and call the Playlist Create service to create a temporary playlist, then call the Playlist Items Add service to add the tracks to the new temporary playlist, then call the Player Media Play Context service to play the temporary playlist with shuffle turned on. Example:

# create a temp playlist
service: spotifyplus.playlist_create
data:
  entity_id: media_player.spotifyplus_john_s
  name: My Temp Playlist
  description: My temporary playlist.
  public: false
  collaborative: false
  image_path: www/images/spotify_playlist_default_image.png

# add randomized list of tracks to temporary playlist.
service: spotifyplus.playlist_items_add
data:
  entity_id: media_player.spotifyplus_john_s
  playlist_id: [TEMP_PLAYLIST_ID from above service result]
  uris: spotify:track:6zd8T1PBe9JFHmuVnurdRp,spotify:track:1kWUud3vY5ij5r62zxpTRy, ... etc

# turn shuffle on.
service: spotifyplus.player_set_shuffle_mode
data:
  entity_id: media_player.spotifyplus_john_s
  state: true

# play temporary playlist.
service: spotifyplus.player_media_play_context
data:
  entity_id: media_player.spotifyplus_john_s
  context_uri: [TEMP_PLAYLIST_URI (not ID!) from above service result]

Check out the Queue Info List Dashboard wiki topic if you are looking to create sensors of Spotify data; this particular example creates a sensor that is updated with basic track info (name, image, uri, artist name) when the currently playing track changes. The sensor is then referenced in a dashboard that displays current Spotify queue info.

Hope it helps!

1 Like