u/Jochen_der_Rochen

▲ 136 r/VLC+1 crossposts

hi, i have vibe coded a VLC plugin to view my jellyfin library directly from VLC (no copy stream URL necessary). maybe helpful for some of you too. here are the necessary steps for macOS, for windows/linux i have no idea:

  1. navigate to System/Volumes/Data/Applications/VLC.app/Contents/MacOS/share/lua/sd
  2. create a file called jellyfin.lua
  3. paste the following content in the file:
-- jellyfin.lua (Single-File Service Discovery)

local json = require("dkjson")

-- ================= CONFIGURATION =================
local JELLYFIN_URL = "YOUR_JELLYFIN_URL"
local API_KEY = "YOUR_JELLYFIN_API_KEY" -- generate api key in jellyfin admin dashboard
local USER_ID = "YOUR_JELLYFIN_USER_ID" -- not the username, click on your profile in the jellyfin browser page,  will appear in the url then
-- =================================================

function descriptor()
    return { title = "Jellyfin Library" }
end

-- Helper to download and parse JSON from the API
function fetch_json(url)
    local stream = vlc.stream(url)
    if not stream then return {} end
    
    local content = ""
    local line = ""
    repeat
        line = stream:readline()
        if line then content = content .. line end
    until line == nil
    
    return json.decode(content) or {}
end

-- Main function builds the entire tree on load
function main()
    -- Get the user's libraries (e.g., "Movies", "TV Shows")
    local views_url = JELLYFIN_URL .. "/Users/" .. USER_ID .. "/Views?api_key=" .. API_KEY
    local views_data = fetch_json(views_url)
    
    if views_data and views_data.Items then
        for _, library in ipairs(views_data.Items) do
            local ctype = library.CollectionType or "unknown"
            
            if ctype == "tvshows" then
                -- 1. Create the main "TV Shows" Folder
                local tv_node = vlc.sd.add_node({ title = "📺 " .. library.Name })
                
                -- 2. Fetch all TV Series inside this library
                local shows_url = JELLYFIN_URL .. "/Users/" .. USER_ID .. "/Items?ParentId=" .. library.Id .. "&IncludeItemTypes=Series&Recursive=true&api_key=" .. API_KEY
                local shows_data = fetch_json(shows_url)
                
                for _, show in ipairs(shows_data.Items or {}) do
                    -- 3. Create a Folder for each specific TV Show (e.g., "The Discounters")
                    local show_node = tv_node:add_subnode({ title = "📂 " .. show.Name })
                    
                    -- 4. Fetch all Episodes for this specific TV Show
                    local eps_url = JELLYFIN_URL .. "/Users/" .. USER_ID .. "/Items?ParentId=" .. show.Id .. "&IncludeItemTypes=Episode&Recursive=true&api_key=" .. API_KEY
                    local eps_data = fetch_json(eps_url)
                    
                    for _, ep in ipairs(eps_data.Items or {}) do
                        -- 5. Add the actual playable episode files into the Show folder
                        local season = ep.ParentIndexNumber or 0
                        local ep_num = ep.IndexNumber or 0
                        local formatted_title = string.format("S%02dE%02d - %s", season, ep_num, ep.Name)
                        
                        show_node:add_subitem({
                            title = formatted_title,
                            path = JELLYFIN_URL .. "/Videos/" .. ep.Id .. "/stream?static=true&api_key=" .. API_KEY,
                            arturl = JELLYFIN_URL .. "/Items/" .. ep.Id .. "/Images/Primary?api_key=" .. API_KEY
                        })
                    end
                end
                
            else
                -- 1. Create the main "Movies" Folder
                local movie_node = vlc.sd.add_node({ title = "🎬 " .. library.Name })
                
                -- 2. Fetch all Movies and add them directly as playable items
                local movies_url = JELLYFIN_URL .. "/Users/" .. USER_ID .. "/Items?ParentId=" .. library.Id .. "&IncludeItemTypes=Movie&Recursive=true&api_key=" .. API_KEY
                local movies_data = fetch_json(movies_url)
                
                for _, movie in ipairs(movies_data.Items or {}) do
                    movie_node:add_subitem({
                        title = movie.Name,
                        path = JELLYFIN_URL .. "/Videos/" .. movie.Id .. "/stream?static=true&api_key=" .. API_KEY,
                        arturl = JELLYFIN_URL .. "/Items/" .. movie.Id .. "/Images/Primary?api_key=" .. API_KEY
                    })
                end
            end
        end
    end
end
  1. replace YOUR_JELLYFIN_URL, YOUR_JELLYFIN_API_KEY and YOUR_JELLYFIN_USER_ID with your credentials
  2. restart VLC
  3. done! you should see the jellyfin library as in the attached screenshot
u/Jochen_der_Rochen — 26 days ago