Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion addon.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<forum>https://botallen.com/discord</forum>
<website>https://botallen.com</website>
<email>[email protected]</email>
<source>https://github.com/botallen/plugin.video.jiotv</source>
<source>https://github.com/Geletinousamigo/plugin.video.jiotv</source>
<news>
[- 2.3.0 -]
[added] more extra channels
Expand Down
5,354 changes: 0 additions & 5,354 deletions resources/extra/channels.json

This file was deleted.

32 changes: 24 additions & 8 deletions resources/lib/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@
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"
EXTRA_CHANNELS = os.path.join(translatePath(
ADDON.getAddonInfo("path")), "resources", "extra", "channels.json")
CHANNELS_SRC = "http://jiotv.data.cdn.jio.com/apis/v1.3/getMobileChannelList/get/?os=android&devicetype=phone&version=6.0.9"
GET_CHANNEL_URL = "https://tv.media.jio.com/apis/v1.4/getchannelurl/getchannelurl?langId=6&userLanguages=All"
""" EXTRA_CHANNELS = os.path.join(translatePath(
ADDON.getAddonInfo("path")), "resources", "extra", "channels.json") """
CHANNELS_SRC = "https://jiotv.data.cdn.jio.com/apis/v3.0/getMobileChannelList/get/?langId=6&os=android&devicetype=phone&usertype=JIO&version=290&langId=6"
GET_CHANNEL_URL = "https://jiotvapi.media.jio.com/playback/apis/v1/geturl?langId=6"
CATCHUP_SRC = "http://jiotv.data.cdn.jio.com/apis/v1.3/getepg/get?offset={0}&channel_id={1}&langId=6"
M3U_SRC = os.path.join(translatePath(
ADDON.getAddonInfo("profile")), "playlist.m3u")
Expand Down Expand Up @@ -154,14 +154,30 @@
"tvImg": IMG_PUBLIC + "logos/langGen/Malayalam_1579245819981.jpg",
"promoImg": IMG_PUBLIC+"67/0/Malayalam_1580459753008_promo.jpg",
},
# {
# "name": "Odia",
# "tvImg": IMG_PUBLIC + "logos/langGen/Odia_1579245819981.jpg",
# "promoImg": IMG_PUBLIC+"67/0/Odia_1580459753008_promo.jpg",
# }
{
"name": "Odia",
"tvImg": IMG_PUBLIC + "logos/langGen/Odia_1579245819981.jpg",
"promoImg": IMG_PUBLIC+"67/0/Odia_1580459753008_promo.jpg",
"tvImg": IMG_PUBLIC + "logos/langGen/Malayalam_1579245819981.jpg",
"promoImg": IMG_PUBLIC+"67/0/Malayalam_1580459753008_promo.jpg",
},
{
"name": "Manipuri",
"tvImg": IMG_PUBLIC + "logos/langGen/Malayalam_1579245819981.jpg",
"promoImg": IMG_PUBLIC+"67/0/Malayalam_1580459753008_promo.jpg",
},
{
"name": "Koshali",
"tvImg": IMG_PUBLIC + "logos/langGen/Malayalam_1579245819981.jpg",
"promoImg": IMG_PUBLIC+"67/0/Malayalam_1580459753008_promo.jpg",
}
]
LANG_MAP = {6: "English", 1: "Hindi", 2: "Marathi", 3: "Punjabi", 4: "Urdu", 5: "Bengali", 7: "Malayalam", 8: "Tamil",
9: "Gujarati", 10: "Odia", 11: "Telugu", 12: "Bhojpuri", 13: "Kannada", 14: "Assamese", 15: "Nepali", 16: "French"}
9: "Gujarati", 10: "Odia", 11: "Telugu", 12: "Bhojpuri", 13: "Kannada", 14: "Assamese", 15: "Nepali", 16: "French",
18: "Manipuri", 19: "Koshali"}
GENRE_MAP = {8: "Sports", 5: "Entertainment", 6: "Movies", 12: "News", 13: "Music", 7: "Kids", 9: "Lifestyle",
10: "Infotainment", 15: "Devotional", 16: "Business", 17: "Educational", 18: "Shopping", 19: "JioDarshan"}
10: "Infotainment", 15: "Devotional", 16: "Business", 17: "Educational", 18: "TestChannels", 19: "JioDarshan"}
CONFIG = {"Genres": GENRE_CONFIG, "Languages": LANGUAGE_CONFIG}
102 changes: 48 additions & 54 deletions resources/lib/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
from codequick.storage import PersistentDict

