#Play music: GPT + Music Assistant

1 messages · Page 1 of 1 (latest)

frozen iris
#

Sure, let me paste some code here,

#

Here's sentence:

language: "en"
intents:
  PlayMedia:
    data:
      - sentences:
        - "play {media}"
        requires_context:
          area:
            slot: true
      - sentences:
        - "play {media} in [the | a] <area>"
#

Intent script:

PlayMedia:
  action:
    - service: script.play_media_request
      data:
        f_prompt: "Play {{ media }}"
        f_area: "{{ area }}"
  async_action: true
  speech:
    text: "Playing {{ media }}"
#

Here's play_media_request script:

play_media_request:
  alias: Play media request
  sequence:
  - action: script.refine_play_request
    metadata: {}
    data:
      f_prompt: '{{ f_prompt }}'
    response_variable: input
  - choose:
    - conditions:
      - condition: template
        value_template: '{{ input.type == "movie" or input.type == "show" }}'
      sequence:
      - data:
          f_search_string: '{{ input.title }}'
          f_media_type: ' {{ iif(input.type == ''show'', ''Series'', ''Movie'') }}'
        response_variable: play_result
        action: script.play_video_on_jellyfin
      - stop: Result
        response_variable: play_result
    - conditions:
      - condition: template
        value_template: '{{ input.type == "music" }}'
      sequence:
      - action: script.play_on_music_assistant
        metadata: {}
        data:
          f_artist: '{{ input.artist or ''''}}'
          f_album: '{{ input.album or '''' }}'
          f_track: '{{ input.track or ''''}}'
          f_areas: '{{ [input.area or f_area] }}'
        response_variable: play_result
      - stop: Result
        response_variable: play_result
  description: ''
  icon: mdi:multimedia
  fields:
    f_prompt:
      selector:
        text:
      name: Prompt
      required: true
      default: music
    f_area:
      selector:
        area:
          entity:
            integration: mass
          multiple: false
      name: Area
      required: false
#

Sorry, there's also video there, but Jellyfin integration is broken pretty much... I have bug filed about it.

#

Anyways, there's refine_request:

refine_play_request:
  alias: Refine play request
  sequence:
  - data:
      agent_id: conversation.openai_conversation
      text: 'Parse following user play prompt and return the type (music, movie or
        show). If prompt includes room name, add it into response as "area" field.
        If it''s music - then also return artist, album and track, if it''s possible,
        otherwise don''t include that fields in your response. If it''s video, return
        its title. Format your response as JSON, omit unnecessary wrapping symbols.
        Prompt is: "{{ f_prompt }}"'
    response_variable: processed
    action: conversation.process
  - variables:
      json_data: '{{ processed.response.speech.plain.speech | from_json }}'
  - variables:
      result:
        type: '{{ json_data.type }}'
        artist: '{{ iif(json_data.artist, json_data.artist, None) }}'
        album: '{{ iif(json_data.album, json_data.album, None) }}'
        track: '{{ iif(json_data.track, json_data.track, None) }}'
        title: '{{ iif(json_data.title, json_data.title, None) }}'
        area: '{{ iif(json_data.area, json_data.area, None) }}'
  - stop: Result
    response_variable: result
  fields:
    f_prompt:
      selector:
        text:
      name: Prompt
      required: true
  description: ''
#

After that it goes to:

#
play_on_music_assistant:
  alias: Play on Music Assistant
  sequence:
  - variables:
      v_media_type: "{% if f_track %}\n  track\n{% elif f_album %}\n  album\n{% elif
        f_artist %}\n  artist\n{% endif %}"
      v_search: "{% if f_track %}\n  {{ f_track }}\n{% elif f_album %}\n  {{ f_album
        }}\n{% elif f_artist %}\n  {{ f_artist }}\n{% endif %}"
      v_players: '{{ f_areas|map(''area_entities'')
        |map(''select'', ''in'', integration_entities(''mass''))
        |map(''list'')|sum(start = []) }}'
  - variables:
      result:
        message: "{% if v_players is defined %}\n  Playing {{ v_search }} \n{% else %}\n  No suitable
          players found.\n{% endif %}"
  - if:
    - condition: template
      value_template: '{{ v_players is defined }}'
    then:
    - action: mass.search
      metadata: {}
      data:
        limit: 1
        name: '{{ v_search }}'
        artist: '{{ f_artist }}'
        album: '{{ f_album }}'
        media_type:
        - '{{ v_media_type }}'
      response_variable: search_result
    - action: mass.play_media
      metadata: {}
      data:
        media_id: '{{ search_result[v_media_type + ''s''][0].uri }}'
        media_type: '{{ v_media_type }}'
        artist: '{{ f_artist }}'
        album: '{{ f_album }}'
      target:
        entity_id: '{{ v_players }}'
    - action: media_player.shuffle_set
      metadata: {}
      data:
        shuffle: true
      target:
        entity_id: '{{ v_players }}'
  - stop: Result
    response_variable: result
#
  description: ''
  icon: mdi:music
  fields:
    f_artist:
      selector:
        text:
      name: Artist
      required: false
    f_album:
      selector:
        text:
      name: Album
      required: false
    f_track:
      selector:
        text:
      name: Track
      required: false
    f_areas:
      selector:
        area:
          entity:
            integration: mass
          multiple: true
      name: Areas
      required: true
#

Sorry this last one is in two messages, too long for single