Media Player playlists and how to make them work

Edit: 27 Apr 24 - Setting simplified in script, updated text

For some time now I was lurking the forum, the internet and beyond to make it possible to start a playlist instead of playing a single file each time. But now I have a solution that works for me and hopefully also for you.

Let me say first that my playlist requirements are not that high. My main goal is to select a folder and just play all the music in that folder one after the other, For output I want to send the stream to the available media players that I have in HA . For me that are VLC(-telnet), Mopidy, MPD, Google mini and my Samsung TV

Requirements
To make this work then the Media player you want to use has to support the Previous action. You can check this in the developer tools - Service: Media player: Previous and Targets: Choose entity.
See if the Media player you want to use is there.

The music files you want to play must be accessible from the HA machine !!
To make this possible for media that is not available on your HA server you have to make under Settings - System - Storage - Network Storage a new connection to your NAS or any other place where the media sits.
For me my HA server (HAOS) is a running on a miniPC. My media is on a external USB drive that is connected to a RPi3 configured as a NAS and available in my network as PiNas.

After this your files can be found under the media tab in HA or if you use an other PC like your desktop PC you can see the storage in your file browser when entering \[HA server IP address]\media
In my case its shows up there as a folder named PiNas

How this works
To make this work the following will have to happen

  • Load all music files into the media player.
  • Do media player.previous for each file load minus 1. (so 3 files loaded then 2x previous)
    Now your media player will play your files one after the other.

Okay, I understand this is rather cumbersome to do.
‘Can’t you do better?’
Well yes I can. How? Read further.

I made a python script to handle this workflow for you. It’s not super well written because a lot of error checking is missing but the bare bones are there and the script isn’t doing any dangerous things to your system. Why in Python? Well that way I can support a wide range of OS’s to run it on.

Basically what is does is this.

  • Read your media folder that you want as a playlist
  • Make an automation to do all the actions
  • Write this to a file in the same location as where this script is.

After that you take the file and copy the contents into an automation in HA.
This automation is then your actual playlist

This is the Python script.
Copy it and save it as Playlist_maker.py
There are a few settings that you have to fill in. Hopefully I added enough details for you to figure it out what to fill in. If not then at the end of this post there are more details

Start it with: Playlist_maker.py “playlist name in quotes if it contains spaces” the-music-folder-to-scan
Nothing or ? will to show the help info

# Playlist_maker
# by A.A. van Zoelen
# Version : 1.1 - 27 Apr 2024 - Simplified the settings
# Version : 1.0 - 26 Apr 2024 - Initial release
#
# Description
# This script creates an automation file for Home Assistant
# Just give a folder to scans for files and an automation is
# created to play all the files via VLC-Telnet in HA
#
# Works with the following media players in HA
# - VLC
# - Mopidy
# - Google home mini speakers might work too
#
# Work to do for you, Look at the settings below
# 
# Issues
# - The files must be accesable from the HA machine!
#   Adding as a Network storage is an option to us.
# - Not all media players supports the enqueue option and the
#   previous action. Look in the developers window of HA if
#   these actions are supported by the media player you like to use

import sys
import os

print ('', sys.argv)
if (((len(sys.argv)-1) != 2) or (sys.argv[1] == '?') ):
    print('''
    ***************************************************************************
    * Usage: Playlist_maker.py [playlist name] [music_folder] *
    ***************************************************************************
    * Example:
    *   Playlist name: The name the automation and output file will get.
    *                  If there are spaces in this then use quotes aroud it
    *   music_folder : Mody  (folder containing the music seen from SHAREPATH)
    ***************************************************************************''')
    sys.exit()
playlist_title = sys.argv[1]
output_file    = sys.argv[1]
music_folder   = sys.argv[2]


# ==============
# == SETTINGS ==
# ==============
# If running this on a different machine then your HA machine
# For example running it on a Windows system connecting to a NAS
# Path from share to media folder including trailing /
SHAREPATH = "X:/Media/Audio/"
# In HA you can set a Network Storage
# This is the path from HA(media) to the media folder itself
# containing your music sorted in folders (or not)
# Full path example:
# -  //media_source/local/PiNas/Media/Audio/Moby/03-moby-porcelain.mp3
# Where //media_source/local/ is default
# See: https://www.home-assistant.io/integrations/media_source/
# Path from HA share to media folder including trailing /
HA_SHAREPATH = "PiNas/Media/Audio/"

