• 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 General Questions Convert m3u, m3u8 or xspf to jellyfin's XML

     
    • 0 Vote(s) - 0 Average

    Convert m3u, m3u8 or xspf to jellyfin's XML

    Looking for a script
    johnson
    Offline

    Junior Member

    Posts: 18
    Threads: 7
    Joined: 2024 May
    Reputation: 0
    Country:United States
    #1
    2025-01-23, 06:05 PM
    Does anyone know of an automated way to turn an xspf, m3u or any other playlist from VLC into Jellyfin's XML format? I can create folders & images manually but the playlist conversion is a PITA to do manually.

    Looking for a script, website, or other automated way of doing this. xspf uses full filepaths of media files so it shouldn't be an issue... just can't find the right tool.
    TheDreadPirate
    Offline

    Community Moderator

    Posts: 15,375
    Threads: 10
    Joined: 2023 Jun
    Reputation: 460
    Country:United States
    #2
    2025-01-23, 06:30 PM
    If the M3U is using absolute paths, you can just put it in Jellyfin and it will read the M3U. If you then want it to be in a proper Jellyfin playlist, you can click on the "..." context menu for the playlist and then "Add to playlist" and create a new one. It will add the entire contents of the M3U playlist into a Jellyfin playlist.

    XSPF MIGHT be supported. I see xspf in one of the mimetype files, but I don't see references to it in other parts of Jellyfin's code.
    Jellyfin 10.10.7 (Docker)
    Ubuntu 24.04.2 LTS w/HWE
    Intel i3 12100
    Intel Arc A380
    OS drive - SK Hynix P41 1TB
    Storage
        4x WD Red Pro 6TB CMR in RAIDZ1
    [Image: GitHub%20Sponsors-grey?logo=github]
    johnson
    Offline

    Junior Member

    Posts: 18
    Threads: 7
    Joined: 2024 May
    Reputation: 0
    Country:United States
    #3
    2025-01-23, 06:48 PM (This post was last modified: 2025-01-23, 06:50 PM by johnson. Edited 1 time in total.)
    (2025-01-23, 06:30 PM)TheDreadPirate Wrote: If the M3U is using absolute paths, you can just put it in Jellyfin and it will read the M3U.  If you then want it to be in a proper Jellyfin playlist, you can click on the "..." context menu for the playlist and then "Add to playlist" and create a new one.  It will add the entire contents of the M3U playlist into a Jellyfin playlist.


    Hmm.

    This is the format of my m3u playlist:
    Code:
    #EXTM3U
    #EXTINF:153,The Beach Boys - Wouldn’t It Be Nice (Remastered 2000 / Stereo Mix)
    file:///media/me/music/The%20Beach%20Boys/Pet%20Sounds%20(Original%20Mono%20&%20Stereo%20Mix)/15.%20The%20Beach%20Boys%20-%20Wouldn't%20It%20Be%20Nice.flac

    Jellyfin recognizes that there is a playlist but it is empty, even after re-scanning both the playlist and music libraries for new metadata. Even restarted JF, but the playlists are still empty.

    Edit to add: That is the absolute path, beginning with /media/me....
    TheDreadPirate
    Offline

    Community Moderator

    Posts: 15,375
    Threads: 10
    Joined: 2023 Jun
    Reputation: 460
    Country:United States
    #4
    2025-01-23, 07:12 PM
    If you are using Docker to run Jellyfin, do those absolute paths match the same path from within the container's reference frame?
    Jellyfin 10.10.7 (Docker)
    Ubuntu 24.04.2 LTS w/HWE
    Intel i3 12100
    Intel Arc A380
    OS drive - SK Hynix P41 1TB
    Storage
        4x WD Red Pro 6TB CMR in RAIDZ1
    [Image: GitHub%20Sponsors-grey?logo=github]
    johnson
    Offline

    Junior Member

    Posts: 18
    Threads: 7
    Joined: 2024 May
    Reputation: 0
    Country:United States
    #5
    2025-01-23, 07:21 PM
    (2025-01-23, 07:12 PM)TheDreadPirate Wrote: If you are using Docker to run Jellyfin, do those absolute paths match the same path from within the container's reference frame?


    I'm not using docker, installed on Ubuntu 24.04 LTS, bare metal. Paths are accurate.
    TheDreadPirate
    Offline

    Community Moderator

    Posts: 15,375
    Threads: 10
    Joined: 2023 Jun
    Reputation: 460
    Country:United States
    #6
    2025-01-23, 08:09 PM (This post was last modified: 2025-01-23, 08:09 PM by TheDreadPirate.)
    Remove all the URL encoded characters and replace them with what they should be in plain text. Looks like theyre all %20 in the example (spaces).

    And remove "file: //" So it is just a plain absolute path. You also don't need any of the #EXT lines. I recall another user had better results with M3U playlists once they removed all the extraneous #EXT tags.
    Jellyfin 10.10.7 (Docker)
    Ubuntu 24.04.2 LTS w/HWE
    Intel i3 12100
    Intel Arc A380
    OS drive - SK Hynix P41 1TB
    Storage
        4x WD Red Pro 6TB CMR in RAIDZ1
    [Image: GitHub%20Sponsors-grey?logo=github]
    johnson
    Offline

    Junior Member

    Posts: 18
    Threads: 7
    Joined: 2024 May
    Reputation: 0
    Country:United States
    #7
    2025-01-23, 09:18 PM (This post was last modified: 2025-01-23, 09:23 PM by johnson. Edited 5 times in total.)
    For anyone else who does a search, I wrote my own little python script. This gets you 90% of the way and the last 10% is manual. All steps are below.

    1. Export playlist from VLC in xspf format. Name it input.xspf
    2. Run the script below in the terminal $ python3 convert_xspf_to_xml.py. It will create a file called output.xml
    3. In output.xml, manually change the url encoded characters to spaces, apostrophes, etc. Do a search for % (the percent sign). Use "Find & Replace All" to do replace these out quickly.
    4. Manually delete the text
    file: // Again, "Find & Replace All" does this in one shot
    5. Create a Playlist in Jellyfin with one song in the JF app/UI. Give your playlist a title.
    6. Navigate to
    /var/lib/jellyfin/data/playlists/ and find your playlist folder, in that folder there will be a playlist.xml file. Open it and add in the extra songs from your output.xml file. Then save it.
    7. Rescan metadata in Jellyfin.
    8. Profit.


    Code:
    import xml.etree.ElementTree as ET

    def parse_xspf(file_path):
        tree = ET.parse(file_path)
        root = tree.getroot()
       
        # Define the namespace dictionary
        ns = {'xspf': 'http://xspf.org/ns/0/', 'vlc': 'http://www.videolan.org/vlc/playlist/ns/0/'}
       
        playlist_items = []

        # Iterate through each track in the trackList and extract relevant information
        for track in root.find('xspf:trackList', ns):
            location = track.find('xspf:location', ns).text

            playlist_item = ET.Element("PlaylistItem")
            path_elem = ET.SubElement(playlist_item, "Path")
            path_elem.text = location
           
            playlist_items.append(playlist_item)

        return playlist_items

    def generate_xml(output_path, playlist_items):
        root_element = ET.Element("Item")

        # Add static elements inside the Item element
        added = ET.SubElement(root_element, "Added")
        lock_data = ET.SubElement(root_element, "LockData")
        local_title = ET.SubElement(root_element, "LocalTitle")
        running_time = ET.SubElement(root_element, "RunningTime")
        owner_user_id = ET.SubElement(root_element, "OwnerUserId")
       
        # Add empty elements
        added.text = ""
        lock_data.text = ""
        local_title.text = ""
        running_time.text = ""
        owner_user_id.text = ""

        shares = ET.SubElement(root_element, "Shares")
        playlist_media_type = ET.SubElement(root_element, "PlaylistMediaType")
        playlist_media_type.text = "Audio"

        # Create PlaylistItems element and append PlaylistItem elements
        playlist_items_elem = ET.SubElement(root_element, "PlaylistItems")
       
        for item in playlist_items:
            playlist_items_elem.append(item)
       
        tree = ET.ElementTree(root_element)
        tree.write(output_path, encoding='utf-8', xml_declaration=True)

    def main():
        input_file = 'input.xspf'  # Path to the XSPF file
        output_file = 'output.xml'  # Desired path for the output XML file

        playlist_items = parse_xspf(input_file)
       
        generate_xml(output_file, playlist_items)

    if __name__ == "__main__":
        main()

    Save & run this as:
    convert_xspf_to_xml.py
    1
    « Next Oldest | Next Newest »

    Users browsing this thread: 1 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