diff --git a/addon.xml b/addon.xml index 86ef693..1feaa39 100644 --- a/addon.xml +++ b/addon.xml @@ -1,18 +1,19 @@ - + - - - - - - + + + + + + + video - + Stream Live Indian Channels From JioTV on Kodi Enjoy Live TV experience in Kodi. @@ -24,51 +25,65 @@ kodi@botallen.com https://github.com/tobalan/plugin.video.jiotv -[- 2.3.4 -] -[added] AAC multi-audio fix (3rd Jun 2023) -[added] Genres selection in Settings with Languages -[added] EPG Source URL editable in Settings -[added] Settings sections rearranged, removed 'Welcome-donate' popup. + [- 2.3.7 -] + [added] fix for runtime error in channel list -[- 2.3.3 -] -[added] updated epg url -[added] set epg cache to false -[added] updset useInputstreamAdaptiveforHls to true + [- 2.3.6 -] + [added] language filter -[- 2.3.2 -] -[added] generate playlist is off by default + [- 2.3.5 -] + [added] handle playback exceptions + [added] remove unused code + [added] save mobile no automatically on login + [added] added request dependency for lower version + [added] revert inputstreamhelper dependency version -[- 2.3.1 -] -[added] caching of reponses + [- 2.3.4 -] + [added] AAC multi-audio fix (3rd Jun 2023) + [added] Genres selection in Settings with Languages + [added] EPG Source URL editable in Settings + [added] Settings sections rearranged, removed 'Welcome-donate' popup. -[- 2.3.0 -] -[added] more extra channels -[added] inputstream adaptive as a dependency + [- 2.3.3 -] + [added] updated epg url + [added] set epg cache to false + [added] updset useInputstreamAdaptiveforHls to true -[- 2.2.0 -] -[fixed] Bugs related to playback -[added] Login with OTP + [- 2.3.2 -] + [added] generate playlist is off by default -[- 2.1.0 -] + [- 2.3.1 -] + [added] caching of reponses -[added] Kodi Matrix support -[added] Star channels support + [- 2.3.0 -] + [added] more extra channels + [added] inputstream adaptive as a dependency -[- 2.0.14 -] + [- 2.2.0 -] + [fixed] Bugs related to playback + [added] Login with OTP -[added] Featured Content + [- 2.1.0 -] -[- 2.0.13 -] + [added] Kodi Matrix support + [added] Star channels support -[added] Web login + [- 2.0.14 -] -[- 2.0.0 -] + [added] Featured Content -[fixed] All major issues related to playback almost solved -[added] Categorized by Language -[added] Filter channels by specific language in genre. (from settings) + [- 2.0.13 -] + + [added] Web login + + [- 2.0.0 -] + + [fixed] All major issues related to playback almost solved + [added] Categorized by Language + [added] Filter channels by specific language in genre. (from settings) - This plugin is not officially commissioned/supported by Jio. The trademark "Jio" is registered by "Reliance Corporate IT Park Limited (RCITPL)" + This plugin is not officially commissioned/supported by Jio. The trademark "Jio" + is registered by "Reliance Corporate IT Park Limited (RCITPL)" resources/icon.png resources/icon.png @@ -78,4 +93,4 @@ true - + \ No newline at end of file diff --git a/changelog.txt b/changelog.txt index 6fa8d2e..c852242 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,9 @@ +[- 2.3.4 -] +[added] AAC multi-audio fix (3rd Jun 2023) +[added] Genres selection in Settings with Languages +[added] EPG Source URL editable in Settings +[added] Settings sections rearranged, removed 'Welcome-donate' popup. + [- 2.3.3 -] [added] updated epg url [added] set epg cache to false diff --git a/resources/lib/constants.py b/resources/lib/constants.py index cc6718a..cce059e 100644 --- a/resources/lib/constants.py +++ b/resources/lib/constants.py @@ -5,13 +5,13 @@ from codequick.script import Settings ADDON = xbmcaddon.Addon() +ADDON_ID = 'plugin.video.jiotv' # Urls IMG_PUBLIC = "https://jioimages.cdn.jio.com/imagespublic/" IMG_CATCHUP = "https://jiotv.catchup.cdn.jio.com/dare_images/images/" IMG_CATCHUP_SHOWS = "https://jiotv.catchup.cdn.jio.com/dare_images/shows/" PLAY_URL = "plugin://plugin.video.jiotv/resources/lib/main/play/?" -PLAY_EX_URL = "plugin://plugin.video.jiotv/resources/lib/main/play_ex/?_pickle_=" FEATURED_SRC = "https://tv.media.jio.com/apis/v1.6/getdata/featurednew?start=0&limit=30&langId=6" CHANNELS_SRC_NEW = "https://jiotv.data.cdn.jio.com/apis/v3.0/getMobileChannelList/get/?langId=6&os=android&devicetype=phone&usertype=tvYR7NSNn7rymo3F&version=285" CHANNELS_SRC = CHANNELS_SRC_NEW if Settings.get_boolean( @@ -24,7 +24,7 @@ ADDON.getAddonInfo("profile")), "jiotv-epg.xml.gz") M3U_CHANNEL = "\n#EXTINF:0 tvg-id=\"{tvg_id}\" tvg-name=\"{channel_name}\" group-title=\"{group_title}\" tvg-chno=\"{tvg_chno}\" tvg-logo=\"{tvg_logo}\"{catchup},{channel_name}\n{play_url}" # EPG_SRC = "https://kodi.botallen.com/tv/epg.xml.gz" -EPG_SRC = "https://tobalan.github.io/epg.xml.gz" +EPG_SRC = ADDON.getSetting("epgsource") DICTIONARY_URL = "https://jiotvapi.cdn.jio.com/apis/v1.3/dictionary/dictionary?langId=6" IMG_CONFIG = { diff --git a/resources/lib/main.py b/resources/lib/main.py index af42721..e2c99e9 100644 --- a/resources/lib/main.py +++ b/resources/lib/main.py @@ -14,7 +14,7 @@ # add-on imports from resources.lib.utils import getTokenParams, getHeaders, isLoggedIn, login as ULogin, logout as ULogout, check_addon, sendOTPV2, get_local_ip, getChannelHeaders, quality_to_enum, _setup, kodi_rpc, Monitor, getCachedChannels, getCachedDictionary, cleanLocalCache, getFeatured -from resources.lib.constants import GET_CHANNEL_URL, IMG_CATCHUP, PLAY_URL, IMG_CATCHUP_SHOWS, CATCHUP_SRC, M3U_SRC, EPG_SRC, M3U_CHANNEL, IMG_CONFIG, EPG_PATH +from resources.lib.constants import GET_CHANNEL_URL, IMG_CATCHUP, PLAY_URL, IMG_CATCHUP_SHOWS, CATCHUP_SRC, M3U_SRC, EPG_SRC, M3U_CHANNEL, IMG_CONFIG, EPG_PATH, ADDON, ADDON_ID # additional imports import urlquick @@ -158,7 +158,30 @@ def show_listby(plugin, by): }) +def is_lang_allowed(langId, langMap): + if langId in langMap.keys(): + return Settings.get_boolean(langMap[langId]) + else: + return Settings.get_boolean("Extra") + + +def is_genre_allowed(id, map): + if id in map.keys(): + return Settings.get_boolean(map[id]) + else: + return False + + +def isPlayAbleLang(each, LANG_MAP): + return not each.get("channelIdForRedirect") and is_lang_allowed(str(each.get("channelLanguageId")), LANG_MAP) + + +def isPlayAbleGenre(each, GENRE_MAP): + return not each.get("channelIdForRedirect") and is_genre_allowed(str(each.get("channelCategoryId")), GENRE_MAP) + # Shows channels by selected filter/category + + @Route.register def show_category(plugin, categoryOrLang, by): resp = getCachedChannels() @@ -169,39 +192,52 @@ def show_category(plugin, categoryOrLang, by): def fltr(x): fby = by.lower()[:-1] if fby == "genre": - return GENRE_MAP[str(x.get("channelCategoryId"))] == categoryOrLang + return GENRE_MAP[str(x.get("channelCategoryId"))] == categoryOrLang and isPlayAbleLang(x, LANG_MAP) else: if (categoryOrLang == 'Extra'): - return str(x.get("channelLanguageId")) not in LANG_MAP.keys() + return str(x.get("channelLanguageId")) not in LANG_MAP.keys() and isPlayAbleGenre(x, GENRE_MAP) else: if (str(x.get("channelLanguageId")) not in LANG_MAP.keys()): return False - return LANG_MAP[str(x.get("channelLanguageId"))] == categoryOrLang + return LANG_MAP[str(x.get("channelLanguageId"))] == categoryOrLang and isPlayAbleGenre(x, GENRE_MAP) + try: + flist = list(filter(fltr, resp)) + if len(flist) < 1: + yield Listitem.from_dict(**{ + "label": "No Results Found, Go Back", + "callback": show_listby, + "params": { + "by": by + } + }) + else: + for each in flist: + litm = Listitem.from_dict(**{ + "label": each.get("channel_name"), + "art": { + "thumb": IMG_CATCHUP + each.get("logoUrl"), + "icon": IMG_CATCHUP + each.get("logoUrl"), + "fanart": IMG_CATCHUP + each.get("logoUrl"), + "clearlogo": IMG_CATCHUP + each.get("logoUrl"), + "clearart": IMG_CATCHUP + each.get("logoUrl"), + }, + "callback": play, + "params": { + "channel_id": each.get("channel_id") + } + }) + if each.get("isCatchupAvailable"): + litm.context.container(show_epg, "Catchup", + 0, each.get("channel_id")) + yield litm + except Exception as e: + Script.notify("Error", e) + monitor.waitForAbort(1) + return False - for each in filter(fltr, resp): - if each.get("channelIdForRedirect"): - continue - litm = Listitem.from_dict(**{ - "label": each.get("channel_name"), - "art": { - "thumb": IMG_CATCHUP + each.get("logoUrl"), - "icon": IMG_CATCHUP + each.get("logoUrl"), - "fanart": IMG_CATCHUP + each.get("logoUrl"), - "clearlogo": IMG_CATCHUP + each.get("logoUrl"), - "clearart": IMG_CATCHUP + each.get("logoUrl"), - }, - "callback": play, - "params": { - "channel_id": each.get("channel_id") - } - }) - if each.get("isCatchupAvailable"): - litm.context.container(show_epg, "Catchup", - 0, each.get("channel_id")) - yield litm +# Shows EPG container from Context menu -# Shows EPG container from Context menu @Route.register def show_epg(plugin, day, channel_id): resp = urlquick.get(CATCHUP_SRC.format(day, channel_id), max_age=-1).json() @@ -260,33 +296,6 @@ def show_epg(plugin, day, channel_id): }) -@Resolver.register -@isLoggedIn -def play_ex(plugin, dt=None): - is_helper = inputstreamhelper.Helper( - dt.get("proto", "mpd"), drm=dt.get("drm")) - if is_helper.check_inputstream(): - licenseUrl = dt.get("lUrl") and dt.get("lUrl").replace("{HEADERS}", urlencode( - getHeaders())).replace("{TOKEN}", urlencode(getTokenParams())) - art = {} - if dt.get("default_logo"): - art['thumb'] = art['icon'] = IMG_CATCHUP + \ - dt.get("default_logo") - return Listitem().from_dict(**{ - "label": dt.get("label") or plugin._title, - "art": art or None, - "callback": dt.get("pUrl"), - "properties": { - "IsPlayable": True, - "inputstream": is_helper.inputstream_addon, - "inputstream.adaptive.stream_headers": dt.get("hdrs"), - "inputstream.adaptive.manifest_type": dt.get("proto", "mpd"), - "inputstream.adaptive.license_type": dt.get("drm"), - "inputstream.adaptive.license_key": licenseUrl, - } - }) - - # Play live stream/ catchup according to params. # Also insures that user is logged in. @Resolver.register @@ -376,12 +385,12 @@ def play(plugin, channel_id, showtime=None, srno=None, programId=None, begin=Non } }) except Exception as e: - Script.notify("Login Error", "Session expired. Please login again") - executebuiltin( - "RunPlugin(plugin://plugin.video.jiotv/resources/lib/main/login/)") + Script.notify("Error while playback , Check connection", e) return False # Login `route` to access from Settings + + @Script.register def login(plugin): method = Dialog().yesno("Login", "Select Login Method", @@ -393,6 +402,7 @@ def login(plugin): mobile = Settings.get_string("mobile") if not mobile or (len(mobile) != 10): mobile = Dialog().numeric(0, "Enter your Jio mobile number") + ADDON.setSetting('mobile', mobile) error = sendOTPV2(mobile) if error: Script.notify("Login Error", error) @@ -419,13 +429,11 @@ def login(plugin): @Script.register def setmobile(plugin): - ADDON_ID = 'plugin.video.jiotv' - addon = Addon(ADDON_ID) prevMobile = Settings.get_string("mobile") mobile = Dialog().numeric(0, "Update Jio mobile number", prevMobile) kodi_rpc('Addons.SetAddonEnabled', { 'addonid': ADDON_ID, 'enabled': False}) - addon.setSetting('mobile', mobile) + ADDON.setSetting('mobile', mobile) kodi_rpc('Addons.SetAddonEnabled', { 'addonid': ADDON_ID, 'enabled': True}) monitor.waitForAbort(1) @@ -434,7 +442,6 @@ def setmobile(plugin): @Script.register def applyall(plugin): - ADDON_ID = 'plugin.video.jiotv' kodi_rpc('Addons.SetAddonEnabled', { 'addonid': ADDON_ID, 'enabled': False}) monitor.waitForAbort(1)