diff options
-rw-r--r-- | main.lua | 187 |
1 files changed, 133 insertions, 54 deletions
@@ -6,7 +6,7 @@ local utils = require('mp.utils') local font_size = 20 local colours = { default='{\\c}', - category='{\\c&H99DDFF&}', + group='{\\c&H99DDFF&}', selected='{\\c&HFF00&}', title='{\\c&999999&}', search_hl='{\\c&FFDD&}', @@ -17,7 +17,9 @@ local colours = { } local script_dir = mp.get_script_directory() -local stream_prefix = mp.get_opt('iptv_menu.stream_prefix') +local xc_server = mp.get_opt('iptv_menu.xc_server') +local xc_user = mp.get_opt('iptv_menu.xc_user') +local xc_pass = mp.get_opt('iptv_menu.xc_pass') local osd = mp.create_osd_overlay('ass-events') local osd_lines = math.floor((720 / font_size) + 0.5) - 1 @@ -33,7 +35,7 @@ osd_bg.data = '{\\pos(0,0)}' .. colours.bg .. local objects = {} local favourites -local playing_stream_id +local playing_id local depth = 0 local menus = {} @@ -63,61 +65,73 @@ local function write_json_file(fn, data) f:close() end -local function add_object(v) - objects[v.id] = v +local function add_object(obj) + objects[obj.id] = obj - if v.type == 'category' then - v.children = {} + if obj.type == 'group' then + obj.children = {} end - if not v.parent_id or not objects[v.parent_id] then + if not obj.parent_id or not objects[obj.parent_id] then return end - local parent_children = objects[v.parent_id].children - parent_children[#parent_children+1] = v + local parent_children = objects[obj.parent_id].children + parent_children[#parent_children+1] = obj end -local function load_section(prefix, name) +local function load_section(section, name) add_object({ - id=prefix .. ':category:0', - type='category', - name=name, + section=section, + type='group', + group_type='category', + id=section .. ':category:0', parent_id='root', + name=name, }) - local tmp = read_json_file(prefix .. '_categories.json') + local tmp = read_json_file(section .. '_categories.json') for _, v in ipairs(tmp) do - v.type = 'category' - v.id = prefix .. ':' .. v.type .. ':' .. v.category_id + v.section = section + v.type = 'group' + v.group_type = 'category' + v.id = section .. ':category:' .. v.category_id + v.parent_id = section .. ':category:' .. v.parent_id v.name = v.category_name - v.parent_id = prefix .. ':' .. v.type .. ':' .. v.parent_id add_object(v) end - tmp = read_json_file(prefix .. '_streams.json') + tmp = read_json_file(section .. '_streams.json') for _, v in ipairs(tmp) do - v.type = 'stream' - v.id = prefix .. ':' .. v.type .. ':' .. v.stream_id - v.parent_id = prefix .. ':category:' .. v.category_id + v.section = section + if v.series_id then + v.type = 'group' + v.group_type = 'series' + v.id = section .. ':series:' .. v.series_id + else + v.type = 'stream' + v.id = section .. ':stream:' .. v.stream_id + end + v.parent_id = section .. ':category:' .. v.category_id add_object(v) end end local function load_data() add_object({ + type='group', id='root', - type='category', }) add_object({ + type='group', id='favourites', - type='category', - name='Favourites', parent_id='root', + name='Favourites', }) load_section('live', 'Live TV') load_section('movie', 'Movies') + load_section('series', 'Series') favourites = read_json_file('favourites.json') -- json loading/dumping breaks when the table is empty, so we need a @@ -161,8 +175,8 @@ local function update_osd() if i == menu.cursor and not menu.search_active then col = colours.selected icons = col .. '› ' .. icons - elseif opt.type == 'category' then - col = colours.category + elseif opt.type == 'group' then + col = colours.group end if opt.matches then @@ -180,9 +194,9 @@ local function update_osd() str = col .. str end - if opt.type == 'category' then + if opt.type == 'group' then str = col .. '[' .. str .. ']' - elseif opt.stream_id == playing_stream_id then + elseif opt.id == playing_id then icons = icons .. colours.icon_playing .. '\226\143\186 ' end @@ -279,44 +293,108 @@ local function push_menu(t) menus[depth] = menu end -local function category_menu_options(category_id) - if category_id == 'favourites' then - local options = {} - for id in pairs(favourites) do - v = objects[id] - if v then - options[#options+1] = v +local function favourites_group_menu_options(group) + local options = {} + for id in pairs(favourites) do + local obj = objects[id] + if obj then + options[#options+1] = obj + end + end + return options +end + +local function get_series_info(series_id) + local cmd = 'curl -sSfL \'' .. xc_server .. '/player_api.php' .. + '?username=' .. xc_user .. '&password=' .. xc_pass .. '&' .. + 'action=get_series_info&series_id=' .. series_id .. '\'' + print('exec: ' .. cmd) + local fd = io.popen(cmd) + local json = fd:read('*all') + fd:close() + return utils.parse_json(json) +end + +local function series_group_menu_options(series) + local info = get_series_info(series.series_id) + + if not info or not info.seasons then + return {} + end + + local seasons = {} + for _, season in pairs(info.seasons) do + local episodes = {} + local season_num = tostring(season.season_number) + if info.episodes[season_num] then + for i, episode in pairs(info.episodes[season_num]) do + episodes[#episodes+1] = { + name=episode.title, + type='stream', + stream_type='series', + id=series.section .. ':stream:' .. + episode.id, + stream_id=episode.id, + } end end - return options + + seasons[#seasons+1] = { + type='group', + group_type='season', + id=series.section .. 'series:season:' .. season.id, + children=episodes, + name=season.name, + } + end + + return seasons +end + +local function group_menu_options(group) + if group.id == 'favourites' then + return favourites_group_menu_options(group) + end + + if group.group_type == 'series' then + return series_group_menu_options(group) end - return objects[category_id].children + return group.children end -local function push_category_menu(category_id, title) +local function push_group_menu(group) push_menu({ - options=category_menu_options(category_id), - title=title, + options=group_menu_options(group), + title=group.name, }) update_osd() end -local function play_stream(stream_id) - -- add a per-file option containing the stream_id, allowing it to be +local function play_stream(stream) + -- add a per-file option containing the stream id, allowing it to be -- retrieved when a start-file event is received - mp.commandv('loadfile', stream_prefix .. stream_id, 'replace', -1, - 'script-opt=iptv_menu.tmp.stream_id=' .. stream_id) + local url + if stream.stream_type == 'series' then + url = xc_server .. '/series/' .. xc_user .. '/' .. xc_pass .. + '/' .. stream.stream_id .. '.vod' + else + url = xc_server .. '/' .. xc_user .. '/' .. xc_pass .. '/' .. + stream.stream_id + end + + mp.commandv('loadfile', url, 'replace', -1, + 'script-opt=iptv_menu.playing_id=' .. stream.id) end local function select_option() local menu = menus[depth] local opt = menu.options[menu.cursor] - if opt.type == 'category' then - push_category_menu(opt.id, opt.name) + if opt.type == 'group' then + push_group_menu(opt) else - play_stream(opt.stream_id) + play_stream(opt) end end @@ -359,11 +437,12 @@ local function search_menu_options_build(options, t, path) v.path = path t[v.type][#t[v.type]+1] = v - if v.type == 'category' and v.id ~= 'favourites' then + if v.type == 'group' and v.id ~= 'favourites' + and v.group_type ~= 'series' then local path = copy_table(path) path[#path+1] = v search_menu_options_build( - category_menu_options(v.id), t, path) + group_menu_options(v), t, path) end end end @@ -373,7 +452,7 @@ local function search_menu_options(options) search_menu_options_build(options, t) -- display categories before streams - local ret = t.category or {} + local ret = t.group or {} if t.stream then for _, v in ipairs(t.stream) do ret[#ret+1] = v @@ -583,16 +662,16 @@ local function toggle_menu() end mp.register_event('start-file', function() - playing_stream_id = tonumber(mp.get_opt('iptv_menu.tmp.stream_id')) + playing_id = tonumber(mp.get_opt('iptv_menu.playing_id')) update_osd() end) mp.register_event('end-file', function() - playing_stream_id = nil + playing_id = nil update_osd() end) mp.add_forced_key_binding('TAB', 'toggle-menu', toggle_menu) bind_menu_keys() load_data() -push_category_menu('root') +push_group_menu(objects['root']) |