Hello.
I am not an expert in programming under Enigma2. So I ask for advice from the more experienced Enigma2 programmers. I've just created a simple plugin for testing.
I'm looking for a way to run a Youtube video from a certain position (not from the beginning). I can translate the original Youtube link to the Youtube streaming link. This can be done by using the imported "youtube_dl" python module (source: github / youtube-dl) or via imported code (as a module) from the original Youtube plug-in. Unfortunately, in the "youtube-dl" project, it is not possible to get a streaming video link directly from the specified position.
Is there a way to start a Youtube video from a certain position? (of course streaming URL, after translation from the original Youtube URL, which is determined by its video-ID code)
Or run a stream in Enigma2, and then set a new stream position immediately?
I have also searched for a code on the github server (Youtube plug-in), but I did not understand much :-). I found only a video shift left / right. Unfortunately, it does not work. I do not know how exactly the "4097 service" in Enigma is used to play the online stream. Is it at all possible to start the stream from a certain position?
Thanks.
Here is the plugin code example:
# -*- coding: utf-8 -*- #### from __future__ import unicode_literals from youtube_dl import YoutubeDL # opkg update && opkg install python-youtube-dl from Plugins.Plugin import PluginDescriptor from Screens.MessageBox import MessageBox from Screens.Screen import Screen from Screens.InfoBarGenerics import InfoBarNotifications from enigma import eTimer, eConsoleAppContainer, ePicLoad, loadPNG, loadJPG, getDesktop, eServiceReference, iPlayableService, eListboxPythonMultiContent, RT_HALIGN_LEFT, RT_HALIGN_RIGHT, RT_HALIGN_CENTER, RT_VALIGN_CENTER from Components.ServiceEventTracker import ServiceEventTracker from Components.ActionMap import ActionMap from Components.Label import Label def ytStreamURL(video_id = ''): # video_id = youtube URL link or video-ID only, to translate into streaming youtube URL ydl_opts = {'format': 'bestvideo+bestaudio', 'verbose': True} data = video_url = audio_url = '' with YoutubeDL(ydl_opts) as ydl: data = ydl.extract_info(video_id, download=False) if not data: return '' data = data['formats'] for row in data: # browse thorough all possible formats (audio+video / video / audio tracks) if not video_url and row['format_id'] == '137' or row['format_id'] == '136': video_url = row['url'] # '22' if not audio_url and row['format_id'] == '140' or row['format_id'] == '171': audio_url = row['url'] if video_url and audio_url: return str(video_url + '&suburi=' + audio_url) # return the two URL streams - joined as together with the "&suburi=" parameter else: return '' class AthanTimesStreamVideo(Screen, InfoBarNotifications): STATE_IDLE = 0 STATE_PLAYING = 1 STATE_PAUSED = 2 ENABLE_RESUME_SUPPORT = True ALLOW_SUSPEND = True PLAYER_STOPS = 3 skinfhd = ''' <screen name="AthanTimesStreamVideo" flags="wfNoBorder" position="0,0" size="1920,1080" title="AthanTimesStreamVideo" backgroundColor="transparent"> <widget source="global.CurrentTime" render="Label" position="13,9" size="250,100" font="Regular; 28" halign="left" backgroundColor="#263c59" shadowColor="#1d354c" shadowOffset="-1,-1" transparent="1" zPosition="1"> <convert type="ClockToText">Format:%d.%m.%Y</convert> </widget> </screen>''' skinhd = ''' <screen name="AthanTimesStreamVideo" flags="wfNoBorder" position="0,0" size="1280,720" title="LiveSoccerStream" backgroundColor="transparent"> <widget source="global.CurrentTime" render="Label" position="3,5" size="150,100" font="Regular; 24" halign="left" backgroundColor="#263c59" shadowColor="#1d354c" shadowOffset="-1,-1" transparent="1" zPosition="1"> <convert type="ClockToText">Format:%d.%m.%Y</convert> </widget> </screen>''' def __init__(self, session, service): Screen.__init__(self, session) self.skin = AthanTimesStreamVideo.skinhd #if dwidth == 1280: # self.skin = AthanTimesStreamVideo.skinhd #else: # self.skin = AthanTimesStreamVideo.skinfhd InfoBarNotifications.__init__(self) self.session = session self.initialservice = self.session.nav.getCurrentlyPlayingServiceReference() self.service = service self.screen_timeout = 1000 self.__event_tracker = ServiceEventTracker(screen = self, eventmap = { iPlayableService.evSeekableStatusChanged : self.__seekableStatusChanged, iPlayableService.evStart : self.__serviceStarted, iPlayableService.evEOF : self.__evEOF } ) self['actions'] = ActionMap( ['OkCancelActions', 'InfobarSeekActions', 'ColorActions', 'MediaPlayerActions', 'MovieSelectionActions'], { 'ok' : self.leavePlayer, 'cancel' : self.leavePlayer, 'stop' : self.leavePlayer } , -2) self['pauseplay'] = Label(_('Play')) self.hidetimer = eTimer() #self.repeter = True self.repeater = True self.state = self.STATE_PLAYING self.onPlayStateChanged = [] self.play() self.onClose.append(self.__onClose) def __onClose(self): self.session.nav.stopService() self.session.nav.playService(self.initialservice) def __evEOF(self): self.STATE_PLAYING = True self.state = self.STATE_PLAYING self.session.nav.playService(self.service) if self.session.nav.stopService(): self.state = self.STATE_PLAYING self.session.nav.playService(self.service) else: self.leavePlayer() def __setHideTimer(self): self.hidetimer.start(self.screen_timeout) def ok(self): self.leavePlayer() def playNextFile(self): self.session.open(MessageBox, 'only to watch not play Next and Prev File', MessageBox.TYPE_INFO) def playPrevFile(self): self.session.open(MessageBox, 'only to watch not play Next and Prev File', MessageBox.TYPE_INFO) def playService(self, newservice): if self.state == self.STATE_IDLE: self.play() self.service = newservice def play(self): self.state = self.STATE_PLAYING self['pauseplay'].setText('PLAY') self.session.nav.playService(self.service) self.__evEOF def __seekableStatusChanged(self): service = self.session.nav.getCurrentService() if service is not None: seek = service.seek() if seek is None or not seek.isCurrentlySeekable(): self.setSeekState(self.STATE_PLAYING) self.__evEOF return def __serviceStarted(self): self.state = self.STATE_PLAYING self.__evEOF def setSeekState(self, wantstate): print 'setSeekState' if wantstate == self.STATE_PAUSED: print 'trying to switch to Pause- state:', self.STATE_PAUSED elif wantstate == self.STATE_PLAYING: print 'trying to switch to playing- state:', self.STATE_PLAYING service = self.session.nav.getCurrentService() if service is None: print 'No Service found' return False else: pauseable = service.pause() if pauseable is None: print 'not pauseable.' self.state = self.STATE_PLAYING if pauseable is not None: print 'service is pausable' if wantstate == self.STATE_PAUSED: print 'WANT TO PAUSE' pauseable.pause() self.state = self.STATE_PAUSED if not self.shown: self.hidetimer.stop() self.show() elif wantstate == self.STATE_PLAYING: print 'WANT TO PLAY' pauseable.unpause() self.state = self.STATE_PLAYING if self.shown: self.__setHideTimer() for c in self.onPlayStateChanged: c(self.state) return True return def handleLeave(self): self.close() def leavePlayer(self): self.close() def backToIntialService(): pass def pluginOpen(session, **kwargs): streamURL = ytStreamURL('LXb3EKWsInQ') # LXb3EKWsInQ(costa rica 4k) zw5BReAqBS8(do 1080p building machines) fDWFVI8PQOI(shufle-dance-1080p) e8WhbRgxe64(videoclip up to max. 4K resolution) sref = eServiceReference(4097, 0, streamURL) sref.setName('') session.openWithCallback(backToIntialService, AthanTimesStreamVideo, sref) #print(message) #session.open(MessageBox, message, type = MessageBox.TYPE_INFO) def Plugins(**kwargs): return PluginDescriptor( name = "test plugin No. 42", description = "YouTube link transform - from original URL to a streaming URL & play it", where = [ PluginDescriptor.WHERE_EXTENSIONSMENU , PluginDescriptor.WHERE_PLUGINMENU ] , icon = "/usr/lib/enigma2/python/Plugins/Extensions/EnhancedMovieCenter/img/link.png", fnc = pluginOpen)