Imported playlists with special characters - Scripted Solution

  • 29 October 2022
  • 3 replies
  • 178 views

I’ve been having issues with playlists exported from iTunes, where any songs with special characters in the filename wouldn’t play in the playlist, despite playing fine when playing through my library within Sonos. Support weren’t unable to resolve this, their solution was to export as .xml instead of .m3u or .m3u8 - from what I can see it doesn’t even support .xml playlists.

Anyway I came across this manual workaround within these forums, which did solve the problem, however I have quite a few playlists, with a number of problem tracks in each, I also export regularly to pick up any updates to the playlists so manually editing every time would be a nightmare.

I’ve ended up writing a PowerShell script to fix all of my playlists with one click. I saw a request elsewhere for a script to do this so posting it here in case it is of use to anyone. Simple copy the  script to a new file and save as type .ps1, editing the three variables at the top as per your own structure.

If your playlist path is a network path you can run this from any machine that has access to it, otherwise you will need to copy the script to the machine where the playlist folder resides. Then right click the file and select “Run with Powershell”.

This is probably only useful on Windows, unless you have Powershell installed on another OS. I’m not sure how that will work out of the box though, with the .Net assembly required for UrlEncoding.

#The following two variables are dependant upon your folder structure
#For example my music library physically lives in "D:\John\Music" on the server"
#And the network path to the same folder is "\\MY-SERVER\MediaServer\Music"
#So these variables should be populated with only the parts of the root path that differ
#In this case everthing before "\Music" in the paths
$localRoot = 'D:\John'
$networkRoot = '\\MY-SERVER\MediaServer'

#Path to the location of your exported playlists
$playlistPath = 'D:\John\Music\Playlists\'

#####################################################################
######## You shouldn't need to edit anything below here ########
#####################################################################

Add-Type -AssemblyName System.Web

$localRoot = $localRoot -replace '\\', '\\'

$playlistFiles = Get-ChildItem $playlistPath

foreach($playlistFile in $playlistFiles)
{
$filePathFull = $playlistPath + $playlistFile

$playlistContent = Get-Content $filePathFull

$playlistContent = $playlistContent -replace $localRoot, $networkRoot

$parsedContent = @()

foreach($line in $playlistContent)
{

if ($line -like "*" + $networkRoot + "*")
{
$parsedLine = 'x-file-cifs:' + [System.Web.HTTPUtility]::UrlEncode($line) -replace '%5c', '/'
$parsedContent += $parsedLine
}
else
{
$parsedContent += $line
}
}

Set-Content -Path $filePathFull -Value $parsedContent
}

 


This topic has been closed for further comments. You can use the search bar to find a similar topic, or create a new one by clicking Create Topic at the top of the page.

3 replies

In fact this doesn’t work please pretend you never saw this. The UrlEncoding is different to the one from Excel,

Here’s how I (just last night!) managed to solve the issue with Sonos not recognizing special characters in an imported playlist generated from iTunes in a Windows (10) environment:

    1) Create the .M3U playlist in iTunes

    2) Edit the .M3U file using Notepad.exe, and globally remove all hard drive references:

          Before:  D:\Café Tacuba\Yo Soy [CD Master]\05 Dos Niños.m4a

          After:         \Café Tacuba\Yo Soy [CD Master]\05 Dos Niños.m4a

     3)  Exit Notepad using SAVE AS, and change the file format from UTF-8 to ANSI

     4)  Move the new, edited ANSI version .M3U file to your Sonos music library and rebuild

 

When I updated my music library with the new file, FINALLY, I was able to play all the tracks in the playlist :’)

I should mention that this fix worked for my system which is still running Sonos 8.1 (it´s not connected to internet.  I stream online content via an iPhone connected to a legacy Sonos iPod dock).

 

Your mileage may vary.  Hope this helps.

 

 

 

Thanks, I might try that!

I did eventually manage to update my script so it does it automatically, but it involved finding all the characters that PowerShell's url encoding misinterpreted within my playlists, then hardcoding in a replacement for each one with the correct encoding within the script.

Totally hacky but it now works for all my current playlists, will probably need extending next time it comes across another character it doesn’t like though.

 

function Change-ToNetworkPath 
{
param([string] $path)

if ($path -notlike $networkRoot)
{
$path = $path -replace $localRoot, $networkRoot
$path = 'x-file-cifs:' + [uri]::EscapeDataString($path)
$path = $path -replace '%5c', '/'
}

return $path
}


$serverName = "MY-SERVER"
$networkRoot = '\\' + $serverName + '\MediaServer\'
$localRoot = "D:\\"
$playlistPath = $networkRoot + 'Music\Playlists\'

$playlistFiles = Get-ChildItem $playlistPath

$remove83C2Chars = @('ö','á', 'è', 'à', 'é', 'ä')

foreach($playlistFile in $playlistFiles)
{
$filePathFull = $playlistPath + $playlistFile

$playlistContent = Get-Content $filePathFull

$parsedContent = @()

foreach($line in $playlistContent)
{
$parsedLine = $line

if ($parsedLine -notlike "#EXT*")
{
if (($remove83C2Chars | %{$parsedLine.contains($_)}) -contains $true)
{
$parsedLine = Change-ToNetworkPath($parsedLine)
$parsedLine = $parsedLine -replace '%83%C2', ''
}

if ($parsedLine -like "*Â*")
{
$parsedLine = Change-ToNetworkPath($parsedLine)
$parsedLine = $parsedLine -replace '%C3%83%E2%80%9A', '%C3%82'
}

if ($parsedLine -like "*Å *")
{
$parsedLine = Change-ToNetworkPath($parsedLine)
$parsedLine = $parsedLine -replace '%C3%85%C2%A0', '%C5%A0'
}

if (($parsedLine -like "*Tuk Tuk (feat.*") -and ($parsedLine -like "*Jackmaster & S*"))
{
$parsedLine = Change-ToNetworkPath($parsedLine)
$parsedLine = $parsedLine -replace '%C3%83%E2%80%9E', '%C3%84'
}
}

$parsedContent += $parsedLine
}

Set-Content -Path $filePathFull -Value $parsedContent
}