| Metadata - mpv-jellyfin - MPV script for adding an interface for Jellyfin. | |
| Log | |
| Files | |
| Refs | |
| README | |
| LICENSE | |
| --- | |
| commit e674db1a8e8867e6ed06a3023a54d5cc10e37afc | |
| parent 04bef7fbe5bcbfd42f4366228394d1b2e6a5d7cc | |
| Author: EmperorPenguin18 <[email protected]> | |
| Date: Tue, 15 Nov 2022 14:31:09 -0500 | |
| Metadata | |
| Diffstat: | |
| M script-opts/jellyfin.conf | 2 ++ | |
| M scripts/jellyfin.lua | 147 +++++++++++++++++++++++++----… | |
| 2 files changed, 122 insertions(+), 27 deletions(-) | |
| --- | |
| diff --git a/script-opts/jellyfin.conf b/script-opts/jellyfin.conf | |
| @@ -1,3 +1,5 @@ | |
| url= | |
| username= | |
| password= | |
| +image_path= | |
| +hide_spoilers= | |
| diff --git a/scripts/jellyfin.lua b/scripts/jellyfin.lua | |
| @@ -4,21 +4,25 @@ local utils = require 'mp.utils' | |
| local options = { | |
| url = "", | |
| username = "", | |
| - password = "" | |
| + password = "", | |
| + image_path = "", | |
| + hide_spoilers = "on" | |
| } | |
| opt.read_options(options, mp.get_script_name()) | |
| local overlay = mp.create_osd_overlay("ass-events") | |
| +local meta_overlay = mp.create_osd_overlay("ass-events") | |
| local connected = false | |
| local shown = false | |
| -local user_id = nil | |
| -local api_key = nil | |
| +local user_id = "" | |
| +local api_key = "" | |
| local library_id = nil | |
| local title_id = nil | |
| local season_id = nil | |
| -local video_id = nil | |
| +local video_id = "" | |
| local selection = 1 | |
| local items = {} | |
| +local ow, oh, op = 0, 0, 0 | |
| local toggle_overlay | |
| @@ -36,26 +40,74 @@ local function send_request(url) | |
| return nil | |
| end | |
| -local function connect() | |
| - local request = mp.command_native({ | |
| - name = "subprocess", | |
| - capture_stdout = true, | |
| - capture_stderr = true, | |
| - playback_only = false, | |
| - args = {"curl", options.url.."/Users/AuthenticateByName", "-H"… | |
| - }) | |
| - local result = utils.parse_json(request.stdout) | |
| - user_id = result.User.Id | |
| - api_key = result.AccessToken | |
| - connected = true | |
| +local function line_break(str, flags, space) | |
| + if str == nil then return "" end | |
| + local text = flags | |
| + local n = 0 | |
| + for i = 1, #str do | |
| + local c = str:sub(i, i) | |
| + if (c == ' ' and i-n > space) or c == '\n' then | |
| + text = text..str:sub(n, i-1).."\n"..flags | |
| + n = i+1 | |
| + end | |
| + end | |
| + text = text..str:sub(n, -1) | |
| + return text | |
| +end | |
| + | |
| +local function update_metadata() | |
| + local metadata = send_request(options.url.."/Users/"..user_id.."/Items… | |
| + local image_data = nil | |
| + for _, image in ipairs(send_request(options.url.."/Items/"..metadata.I… | |
| + if image.ImageType == "Primary" then | |
| + image_data = image | |
| + end | |
| + end | |
| + mp.commandv("overlay-remove", "0") | |
| + if image_data then | |
| + local filepath = options.image_path.."/"..metadata.Name..".bgr… | |
| + local ratio = image_data.Height / image_data.Width | |
| + if ratio > 0.5 then | |
| + local width = math.floor(ow/3) | |
| + local height = math.floor(width*ratio) | |
| + local res = mp.command_native({ name = "subprocess", a… | |
| + mp.commandv("overlay-add", "0", tostring(math.floor(ow… | |
| + end | |
| + end | |
| + | |
| + meta_overlay.data = "" | |
| + local name = line_break(metadata.Name, "{\\a7}{\\fs24}", 30) | |
| + meta_overlay.data = meta_overlay.data..name.."\n" | |
| + local year = "" | |
| + if metadata.ProductionYear then year = metadata.ProductionYear end | |
| + local time = "" | |
| + if metadata.RunTimeTicks then time = " "..math.floor(metadata.RunTim… | |
| + local rating = "" | |
| + if metadata.CommunityRating then rating = " "..metadata.CommunityRat… | |
| + local hidden = "" | |
| + local watched = "" | |
| + if metadata.UserData.Played == false then | |
| + if options.hide_spoilers ~= "off" then hidden = "{\\bord0}{\\1… | |
| + else | |
| + watched = " Watched" | |
| + end | |
| + local favourite = "" | |
| + if metadata.UserData.IsFavorite == true then | |
| + favourite = " Favorite" | |
| + end | |
| + meta_overlay.data = meta_overlay.data.."{\\a7}{\\fs16}"..year..time..r… | |
| + local tagline = line_break(metadata.Taglines[1], "{\\a7}{\\fs20}", 35) | |
| + meta_overlay.data = meta_overlay.data..tagline.."\n" | |
| + local description = line_break(metadata.Overview, "{\\a7}{\\fs16}"..hi… | |
| + meta_overlay.data = meta_overlay.data..description | |
| + meta_overlay:update() | |
| end | |
| local function update_data() | |
| overlay.data = "" | |
| - local ow, oh, op = mp.get_osd_size() | |
| for _, item in ipairs(items) do | |
| - if _ >= selection - (19.5 * op / 1.12) + 1 then | |
| - if _ - selection < (19.5 * op / 1.12) then | |
| + if _ > selection - (53 / op) then | |
| + if _ < selection + (20 * op) then | |
| if _ == selection then | |
| overlay.data = overlay.data.."{\\fs16}… | |
| else | |
| @@ -67,6 +119,20 @@ local function update_data() | |
| overlay:update() | |
| end | |
| +local function resize() | |
| + ow, oh, op = mp.get_osd_size() | |
| +end | |
| + | |
| +local function refresh() | |
| + resize() | |
| + update_data() | |
| + update_metadata() | |
| +end | |
| + | |
| +local function property_change(name, data) | |
| + refresh() | |
| +end | |
| + | |
| local function update_overlay() | |
| local result | |
| if not library_id then | |
| @@ -79,18 +145,20 @@ local function update_overlay() | |
| result = send_request(options.url.."/Items?api_key="..api_key.… | |
| end | |
| items = result.Items | |
| - update_data() | |
| + if ow > 0 then refresh() end | |
| end | |
| local function play_video() | |
| toggle_overlay() | |
| mp.commandv("loadfile", options.url.."/Videos/"..video_id.."/stream?st… | |
| + mp.set_property("force-media-title", items[selection].Name) | |
| end | |
| local function key_up() | |
| selection = selection - 1 | |
| if selection == 0 then selection = table.getn(items) end | |
| update_data() | |
| + update_metadata() | |
| end | |
| local function key_right() | |
| @@ -115,11 +183,12 @@ local function key_down() | |
| selection = selection + 1 | |
| if selection > table.getn(items) then selection = 1 end | |
| update_data() | |
| + update_metadata() | |
| end | |
| local function key_left() | |
| if not library_id then | |
| - --nothing | |
| + return | |
| elseif not title_id then | |
| library_id = nil | |
| elseif not season_id then | |
| @@ -130,20 +199,44 @@ local function key_left() | |
| update_overlay() | |
| end | |
| +local function connect() | |
| + local request = mp.command_native({ | |
| + name = "subprocess", | |
| + capture_stdout = true, | |
| + capture_stderr = true, | |
| + playback_only = false, | |
| + args = {"curl", options.url.."/Users/AuthenticateByName", "-H"… | |
| + }) | |
| + local result = utils.parse_json(request.stdout) | |
| + user_id = result.User.Id | |
| + api_key = result.AccessToken | |
| + connected = true | |
| +end | |
| + | |
| toggle_overlay = function() | |
| if shown then | |
| - overlay:remove() | |
| mp.remove_key_binding("jup") | |
| mp.remove_key_binding("jright") | |
| mp.remove_key_binding("jdown") | |
| mp.remove_key_binding("jleft") | |
| + mp.unobserve_property(property_change) | |
| + mp.commandv("overlay-remove", "0") | |
| + overlay:remove() | |
| + meta_overlay:remove() | |
| else | |
| - if not connected then connect() end | |
| - if table.getn(items) == 0 then update_overlay() end | |
| - mp.add_forced_key_binding("UP", "jup", key_up) | |
| + mp.add_forced_key_binding("UP", "jup", key_up, { repeatable = … | |
| mp.add_forced_key_binding("RIGHT", "jright", key_right) | |
| - mp.add_forced_key_binding("DOWN", "jdown", key_down) | |
| + mp.add_forced_key_binding("DOWN", "jdown", key_down, { repeata… | |
| mp.add_forced_key_binding("LEFT", "jleft", key_left) | |
| + if not connected then | |
| + mp.observe_property("osd-width", number, property_chan… | |
| + connect() | |
| + end | |
| + if table.getn(items) == 0 then | |
| + update_overlay() | |
| + else | |
| + refresh() | |
| + end | |
| end | |
| shown = not shown | |
| end | |
| @@ -151,7 +244,7 @@ end | |
| local function mark_watched(data) | |
| if data.reason == "eof" then | |
| send_request(options.url.."/Users/"..user_id.."/PlayedItems/".… | |
| - video_id = nil | |
| + video_id = "" | |
| end | |
| end | |