# add-on imports
from resources.lib.utils import getTokenParams, getHeaders, isLoggedIn, login as ULogin, logout as ULogout, check_addon, sendOTP, get_local_ip
from resources.lib.constants import GET_CHANNEL_URL, PLAY_EX_URL, EXTRA_CHANNELS, GENRE_MAP, LANG_MAP, FEATURED_SRC, CONFIG, CHANNELS_SRC, IMG_CATCHUP, PLAY_URL, IMG_CATCHUP_SHOWS, CATCHUP_SRC, M3U_SRC, EPG_SRC, M3U_CHANNEL
from resources.lib.utils import getHeaders, isLoggedIn, login as ULogin, logout as ULogout, check_addon, sendOTP, get_local_ip
from resources.lib.constants import GET_CHANNEL_URL, GENRE_MAP, LANG_MAP, FEATURED_SRC, CONFIG, CHANNELS_SRC, IMG_CATCHUP, PLAY_URL, IMG_CATCHUP_SHOWS, CATCHUP_SRC, M3U_SRC, EPG_SRC, M3U_CHANNEL

# additional imports
import urlquick
Expand Down Expand Up @@ -57,7 +57,7 @@ def show_featured(plugin, id=None):
"usergroup": "tvYR7NSNn7rymo3F",
"os": "android",
"devicetype": "phone",
"versionCode": "226"
"versionCode": "290"
}, max_age=-1).json()
for each in resp.get("featuredNewData", []):
if id:
Expand All @@ -76,8 +76,8 @@ def show_featured(plugin, id=None):
'originaltitle': child.get("showname"),
"tvshowtitle": child.get("showname"),
"genre": child.get("showGenre"),
"plot": child.get("description"),
"episodeguide": child.get("episode_desc"),
"plot": child.get("episode_desc"),
"episodeguide": child.get("description"),
"episode": 0 if child.get("episode_num") == -1 else child.get("episode_num"),
"cast": child.get("starCast", "").split(', '),
"director": child.get("director"),
Expand Down Expand Up @@ -109,12 +109,15 @@ def show_featured(plugin, id=None):
info_dict["params"] = {
"channel_id": child.get("channel_id"),
"showtime": child.get("showtime", "").replace(":", ""),
"srno": datetime.fromtimestamp(int(child.get("startEpoch", 0)*.001)).strftime('%Y%m%d')
"srno": datetime.fromtimestamp(int(child.get("startEpoch", 0)*.001)).strftime('%Y%m%d'),
"programId": child.get("srno", ""),
"begin": datetime.fromtimestamp(int(child.get("startEpoch", 0)*.001)).strftime('%Y%m%dT%H%M%S'),
"end": datetime.fromtimestamp(int(child.get("endEpoch", 0)*.001)).strftime('%Y%m%dT%H%M%S'),
}
yield Listitem.from_dict(**info_dict)
else:
yield Listitem.from_dict(**{
"label": each.get("name"),
"label": each.get("showname"),
"art": {
"thumb": IMG_CATCHUP_SHOWS + each.get("data", [{}])[0].get("episodePoster"),
"icon": IMG_CATCHUP_SHOWS + each.get("data", [{}])[0].get("episodePoster"),
Expand Down Expand Up @@ -203,8 +206,8 @@ def show_epg(plugin, day, channel_id):
'originaltitle': each['showname'],
"tvshowtitle": each['showname'],
'genre': each['showGenre'],
'plot': each['description'],
"episodeguide": each.get("episode_desc"),
"plot": each.get("episode_desc"),
"episodeguide": each.get("description"),
'episode': 0 if each['episode_num'] == -1 else each['episode_num'],
'cast': each['starCast'].split(', '),
'director': each['director'],
Expand All @@ -215,7 +218,10 @@ def show_epg(plugin, day, channel_id):
"params": {
"channel_id": each.get("channel_id"),
"showtime": None if islive else each.get("showtime", "").replace(":", ""),
"srno": None if islive else datetime.fromtimestamp(int(each.get("startEpoch", 0)*.001)).strftime('%Y%m%d')
"srno": None if islive else datetime.fromtimestamp(int(each.get("startEpoch", 0)*.001)).strftime('%Y%m%d'),
"programId": None if islive else each.get("srno", ""),
"begin": None if islive else datetime.fromtimestamp(int(each.get("startEpoch", 0)*.001)).strftime('%Y%m%dT%H%M%S'),
"end": None if islive else datetime.fromtimestamp(int(each.get("endEpoch", 0)*.001)).strftime('%Y%m%dT%H%M%S'),
}
})
if int(day) == 0:
Expand All @@ -232,49 +238,15 @@ 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
@isLoggedIn
def play(plugin, channel_id, showtime=None, srno=None):
def play(plugin, channel_id, showtime=None, srno=None , programId=None, begin=None, end=None):
is_helper = inputstreamhelper.Helper("mpd", drm="com.widevine.alpha")
hasIs = is_helper.check_inputstream()
if not hasIs:
return
if showtime is None and Settings.get_boolean("extra"):
with open(EXTRA_CHANNELS, "r") as f:
extra = json.load(f)
if extra.get(str(channel_id)):
if extra.get(str(channel_id)).get("ext"):
return extra.get(str(channel_id)).get("ext")
return PLAY_EX_URL + extra.get(str(channel_id)).get("data")

rjson = {
"channel_id": int(channel_id),
Expand All @@ -284,22 +256,44 @@ def play(plugin, channel_id, showtime=None, srno=None):
rjson["showtime"] = showtime
rjson["srno"] = srno
rjson["stream_type"] = "Catchup"
rjson["programId"] = programId
rjson["begin"] = begin
rjson["end"] = end

getUrlHeaders = {
"devicetype":"phone",
"host":"tv.media.jio.com",
"os":"android",
"versioncode":"290",
"Content-Type":"application/json",
"channel_id":str(channel_id),
"srno":rjson["srno"] if "srno" in rjson else str(None)
}

resp = urlquick.post(GET_CHANNEL_URL, json=rjson).json()
headers = getHeaders()
headers['channelid'] = str(channel_id)
headers['srno'] = rjson["srno"] if "srno" in rjson else str(None)
resp = urlquick.post(GET_CHANNEL_URL, json=rjson, headers=getUrlHeaders, max_age=-1).json()
art = {}
channelName_m3u8 = resp.get("result", "").split("?")[0].split('/')[-1]
channelName = channelName_m3u8[:-5].replace("_"," ")
art["thumb"] = art["icon"] = IMG_CATCHUP + \
resp.get("result", "").split("/")[-1].replace(".m3u8", ".png")
params = getTokenParams()
channelName_m3u8.replace(".m3u8", ".png")
cookie = resp.get("result", "").split("?")[1]
headers['cookie'] = cookie
uriToUse = resp.get("result","")

return Listitem().from_dict(**{
"label": plugin._title,
"label": channelName,
"art": art,
"callback": resp.get("result", "") + "?" + urlencode(params),
"callback": uriToUse,
"properties": {
"IsPlayable": True,
"inputstream": "inputstream.adaptive",
"inputstream.adaptive.stream_headers": "User-Agent=KAIOS",
"inputstream.adaptive.manifest_headers": urlencode(headers),
"inputstream.adaptive.manifest_params": cookie,
"inputstream.adaptive.manifest_type": "hls",
"inputstream.adaptive.license_key": urlencode(params) + "|" + urlencode(getHeaders()) + "|R{SSM}|",
"inputstream.adaptive.license_key": "|" + urlencode(headers) + "|R{SSM}|",
}
})

Expand Down Expand Up @@ -360,7 +354,7 @@ def m3ugen(plugin, notify="yes"):
"channel_id={0}".format(channel.get("channel_id"))
catchup = ""
if channel.get("isCatchupAvailable"):
catchup = ' catchup="vod" catchup-source="{0}channel_id={1}&showtime={{H}}{{M}}{{S}}&srno={{Y}}{{m}}{{d}}" catchup-days="7"'.format(
catchup = ' catchup="vod" catchup-source="{0}channel_id={1}&showtime={{H}}{{M}}{{S}}&srno={{Y}}{{m}}{{d}}&programId={{catchup-id}}" catchup-days="7"'.format(
PLAY_URL, channel.get("channel_id"))
m3ustr += M3U_CHANNEL.format(
tvg_id=channel.get("channel_id"),
Expand Down Expand Up @@ -402,4 +396,4 @@ def set_setting(id, value):
@Script.register
def cleanup(plugin):
urlquick.cache_cleanup(-1)
Script.notify("Cache Cleaned", "")
Script.notify("Cache Cleaned", "")
20 changes: 11 additions & 9 deletions resources/lib/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,21 +83,23 @@ def login(username, password, mode="unpw"):
if resp.get("ssoToken", "") != "":
_CREDS = {
"ssotoken": resp.get("ssoToken"),
"userId": resp.get("sessionAttributes", {}).get("user", {}).get("uid"),
"uniqueId": resp.get("sessionAttributes", {}).get("user", {}).get("unique"),
"userid": resp.get("sessionAttributes", {}).get("user", {}).get("uid"),
"uniqueid": resp.get("sessionAttributes", {}).get("user", {}).get("unique"),
"crmid": resp.get("sessionAttributes", {}).get("user", {}).get("subscriberId"),
"subcriberid": resp.get("sessionAttributes",{}).get("user", {}).get("subscriberId")
}
headers = {
"User-Agent": "JioTV",
"os": "Android",
"appkey": "NzNiMDhlYzQyNjJm",
"accesstoken": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7ImF1dGhUb2tlbklkIjoiYmQwMmFlMzUtZjc3NS00NjBhLTk4OTYtYjUzY2E3ZmNmMDI3IiwidXNlcklkIjoiODcxMmY2NzgtNzE4MS00MTIxLWEyZmUtMTRmMmUzNTRlZTNmIiwidXNlclR5cGUiOiJKSU8iLCJvcyI6ImFuZHJvaWQiLCJkZXZpY2VUeXBlIjoicGhvbmUiLCJhY2Nlc3NMZXZlbCI6IjkiLCJkZXZpY2VJZCI6IjcwYTZhM2ExMTc2ZGMxMGQiLCJleHRyYSI6IntcIm51bWJlclwiOlwiOFNMQ0J5Q1h2NEFjb0cyMG85MUtiQm03aWRYOGtJSmlRa1FiS3B6dFJ0WU9jbFRtSXc3Uk9hUT1cIixcInBsYW5kZXRhaWxzXCI6e1wiUGFja2FnZUluZm9cIjpbe1wicGxhbmlkXCI6XCIxXCIsXCJzdWJzY3JpcHRpb25zdGFydFwiOjE2NTkwMjI0NDcsXCJzdWJzY3JpcHRpb25lbmRcIjoxNjkwNTU4NDQ3LFwicGxhbnR5cGVcIjpcInByZW1pdW1cIixcImJ1c2luZXNzVHlwZVwiOlwiamlvXCIsXCJpc2FjdGl2ZVwiOnRydWUsXCJub3Rlc1wiOlwiXCJ9XX19Iiwic3Vic2NyaWJlcklkIjoiMTE0MzAzNTMyMSJ9LCJleHAiOjE2NzUwMjI1NTksImlhdCI6MTY3NTAxNTM1OX0.uja0tHTRGSzsEssNEq08JOJyL-Q8C3la9wZQGlapH7DWxvnXq6nzKWGnyRiCMEjcp1V0WSbICSOA_aeN0dxR8w",
"os": "android",
"deviceId": str(uuid4()),
"versionCode": "226",
"devicetype": "phone",
"srno": "200206173037",
"appkey": "NzNiMDhlYzQyNjJm",
"channelid": "100",
"lbcookie": "1",
"os":"android",
"osversion":"11",
"user-agent": "plaYtv/7.0.8 (Linux;Android 11) ExoPlayerLib/2.11.7",
"usergroup": "tvYR7NSNn7rymo3F",
"lbcookie": "1"
"versionCode": "290"
}
headers.update(_CREDS)
with PersistentDict("headers") as db:
Expand Down
3 changes: 2 additions & 1 deletion resources/settings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,12 @@
<setting id="Assamese" type="bool" label="Assamese" default="true"/>
<setting id="Urdu" type="bool" label="Urdu" default="true"/>
<setting id="Nepali" type="bool" label="Nepali" default="true"/>
<setting id="Manipuri" type="bool" label="Manipuri" default="true"/>
<setting id="Koshali" type="bool" label="Koshali" default="true"/>
</category>
<category label="More">
<setting id="cleanup" type="action" label="Clear Cache" action="RunPlugin(plugin://plugin.video.jiotv/resources/lib/main/cleanup/)" option="close"/>
<setting id="popup" type="bool" label="Disable Welcome Popup" default="false"/>
<setting id="extra" type="bool" label="Extra HD Channels" default="false"/>
</category>
</settings>