# Search for these files only
FILE_EXTENTION = ".mp3"

# Media player you want to use
MEDIA_PLAYER = "media_player.vlc_telnet"


# =====================
# == END OF SETTINGS ==
# == No need to edit ==
# ==   below this    ==
# =====================

# Sanitize the folder path and make sure there is a / at the end
music_folder = music_folder.replace('\\','/')
music_folder = music_folder.strip('/')
music_folder = music_folder + "/"

# The header info of the automation
HEADER = "alias: " + playlist_title + """
description: 'Created with Playlist maker v1.0'
trigger: []
condition: []
action: """


# Building the service tag for the automation
SERVICE = """
  - service: media_player.play_media
    target:
      entity_id: """ + MEDIA_PLAYER + """
    data:
      enqueue: 'yes'
      media_content_type: music
      media_content_id: >-
        media-source://media_source/local/"""

# Building the previous action tag for the automation
PREVIOUS = """
  - service: media_player.media_previous_track
    data: {}
    target:
      entity_id: """ + MEDIA_PLAYER

# Making some complete folder paths
Complete_file_path = SHAREPATH + music_folder
Complete_HA_file_path = HA_SHAREPATH + music_folder

print("Searching for files in " + Complete_file_path + "\nFound\n\n")
files_found = []
for filename in os.listdir(Complete_file_path):
    if filename.endswith(FILE_EXTENTION):
        print(filename)
        files_found.append(filename)

        
outputfile = open(output_file + ".yaml", "w")
count = 0
 
# Header for the automation
outputfile.write(HEADER)

#for line in inputfile:
for x in range(len(files_found)):
    outputfile.write(SERVICE)
    outputfile.write(Complete_HA_file_path)
    outputfile.write(files_found[x])
    count = count + 1

# Do previous to get to the first added track
# and start playing from there
while count > 1:
  outputfile.write(PREVIOUS)
  count = count -1 

outputfile.close()

print ("\nReady\nFile saved as : " + output_file)
print ("Add this to Home Assistant as an automation")

Some additional setting details

SHAREPATH
For me this is the path when using my desktop PC with windows. The X drive is connected to my RPi NAS. When I go to this location “X:/Media/Audio/” then I am in my folder that contains my music. Each album is in it’s own separate folder with it’s own name

HA_SHAREPATH
This connects to the same folder as SHAREPATH only this is done from the HA server. In HA go to Media - My Media. From there note the path that you have to follow to get to the same audio folder as in SHAREPATH

FILE_EXTENTION
Include only files with this extension. Sorry, only 1 filetype for now because I don’t need any other. Everything is there for you to expand the code and make this work for you.

MEDIA_PLAYER
Enter here the HA media player you want to use

I am open to any remarks and improvements on this subject

3 Likes

thx for sharing! this maybe should be in community guides?

Oh, where is that and how to do so?

with your blessing, i just changed the category (you had chosen configuration for the category).

1 Like

Shouldn’t the value for “enqueue” be “add”, or possibly “play” for the first one and “add” for the others?
The documentation seems to indicate that.

Just wondering

Thx for your remark
When I look at the documentation is see

enqueue boolean (optional, default: false)

If True, enqueue the media instead of play it.

Sadly a boolean can’t be ‘play’ or ‘add’

Weird… for Service media_player.play_media Service data attribute enqueue I see

How the new media should interact with the queue. Must be one of add, next, play, replace. If the media player doesn’t support this feature, the new media will play and the enqueue directive is ignored.

Oh, I see. You are looking at the configuration variable. Shouldn’t you use the service data attribute"? You put it in the “data” bit.

I am interested. Could you supply a working example because I think we are both looking at different things

I do not have a working example, I was looking at your code and wondering why it had to be that complex.

In any case, with Music Assistant it is all much simpler now.

Cheers

You saw extra.enqueue of media_player.play_media service, instead of enqueue.