[NEWBIE] Play a m3u8 mpeg-ts playlist on my Plex Channel

plugin-dev

#1

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))


#2

im sorry, thats really messed up but i cant edit it.

https://codepaste.net/nfqi2i