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)