plugin/Python - I'm looking for a way...
s3n0 14 Feb 2019
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)
zeros 14 Feb 2019
Just why you need this thing? The speeding works perfectly. With 2x or 4x or 16x or ... velocity you will find quickly your desired location.
s3n0 14 Feb 2019
Hi. Thanks for the answers.
I have tried the doSeek and doSeekRelative methods, unfortunately without success. Then I've also tried those rewind and forward video shifting methods that you're showing, but nothing else. There will probably be a poorly implemented class of Athan........ whose authorship does not belong to me. It is taken from another plugin (only for testing, of course, I will build my own class later).
I really do not know how to do it. I have also seen the Youtube plug-in code (Taapat/github), which also has its Screen to play video, but there is only a short video shift. And even so I dont know use it in Athan........ class code . It did not work.