MP3s are everywhere and back in 2014 I finally had a phone with enough storage to store a decent amount of them. I use MediaMonkey to add high resolution album covers and to rename the files in a predictable format: Artist - Album - # - Title
. The only thing I was missing was a simple way of creating a M3U playlist: PowerShell to the rescue!
Generate M3U function
Let's create a function that takes a directory and generates an M3U playlist file:
function GenerateM3U {
param(
[System.IO.DirectoryInfo] $directory,
[string] $playlistFileName = "",
[string] $pattern = "*.mp3"
)
# make sure we add m3u as an extension
if ( "$playlistFileName" -eq "" ) {
$playlistFileName = $directory.Name + ".m3u"
}
elseif ( ! $playlistFileName.EndsWith("m3u") ) {
$playlistFileName = "$playlistFileName.m3u"
}
# store relative paths in the same directory
if ( ! [System.IO.Path]::IsPathRooted($playlistFileName) ) {
$playlistFileName = Join-Path -Path $directory -ChildPath $playlistFileName
}
# remove old file
if ( Test-Path $playlistFileName -PathType Leaf ) {
Remove-Item $playlistFileName
}
# only read mp3 files
if ( ! $pattern.EndsWith(".mp3") ) {
$pattern = "$pattern*.mp3"
}
# write m3u
$directory.GetFiles($pattern) |
ForEach-Object { $_.Name } |
Sort-Object |
Out-File -Encoding UTF8 -FilePath $playlistFileName
}
Now we can call the function in a few different ways to create an M3u playlist:
# generate based on a directory:
GenerateM3U "./Gavin James - For You"
# generate named m3u:
GenerateM3U "./Gavin James - For You" "kees.m3u"
# generate named m3u of certain mp3 files:
GenerateM3U "./Gavin James - For You" "kees2.m3u" "Gavin*.mp3"
# generate m3u in a different directory:
GenerateM3U "./Gavin James - For You" "c:\temp\" "Gavin*.mp3"
Caveat: Out-File encoding
While working on this code I initially omitted the encoding. This led to an MRL exception in VLC:

When inspecting the file in an online HEX editor, we see some weird characters:

This is a UTF-16, little endian, byte order mark -- which is not interpreted correctly by the VLC player. That is why we need to add -Encoding utf8
to the Out-File
statement. This will add an EF BB EF
to the beginning of the file, which means the file is UTF-8 and something VLC understands.
In the comments it is pointed out that -Encoding default
works better for Windows Media Player. It will work for VLC as well, but if your file names contain UTF-8 characters, it will not work anymore.
Final thoughts
Because of the default PowerShell Out-File
encoding, generation of an M3U playlist is less straightforward as I thought. A HEX editor is a great way of debugging these encoding problems.
Improvements
2021-07-09: Added comment about -Encoding default
and Windows Media Player.
2020-12-31: Images are now zoomable.
2020-08-06: Rewrote the article. Created a simple function instead of a script. Added an analysis of the encoding problem VLC was facing.
2014-02-01: Initial article
Hi thats great ;Just what I was looking for!!!
one thing that would really help me and I would be so grateful if you could advise:
Is there a way it could only add the files if they were created after a certain date/time.
Eg if I passed the function a TimeStamp “2020-08-05 15:50:00” could I make the function add all files to the playlist after that time, including sub directories?
Thank you for your help so far!
Baz
Hi Kees,
On my Windows 10 Pro system, if I used
Out-File -Encoding default
it would save in the .m3u file in a UTF-8 format that was readable by Windows Media Player. When I used
Out-File -Encoding utf8
it would save in the .m3u file in a UTF-8 w/ BOM format that was unreadable in Windows Media Player.
Now if I could only figure out how to have PowerShell read the track # from the MP3tag and then create the playlist in the proper order.
Willy
Thanks Willy, I added the comment (a bit late). If you’re still looking into reading MP3 tags, I’ve used https://www.nuget.org/packages/TagLibSharp in a C# project and it works really well. You might be able to use it in PowerShell as well.