NOTE: The technology explained here is already available in the enigma2 tarball that has been published with Opendreambox 2.5 (krogoth).
During the last weeks we've put some work in building a better solution for handling streaming services with temporary or "usually unknown" URLs.
So we came up with the all new "eServiceUri" (Service ID 0x2001 / 8193).
eServiceUri brings the possibility to register an "eUriResolver" for custom transport-type-schemas.
An eUriResolver can be used to asynchronously resolve some arbitary "alias url" to a real streaming url and "standard" service type like eServiceMP3 or eServiceDVB.
For further explanation here's how this has been implemented for youtube using yt://<videoid> or youtube://<videoid> as pseudo-transport (this has not yet been pushed to public plugin git)
For better undestanding it has lots of comments
from enigma import eServiceReference, eUriResolver, StringList
from Videos import VideoUrlRequest
from Tools.Log import Log
class YoutubeUriResolver(eUriResolver):
_schemas = ("youtube", "yt")
instance = None
def __init__(self):
#call eUriResolver.__init__ with a StringList of supported schemas (if you don't you'll never be called!)
eUriResolver.__init__(self, StringList(self._schemas))
Log.i(self._schemas)
#EVERY eUriResolver HAS TO implement the resolve method
def resolve(self, service, uri):
Log.i(uri)
#There is no mandatory need to check the transport.
#Resolver matching has already been done by the core.
video_id = uri.split("://")[1]
watch_url = "http://youtube.com/watch?v=%s" % (video_id,)
#for youtube this is the async callback once the video url is ready
def onUrlReady(uri, format):
Log.d("%s (%s)" %(uri, format))
#Especially when doing web stuff there's always a proper high risk of running into an exception, it's advised to surround any "potentially dangerous" code with try/except
try:
# it is essential to check service.ptrValid() before accessing the service once resolving has finished.
# The user may have changed service already which would cause the service to be gone.
if not service.ptrValid():
Log.w("Service became invalid!")
#Just quit processing if the service has been invalidated, there's nothing to do anymore
return
if uri:
# So we have the "actual" uri ready and set it calling "service.setResolvedUri(uri, eServiceReference.<id*>)" (Where <id*> is any valid real service type like idDVB or idGST)
# Again: If you didn't check service.ptrValid() like you've been told to do, this will crash the core whenever someone zapped away before you finished resolving
# Once setResolvedUri has been set the eServiceUri will internally create a service of the given service-type and start it. All events will be proxied (even EPG will if you resolve to a standard dvb service).
if VideoUrlRequest.isHls(format): # HLS uses transport streams and works best as DVB service
service.setResolvedUri(uri, eServiceReference.idDVB)
else: #anything but hls goes the standard gst route
service.setResolvedUri(uri, eServiceReference.idGST)
else:
# Whenever you haven't been able to resolve the service, please do not forget to call "service.failedToResolveUri()" so the service can core can raise proper events
service.failedToResolveUri()
except:
# Seems we did somethings wrong, so we tell the service we failed.
# remember? Resolving urls doing http(s) requests may always throw exceptions!
service.failedToResolveUri()
# Start the async resolve using our onUrlReady method as callback
VideoUrlRequest(watch_url, [onUrlReady], async=True)
# Tell the core that we think we can resolve this (return False if you know you can't)
return True
#Register/Activate our YoutubeUriResolver
YoutubeUriResolver.instance = YoutubeUriResolver()
eUriResolver.addResolver(YoutubeUriResolver.instance)
Alles anzeigen
With this you can now simply add any youtube video or live-stream to any boquuet:
#SERVICE 8193:0:1:0:0:0:0:0:0:0:yt%3a//<videoid>:My Favorite YT-Live Channel
#DESCRIPTION My Favorite YT-Live Channel
We hope you like it.
This code and functionality for youtube will soon be available in our github plugin repository (and on any box that runs krogoth based images)!