Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
Size: Mime:
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()