mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-05-04 18:09:12 +03:00
Adding a track to a playlist changes all absolute paths to relative paths in m3u8 playlist #975
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @SegiH on GitHub (Oct 9, 2019).
Describe the bug
I am using Jellyfin 10.4 on Windows 10 64 bit. I use m3u8 playlists instead of the default XML format because they are easier to work with and back up. I have a music library that points to E:\Music and a folder called Playlists in E:\Music which contains 28 playlist m3u8 files. This has worked perfectly pre 10.4. Before updating to 10.4, when I would add a track to the playlist, if I open the m3u8, you can see that a new entry has been added for the song with the absolute path to the song.
After upgrading to 10.4, when you add a song to an m3u8 playlist, it replaces all absolute paths to all songs in the playlists with a relative path ..\
For example E:\Music\Beethoven\Immortal Beloved\02 Fur Elise.mp3 would be replaced with ..\Beethoven\Immortal Beloved\02 Fur Elise.mp3
It does not do this for only the song that you have just added but every single song in the playlist.
I tested this in the web UI and on Android and the problem exists on both platforms so it is a server related issue.
To Reproduce
Expected behavior
I would expect that the server not replace all of the absolute paths with relative ones.
Logs
After replacing the paths with relative ones, an error appears in the server logs for each track in the playlist:
[2019-10-09 10:03:08.339 -07:00] [WRN] Unable to find linked item at path "..\Beethoven\Immortal Beloved\02 Fur Elise.mp3"
Screenshots
N/A
System (please complete the following information):
Additional context
@anthonylavado commented on GitHub (Oct 15, 2019):
Is it this by any chance?
0ccbc2f374/Emby.Server.Implementations/Playlists/PlaylistManager.cs (L410-L437)Specifically L418, and L436-437
Edit: Maybe it's not? According to the blame, that was already there since last year. Unless this is just showing up now
@JustAMan commented on GitHub (Oct 16, 2019):
This looks very suspicious indeed, and we might've changed something in the code flow (like uncomment some call to a function) which made this particular (unchanged) part to start executing now.
@SegiH commented on GitHub (Oct 16, 2019):
This seems to be the more likely explanation. It was working fine in 10.3.6.
Based on the release date of 10.3.6 and looking at the commits to this cs class there doesn't seem to be any significant changes.
Also want to add that in 10.4.0 if you add a song to an m3u8 playlist it removes all songs that were previously in the playlist and replaces it with the song that you have just added so it only has 1 track
@SegiH commented on GitHub (Oct 21, 2019):
As far as previous playlist items being removed, I wonder if in the method AddToPlaylistInternal in PlaylistManager.cs which looks like this:
`
Could the line
var items = GetPlaylistItems(itemIds, playlist.MediaType, user, options) .Where(i => i.SupportsAddingToPlaylist) .ToList();, specifically i.SupportsAddingToPlaylist cause the previous playlist items to be removed from the playlist ?
@SegiH commented on GitHub (Nov 4, 2019):
Downgraded to 10.3.7 a few minutes ago and can confirm that the problem isn't there on 10.3.7
@anthonylavado commented on GitHub (Nov 6, 2019):
@SegiH I'm having this issue happen to me in 10.3.7, with a .M3U playlist (on my Mac).
It starts like this:
and then when I add a song using the interface, it changes to:
@anthonylavado commented on GitHub (Nov 6, 2019):
And I can confirm the same behaviour in the latest version of Emby (4.2.1.0 at the time of writing). This is apparently expected behaviour.
Maybe there is an issue with permissions when you're running Jellyfin 10.3.7, such that it can't modify the playlist file, but it will modify the library database entries? Could you attach a playlist of yours that has this issue?
@JustAMan commented on GitHub (Nov 6, 2019):
That is a very strange expected behaviour to see... looks more like unnoticed bug or incorrect design decision to me.
@anthonylavado commented on GitHub (Nov 6, 2019):
@JustAMan Everywhere I look, it seems that it’s because it can only access things in your library, and thus the paths need to match.
https://emby.media/community/index.php?/topic/73348-m3u-music-playlist/page-3
@SegiH commented on GitHub (Nov 6, 2019):
I downgraded from 10.4.0 to 10.3.7 and strangely, I am now seeing this behavior where the tracks are added using a relative path to the m3u8 file.
For example, this is the contents of Classical.m3u8
After adding a track to this m3u8 playlist, all paths that begin with E:\Music\ are replaced with ..\ for all existing tracks as well as the track that was just added.
On 10.4.0, the problem is even worse. When you add a song to a playlist, Jellyfin automatically removes all of the previous tracks and only retains the one that you just added, also with a relative path.
What is strange is that before upgrading to to 10.4.0, tracks to an m3u8 playlist were added with an absolute path not a relative one. It almost seems like after upgrading to 10.4.0 then downgrading back to 10.3.7 causes this bug to happen again. I know for sure that songs were NOT added to an m3u8 with a relative playlist when I was originally on 10.3.7 and before upgrading to 10.4.0. I had edited the m3u8 previously when I was on 10.3.7 (and before upgrading to 10.4) and the paths were always absolute paths.
@anthonylavado commented on GitHub (Nov 6, 2019):
I bisected from 10.4.0 all the way back to 10.2.2, setting up entirely new libraries (erasing the whole configuration each time), and this still happened with the playlist samples I posted.
@anthonylavado commented on GitHub (Nov 6, 2019):
@SegiH It would have been interesting to know if when you added music before, if it actually got saved in to the playlist file or not.
@SegiH commented on GitHub (Nov 6, 2019):
What do you mean exactly ?
@anthonylavado commented on GitHub (Nov 10, 2019):
Investigation Notes
All testing carried out using 10.4.1. I did check 10.3.7 behaviour, see the Conclusion section for details.
Initial Setup
Starting with a clean system, I have imported a music library containing a playlist. The playlist is structured as follows:
The files are in those respective folders. The playlist is named
Classical.m3u8, and is located in/Volumes/Library/Sample/Music/Playlists.I have verified that the music files in this playlist work as intended.
Library Database
Upon import, the playlist gets copied in to the database. In
Library.db, there is a table called "TypedBaseItem". The following query returns all playlists:SELECT * FROM TypedBaseItems WHERE TYPE = "MediaBrowser.Controller.Playlists.Playlist"In
Library.db, there is a column namedData, where JSON may be stored. In the case of the playlist, it is this:Adding A New Song, different root folder
I added a new song from a different root folder. At this point, the following happened:
Volumes/Library/Sample/Music/Beethoven/Immortal Beloved/02 Fur Elise.mp3becomes../Beethoven/Immortal Beloved/02 Fur Elise.mp3)2edc10e15d1cc7e39b58159644b0dde8to00000000000000000000000000000000)Viewing the Playlist
When you go to view the playlist in the browser, it is empty. This is because of the null ItemId. When the ItemId is null, the server doesn't know which folder to start from for the relative path search. As a result, the entry is considered "Invalid". In the logs/console, this is confirmed with a log entry for each file, indicating "Unable to find linked item at path". Attempting to play the playlist in this broken state just results in a "PlaybackError" with message "PlaybackErrorNoCompatibleStream".
Recovery Method
If the ItemId for the songs are inserted back in to the database JSON, the item will return in the playlist. This is presumably because it has a full absolute path (in the column named "Path").
The Library Becomes The Truth
If you attempt to fix the issue by putting absolute paths back in the playlist file, this will not affect the entry in the database. This is because the system considers the database version to be the authoritative copy, and the disk one to be simply a backup.
Adding a song, again, deletes data
If you continue to add another song to the playlist, all the now invalid entries (the original list, the first song added), are removed. This happens to the playlist entry in the library, and also to the file on disk!
This is presumably because the invalid entries are considered not to exist, and playlists are written to when updated. At this point, your original playlist is lost, and it is not possible to restore it.
An Alternate Scenario
When a new song is added from the Music library, to the playlist, there are two different scenarios to consider:
Note that in each case, the playlist is written to when it is updated.
Scenario 1
In this case, assume the following structure:
The playlist may have an absolute path in it:
When the song "Resonance" is added, the paths are written, relative to the playlist:
This will work, and will not result in the blanking of ItemId in the database. Adding further songs from subfolders will work.
Scenario 2
In this case, assume the following structure:
The playlist may have an absolute path in it:
When the song "Resonance" is added, the paths are written relative to the playlist:
This will fail.
This results in the blanking of ItemId in the database, and further songs will also fail, resulting in the wiping of "invalid" entries from the playlist file on disk.
Conclusion
There are several issues at hand:
Rewriting the paths to be relative appears to be inherited code from Emby (see forum post).
However, in 10.3.7, adding an item does not blank the ItemId in the database. This behaviour appears to be new to versions 10.4.0+. As a result, playlists are breaking.
What changed that caused this? Was it the change in database journalling? Was it an unrelated change in a query?
@anthonylavado commented on GitHub (Jan 7, 2020):
Using this query to search for commits that might have affected this:
is:pr is:closed merged:2019-07-24..2019-11-04 base:master@anthonylavado commented on GitHub (Jan 8, 2020):
So in this section of code:
76b4ba3c5e/Emby.Server.Implementations/Playlists/PlaylistManager.cs (L462-L465)If I take line 464 and change it to:
Then the playlist modifications succeed.
@dkanada commented on GitHub (Jan 8, 2020):
Now we need to think of the ramifications from changing that line for other playlists.
@anthonylavado commented on GitHub (Jan 8, 2020):
@dkanada That's true. This was just part of the investigation. Testing this in 10.3.7 just now confirms that the file paths are made relative, exactly as what happens in 10.4.x. It seems that starting in the newer version, it can't find the files/make the relative path, so then it "loses" it, and thus the item is scheduled for removal.
@SegiH commented on GitHub (Jan 8, 2020):
Great to hear that you found a possible solution
@anthonylavado commented on GitHub (Jan 8, 2020):
https://github.com/jellyfin/jellyfin/pull/1168
In versions prior to 10.4.z, under
MakeAbsolutePath, this is thetryfor the update:595a68b822/Emby.Server.Implementations/IO/ManagedFileSystem.cs (L126-L131)In 10.4.z, this is the same code:
d8c3b26fa6/Emby.Server.Implementations/IO/ManagedFileSystem.cs (L108-L111)This is the source of the issue with file paths.