local utils = require('mp.utils') local script_dir = mp.get_script_directory() local stream_prefix = mp.get_opt('iptv_menu.stream_prefix') function load_json_file(path) local f = io.open(script_dir .. '/' .. path, 'r') local data = f:read('*all') f:close() return utils.parse_json(data) end local osd = mp.create_osd_overlay('ass-events') local osd_lines = 23 local categories = load_json_file('categories.json') local streams = load_json_file('streams.json') local depth = 1 local menus = {categories} local menu_top = {1} local menu_pos = {1} function update_osd() local out = {} for i = menu_top[depth], math.min( menu_top[depth] + osd_lines - 1, #menus[depth]) do local key = (depth == 1 and 'category_name' or 'name') local str = menus[depth][i][key] if i == menu_pos[depth] then str = '{\\c&HFF00&}* ' .. str .. '{\\c&HFFFFFF&}' end out[#out+1] = str end osd.data = '{\\q2}' .. table.concat(out, '\\N') osd:update() end function handle_up() if menu_pos[depth] <= 1 then return end menu_pos[depth] = menu_pos[depth] - 1 if menu_pos[depth] < menu_top[depth] then menu_top[depth] = menu_top[depth] - 1 end update_osd() end function handle_down() if menu_pos[depth] >= #menus[depth] then return end menu_pos[depth] = menu_pos[depth] + 1 if menu_pos[depth] > menu_top[depth] + osd_lines - 1 then menu_top[depth] = menu_top[depth] + 1 end update_osd() end function select_category() local cat = categories[menu_pos[depth]] local menu = {} for _, v in ipairs(streams) do if v['category_id'] == cat['category_id'] then menu[#menu+1] = v end end depth = depth + 1 menus[depth] = menu menu_top[depth] = 1 menu_pos[depth] = 1 update_osd() end function select_stream() local url = stream_prefix .. menus[depth][menu_pos[depth]]['stream_id'] mp.commandv('loadfile', url) end function handle_enter() if depth == 1 then select_category() else select_stream() end end function handle_backspace() if depth > 1 then depth = depth - 1 end update_osd() end mp.add_forced_key_binding('UP', 'up', handle_up, {repeatable=true}) mp.add_forced_key_binding('DOWN', 'down', handle_down, {repeatable=true}) mp.add_forced_key_binding('ENTER', 'enter', handle_enter) mp.add_forced_key_binding('BS', 'backspace', handle_backspace) update_osd()