• Login
  • Register
  • Login Register
    Login
    Username/Email:
    Password:
    Or login with a social network below
  • Forum
  • Website
  • GitHub
  • Status
  • Translation
  • Features
  • Team
  • Rules
  • Help
  • Feeds
User Links
  • Login
  • Register
  • Login Register
    Login
    Username/Email:
    Password:
    Or login with a social network below

    Useful Links Forum Website GitHub Status Translation Features Team Rules Help Feeds
    Jellyfin Forum Support Guides, Walkthroughs & Tutorials [Guide] Recoving lost playlists

     
    • 0 Vote(s) - 0 Average

    [Guide] Recoving lost playlists

    ryogamasaki
    Offline

    Junior Member

    Posts: 2
    Threads: 1
    Joined: 2025 Feb
    Reputation: 0
    Country:Japan
    #1
    2025-09-26, 06:13 AM
    Playlists are an incredibly useful feature when you have a large music library, and have a number of playlists that I've ported around from various music libraries and tools over the years, and now finally to Jellyfin,with which I am extremely happy.

    Except for when it deletes all my playlists.In my particular case, if I rebooted the server running Jellyfin and the NFS share to the NAS machine hadn't come up, then Jellyfin would delete all the playlists since the files were no longer present. This would happen as a startup task clearing out playlists. That task can be changed to run at an interval instead of startup (and has been changed in my configuration), that doesn't help much ifit's already happened and the playlists are gone.

    Fortunately, Jellyfin logs each of the files removed when they are not found. Unfortunately, there's not a straightforward way to restore them. But it can be done, so let's get into it.

    There are two methods that can be used, but in both cases, we need to find the log file that contains all the removed entries. The logs are stored at /var/log.jellyfin by default. Inside that directory run a grep to find which logs contain the playlist entries:

    Code:
    grep -l "cannot be found at" jellyfin*.log

    Copy the file somewhere else where it can be worked with (and because Jellyfin cycles logs, so it may disappear after a couple days), perhaps to your home directory.

    The first method is quite straightforward. It will pull all the entries out and generate a good old fashioned .m3u file for each playlist. Copy this shell script into a file (we'll call it restore_playlists1.sh) and make it executable:

    Code:
    #!/bin/bash

    regex='^.*Item in \"(.+)\" cannot be found at \"(.+)\"$'

    while read line; do
            if [[ $line =~ $regex ]]; then
                    playlist="${BASH_REMATCH[1]}.m3u"
                    item="${BASH_REMATCH[2]}"
                    echo "$item" >> "$playlist"
            fi
    done
    Then pipe the contents of the log file into the script:
    Code:
    ./restore_playlists1.sh < jellyfin20250926.log
    (As always, don't trust blocks of random shell code from the internet. Give it a quick review before executing.)
    This will generate .m3u files within the working directory. You can then copy these into e.g. your music folder and rescan your library, and the playlists will be available. However,playlists imported from m3u's will not be modifiable: you will need to make a "native" Jellyfin playlist. This can be done by opening the m3u playlist, then clicking the three dots in the upper right, then select "Add to playlist" and create a new list using this old list's content. This is fine if you only have a small handful of playlists, but if you have dozens, you will probably want to try method 2 instead...
    The second method involves reconstructing the "native" Jellyfin XML playlists, reimporting them, and changing the owner ID. As above, you need the log file containing the removed entries. You will also need to get your owner ID (this can be found when going to your profile: it is the userId value in the url). Save this script (we'll call it restore_playlists2.sh) and make it executable:
    Code:
    #!/bin/bash

    regex='^.*Item in \"(.+)\" cannot be found at \"(.+)\"$'

    owner_id="user_id_here

    function make_xml_string() {
            out=$1
            out=$(echo "$out" | sed 's/&/\&amp;/g')
            out=$(echo "$out" | sed 's/</\&lt;/g')
            out=$(echo "$out" | sed 's/>/\&gt;/g')
            out=$(echo "$out" | sed 's/"/\&quot;/g')
            out=$(echo "$out" | sed "s/'/\&apos;/g")
            echo "$out"
    }

    while read line; do
            if [[ $line =~ $regex ]]; then
                    dir="${BASH_REMATCH[1]}"
                    item="${BASH_REMATCH[2]}"
                    item=$(make_xml_string "$item")
                    mkdir -p "$dir"
                    playlist="$dir/playlist_temp.xml"
                    touch "$playlist"
                    echo "    <PlaylistItem>" >> "$playlist"
                    echo "      <Path>$item</Path>" >> "$playlist"
                    echo "    </PlaylistItem>" >> "$playlist"
            fi
    done

    for dir in */; do
            echo "Creating playlist ${dir%/}"
            playlist_temp="${dir}playlist_temp.xml"
            playlist="${dir}playlist.xml"
            if [ -f "$playlist_temp" ]; then
                    title=${dir%/}
                    title=$(make_xml_string "$title")
                    touch "$playlist"
                    # byte order mark
                    printf '\xef\xbb\xbf' > "$playlist"
                    echo "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>" >> "$playlist"
                    echo "<Item>" >> "$playlist"
                    echo "  <Added>09/26/2025 10:40:07</Added>" >> "$playlist"
                    echo "  <LockData>false</LockData>" >> "$playlist"
                    echo "  <LocalTitle>${dir%/}</LocalTitle>" >> "$playlist"
                    echo "  <RunningTime>10</RunningTime>" >> "$playlist"
                    echo "  <OwnerUserId>245f053498fe4295b60ca2447b0ecd89</OwnerUserId>" >> "$playlist"
                    echo "  <PlaylistItems>" >> "$playlist"
                    cat "$playlist_temp" >> "$playlist"
                    echo "  </PlaylistItems>" >> "$playlist"
                    echo "  <Shares />" >> "$playlist"
                    echo "  <PlaylistMediaType>Audio</PlaylistMediaType>" >> "$playlist"
                    echo "</Item>" >> "$playlist"
                    rm -f "$playlist_temp"
            fi
    done

    Be sure to modify the owner_id variable at the top of the file.

    Before we run it, we need to clean up the remnants of the old playlists, which, despite being gone, will still have files that are empty.

    The playlists are located in /var/lib/jellyfin/data/playlists

    Assuming that you have lost all playlists are are redoing everything, you can simply remove all files in this directory: rm -rf /var/lib/jellyfin/data/playlists/*

    Jellyfin also stores the playlists in the library database. This is a sqlite database located at /var/lib/jellyfin/data/library.db. We will want to remove all playlist entries from here:

    Code:
    echo "delete from TypedBaseItems where type = 'MediaBrowser.Controller.Playlists.Playlist';" | sqlite3 /var/lib/jellyfin/data/library.db

    Within Jellyfin itself, you'll want to go to Admin Dashboard -> Schedulaed Tasks and manually run Scan Media Library. This will ensure all traces of the playlists are gone.
    We now runt to run the script to restore the XML playlists. This is best done from within the playlists directory itself. Note that you'll need to either become super user or the jellyfin user (if it is configured with a shell) to access the jellyfin data directory. After doing so:

    Code:
    cd /var/lib/jellyfin/data/playlists
    /home/user/restore_playlists2.sh < /home/user/jellyfin20250926.log
    chown -r jellyfin:jellyfin *

    With the XML playlists in place, re-run the Scan Media Library task within Jellyfin. The playlists are back! BUT.... we can't add to them, or change the order...
    This is because Jellyfin (for some reason) does notuse the Owner ID tag within the playlist XML when importing to the database. So we will need to manually set this within library.db:

    Code:
    echo "update TypedBaseItems set data=replace(data, '\"OwnerUserId\":\"00000000000000000000000000000000\"', '\"OwnerUserId\":\"your_user_id_here\"') where type = 'MediaBrowser.Controller.Playlists.Playlist';" | sqlite3 /var/lib/jellyfin/data/library.db

    At this point, the playlists should be fully restored.
    « Next Oldest | Next Newest »

    Users browsing this thread: 2 Guest(s)


    • View a Printable Version
    • Subscribe to this thread
    Forum Jump:

    Home · Team · Help · Contact
    © Designed by D&D - Powered by MyBB
    L


    Jellyfin

    The Free Software Media System

    Linear Mode
    Threaded Mode