Hey,
im developing a plex channel for Teleboy a German/CH/AT Live Tv service. It works all but i do not understand how to play the m3u8 playlist after i received the link.
This is my SourceCode:
init.py
import os, re, sys, base64
import cookielib, urllib, urllib2
import simplejson
PAGE_LIMIT = 20
NAME = ‘Test123’
PREFIX = ‘/video/test123’
ICON = ‘icon-default.png’
ART = ‘art-default.png’
#############################################################################
MODE_RECORDINGS = “recordings”
MODE_PLAY = “play”
MODE_PLAY_RECORDING = “playrec”
PARAMETER_KEY_MODE = “mode”
PARAMETER_KEY_STATION = “station”
PARAMETER_KEY_USERID = “userid”
PARAMETER_KEY_RECID = “recid”
TB_URL = “https://www.teleboy.ch”
IMG_URL = “http://media.cinergy.ch”
API_URL = “http://tv.api.teleboy.ch”
API_KEY = base64.b64decode( Prefs[‘apikey’] )
cookies = cookielib.LWPCookieJar( ‘cookie.txt’ )
def fetchHttp( url, args={}, hdrs={}, post=False):
hdrs[“User-Agent”] = Prefs[‘useragent’]
if post:
req = urllib2.Request( url, urllib.urlencode( args), hdrs)
else:
url = url + “?” + urllib.urlencode( args)
req = urllib2.Request( url, None, hdrs)
response = urllib2.urlopen( req)
encoding = re.findall(“charset=([a-zA-Z0-9-]+)”, response.headers[‘content-type’])
text = response.read()
if len(encoding):
responsetext = unicode( text, encoding[0] )
else:
responsetext = text
response.close()
return responsetext
def ensure_login():
global cookies
opener = urllib2.build_opener( urllib2.HTTPCookieProcessor(cookies))
urllib2.install_opener( opener)
try:
cookies.revert( ignore_discard=True)
for c in cookies:
if c.name == “cinergy_auth”:
return True
except IOError:
pass
cookies.clear()
fetchHttp( TB_URL + "/login")
login = Prefs['username']
password = Prefs['password']
url = TB_URL + "/login_check"
args = { "login": login,
"password": password,
"keep_login": "1" }
reply = fetchHttp( url, args, post=True)
if "Falsche Eingaben" in reply or "Anmeldung war nicht erfolgreich" in reply:
raise Exception('Failed Login')
res = cookies.save( ignore_discard=True)
return True
def fetchHttpWithCookies( url, args={}, hdrs={}, post=False):
if ensure_login():
html = fetchHttp( url, args, hdrs, post)
if “Bitte melde dich neu an” in html:
if not ensure_login():
raise Exception(‘Failed Login’)
html = fetchHttp( url, args, hdrs, post)
return html
return “”
def get_stationLogoURL( station):
return IMG_URL + “/t_station/” + station + “/icon320_light.png”
def fetchApiJson( user_id, url, args={}):
# get session key from cookie
global cookies
cookies.revert( ignore_discard=True)
session_cookie = “”
for c in cookies:
if c.name == “cinergy_s”:
session_cookie = c.value
break
if (session_cookie == ""):
raise Exception('session_cookie error')
hdrs = { "x-teleboy-apikey": API_KEY,
"x-teleboy-session": session_cookie }
url = API_URL + "/users/%s/" % user_id + url
ans = fetchHttpWithCookies( url, args, hdrs)
return simplejson.loads( ans)
def get_videoJson( user_id, sid):
url = “stream/live/%s” % sid
return fetchApiJson( user_id, url, {“alternative”: “false”})
################################################################################################################
def Start():
ObjectContainer.title1 = NAME
ObjectContainer.art = R(ART)
HTTP.CacheTime = CACHE_1MINUTE
@handler(PREFIX, NAME, ICON, ART)
def MainMenu(**kwargs):
return FeaturedStreamsList()
@route(PREFIX + ‘/featured’, limit=int)
def FeaturedStreamsList(**kwargs):
try:
oc = ObjectContainer(title2=‘Channels’, no_cache=True)
html = fetchHttpWithCookies( TB_URL + “/live”)
# extract user id
user_id = ""
lines = html.split( '
')
for line in lines:
if "id: " in line:
dummy, uid = line.split( ": ")
user_id = uid[:-1]
break
content = fetchApiJson(user_id, "broadcasts/now", { "expand": "flags,station,previewImage", "stream": True })
for item in content["data"]["items"]:
channel = item["station"]["name"]
station_id = str(item["station"]["id"])
title = item["title"]
tstart = item["begin"][11:16]
tend = item["end"][11:16]
label = title + " (" + tstart + "-" + tend +")"
img = get_stationLogoURL( station_id)
preview = item["preview_image"]["base_path"] + "teleboyteaser3/" + item["preview_image"]["hash"] + ".jpg"
oc.add(DirectoryObject(
key=Callback(channel_video, channel=channel, label=label, user_id=user_id, station_id=station_id, preview=preview),
title = channel,
summary = label,
thumb = Resource.ContentsOfURLWithFallback(img, fallback=R(ICON)),
art = Resource.ContentsOfURLWithFallback(preview, fallback=R(ICON))
))
return oc
except Exception as exception:
return ObjectContainer(header='Failed', message=str(exception))
def channel_video(channel, label, user_id, station_id, preview):
oc = ObjectContainer(title2=channel, no_cache=True)
try:
json = get_videoJson(user_id, station_id)
url = json[“data”][“stream”][“url”]
#oc.add(VideoClipObject(
#url = url,
#title = label,
#thumb = Resource.ContentsOfURLWithFallback(preview, fallback=R(ICON))
# ))
oc.add(VideoClipObject(
title = label,
thumb = Resource.ContentsOfURLWithFallback(preview, fallback=R(ICON)),
items = [
MediaObject(
protocol='hls',
container='mpegts',
video_codec=VideoCodec.H264,
audio_codec=AudioCodec.AAC,
audio_channels=2,
optimized_for_streaming=True,
parts=[PartObject(key=Callback(PlayHLS, url=url))]
)
]
))
return oc
except Exception as exception:
return ObjectContainer(header='Failed', message=str(exception))
@indirect
def PlayHLS(url, **kwargs):
return IndirectResponse(VideoClipObject, key=HTTPLiveStreamURL(url))