Repository URL to install this package:
|
Version:
0.8-r1 ▾
|
enigma2-plugin-extensions-gtv
/
usr
/
lib
/
enigma2
/
python
/
Plugins
/
Extensions
/
gTV
/
plugin.py
|
|---|
from __future__ import print_function
from __future__ import division
#
# gutemine Display TV Plugin by gutemine
#
gtv_version = "0.8-r1"
#
from Plugins.Plugin import PluginDescriptor
import Plugins.Plugin
from Screens.Screen import Screen
from Components.Label import Label, MultiColorLabel
from Components.Pixmap import Pixmap
from Components.ActionMap import ActionMap, HelpableActionMap
from Components.config import config, ConfigSubsection, ConfigBoolean, ConfigSelection, ConfigSelectionNumber, getConfigListEntry, ConfigNothing
from Components.ConfigList import ConfigListScreen
from Components.PluginComponent import plugins
from enigma import eConsoleAppContainer, eTimer, getDesktop, ePixmap, iServiceInformation, iPlayableService, eServiceReference
from Screens.InfoBar import InfoBar
from Screens.MessageBox import MessageBox
from ServiceReference import ServiceReference
from os import path as os_path, remove as os_remove, listdir as os_listdir, kill as os_kill
from Tools.BoundFunction import boundFunction
import gm
if gm.universal():
colorformat=",colorchannelmixer=0:0:1:0:0:1:0:0:1:0:0"
else:
colorformat=""
gtv_plugindir="/usr/lib/enigma2/python/Plugins/Extensions/gTV"
gtv_title="gutemine"+" "+_("Display")+" TV "+_("Configuration")+" V%s" % gtv_version
gtv_name="gutemine"+" "+_("Display")+" TV"
gtv_description="gutemine"+" "+_("Display")+" TV "+_("Setup")
gtv_menu="gTV "+_("Display")
yes_no_descriptions = {False: _("no"), True: _("yes")}
config.plugins.gtv = ConfigSubsection()
config.plugins.gtv.shown = ConfigBoolean(default = False, descriptions=yes_no_descriptions)
config.plugins.gtv.colour = ConfigBoolean(default = True, descriptions=yes_no_descriptions)
config.plugins.gtv.overscan = ConfigBoolean(default = False, descriptions=yes_no_descriptions)
if gm.arch() == "armhf":
config.plugins.gtv.frames = ConfigSelectionNumber(4, 8, 1, default = 6)
else:
config.plugins.gtv.frames = ConfigSelectionNumber(5, 20, 1, default = 15)
GREENC = '\033[32m'
ENDC = '\033[m'
def cprint(text):
print(GREENC+"[gTV] "+text+ENDC)
def gutemineToggleTV(session,**kwargs):
if gTV.gTVrunning:
gTV.start_stop_gTV(action="stop")
else:
gTV.start_stop_gTV(action="start")
session.openPseudoScreen_timer = eTimer()
session.openPseudoScreen_timer_conn = session.openPseudoScreen_timer.timeout.connect(boundFunction(openPseudoScreen,session))
session.openPseudoScreen_timer.start(50,True)
def openPseudoScreen(session):
session.open(PseudoScreen) # to avoid fire short key in QB-Plugins if gTV set on long key
def gutemineActivateTV(session,**kwargs):
gTV.start_stop_gTV(action="start")
def gutemineDeactivateTV(session,**kwargs):
gTV.start_stop_gTV(action="stop")
class gTVSummaryScreen(Screen):
skin = (
"""<screen name="gTV_summary" position="0,0" size="132,64" id="1">
<widget name="boxdisplay" position="0,0" size="132,64"/>
</screen>""",
"""<screen name="gTV_summary" position="0,0" size="96,64" id="2">
<widget name="boxdisplay" position="0,0" size="96,64"/>
</screen>""",
"""<screen name="gTV_summary" position="0,0" size="400,240" id="3">
<widget name="boxdisplay" position="0,0" size="400,240"/>
</screen>""",
"""<screen name="gTV_summary" position="0,0" size="240,80" id="100">
<widget name="boxdisplay" position="0,0" size="240,80"/>
</screen>""")
def __init__(self, session, parent):
Screen.__init__(self, session, parent)
self.skinName = "gTV_summary"
self["boxdisplay"] = Pixmap()
class gTVStartup():
def __init__(self):
self.gTVrunning=None
self.gTVcontainer = eConsoleAppContainer()
self.gTVcmd=""
self.gTV_summary_org = None
self.gTV_summary = None
def gotSession(self, session):
cprint(">>>> gotSession")
self.session = session
self.snappyTimer = eTimer()
self.snappyTimer_conn = self.snappyTimer.timeout.connect(self.showSnappy)
self.deadStreamTimer = eTimer()
self.deadStreamTimer_conn = self.deadStreamTimer.timeout.connect(self.deadStream)
def setSummary(self, setgTVSummary = False):
InfoBar.instance.session.summary.hide()
if setgTVSummary:
if self.gTV_summary_org is None:
self.gTV_summary_org = InfoBar.instance.session.summary
if self.gTV_summary is None:
self.gTV_summary = InfoBar.instance.session.instantiateSummaryDialog(gTVSummaryScreen, self.session.current_dialog)
InfoBar.instance.session.current_dialog.addSummary(self.gTV_summary)
InfoBar.instance.session.summary = self.gTV_summary
else:
if self.gTV_summary_org and InfoBar.instance.session.summary != self.gTV_summary_org:
InfoBar.instance.session.summary = self.gTV_summary_org
InfoBar.instance.session.summary.show()
def showSnappy(self):
if self.gTVrunning is not None:
for snap in os_listdir("/tmp"):
if snap.startswith("snappy"):
if InfoBar.instance.session.summary == self.gTV_summary:
# cprint(">>>> showSnappy /tmp/%s ..." % snap)
self.session.summary["boxdisplay"].instance.setPixmapFromFile("/tmp/%s" % snap)
os_remove("/tmp/%s" % snap)
repeat=1000//int(config.plugins.gtv.frames.value)
self.snappyTimer.start(repeat, True)
def showStartup(self):
cprint(">>>> showStartup")
self.screenshot_filename = "%s/gTV.svg" % gtv_plugindir
self.session.summary["boxdisplay"].instance.setPixmapFromFile(self.screenshot_filename)
for snap in os_listdir("/tmp"):
if snap.startswith("snappy"):
os_remove("/tmp/%s" % snap)
def deadStream(self):
dead=True
if len(self.gTVcmd) > 0:
check=self.gTVcmd.replace('\"','').replace(" ","")
for dirname in os_listdir('/proc'):
cmd="/proc/"+dirname+"/cmdline"
if os_path.exists(cmd):
f=open(cmd,"rb")
cmdline=f.readline()
f.close()
if cmdline.startswith("/usr/bin/ffmpeg"):
ncmdline=cmdline.replace("\0","")
if check==ncmdline:
dead=False
if dead:
cprint("stream died, restarting ...")
cprint(self.gTVcmd)
self.gTVcontainer.execute(self.gTVcmd)
return dead
def stopStream(self, session):
cprint("stopping ffmpeg ...")
self.gTVcontainer.sendCtrlC()
self.gTVrunning=None
def startStream(self, session, serviceref=None):
if serviceref is None:
serviceref = session.nav.getCurrentlyPlayingServiceReference()
if serviceref is None:
cprint("start streaming - NO service")
return
grey=""
if not config.plugins.gtv.colour.value:
grey="hue=s=0,"
crop=""
if config.plugins.gtv.overscan.value:
service = session.nav.getCurrentService()
info = service and service.info()
vw=-1
vh=-1
if info:
vw = info.getInfo(iServiceInformation.sVideoWidth)
vh = info.getInfo(iServiceInformation.sVideoHeight)
cprint("video width: %s height: %s" % (vw,vh))
if vw > 0 and vh > 0: # cropping 76 Percent of TV screen removes bars and logos ...
crop="crop=%s:%s:%s:%s," % (vw*76//100,vh*76//100,vw*12//100,vh*12//100)
cprint("crop: %s" % crop)
if gm.arch() == "armhf":
ww=400
hh=240
else:
ww=240
hh=80
sref=serviceref.toString().replace("%3a",":")
sp=sref.split("::")
sref=sp[0] # remove channel name on streams after ::
if sref.find("http:") is not -1:
sp=sref.split("http:")
sref="http:"+sp[1]
if not sref.endswith(":0"): # no partnerbox channel
sp=sref.split(":")
print(sp)
sref="http:"+sp[1]
cprint("start remote http streaming %s ..." % sref)
self.gTVcmd="/usr/bin/ffmpeg -re -i \"%s\" -movflags +faststart -vf \"%s%sscale=%s:%s%s\" -y -r %s/1 -qscale:v 2 /tmp/snappy%%03d.jpg" % ((sref,crop,grey,ww,hh,colorformat,config.plugins.gtv.frames.value) )
else:
cprint("start streaming %s ..." % sref)
self.gTVcmd="/usr/bin/ffmpeg -re -i \"http://localhost:8001/%s\" -movflags +faststart -vf \"%s%sscale=%s:%s%s\" -y -r %s/1 -qscale:v 2 /tmp/snappy%%03d.jpg" % ((sref,crop,grey,ww,hh,colorformat,config.plugins.gtv.frames.value) )
cprint(self.gTVcmd)
self.gTVrunning=serviceref
self.gTVcontainer.execute(self.gTVcmd)
self.deadStreamTimer.start(3000, True)
def start_stop_gTV(self, action="start"):
serviceref = self.session.nav.getCurrentlyPlayingServiceReference()
if serviceref is not None:
sref=serviceref.toString()
cprint("current sRef: %s" % sref)
#add/remove Entries from Extensions without GUI-restart
if action == "start":
config.plugins.gtv.shown.value = True
text=_("Activate gutemine TV")
self.startStream(self.session,serviceref)
repeat=1000//int(config.plugins.gtv.frames.value)
self.snappyTimer.start(repeat, True)
self.setSummary(True)
self.showStartup()
else:
config.plugins.gtv.shown.value = False
text=_("Disable gutemine TV")
self.stopStream(self.session)
self.setSummary(False)
cprint(text)
gTV = gTVStartup()
def killStream():
for dirname in os_listdir('/proc'):
cmd="/proc/"+dirname+"/cmdline"
if os_path.exists(cmd):
f=open(cmd,"r")
cmdline=f.read()
f.close()
if cmdline.startswith("/usr/bin/ffmpeg"):
cprint("KILLING ffmpeg ...")
os_kill(int(dirname),9)
def sessionstart(reason, **kwargs):
if reason == 0:
cprint("gutemine TV startup")
gTV.gotSession(kwargs["session"])
# in case we have left over ffmpeg sessions running ...
killStream()
gm.mmap("/usr/bin/ffmpeg")
sz_w = getDesktop(0).size().width()
sz_h = getDesktop(0).size().height()
class gTVConfiguration(Screen, ConfigListScreen):
if sz_w == 2560:
skin = """
<screen position="center,150" size="1640,1240" title="gTV" >
<widget name="logo" position="20,20" size="200,80"/>
<widget backgroundColor="#9f1313" font="Regular;36" halign="center" name="buttonred" position="240,20" foregroundColor="white" shadowColor="black" shadowOffset="-3,-3" size="330,80" valign="center" />
<widget backgroundColor="#1f771f" font="Regular;36" halign="center" name="buttongreen" position="590,20" foregroundColor="white" shadowColor="black" shadowOffset="-3,-3" size="330,80" valign="center" />
<widget backgroundColor="#a08500" font="Regular;36" halign="center" name="buttonyellow" position="940,20" foregroundColor="white" shadowColor="black" shadowOffset="-3,-3" size="330,80" valign="center" />
<widget backgroundColor="#18188b" font="Regular;36" halign="center" name="buttonblue" position="1290,20" foregroundColor="white" shadowColor="black" shadowOffset="-3,-3" size="330,80" valign="center" />
<eLabel backgroundColor="grey" position="20,120" size="1600,2" />
<widget name="config" enableWrapAround="1" position="20,140" size="1600,900" scrollbarMode="showOnDemand" />
<ePixmap pixmap="skin_default/div-h.png" position="20,1060" zPosition="2" size="1600,4" />
<widget name="help" position="20,1080" size="1600,150" font="Regular;44" />
</screen>"""
elif sz_w == 1920:
skin = """
<screen position="center,115" size="1200,945" title="gTV" >
<widget name="logo" position="20,10" size="150,60"/>
<widget backgroundColor="#9f1313" font="Regular;30" halign="center" name="buttonred" position="190,10" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="230,60" valign="center" />
<widget backgroundColor="#1f771f" font="Regular;30" halign="center" name="buttongreen" position="440,10" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="230,60" valign="center" />
<widget backgroundColor="#a08500" font="Regular;30" halign="center" name="buttonyellow" position="690,10" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="230,60" valign="center" />
<widget backgroundColor="#18188b" font="Regular;30" halign="center" name="buttonblue" position="940,10" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="230,60" valign="center" />
<eLabel backgroundColor="grey" position="20,80" size="1160,1" />
<widget name="config" enableWrapAround="1" position="20,90" scrollbarMode="showOnDemand" size="1160,700" />
<ePixmap pixmap="skin_default/div-h.png" position="20,790" zPosition="2" size="1160,2" />
<widget name="help" position="20,800" size="1160,145" font="Regular;32" />
</screen>"""
else:
skin = """
<screen position="center,75" size="820,620" title="gTV" >
<widget name="logo" position="10,10" size="100,40"/>
<widget backgroundColor="#9f1313" font="Regular;18" halign="center" name="buttonred" position="120,10" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="165,40" valign="center" />
<widget backgroundColor="#1f771f" font="Regular;18" halign="center" name="buttongreen" position="295,10" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="165,40" valign="center" />
<widget backgroundColor="#a08500" font="Regular;18" halign="center" name="buttonyellow" position="470,10" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="165,40" valign="center" />
<widget backgroundColor="#18188b" font="Regular;18" halign="center" name="buttonblue" position="645,10" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="165,40" valign="center" />
<eLabel backgroundColor="grey" position="10,60" size="800,1" />
<widget name="config" enableWrapAround="1" position="10,70" size="800,450" scrollbarMode="showOnDemand" />
<ePixmap pixmap="skin_default/div-h.png" position="10,530" zPosition="2" size="800,2" />
<widget name="help" position="10,540" size="800,75" font="Regular;22" />
</screen>"""
def __init__(self, session, args = 0):
Screen.__init__(self, session)
self.skin = gTVConfiguration.skin
self.session = session
self.onShown.append(self.setWindowTitle)
# explicit check on every entry
self.onChangedEntry = []
self.list = []
ConfigListScreen.__init__(self, self.list, session = self.session, on_change = self.changedEntry)
self["config"].onSelectionChanged.append(self.updateHelp)
self.extended=False
self.createSetup()
self["logo"] = Pixmap()
self["buttonred"] = Label(_("Exit"))
self["buttongreen"] = Label(_("Save"))
self["buttonyellow"] = Label(_("default"))
self["buttonblue"] = Label(_("About"))
self["help"] = Label()
self["actions"] = ActionMap(["SetupActions", "ColorActions"],
{"ok": self.save,
"exit": self.cancel,
"cancel": self.cancel,
"red": self.cancel,
"green": self.save,
"yellow": self.setToDefault,
"blue": self.about,
})
def setWindowTitle(self):
self["logo"].instance.setPixmapFromFile("%s/gtv.svg" % gtv_plugindir)
self.setTitle(gtv_title)
def updateHelp(self):
cur = self["config"].getCurrent()
if cur:
self["help"].text = cur[2]
def save(self):
for x in self["config"].list:
if len(x) > 1:
x[1].save()
self.close(True)
def cancel(self):
for x in self["config"].list:
if len(x) > 1:
x[1].cancel()
self.close(False)
def about(self):
self.session.open(MessageBox, gtv_title+"\n\n(c) gutemine V%s" % gtv_version, MessageBox.TYPE_INFO)
def setToDefault(self):
text=_("Reset to defaults?") + " (all gTV options)"
self.session.openWithCallback(self.setToDefaultCallBack, MessageBox,text, MessageBox.TYPE_YESNO)
def setToDefaultCallBack(self,retValue):
if retValue:
cprint("set options to default")
for x in self["config"].list:
if len(x) > 1:
x[1].value = x[1].default
self["config"].l.setList(self.list)
def createSetup(self):
self.list = []
self.list.append(getConfigListEntry(_("Frames")+ "/"+_("sec"), config.plugins.gtv.frames, "to reduce CPU load select lower value."))
self.list.append(getConfigListEntry(_("Overscan"), config.plugins.gtv.overscan, "enable overscan zooming."))
self.list.append(getConfigListEntry(_("Color Format"), config.plugins.gtv.colour, "disable for black & white."))
self["config"].list = self.list
self["config"].l.setList(self.list)
def changedEntry(self):
choice = self["config"].getCurrent()
if choice != None:
self.createSetup()
def startgTV(session,**kwargs):
session.open(gTVConfiguration)
def mainconf(menuid):
if menuid != "osd_video_audio":
return []
return [(gtv_name, startgTV, "gtv", None)]
def gTVMain(session, **kwargs):
session.open(gTVConfiguration)
MenuDescriptor = PluginDescriptor(name=gtv_name, description=gtv_description, where=PluginDescriptor.WHERE_MENU, fnc=mainconf)
PluginMenuDescriptor = PluginDescriptor(name=gtv_name, description=gtv_description, where = [PluginDescriptor.WHERE_PLUGINMENU], fnc=gTVMain, needsRestart = False, icon="gtv.svg")
StartupDescriptor = PluginDescriptor(where=[PluginDescriptor.WHERE_SESSIONSTART], fnc=sessionstart)
ToggleDescriptor = PluginDescriptor(name = gtv_menu, description = _("enable")+"/"+_("disable")+" gutemine "+_("Display")+" TV", where = [PluginDescriptor.WHERE_EXTENSIONSMENU], fnc=gutemineToggleTV, needsRestart = False, weight=-99)
def Plugins(**kwargs):
cprint("set Plugins for gTV")
plugin_desc=[]
plugin_desc.append(MenuDescriptor)
plugin_desc.append(PluginMenuDescriptor)
plugin_desc.append(StartupDescriptor)
plugin_desc.append(ToggleDescriptor)
return plugin_desc
class PseudoScreen(Screen):
skin = """
<screen position="center,center" size="0,0" flags="wfNoBorder">
</screen>"""
def __init__(self, session):
Screen.__init__(self, session)
self.close()