From 94913d0f73c36623ae19916d79cee759b7f6bc98 Mon Sep 17 00:00:00 2001 From: ghost Date: Sun, 16 Nov 2008 13:14:59 +0100 Subject: change pictureplayer to use async pic loading --- .../Plugins/Extensions/PicturePlayer/plugin.py | 901 +++++++++++---------- 1 file changed, 464 insertions(+), 437 deletions(-) (limited to 'lib/python/Plugins') diff --git a/lib/python/Plugins/Extensions/PicturePlayer/plugin.py b/lib/python/Plugins/Extensions/PicturePlayer/plugin.py index ea906f0d..7d62d2be 100644 --- a/lib/python/Plugins/Extensions/PicturePlayer/plugin.py +++ b/lib/python/Plugins/Extensions/PicturePlayer/plugin.py @@ -1,318 +1,511 @@ -from enigma import eTimer, loadPic, getExif +from enigma import ePicLoad, eTimer, getDesktop + from Screens.Screen import Screen -from Screens.ServiceInfo import ServiceInfoList, ServiceInfoListEntry -from Components.ActionMap import ActionMap, NumberActionMap +from Tools.Directories import resolveFilename, pathExists, SCOPE_MEDIA +from Plugins.Plugin import PluginDescriptor + from Components.Pixmap import Pixmap, MovingPixmap +from Components.ActionMap import ActionMap, NumberActionMap from Components.Label import Label - -from Components.ConfigList import ConfigList -from Components.config import * - -from Tools.Directories import resolveFilename, fileExists, pathExists, createDir, SCOPE_MEDIA +from Components.Button import Button from Components.FileList import FileList from Components.AVSwitch import AVSwitch +from Components.Sources.List import List +from Components.ConfigList import ConfigList -from Plugins.Plugin import PluginDescriptor +from Components.config import config, ConfigSubsection, ConfigInteger, ConfigSelection, ConfigText, ConfigEnableDisable, KEY_LEFT, KEY_RIGHT, KEY_0, getConfigListEntry + +def getAspectforPic(): + return AVSwitch().getFramebufferScale() config.pic = ConfigSubsection() -config.pic.slidetime = ConfigInteger(default=10, limits=(5, 60)) -config.pic.resize = ConfigSelection(default="0", choices = [("0", _("simple")), ("1", _("better"))]) +config.pic.framesize = ConfigInteger(default=30, limits=(5, 99)) +config.pic.slidetime = ConfigInteger(default=10, limits=(10, 60)) +config.pic.resize = ConfigSelection(default="1", choices = [("0", _("simple")), ("1", _("better"))]) config.pic.cache = ConfigEnableDisable(default=True) config.pic.lastDir = ConfigText(default=resolveFilename(SCOPE_MEDIA)) -config.pic.rotate = ConfigSelection(default="0", choices = [("0", _("none")), ("1", _("manual")), ("2", _("by Exif"))]) +config.pic.infoline = ConfigEnableDisable(default=True) +config.pic.loop = ConfigEnableDisable(default=True) +config.pic.bgcolor = ConfigSelection(default="#00000000", choices = [("#00000000", _("black")),("#009eb9ff", _("blue")),("#00ff5a51", _("red")), ("#00ffe875", _("yellow")), ("#0038FF48", _("green"))]) +config.pic.textcolor = ConfigSelection(default="#0038FF48", choices = [("#00000000", _("black")),("#009eb9ff", _("blue")),("#00ff5a51", _("red")), ("#00ffe875", _("yellow")), ("#0038FF48", _("green"))]) -def getAspect(): - val = AVSwitch().getAspectRatioSetting() - return val/2 +class picshow(Screen): + def __init__(self, session): + self.skin = """ + + + + + + + + + + + + """ -#------------------------------------------------------------------------------------------ + Screen.__init__(self, session) + + self["actions"] = ActionMap(["OkCancelActions", "ColorActions", "DirectionActions"], + { + "cancel": self.KeyExit, + "red": self.KeyRed, + "yellow": self.KeyYellow, + "blue": self.KeyBlue, + "ok": self.KeyOk + }, -1) + + self["key_red"] = Button(_("Thumbnails")) + self["key_green"] = Button() + self["key_yellow"] = Button(_("Exif")) + self["key_blue"] = Button(_("Setup")) + self["label"] = Label() + self["thn"] = Pixmap() -class ThumbView(Screen): - skin = """ - - - - - - - - - - - - - - - - """ + currDir = config.pic.lastDir.value + if not pathExists(currDir): + currDir = "/" + + self.filelist = FileList(currDir, matchingPattern = "(?i)^.*\.(jpeg|jpg|jpe|png|bmp|gif)") + self["filelist"] = self.filelist + self["filelist"].onSelectionChanged.append(self.selectionChanged) + + self.ThumbTimer = eTimer() + self.ThumbTimer.callback.append(self.showThumb) + + self.picload = ePicLoad() + self.picload.PictureData.get().append(self.showPic) + + self.onLayoutFinish.append(self.setConf) + + def showPic(self, picInfo=""): + ptr = self.picload.getData() + if ptr != None: + self["thn"].instance.setPixmap(ptr.__deref__()) + self["thn"].show() + + text = picInfo.split('\n',1) + self["label"].setText(text[1]) + self["label"].show() + + def showThumb(self): + if not self.filelist.canDescent(): + if self.picload.getThumbnail(self.filelist.getCurrentDirectory() + self.filelist.getFilename()) == 1: + self.ThumbTimer.start(500, True) + + def selectionChanged(self): + if not self.filelist.canDescent(): + self.ThumbTimer.start(500, True) + else: + self["label"].hide() + self["thn"].hide() + + def KeyRed(self): + #if not self.filelist.canDescent(): + self.session.openWithCallback(self.callbackView, Pic_Thumb, self.filelist.getFileList(), self.filelist.getSelectionIndex(), self.filelist.getCurrentDirectory()) + + def KeyYellow(self): + if not self.filelist.canDescent(): + self.session.open(Pic_Exif, self.picload.getInfo(self.filelist.getCurrentDirectory() + self.filelist.getFilename())) - def __init__(self, session, filelist, name, path): - self.skin = ThumbView.skin + def KeyBlue(self): + self.session.openWithCallback(self.setConf ,Pic_Setup) + + def KeyOk(self): + if self.filelist.canDescent(): + self.filelist.descent() + else: + self.session.openWithCallback(self.callbackView, Pic_Full_View, self.filelist.getFileList(), self.filelist.getSelectionIndex(), self.filelist.getCurrentDirectory()) + + def setConf(self): + #0=Width 1=Height 2=Aspect 3=use_cache 4=resize_type 5=Background(#AARRGGBB) + self.picload.setPara([self["thn"].instance.size().width(), self["thn"].instance.size().height(), getAspectforPic(), config.pic.cache.value, int(config.pic.resize.value), "#00000000"]) + + def callbackView(self, val=0): + if val > 0: + self.filelist.moveToIndex(val) + + def KeyExit(self): + del self.picload + + if self.filelist.getCurrentDirectory() is None: + config.pic.lastDir.value = "/" + else: + config.pic.lastDir.value = self.filelist.getCurrentDirectory() + + config.pic.save() + self.close() + +#------------------------------------------------------------------------------------------ + +class Pic_Setup(Screen): + def __init__(self, session): + self.skin = """ + + """ + Screen.__init__(self, session) + + self["actions"] = NumberActionMap(["SetupActions"], + { + "cancel": self.close, + "left": self.keyLeft, + "right": self.keyRight, + "0": self.keyNumber, + "1": self.keyNumber, + "2": self.keyNumber, + "3": self.keyNumber, + "4": self.keyNumber, + "5": self.keyNumber, + "6": self.keyNumber, + "7": self.keyNumber, + "8": self.keyNumber, + "9": self.keyNumber + }, -1) + + list = [] + self["liste"] = ConfigList(list) + list.append(getConfigListEntry(_("Slideshow Interval (sec.)"), config.pic.slidetime)) + list.append(getConfigListEntry(_("Scaling Mode"), config.pic.resize)) + list.append(getConfigListEntry(_("Cache Thumbnails"), config.pic.cache)) + list.append(getConfigListEntry(_("show Infoline"), config.pic.infoline)) + list.append(getConfigListEntry(_("Frame size in full view"), config.pic.framesize)) + list.append(getConfigListEntry(_("slide picture in loop"), config.pic.loop)) + list.append(getConfigListEntry(_("backgroundcolor"), config.pic.bgcolor)) + list.append(getConfigListEntry(_("textcolor"), config.pic.textcolor)) + + def keyLeft(self): + self["liste"].handleKey(KEY_LEFT) + + def keyRight(self): + self["liste"].handleKey(KEY_RIGHT) + + def keyNumber(self, number): + self["liste"].handleKey(KEY_0 + number) + +#--------------------------------------------------------------------------- + +class Pic_Exif(Screen): + def __init__(self, session, exiflist): + self.skin = """ + + + {"template": [ MultiContentEntryText(pos = (5, 5), size = (250, 30), flags = RT_HALIGN_LEFT, text = 0), MultiContentEntryText(pos = (260, 5), size = (290, 30), flags = RT_HALIGN_LEFT, text = 1)], "fonts": [gFont("Regular", 20)], "itemHeight": 30 } + + + """ Screen.__init__(self, session) - self["actions"] = ActionMap(["OkCancelActions", "DirectionActions", "MovieSelectionActions"], + self["actions"] = ActionMap(["OkCancelActions"], + { + "cancel": self.close + }, -1) + + exifdesc = [_("Filename:"), "EXIF-Version:", "Make:", "Camera:", "Date/Time:", "Width / Height:", "Flash used:", "Orientation:", "User Comments:", "Metering Mode:", "Exposure Program:", "Light Source:", "CompressedBitsPerPixel:", "ISO Speed Rating:", "X-Resolution:", "Y-Resolution:", "Resolution Unit:", "Brightness:", "Exposure Time:", "Exposure Bias:", "Distance:", "CCD-Width:", "ApertureFNumber:"] + list = [] + + for x in range(len(exiflist)): + if x>0: + list.append((exifdesc[x], exiflist[x])) + else: + name = exiflist[x].split('/')[-1] + list.append((exifdesc[x], name)) + self["menu"] = List(list) + +#---------------------------------------------------------------------------------------- + +T_INDEX = 0 +T_FRAME_POS = 1 +T_PAGE = 2 +T_NAME = 3 +T_FULL = 4 + +class Pic_Thumb(Screen): + def __init__(self, session, piclist, lastindex, path): + + self.textcolor = config.pic.textcolor.value + self.color = config.pic.bgcolor.value + textsize = 20 + self.spaceX = 35 + self.picX = 190 + self.spaceY = 30 + self.picY = 200 + + size_w = getDesktop(0).size().width() + size_h = getDesktop(0).size().height() + self.thumbsX = size_w / (self.spaceX + self.picX) # thumbnails in X + self.thumbsY = size_h / (self.spaceY + self.picY) # thumbnails in Y + self.thumbsC = self.thumbsX * self.thumbsY # all thumbnails + + self.positionlist = [] + skincontent = "" + + posX = -1 + for x in range(self.thumbsC): + posY = x / self.thumbsX + posX += 1 + if posX >= self.thumbsX: + posX = 0 + + absX = self.spaceX + (posX*(self.spaceX + self.picX)) + absY = self.spaceY + (posY*(self.spaceY + self.picY)) + self.positionlist.append((absX, absY)) + skincontent += "" + + skincontent += "" + + + # Screen, backgroundlabel and MovingPixmap + self.skin = " \ + " + skincontent + "" + + Screen.__init__(self, session) + + self["actions"] = ActionMap(["OkCancelActions", "ColorActions", "DirectionActions", "MovieSelectionActions"], { "cancel": self.Exit, "ok": self.KeyOk, - "showEventInfo": self.StartExif, - "right": self.key_right, "left": self.key_left, + "right": self.key_right, "up": self.key_up, - "down": self.key_down + "down": self.key_down, + "showEventInfo": self.StartExif, }, -1) - for x in range(6): + self["frame"] = MovingPixmap() + for x in range(self.thumbsC): self["label"+str(x)] = Label() self["thumb"+str(x)] = Pixmap() - self["frame"] = MovingPixmap() - - self.aspect = getAspect() - self.path = path - self.filelist = filelist + + self.Thumbnaillist = [] + self.filelist = [] self.currPage = -1 - self.index = 0 - self.old_index = 0 - self.thumblist = [] - self.thumbindex = 0 - self.list = [] - self.poslist = [[50,63],[265,63],[480,63],[50,288],[265,288],[480,288]] - - count=0 - pos=0 - for x in self.filelist: + self.dirlistcount = 0 + self.path = path + + index = 0 + framePos = 0 + Page = 0 + for x in piclist: if x[0][1] == False: - self.list.append((x[0][0], self.path + x[0][0], count/6, pos, "(" + str(count+1) + ") ")) - pos += 1 - if pos == 6: - pos = 0 - if x[0][0] == name: - self.index = count - count += 1 - self.maxentry = len(self.list)-1 + self.filelist.append((index, framePos, Page, x[0][0], path + x[0][0])) + index += 1 + framePos += 1 + if framePos > (self.thumbsC -1): + framePos = 0 + Page += 1 + else: + self.dirlistcount += 1 - if self.maxentry < 0: - self["label0"].setText(_("no Picture found")) + self.maxentry = len(self.filelist)-1 + self.index = lastindex - self.dirlistcount + if self.index < 0: + self.index = 0 + + self.picload = ePicLoad() + self.picload.PictureData.get().append(self.showPic) + + self.onLayoutFinish.append(self.setPicloadConf) self.ThumbTimer = eTimer() - self.ThumbTimer.callback.append(self.showThumb) + self.ThumbTimer.callback.append(self.showPic) - self.fillPage() + def setPicloadConf(self): + self.picload.setPara([self["thumb0"].instance.size().width(), self["thumb0"].instance.size().height(), getAspectforPic(), config.pic.cache.value, int(config.pic.resize.value), self.color]) + self.paintFrame() + + def paintFrame(self): + #print "index=" + str(self.index) + if self.maxentry < self.index or self.index < 0: + return + + pos = self.positionlist[self.filelist[self.index][T_FRAME_POS]] + self["frame"].moveTo( pos[0], pos[1], 1) + self["frame"].startMoving() + + if self.currPage != self.filelist[self.index][T_PAGE]: + self.currPage = self.filelist[self.index][T_PAGE] + self.newPage() + + def newPage(self): + self.Thumbnaillist = [] + #clear Labels and Thumbnail + for x in range(self.thumbsC): + self["label"+str(x)].setText("") + self["thumb"+str(x)].hide() + #paint Labels and fill Thumbnail-List + for x in self.filelist: + if x[T_PAGE] == self.currPage: + self["label"+str(x[T_FRAME_POS])].setText("(" + str(x[T_INDEX]+1) + ") " + x[T_NAME]) + self.Thumbnaillist.append([0, x[T_FRAME_POS], x[T_FULL]]) + + #paint Thumbnail start + self.showPic() + + def showPic(self, picInfo=""): + for x in range(len(self.Thumbnaillist)): + if self.Thumbnaillist[x][0] == 0: + if self.picload.getThumbnail(self.Thumbnaillist[x][2]) == 1: #zu tun probier noch mal + self.ThumbTimer.start(500, True) + else: + self.Thumbnaillist[x][0] = 1 + break + elif self.Thumbnaillist[x][0] == 1: + self.Thumbnaillist[x][0] = 2 + ptr = self.picload.getData() + if ptr != None: + self["thumb" + str(self.Thumbnaillist[x][1])].instance.setPixmap(ptr.__deref__()) + self["thumb" + str(self.Thumbnaillist[x][1])].show() + def key_left(self): self.index -= 1 if self.index < 0: self.index = self.maxentry - self.fillPage() + self.paintFrame() def key_right(self): self.index += 1 if self.index > self.maxentry: self.index = 0 - self.fillPage() + self.paintFrame() def key_up(self): - self.index -= 3 + self.index -= self.thumbsX if self.index < 0: - self.index = 0 - self.fillPage() + self.index =self.maxentry + self.paintFrame() def key_down(self): - self.index += 3 + self.index += self.thumbsX if self.index > self.maxentry: - self.index = self.maxentry - self.fillPage() - - def fillPage(self): - if self.maxentry < 0: - return + self.index = 0 + self.paintFrame() - self["frame"].moveTo(self.poslist[self.list[self.index][3]][0], self.poslist[self.list[self.index][3]][1], 1) - self["frame"].startMoving() - - if self.list[self.index][2] != self.currPage: - self.currPage = self.list[self.index][2] - textlist = ["","","","","",""] - self.thumblist = ["","","","","",""] - - for x in self.list: - if x[2] == self.currPage: - textlist[x[3]] = x[4] + x[0] - self.thumblist[x[3]] = x[0] - - for x in range(6): - self["label"+str(x)].setText(textlist[x]) - self["thumb"+str(x)].hide() - - self.ThumbTimer.start(500, True) - - def showThumb(self): - if self.thumblist[self.thumbindex] != "": - cachefile = "" - if config.pic.cache.value: - cachedir = self.path + ".Thumbnails/" - cachefile = cachedir + self.thumblist[self.thumbindex] + str(180) + str(160) + str(self.aspect) - if not pathExists(cachedir): - if not createDir(cachedir): - cachefile = "" - - ptr = loadPic(self.path + self.thumblist[self.thumbindex], 180, 160, self.aspect, int(config.pic.resize.value), int(config.pic.rotate.value), 1, cachefile, 1) - if ptr != None: - self["thumb"+str(self.thumbindex)].show() - self["thumb"+str(self.thumbindex)].instance.setPixmap(ptr) - - self.thumbindex += 1 - if self.thumbindex < 6: - self.ThumbTimer.start(500, True) - else: - self.thumbindex = 0 - else: - self.thumbindex = 0 - def StartExif(self): if self.maxentry < 0: return - - self.session.open(ExifView, self.list[self.index][1], self.list[self.index][0]) + self.session.open(Pic_Exif, self.picload.getInfo(self.filelist[self.index][T_FULL])) def KeyOk(self): if self.maxentry < 0: return - self.old_index = self.index - self.session.openWithCallback(self.returnView ,PicView, self.filelist, self.list[self.index][0], self.path) - - def returnView(self, val=0): + self.session.openWithCallback(self.callbackView, Pic_Full_View, self.filelist, self.index, self.path) + + def callbackView(self, val=0): self.index = val if self.old_index != self.index: - self.fillPage() - + self.paintFrame() def Exit(self): - self.close(self.index) + del self.picload + self.close(self.index + self.dirlistcount) -#------------------------------------------------------------------------------------------ +#--------------------------------------------------------------------------- -class PicView(Screen): - skin = """ - - - - - - - - - - - """ - - def __init__(self, session, filelist, name, path): - self.skin = PicView.skin - Screen.__init__(self, session) +class Pic_Full_View(Screen): + def __init__(self, session, filelist, index, path): - self["actions"] = ActionMap(["OkCancelActions", "ColorActions", "MovieSelectionActions"], + self.textcolor = config.pic.textcolor.value + self.bgcolor = config.pic.bgcolor.value + space = config.pic.framesize.value + size_w = getDesktop(0).size().width() + size_h = getDesktop(0).size().height() + + self.skin = " \ + \ + \ + \ + " + + Screen.__init__(self, session) + + self["actions"] = ActionMap(["OkCancelActions", "ColorActions", "DirectionActions", "MovieSelectionActions"], { "cancel": self.Exit, - "showEventInfo": self.StartExif, - "green": self.Play, - "yellow": self.Pause, + "green": self.PlayPause, + "yellow": self.PlayPause, "blue": self.nextPic, - "red": self.prevPic + "red": self.prevPic, + "left": self.prevPic, + "right": self.nextPic, + "showEventInfo": self.StartExif, }, -1) - - self.aspect = getAspect() - self.blinking = False - self.autoShow = True - self.slideOn = False - self.pauseOn = False - self.index = 0 - self.old = 0 - self.list = [] - count=0 - for x in filelist: - if x[0][1] == False: - self.list.append((x[0][0], path + x[0][0], 0)) - if x[0][0] == name: - self.index = count - count += 1 - self.maxentry = len(self.list)-1 - - self["file"] = Label(_("please wait, loading picture...")) - self["picture"] = Pixmap() self["point"] = Pixmap() - self["play"] = Pixmap() - self["pause"] = Pixmap() + self["pic"] = Pixmap() + self["play_icon"] = Pixmap() + self["file"] = Label(_("please wait, loading picture...")) - self.decodeTimer = eTimer() - self.decodeTimer.callback.append(self.decodePic) - self.decodeTimer.start(300, True) + self.old_index = 0 + self.filelist = [] + self.lastindex = index + self.currPic = [] + self.shownow = True + self.dirlistcount = 0 - self.slideTimer = eTimer() - self.slideTimer.callback.append(self.slidePic) - - - def Pause(self): - if self.slideOn: - if self.pauseOn: - self.pauseOn=False - self["pause"].show() - else: - self.pauseOn=True - self["play"].show() - self.slideValue = 0 - - def Play(self): - if self.pauseOn == False: - if self.slideOn: - self.slideOn=False - self["play"].show() - else: - self.slideOn=True - self.slideTimer.start(1000, True) - - self.slideValue = int(config.pic.slidetime.value) + for x in filelist: + if len(filelist[0]) == 3: #orig. filelist + if x[0][1] == False: + self.filelist.append(path + x[0][0]) + else: + self.dirlistcount += 1 + else: # thumbnaillist + self.filelist.append(x[T_FULL]) + + self.maxentry = len(self.filelist)-1 + self.index = index - self.dirlistcount + if self.index < 0: + self.index = 0 - def slidePic(self): - if self.slideOn == True and self.pauseOn == False: - self.blinkingWidget("play") - self.slideValue -= 1 - if self.slideValue <= 0: - self.slideValue = int(config.pic.slidetime.value) - self.nextPic() + self.picload = ePicLoad() + self.picload.PictureData.get().append(self.finish_decode) - self.slideTimer.start(1000, True) + self.slideTimer = eTimer() + self.slideTimer.callback.append(self.slidePic) - if self.pauseOn: - self.blinkingWidget("pause") - self.slideTimer.start(1000, True) + if self.maxentry >= 0: + self.onLayoutFinish.append(self.setPicloadConf) - def decodePic(self): - self.currPic = loadPic(self.list[self.index][1], 560, 450, self.aspect, int(config.pic.resize.value), int(config.pic.rotate.value),1) - self["point"].hide() - if self.autoShow: - self.showPic() - self.autoShow = False + def setPicloadConf(self): + self.picload.setPara([self["pic"].instance.size().width(), self["pic"].instance.size().height(), getAspectforPic(), 0, int(config.pic.resize.value), self.bgcolor]) - def showPic(self): - if self.currPic != None: - self.old = self.index - self["file"].setText(self.list[self.old][0] + " (" + str(self.old+1) + "/" + str(self.maxentry+1) + ")") - self["picture"].instance.setPixmap(self.currPic) + self["play_icon"].hide() + if config.pic.infoline.value == False: + self["file"].hide() + self.start_decode() - self.next() - self["point"].show() - self.decodeTimer.start(300, True) - - def nextPic(self): - self.showPic() - - def prevPic(self): - self.index = self.old - self.prev() - self.autoShow = True + def ShowPicture(self): + if self.shownow and len(self.currPic): + self.shownow = False + self["file"].setText(self.currPic[0]) + self.lastindex = self.currPic[1] + self["pic"].instance.setPixmap(self.currPic[2].__deref__()) + self.currPic = [] + + self.next() + self.start_decode() + + def finish_decode(self, picInfo=""): + self["point"].hide() + ptr = self.picload.getData() + if ptr != None: + text = "" + try: + text = picInfo.split('\n',1) + text = "(" + str(self.index+1) + "/" + str(self.maxentry+1) + ") " + text[0].split('/')[-1] + except: + pass + self.currPic = [] + self.currPic.append(text) + self.currPic.append(self.index) + self.currPic.append(ptr) + self.ShowPicture() + + def start_decode(self): + self.picload.startDecode(self.filelist[self.index]) self["point"].show() - self.decodeTimer.start(300, True) - + def next(self): self.index += 1 if self.index > self.maxentry: @@ -322,218 +515,52 @@ class PicView(Screen): self.index -= 1 if self.index < 0: self.index = self.maxentry - - def blinkingWidget(self, name): - if self.blinking: - self.blinking=False - self[name].show() - else: - self.blinking=True - self[name].hide() - - def StartExif(self): - if self.pauseOn == False: - self.Pause() - self.session.openWithCallback(self.StopExif ,ExifView, self.list[self.old][1], self.list[self.old][0]) - - def StopExif(self): - if self.pauseOn: - self.Pause() - - def Exit(self): - self.close(self.old) - -#------------------------------------------------------------------------------------------ -class ExifView(Screen): - skin = """ - - - """ - - def __init__(self, session, fullname, name): - self.skin = ExifView.skin - Screen.__init__(self, session) - - self["actions"] = ActionMap(["OkCancelActions"], - { - "cancel": self.close - }, -1) - - dlist = ["Name:", "EXIF-Version:", "Camera-Make:", "Camera-Model:", "Date/Time:", "User Comments:", "Width / Height:", "Orientation:", "Metering Mode:", "Exposure Program:", "Light Source:", "Flash used:", "CompressedBitsPerPixel:", "ISO Speed Rating:", "X-Resolution:", "Y-Resolution:", "Resolution Unit:", "Brightness:", "Exposure Time:", "Exposure Bias:", "Distance:", "CCD-Width:", "ApertureFNumber:"] - tlist = [ ] - self["exiflist"] = ServiceInfoList(tlist) - tlist.append(ServiceInfoListEntry(dlist[0], name)) - count=1 - for x in getExif(fullname): - tlist.append(ServiceInfoListEntry(dlist[count], x)) - count += 1 - -#------------------------------------------------------------------------------------------ - -class PicSetup(Screen): - skin = """ - - - """ - - def __init__(self, session): - self.skin = PicSetup.skin - Screen.__init__(self, session) - - self["actions"] = NumberActionMap(["SetupActions"], - { - "cancel": self.close, - "left": self.keyLeft, - "right": self.keyRight, - "0": self.keyNumber, - "1": self.keyNumber, - "2": self.keyNumber, - "3": self.keyNumber, - "4": self.keyNumber, - "5": self.keyNumber, - "6": self.keyNumber, - "7": self.keyNumber, - "8": self.keyNumber, - "9": self.keyNumber - }, -1) - - self.list = [] - self["liste"] = ConfigList(self.list) - self.list.append(getConfigListEntry(_("Slideshow Interval (sec.)"), config.pic.slidetime)) - self.list.append(getConfigListEntry(_("Scaling Mode"), config.pic.resize)) - self.list.append(getConfigListEntry(_("Cache Thumbnails"), config.pic.cache)) - #self.list.append(getConfigListEntry(_("Rotate Picture"), config.pic.rotate)) - - def keyLeft(self): - self["liste"].handleKey(KEY_LEFT) - - def keyRight(self): - self["liste"].handleKey(KEY_RIGHT) - - def keyNumber(self, number): - self["liste"].handleKey(KEY_0 + number) - - -#------------------------------------------------------------------------------------------ - -class picmain(Screen): - skin = """ - - - - - - - - - - """ - - def __init__(self, session): - self.skin = picmain.skin - Screen.__init__(self, session) - - self["actions"] = ActionMap(["OkCancelActions", "DirectionActions", "ColorActions", "MovieSelectionActions"], - { - "ok": self.KeyOk, - "cancel": self.Exit, - "right": self.rightDown, - "left": self.leftUp, - "up": self.up, - "down": self.down, - "showEventInfo": self.StartExif, - "contextMenu": self.Settings, - "red": self.StartThumb - }, -1) - - self.aspect = getAspect() - currDir = config.pic.lastDir.value - if not pathExists(currDir): - currDir = "/" - - self.filelist = FileList(currDir, matchingPattern = "(?i)^.*\.(jpeg|jpg|jpe|png|bmp|gif)") - self["filelist"] = self.filelist - self["thumbnail"] = Pixmap() - - self.ThumbTimer = eTimer() - self.ThumbTimer.callback.append(self.showThumb) - self.ThumbTimer.start(500, True) - - def up(self): - self["filelist"].up() - self.ThumbTimer.start(1500, True) - - def down(self): - self["filelist"].down() - self.ThumbTimer.start(1500, True) - - def leftUp(self): - self["filelist"].pageUp() - self.ThumbTimer.start(1500, True) - - def rightDown(self): - self["filelist"].pageDown() - self.ThumbTimer.start(1500, True) - - def showThumb(self): - if not self.filelist.canDescent(): - cachefile = "" - if config.pic.cache.value: - cachedir = self.filelist.getCurrentDirectory() + ".Thumbnails/" - cachefile = cachedir + self.filelist.getFilename() + str(180) + str(160) + str(self.aspect) - if not pathExists(cachedir): - if not createDir(cachedir): - cachefile = "" - - ptr = loadPic(self.filelist.getCurrentDirectory() + self.filelist.getFilename(), 180, 160, self.aspect, int(config.pic.resize.value), 0, 0, cachefile, 1) - if ptr != None: - self["thumbnail"].show() - self["thumbnail"].instance.setPixmap(ptr) - else: - self["thumbnail"].hide() - - def KeyOk(self): - if self.filelist.canDescent(): - self.filelist.descent() + def slidePic(self): + print "slide to next Picture index=" + str(self.lastindex) + if config.pic.loop.value==False and self.lastindex == self.maxentry: + self.PlayPause() + self.shownow = True + self.ShowPicture() + + def PlayPause(self): + if self.slideTimer.isActive(): + self.slideTimer.stop() + self["play_icon"].hide() else: - self.session.openWithCallback(self.returnVal, PicView, self.filelist.getFileList(), self.filelist.getFilename(), self.filelist.getCurrentDirectory()) - - def StartThumb(self): - self.session.openWithCallback(self.returnVal, ThumbView, self.filelist.getFileList(), self.filelist.getFilename(), self.filelist.getCurrentDirectory()) + self.slideTimer.start(config.pic.slidetime.value*1000) + self["play_icon"].show() + self.nextPic() - def returnVal(self, val=0): - if val > 0: - for x in self.filelist.getFileList(): - if x[0][1] == True: - val += 1 - self.filelist.moveToIndex(val) + def prevPic(self): + self.currPic = [] + self.index = self.lastindex + self.prev() + self.start_decode() + self.shownow = True + def nextPic(self): + self.shownow = True + self.ShowPicture() + def StartExif(self): - if not self.filelist.canDescent(): - self.session.open(ExifView, self.filelist.getCurrentDirectory() + self.filelist.getFilename(), self.filelist.getFilename()) + if self.maxentry < 0: + return + self.session.open(Pic_Exif, self.picload.getInfo(self.filelist[self.lastindex])) - def Settings(self): - self.session.open(PicSetup) - def Exit(self): - if self.filelist.getCurrentDirectory() is None: - config.pic.lastDir.value = "/" - else: - config.pic.lastDir.value = self.filelist.getCurrentDirectory() - - config.pic.save() - self.close() + del self.picload + self.close(self.lastindex + self.dirlistcount) #------------------------------------------------------------------------------------------ def main(session, **kwargs): - session.open(picmain) + session.open(picshow) def filescan_open(list, session, **kwargs): # Recreate List as expected by PicView filelist = [((file.path, False), None) for file in list] - session.open(PicView, filelist, "", "") + session.open(Pic_Full_View, filelist, 0, file.path) def filescan(**kwargs): from Components.Scanner import Scanner, ScanPath @@ -557,5 +584,5 @@ def filescan(**kwargs): def Plugins(**kwargs): return \ - [PluginDescriptor(name="PicturePlayer", description="Picture Viewer (BMP, PNG, JPG, GIF)", icon="pictureplayer.png", where = PluginDescriptor.WHERE_PLUGINMENU, fnc=main), - PluginDescriptor(name="PicturePlayer", where = PluginDescriptor.WHERE_FILESCAN, fnc = filescan)] + [PluginDescriptor(name=_("PicturePlayer"), description=_("fileformats (BMP, PNG, JPG, GIF)"), icon="pictureplayer.png", where = PluginDescriptor.WHERE_PLUGINMENU, fnc=main), + PluginDescriptor(name=_("PicturePlayer"), where = PluginDescriptor.WHERE_FILESCAN, fnc = filescan)] -- cgit v1.2.3 From 5bbb74ccef1fe4bd524a5cd6427d3c7b803fe82e Mon Sep 17 00:00:00 2001 From: Fraxinas Date: Mon, 17 Nov 2008 08:44:20 +0100 Subject: remove hotplugNotifier on every way of exiting --- lib/python/Plugins/Extensions/DVDBurn/DVDToolbox.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/python/Plugins') diff --git a/lib/python/Plugins/Extensions/DVDBurn/DVDToolbox.py b/lib/python/Plugins/Extensions/DVDBurn/DVDToolbox.py index 836c9fbd..162bf352 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/DVDToolbox.py +++ b/lib/python/Plugins/Extensions/DVDBurn/DVDToolbox.py @@ -50,7 +50,7 @@ class DVDToolbox(Screen): "green": self.update, "yellow": self.format, #"blue": self.eject, - "cancel": self.close, + "cancel": self.exit, "pageUp": self.pageUp, "pageDown": self.pageDown }) -- cgit v1.2.3 From 083c49ace50d1aa702cf47785e0d38966f8e71a1 Mon Sep 17 00:00:00 2001 From: Fraxinas Date: Mon, 17 Nov 2008 10:01:47 +0100 Subject: allow blanking DVD-RAM media. the burn tool however only writes disc-at-once. --- lib/python/Plugins/Extensions/DVDBurn/DVDToolbox.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/python/Plugins') diff --git a/lib/python/Plugins/Extensions/DVDBurn/DVDToolbox.py b/lib/python/Plugins/Extensions/DVDBurn/DVDToolbox.py index 162bf352..b88dbb3f 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/DVDToolbox.py +++ b/lib/python/Plugins/Extensions/DVDBurn/DVDToolbox.py @@ -89,7 +89,7 @@ class DVDToolbox(Screen): for line in mediuminfo.splitlines(): if line.find("Mounted Media:") > -1: mediatype = line.rsplit(',',1)[1][1:] - if mediatype.find("RW") > 0: + if mediatype.find("RW") > 0 or mediatype.find("RAM") > 0: self.formattable = True else: self.formattable = False @@ -186,7 +186,7 @@ class DVDformatTask(Task): if line.startswith("- media is already formatted"): self.error = self.ERROR_ALREADYFORMATTED self.retryargs = [ "-force" ] - if line.startswith("- media is not blank"): + if line.startswith("- media is not blank") or line.startswith(" -format=full to perform full (lengthy) reformat;"): self.error = self.ERROR_ALREADYFORMATTED self.retryargs = [ "-blank" ] if line.startswith(":-( mounted media doesn't appear to be"): -- cgit v1.2.3 From b19b6c15482681e331f346acb56b1566102e1418 Mon Sep 17 00:00:00 2001 From: Fraxinas Date: Mon, 17 Nov 2008 10:10:39 +0100 Subject: actually exit dvd player on pressing exit key in exit choicebox --- lib/python/Plugins/Extensions/DVDPlayer/plugin.py | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) (limited to 'lib/python/Plugins') diff --git a/lib/python/Plugins/Extensions/DVDPlayer/plugin.py b/lib/python/Plugins/Extensions/DVDPlayer/plugin.py index cb5f0e0d..593d4d2e 100644 --- a/lib/python/Plugins/Extensions/DVDPlayer/plugin.py +++ b/lib/python/Plugins/Extensions/DVDPlayer/plugin.py @@ -491,7 +491,7 @@ class DVDPlayer(Screen, InfoBarBase, InfoBarNotifications, InfoBarSeek, InfoBarP def askLeavePlayer(self): choices = [(_("Continue playing"), "play"), (_("Exit"), "exit")] if not self.physicalDVD: - choices.insert(1,(_("Return to file browser"), "browser")) + choices.insert(1,(_("Return to file browser"), "browser")) self.session.openWithCallback(self.exitCB, ChoiceBox, title=_("Leave DVD Player?"), list = choices) def sendKey(self, key): @@ -590,19 +590,16 @@ class DVDPlayer(Screen, InfoBarBase, InfoBarNotifications, InfoBarSeek, InfoBarP print "cur_dlg", self.session.current_dialog def exitCB(self, answer): - if answer is not None: - if answer[1] == "exit": - if self.service: - self.service = None - self.close() - if answer[1] == "browser": + if not answer or answer and answer[1] == "exit": + if self.service: + self.service = None + self.close() + if answer and answer[1] == "browser": #TODO check here if a paused dvd playback is already running... then re-start it... #else - if self.service: - self.service = None - self.showFileBrowser() - else: - pass + if self.service: + self.service = None + self.showFileBrowser() def __onClose(self): for i in (("/proc/stb/video/aspect", self.old_aspect), ("/proc/stb/video/policy", self.old_policy), ("/proc/stb/denc/0/wss", self.old_wss)): -- cgit v1.2.3 From 9ccb92fb3eaca35ec60c1a596db9620f9f302044 Mon Sep 17 00:00:00 2001 From: ghost Date: Mon, 17 Nov 2008 21:17:34 +0100 Subject: more changes for async picture decode support --- lib/gdi/picload.cpp | 109 +++++++++++++++------ lib/gdi/picload.h | 5 + lib/python/Components/AVSwitch.py | 16 ++- .../SystemPlugins/Videomode/VideoHardware.py | 29 ++++++ 4 files changed, 125 insertions(+), 34 deletions(-) (limited to 'lib/python/Plugins') diff --git a/lib/gdi/picload.cpp b/lib/gdi/picload.cpp index 2ef901f5..b1dfd1a1 100644 --- a/lib/gdi/picload.cpp +++ b/lib/gdi/picload.cpp @@ -569,19 +569,29 @@ ePicLoad::ePicLoad() m_conf.thumbnailsize = 180; } -ePicLoad::~ePicLoad() +void ePicLoad::waitFinished() { msg_thread.send(Message(Message::quit)); kill(); +} +ePicLoad::~ePicLoad() +{ + if (threadrunning) + waitFinished(); if(m_filepara != NULL) delete m_filepara; } +void ePicLoad::thread_finished() +{ + threadrunning=false; +} void ePicLoad::thread() { hasStarted(); + threadrunning=true; nice(4); runLoop(); } @@ -759,7 +769,6 @@ void ePicLoad::gotMessage(const Message &msg) break; case Message::decode_finished: // called from main thread //eDebug("[Picload] decode finished... %s", m_filepara->file); - threadrunning=false; if(m_filepara->callback) { PictureData(m_filepara->picinfo.c_str()); @@ -824,7 +833,6 @@ int ePicLoad::startThread(int what, const char *file, int x, int y) return 1; } - threadrunning=true; if(what==1) msg_thread.send(Message(Message::decode_Pic)); else @@ -843,33 +851,6 @@ RESULT ePicLoad::getThumbnail(const char *file, int x, int y) return startThread(0, file, x, y); } -RESULT ePicLoad::setPara(PyObject *val) -{ - if (!PyList_Check(val)) - return 0; - if (PyList_Size(val) < 6) - return 0; - - m_conf.max_x = PyInt_AsLong( PyList_GET_ITEM(val, 0)); - m_conf.max_y = PyInt_AsLong( PyList_GET_ITEM(val, 1)); - m_conf.aspect_ratio = PyFloat_AsDouble( PyList_GET_ITEM(val, 2)); - m_conf.usecache = PyInt_AsLong( PyList_GET_ITEM(val, 3)); - m_conf.resizetype = PyInt_AsLong( PyList_GET_ITEM(val, 4)); - const char *bg_str = PyString_AsString( PyList_GET_ITEM(val, 5)); - - if(bg_str[0] == '#' && strlen(bg_str)==9) - { - int bg = strtoul(bg_str+1, NULL, 16); - m_conf.background[0] = bg&0xFF; //BB - m_conf.background[1] = (bg>>8)&0xFF; //GG - m_conf.background[2] = (bg>>16)&0xFF; //RR - m_conf.background[3] = bg>>24; //AA - } - - eDebug("[Picload] setPara max-X=%d max-Y=%d aspect_ratio=%lf cache=%d resize=%d bg=#%02X%02X%02X%02X", m_conf.max_x, m_conf.max_y, m_conf.aspect_ratio, (int)m_conf.usecache, (int)m_conf.resizetype, m_conf.background[3], m_conf.background[2], m_conf.background[1], m_conf.background[0]); - return 1; -} - PyObject *ePicLoad::getInfo(const char *filename) { ePyObject list; @@ -935,6 +916,7 @@ PyObject *ePicLoad::getInfo(const char *filename) int ePicLoad::getData(ePtr &result) { + result = 0; if(m_filepara->pic_buffer == NULL) return 0; m_filepara->pic_buffer = conv24to32(m_filepara->pic_buffer, m_filepara->ox * m_filepara->oy); @@ -1015,3 +997,70 @@ int ePicLoad::getData(ePtr &result) return 0; } + +RESULT ePicLoad::setPara(PyObject *val) +{ + if (!PyList_Check(val)) + return 0; + if (PyList_Size(val) < 6) + return 0; + + m_conf.max_x = PyInt_AsLong( PyList_GET_ITEM(val, 0)); + m_conf.max_y = PyInt_AsLong( PyList_GET_ITEM(val, 1)); + m_conf.aspect_ratio = PyFloat_AsDouble( PyList_GET_ITEM(val, 2)); + m_conf.usecache = PyInt_AsLong( PyList_GET_ITEM(val, 3)); + m_conf.resizetype = PyInt_AsLong( PyList_GET_ITEM(val, 4)); + const char *bg_str = PyString_AsString( PyList_GET_ITEM(val, 5)); + + if(bg_str[0] == '#' && strlen(bg_str)==9) + { + int bg = strtoul(bg_str+1, NULL, 16); + m_conf.background[0] = bg&0xFF; //BB + m_conf.background[1] = (bg>>8)&0xFF; //GG + m_conf.background[2] = (bg>>16)&0xFF; //RR + m_conf.background[3] = bg>>24; //AA + } + + eDebug("[Picload] setPara max-X=%d max-Y=%d aspect_ratio=%lf cache=%d resize=%d bg=#%02X%02X%02X%02X", m_conf.max_x, m_conf.max_y, m_conf.aspect_ratio, (int)m_conf.usecache, (int)m_conf.resizetype, m_conf.background[3], m_conf.background[2], m_conf.background[1], m_conf.background[0]); + return 1; +} + +//------------------------------------------------------------------------------------ + +//for old plugins +SWIG_VOID(int) loadPic(ePtr &result, std::string filename, int x, int y, int aspect, int resize_mode, int rotate, int background, std::string cachefile) +{ + result = 0; + eDebug("deprecated loadPic function used!!! please use the non blocking version! you can see demo code in Pictureplayer plugin... this function is removed in the near future!"); + ePicLoad mPL; + + double aspect_ratio; + switch(aspect) + { + case 1: aspect_ratio = 1.778 / ((double)720/576); break; //16:9 + case 2: aspect_ratio = 1.600 / ((double)720/576); break; //16:10 + case 3: aspect_ratio = 1.250 / ((double)720/576); break; //5:4 + default: aspect_ratio = 1.333 / ((double)720/576); //4:3 + } + + ePyObject list = PyList_New(6); + PyList_SET_ITEM(list, 0, PyLong_FromLong(x)); + PyList_SET_ITEM(list, 1, PyLong_FromLong(y)); + PyList_SET_ITEM(list, 2, PyFloat_FromDouble(aspect_ratio)); + PyList_SET_ITEM(list, 3, PyLong_FromLong(0)); + PyList_SET_ITEM(list, 4, PyLong_FromLong(resize_mode)); + if(background) + PyList_SET_ITEM(list, 5, PyString_FromString("#ff000000")); + else + PyList_SET_ITEM(list, 5, PyString_FromString("#00000000")); + + mPL.setPara(list); + + if(!mPL.startDecode(filename.c_str())) + { + mPL.waitFinished(); // this blocks until the thread is finished + mPL.getData(result); + } + + return 0; +} diff --git a/lib/gdi/picload.h b/lib/gdi/picload.h index a85567c0..6a0f70b9 100644 --- a/lib/gdi/picload.h +++ b/lib/gdi/picload.h @@ -86,7 +86,9 @@ class ePicLoad: public eMainloop, public eThread, public Object, public iObject void gotMessage(const Message &message); void thread(); int startThread(int what, const char *file, int x, int y); + void thread_finished(); public: + void waitFinished(); PSignal1 PictureData; ePicLoad(); @@ -99,4 +101,7 @@ public: SWIG_VOID(int) getData(ePtr &SWIG_OUTPUT); }; +//for old plugins +SWIG_VOID(int) loadPic(ePtr &SWIG_OUTPUT, std::string filename, int x, int y, int aspect, int resize_mode=0, int rotate=0, int background=0, std::string cachefile=""); + #endif // __picload_h__ diff --git a/lib/python/Components/AVSwitch.py b/lib/python/Components/AVSwitch.py index 7ac2bb98..19aca24d 100644 --- a/lib/python/Components/AVSwitch.py +++ b/lib/python/Components/AVSwitch.py @@ -1,5 +1,5 @@ from config import config, ConfigSlider, ConfigSelection, ConfigYesNo, ConfigEnableDisable, ConfigSubsection, ConfigBoolean -from enigma import eAVSwitch +from enigma import eAVSwitch, getDesktop from SystemInfo import SystemInfo class AVSwitch: @@ -32,9 +32,12 @@ class AVSwitch: if valstr in ("4_3_letterbox", "4_3_panscan"): # 4:3 return 1.333333333 elif valstr == "16_9": # auto ... 4:3 or 16:9 - # TODO: here we must retrieve the current video aspect ratio... - # because the TV can run in 4:3 or in 16:9 mode.. (switched by wss or scart pin8) - # until we have done this we always return the scale value for 16:9!! + try: + aspect_str = open("/proc/stb/vmpeg/0/aspect", "r").read() + if aspect_str == "1": # 4:3 + return 1.333333333 + except IOError: + pass return 1.777777778 elif valstr in ("16_9_always", "16_9_letterbox"): # 16:9 return 1.777777778 @@ -43,6 +46,11 @@ class AVSwitch: print "unknown output aspect!" return 1.0000 + def getFramebufferScale(self): + aspect = self.getOutputAspect() + fb_size = getDesktop(0).size() + return aspect / ((1.0 * fb_size.width()) / fb_size.height()) + def getAspectRatioSetting(self): valstr = config.av.aspectratio.value if valstr == "4_3_letterbox": diff --git a/lib/python/Plugins/SystemPlugins/Videomode/VideoHardware.py b/lib/python/Plugins/SystemPlugins/Videomode/VideoHardware.py index 2422475e..5e38f3e6 100644 --- a/lib/python/Plugins/SystemPlugins/Videomode/VideoHardware.py +++ b/lib/python/Plugins/SystemPlugins/Videomode/VideoHardware.py @@ -59,6 +59,34 @@ class VideoHardware: widescreen_modes = set(["720p", "1080i"]) + def getOutputAspect(self): + ret = 1.777777778 # 16:9 + port = config.av.videoport.value + if port not in config.av.videomode: + print "current port not available in getOutputAspect!!! force 16:9" + else: + mode = config.av.videomode[port].value + force_widescreen = self.isWidescreenMode(port, mode) + is_widescreen = force_widescreen or config.av.aspect.value in ["16_9", "16_10"] + is_auto = config.av.aspect.value == "auto" + if is_widescreen: + if force_widescreen: + pass + else: + aspect = {"16_9": "16:9", "16_10": "16:10"}[config.av.aspect.value] + if aspect == "16:10": + ret = 1.6 + elif is_auto: + try: + aspect_str = open("/proc/stb/vmpeg/0/aspect", "r").read() + if aspect_str == "1": # 4:3 + ret = 1.333333333 + except IOError: + pass + else: # 4:3 + ret = 1.333333333 + return ret + def __init__(self): self.last_modes_preferred = [ ] self.on_hotplug = CList() @@ -80,6 +108,7 @@ class VideoHardware: config.av.tvsystem.notifiers = [ ] config.av.wss.notifiers = [ ] AVSwitch.setInput = self.AVSwitchSetInput + AVSwitch.getOutputAspect = self.getOutputAspect config.av.aspect.addNotifier(self.updateAspect) config.av.wss.addNotifier(self.updateAspect) -- cgit v1.2.3 From cd51d1c8a2ec341b4202689e693b7bf012610d0d Mon Sep 17 00:00:00 2001 From: Fraxinas Date: Mon, 17 Nov 2008 23:17:46 +0100 Subject: change hotplugNotifier to return correct state transition for cd-rom type and flash type devices --- lib/python/Plugins/SystemPlugins/Hotplug/plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/python/Plugins') diff --git a/lib/python/Plugins/SystemPlugins/Hotplug/plugin.py b/lib/python/Plugins/SystemPlugins/Hotplug/plugin.py index 97ddf4a1..e593e942 100644 --- a/lib/python/Plugins/SystemPlugins/Hotplug/plugin.py +++ b/lib/python/Plugins/SystemPlugins/Hotplug/plugin.py @@ -53,7 +53,7 @@ class Hotplug(Protocol): for callback in hotplugNotifier: try: - callback(dev, media_state) + callback(dev, action or media_state) except AttributeError: hotplugNotifier.remove(callback) -- cgit v1.2.3 From 53a9e8c65ffb3c83736be784c894c57beca5bde5 Mon Sep 17 00:00:00 2001 From: Fraxinas Date: Mon, 17 Nov 2008 23:20:56 +0100 Subject: use new hotplugNotifier return value to clear playlist if audio CD was removed --- .../Plugins/Extensions/MediaPlayer/plugin.py | 27 +++++++++++++--------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'lib/python/Plugins') diff --git a/lib/python/Plugins/Extensions/MediaPlayer/plugin.py b/lib/python/Plugins/Extensions/MediaPlayer/plugin.py index 0d5305d7..babef3e7 100644 --- a/lib/python/Plugins/Extensions/MediaPlayer/plugin.py +++ b/lib/python/Plugins/Extensions/MediaPlayer/plugin.py @@ -863,17 +863,22 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB self.session.open(Subtitles) def hotplugCB(self, dev, media_state): - if dev == harddiskmanager.getCD(): - from Components.Scanner import scanDevice - devpath = harddiskmanager.getAutofsMountpoint(harddiskmanager.getCD()) - self.cdAudioTrackFiles = [] - res = scanDevice(devpath) - list = [ (r.description, r, res[r], self.session) for r in res ] - if list: - (desc, scanner, files, session) = list[0] - for file in files: - if file.mimetype == "audio/x-cda": - self.cdAudioTrackFiles.append(file.path) + if dev == harddiskmanager.getCD(): + if media_state == "1": + from Components.Scanner import scanDevice + devpath = harddiskmanager.getAutofsMountpoint(harddiskmanager.getCD()) + self.cdAudioTrackFiles = [] + res = scanDevice(devpath) + list = [ (r.description, r, res[r], self.session) for r in res ] + if list: + (desc, scanner, files, session) = list[0] + for file in files: + if file.mimetype == "audio/x-cda": + self.cdAudioTrackFiles.append(file.path) + else: + self.cdAudioTrackFiles = [] + if self.isAudioCD: + self.clear_playlist() class MediaPlayerLCDScreen(Screen): skin = """ -- cgit v1.2.3 From 95b10a03763a432c7d5940cc83d9e4fa9ed3cc7c Mon Sep 17 00:00:00 2001 From: Fraxinas Date: Mon, 17 Nov 2008 23:22:01 +0100 Subject: use hotplugNotifier to ease use of NFIFlash plugin. change some excess status bar translatables to static english. --- .../Plugins/SystemPlugins/NFIFlash/downloader.py | 50 +++++++++------------- .../Plugins/SystemPlugins/NFIFlash/flasher.py | 10 ++--- 2 files changed, 25 insertions(+), 35 deletions(-) (limited to 'lib/python/Plugins') diff --git a/lib/python/Plugins/SystemPlugins/NFIFlash/downloader.py b/lib/python/Plugins/SystemPlugins/NFIFlash/downloader.py index c2046af7..7e34d2bb 100644 --- a/lib/python/Plugins/SystemPlugins/NFIFlash/downloader.py +++ b/lib/python/Plugins/SystemPlugins/NFIFlash/downloader.py @@ -18,6 +18,7 @@ import urllib from twisted.web import client from twisted.internet import reactor, defer from twisted.python import failure +from Plugins.SystemPlugins.Hotplug.plugin import hotplugNotifier class UserRequestedCancel(Exception): pass @@ -335,7 +336,7 @@ class NFIDownload(Screen): self.download = self.nfo_download self.downloading(True) client.getPage(nfourl).addCallback(self.nfo_finished).addErrback(self.nfo_failed) - self["statusbar"].text = _("Downloading image description...") + self["statusbar"].text = ("Downloading image description...") def nfo_failed(self, failure_instance): print "[nfo_failed] " + str(failure_instance) @@ -400,7 +401,7 @@ class NFIDownload(Screen): pos = self.nfo.find("MD5:") if pos > 0 and len(self.nfo) >= pos+5+32: - self["statusbar"].text = _("Please wait for md5 signature verification...") + self["statusbar"].text = ("Please wait for md5 signature verification...") cmd = "md5sum -c -" md5 = self.nfo[pos+5:pos+5+32] + " " + self.nfilocal print cmd, md5 @@ -489,33 +490,22 @@ class NFIDownload(Screen): def umount_finished(self, retval): self.container.appClosed.remove(self.umount_finished) - self.session.openWithCallback(self.dmesg_clear, MessageBox, _("To make sure you intend to do this, please remove the target USB stick now and stick it back in upon prompt. Press OK when you have taken the stick out."), MessageBox.TYPE_INFO) - - def dmesg_clear(self, answer): self.container.appClosed.append(self.dmesg_cleared) self.taskstring = "" self.cmd = "dmesg -c" print "executing " + self.cmd self.container.execute(self.cmd) - def dmesg_cleared(self, retval): + def dmesg_cleared(self, answer): self.container.appClosed.remove(self.dmesg_cleared) - self.session.openWithCallback(self.stick_back_in, MessageBox, (_("Now please insert the USB stick (minimum size is 64 MB) that you want to format and use as .NFI image flasher. Press OK after you've put the stick back in.")), MessageBox.TYPE_INFO) - - def stick_back_in(self, answer): - self["statusbar"].text = _("Waiting for USB stick to settle...") - self.delayTimer = eTimer() - self.delayTimer.callback.append(self.waiting_for_stick) - self.delayCount = -1 - self.delayTimer.start(1000) - - def waiting_for_stick(self): - self.delayCount += 1 - self["job_progressbar"].range = 6 - self["job_progressbar"].value = self.delayCount - self["job_progresslabel"].text = "-%d s" % (6-self.delayCount) - if self.delayCount > 5: - self.delayTimer.stop() + self.msgbox = self.session.open(MessageBox, _("Please disconnect all USB devices from your Dreambox and (re-)attach the target USB stick (minimum size is 64 MB) now!"), MessageBox.TYPE_INFO) + hotplugNotifier.append(self.hotplugCB) + + def hotplugCB(self, dev, action): + print "[hotplugCB]", dev, action + if dev.startswith("sd") and action == "add": + self.msgbox.close() + hotplugNotifier.remove(self.hotplugCB) self.container.appClosed.append(self.dmesg_scanned) self.taskstring = "" self.cmd = "dmesg" @@ -539,8 +529,8 @@ class NFIDownload(Screen): self.session.openWithCallback(self.fdisk_query, MessageBox, (_("The following device was found:\n\n%s\n\nDo you want to write the USB flasher to this stick?") % self.devicetext), MessageBox.TYPE_YESNO) def fdisk_query(self, answer): - if answer == True: - self["statusbar"].text = _("Partitioning USB stick...") + if answer == True and self.stickdevice: + self["statusbar"].text = ("Partitioning USB stick...") self["job_progressbar"].range = 1000 self["job_progressbar"].value = 100 self["job_progresslabel"].text = "5.00%" @@ -562,7 +552,7 @@ class NFIDownload(Screen): self.tar_finished(0) self["job_progressbar"].value = 700 else: - self["statusbar"].text = _("Decompressing USB stick flasher boot image...") + self["statusbar"].text = ("Decompressing USB stick flasher boot image...") self.taskstring = "" self.container.appClosed.append(self.tar_finished) self.container.setCWD("/tmp") @@ -588,7 +578,7 @@ class NFIDownload(Screen): self.container.appClosed.remove(self.tar_finished) if retval == 0: self.imagefilename = "/tmp/nfiflash_" + self.box + ".img" - self["statusbar"].text = _("Copying USB flasher boot image to stick...") + self["statusbar"].text = ("Copying USB flasher boot image to stick...") self.taskstring = "" self.container.appClosed.append(self.dd_finished) self.cmd = "dd if=%s of=%s" % (self.imagefilename,self.stickdevice+"/part1") @@ -607,7 +597,7 @@ class NFIDownload(Screen): if retval == 0: self["job_progressbar"].value = 950 self["job_progresslabel"].text = "95.00%" - self["statusbar"].text = _("Remounting stick partition...") + self["statusbar"].text = ("Remounting stick partition...") self.taskstring = "" self.container.appClosed.append(self.mount_finished) self.cmd = "mount %s /mnt/usb -o rw,sync" % (self.stickdevice+"/part1") @@ -622,7 +612,7 @@ class NFIDownload(Screen): if retval == 0: self["job_progressbar"].value = 1000 self["job_progresslabel"].text = "100.00%" - self["statusbar"].text = _(".NFI Flasher bootable USB stick successfully created.") + self["statusbar"].text = (".NFI Flasher bootable USB stick successfully created.") self.session.openWithCallback(self.remove_img, MessageBox, _("The .NFI Image flasher USB stick is now ready to use. Please download an .NFI image file from the feed server and save it on the stick. Then reboot and hold the 'Down' key on the front panel to boot the .NFI flasher from the stick!"), MessageBox.TYPE_INFO) self["destlist"].changeDir("/mnt/usb") else: @@ -659,8 +649,8 @@ def filescan(**kwargs): Scanner(mimetypes = ["application/x-dream-image"], paths_to_scan = [ - ScanPath(path = "", with_subdirs = False), + ScanPath(path = "", with_subdirs = False), ], name = "NFI", - description = (_("Download .NFI-Files for USB-Flasher")+"..."), + description = (_("Download .NFI-Files for USB-Flasher")+"..."), openfnc = filescan_open, ) diff --git a/lib/python/Plugins/SystemPlugins/NFIFlash/flasher.py b/lib/python/Plugins/SystemPlugins/NFIFlash/flasher.py index 6a982c58..860efc02 100644 --- a/lib/python/Plugins/SystemPlugins/NFIFlash/flasher.py +++ b/lib/python/Plugins/SystemPlugins/NFIFlash/flasher.py @@ -17,7 +17,7 @@ import re class writeNAND(Task): def __init__(self,job,param,box): - Task.__init__(self,job, _("Writing image file to NAND Flash")) + Task.__init__(self,job, ("Writing image file to NAND Flash")) self.setTool("/usr/lib/enigma2/python/Plugins/SystemPlugins/NFIFlash/mywritenand") if box == "dm7025": self.end = 256 @@ -26,7 +26,7 @@ class writeNAND(Task): if box == "dm8000": self.setTool("/usr/lib/enigma2/python/Plugins/SystemPlugins/NFIFlash/dm8000_writenand") self.args += param - self.weighting = 1 + self.weighting = 1 def processOutput(self, data): print "[writeNand] " + data @@ -174,8 +174,8 @@ class NFIFlash(Screen): print sign if sign.find("NFI1" + self.box + "\0") == 0: if self.md5sum != "": - self["statusbar"].text = _("Please wait for md5 signature verification...") - self.session.summary.setText(_("Please wait for md5 signature verification...")) + self["statusbar"].text = ("Please wait for md5 signature verification...") + self.session.summary.setText(("Please wait for md5 signature verification...")) self.container = eConsoleAppContainer() self.container.setCWD(self["filelist"].getCurrentDirectory()) self.container.appClosed.append(self.md5finished) @@ -252,7 +252,7 @@ class NFIFlash(Screen): def reboot(self): if self.job.status == self.job.FINISHED: - self["statusbar"].text = _("rebooting...") + self["statusbar"].text = ("rebooting...") TryQuitMainloop(self.session,2) def createSummary(self): -- cgit v1.2.3 From e7364f6c8cd59562884f895042980b88a962c945 Mon Sep 17 00:00:00 2001 From: Fraxinas Date: Mon, 17 Nov 2008 23:24:20 +0100 Subject: show dvd burn jobs running in background in main menu and fix potential crash on aborting during CheckDiskspaceTask --- lib/python/Plugins/Extensions/DVDBurn/DVDToolbox.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/python/Plugins') diff --git a/lib/python/Plugins/Extensions/DVDBurn/DVDToolbox.py b/lib/python/Plugins/Extensions/DVDBurn/DVDToolbox.py index b88dbb3f..ce16259e 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/DVDToolbox.py +++ b/lib/python/Plugins/Extensions/DVDBurn/DVDToolbox.py @@ -63,7 +63,7 @@ class DVDToolbox(Screen): def pageDown(self): self["details"].pageDown() - def update(self, dev="", media_state=""): + def update(self, dev="", action=""): self["space_label"].text = _("Please wait... Loading list...") self["info"].text = "" self["details"].setText("") -- cgit v1.2.3 From c2ec827d12f170cb4bee1a42be9e454c7174207b Mon Sep 17 00:00:00 2001 From: Fraxinas Date: Mon, 17 Nov 2008 23:29:31 +0100 Subject: show dvd burn jobs running in background in main menu and fix potential crash on aborting during CheckDiskspaceTask --- lib/python/Plugins/Extensions/DVDBurn/Process.py | 3 +++ lib/python/Plugins/Extensions/DVDBurn/TitleList.py | 22 ++++++++++++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) (limited to 'lib/python/Plugins') diff --git a/lib/python/Plugins/Extensions/DVDBurn/Process.py b/lib/python/Plugins/Extensions/DVDBurn/Process.py index 89ca90fd..946b44ad 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/Process.py +++ b/lib/python/Plugins/Extensions/DVDBurn/Process.py @@ -368,6 +368,9 @@ class CheckDiskspaceTask(Task): self.global_preconditions.append(DiskspacePrecondition(diskSpaceNeeded)) self.weighting = 5 + def abort(self): + self.finish(aborted = True) + def run(self, callback): failed_preconditions = self.checkPreconditions(True) + self.checkPreconditions(False) if len(failed_preconditions): diff --git a/lib/python/Plugins/Extensions/DVDBurn/TitleList.py b/lib/python/Plugins/Extensions/DVDBurn/TitleList.py index 345af877..537da0dd 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/TitleList.py +++ b/lib/python/Plugins/Extensions/DVDBurn/TitleList.py @@ -74,9 +74,22 @@ class TitleList(Screen, HelpableScreen): self["titles"] = List(list = [ ], enableWrapAround = True, item_height=30, fonts = [gFont("Regular", 20)]) self.updateTitleList() - + + def checkBackgroundJobs(self): + for job in job_manager.getPendingJobs(): + print "type(job):", type(job) + print "Process.DVDJob:", Process.DVDJob + if type(job) == Process.DVDJob: + self.backgroundJob = job + return + self.backgroundJob = None + def showMenu(self): menu = [] + self.checkBackgroundJobs() + if self.backgroundJob: + j = self.backgroundJob + menu.append(("%s: %s (%d%%)" % (j.getStatustext(), j.name, int(100*j.progress/float(j.end))), self.showBackgroundJob)) if self.project.settings.output.getValue() == "dvd": menu.append((_("Burn DVD"), self.burnProject)) elif self.project.settings.output.getValue() == "iso": @@ -97,6 +110,11 @@ class TitleList(Screen, HelpableScreen): if choice: choice[1]() + def showBackgroundJob(self): + job_manager.in_background = False + self.session.openWithCallback(self.JobViewCB, JobView, self.backgroundJob) + self.backgroundJob = None + def titleProperties(self): if self.getCurrentTitle(): self.session.openWithCallback(self.updateTitleList, TitleProperties.TitleProperties, self, self.project, self["titles"].getIndex()) @@ -217,7 +235,7 @@ class TitleList(Screen, HelpableScreen): totalsize += title.estimatedDiskspace self["titles"].list = res self.updateSize(totalsize) - + def updateSize(self, totalsize): size = int((totalsize/1024)/1024) max_SL = 4370 -- cgit v1.2.3 From f38670a4ea4d6dc6206e6bd99ad25943d0bf3602 Mon Sep 17 00:00:00 2001 From: Fraxinas Date: Mon, 17 Nov 2008 23:33:56 +0100 Subject: do remove elementary stream files... and do it correctly! --- lib/python/Plugins/Extensions/DVDBurn/Process.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/python/Plugins') diff --git a/lib/python/Plugins/Extensions/DVDBurn/Process.py b/lib/python/Plugins/Extensions/DVDBurn/Process.py index 946b44ad..750e9d9b 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/Process.py +++ b/lib/python/Plugins/Extensions/DVDBurn/Process.py @@ -165,7 +165,7 @@ class DemuxTask(Task): def cleanup(self, failed): if failed: import os - for file in self.generated_files.itervalues(): + for file in self.generated_files: os.remove(file) class MplexTaskPostcondition(Condition): @@ -220,7 +220,7 @@ class RemoveESFiles(Task): def prepare(self): self.args += ["-f"] - self.args += self.demux_task.generated_files.values() + self.args += self.demux_task.generated_files self.args += [self.demux_task.cutfile] class DVDAuthorTask(Task): @@ -794,7 +794,7 @@ class DVDJob(Job): demux = DemuxTask(self, link_name) self.mplextask = MplexTask(self, outputfile=title_filename, demux_task=demux) self.mplextask.end = self.estimateddvdsize - #RemoveESFiles(self, demux) + RemoveESFiles(self, demux) WaitForResidentTasks(self) PreviewTask(self, self.workspace + "/dvd/VIDEO_TS/") output = self.project.settings.output.getValue() -- cgit v1.2.3 From 5aa89f34249397330995cc0ab1e080c1f567e174 Mon Sep 17 00:00:00 2001 From: ghost Date: Mon, 17 Nov 2008 23:34:41 +0100 Subject: get rid of some floating point values --- lib/gdi/picload.cpp | 35 +++++++++++----------- lib/python/Components/AVSwitch.py | 14 ++++----- .../Plugins/Extensions/PicturePlayer/plugin.py | 14 +++++---- .../SystemPlugins/Videomode/VideoHardware.py | 8 ++--- 4 files changed, 36 insertions(+), 35 deletions(-) (limited to 'lib/python/Plugins') diff --git a/lib/gdi/picload.cpp b/lib/gdi/picload.cpp index f67507ca..375f33fb 100644 --- a/lib/gdi/picload.cpp +++ b/lib/gdi/picload.cpp @@ -1011,16 +1011,16 @@ RESULT ePicLoad::setPara(PyObject *val) { if (!PySequence_Check(val)) return 0; - if (PySequence_Size(val) < 6) + if (PySequence_Size(val) < 7) return 0; else { ePyObject fast = PySequence_Fast(val, ""); m_conf.max_x = PyInt_AsLong( PySequence_Fast_GET_ITEM(val, 0)); m_conf.max_y = PyInt_AsLong( PySequence_Fast_GET_ITEM(val, 1)); - m_conf.aspect_ratio = PyFloat_AsDouble( PySequence_Fast_GET_ITEM(val, 2)); - m_conf.usecache = PyInt_AsLong( PySequence_Fast_GET_ITEM(val, 3)); - m_conf.resizetype = PyInt_AsLong( PySequence_Fast_GET_ITEM(val, 4)); - const char *bg_str = PyString_AsString( PySequence_Fast_GET_ITEM(val, 5)); + m_conf.aspect_ratio = (double)PyInt_AsLong( PySequence_Fast_GET_ITEM(val, 2)) / PyInt_AsLong(PySequence_Fast_GET_ITEM(val, 3)); + m_conf.usecache = PyInt_AsLong( PySequence_Fast_GET_ITEM(val, 4)); + m_conf.resizetype = PyInt_AsLong( PySequence_Fast_GET_ITEM(val, 5)); + const char *bg_str = PyString_AsString( PySequence_Fast_GET_ITEM(val, 6)); if(bg_str[0] == '#' && strlen(bg_str)==9) { @@ -1040,29 +1040,30 @@ RESULT ePicLoad::setPara(PyObject *val) //for old plugins SWIG_VOID(int) loadPic(ePtr &result, std::string filename, int x, int y, int aspect, int resize_mode, int rotate, int background, std::string cachefile) { + long asp1, asp2; result = 0; eDebug("deprecated loadPic function used!!! please use the non blocking version! you can see demo code in Pictureplayer plugin... this function is removed in the near future!"); ePicLoad mPL; - double aspect_ratio; switch(aspect) { - case 1: aspect_ratio = 1.778 / ((double)720/576); break; //16:9 - case 2: aspect_ratio = 1.600 / ((double)720/576); break; //16:10 - case 3: aspect_ratio = 1.250 / ((double)720/576); break; //5:4 - default: aspect_ratio = 1.333 / ((double)720/576); //4:3 + case 1: asp1 = 16*576, asp2 = 9*720; break; //16:9 + case 2: asp1 = 16*576, asp2 = 10*720; break; //16:10 + case 3: asp1 = 5*576, asp2 = 4*720; break; //5:4 + default: asp1 = 4*576, asp2 = 3*720; break; //4:3 } - - ePyObject tuple = PyTuple_New(6); + + ePyObject tuple = PyTuple_New(7); PyTuple_SET_ITEM(tuple, 0, PyLong_FromLong(x)); PyTuple_SET_ITEM(tuple, 1, PyLong_FromLong(y)); - PyTuple_SET_ITEM(tuple, 2, PyFloat_FromDouble(aspect_ratio)); - PyTuple_SET_ITEM(tuple, 3, PyLong_FromLong(0)); - PyTuple_SET_ITEM(tuple, 4, PyLong_FromLong(resize_mode)); + PyTuple_SET_ITEM(tuple, 2, PyLong_FromLong(asp1)); + PyTuple_SET_ITEM(tuple, 3, PyLong_FromLong(asp2)); + PyTuple_SET_ITEM(tuple, 4, PyLong_FromLong(0)); + PyTuple_SET_ITEM(tuple, 5, PyLong_FromLong(resize_mode)); if(background) - PyTuple_SET_ITEM(tuple, 5, PyString_FromString("#ff000000")); + PyTuple_SET_ITEM(tuple, 6, PyString_FromString("#ff000000")); else - PyTuple_SET_ITEM(tuple, 5, PyString_FromString("#00000000")); + PyTuple_SET_ITEM(tuple, 6, PyString_FromString("#00000000")); mPL.setPara(tuple); diff --git a/lib/python/Components/AVSwitch.py b/lib/python/Components/AVSwitch.py index 19aca24d..00350cbb 100644 --- a/lib/python/Components/AVSwitch.py +++ b/lib/python/Components/AVSwitch.py @@ -30,26 +30,24 @@ class AVSwitch: def getOutputAspect(self): if valstr in ("4_3_letterbox", "4_3_panscan"): # 4:3 - return 1.333333333 + return (4,3) elif valstr == "16_9": # auto ... 4:3 or 16:9 try: aspect_str = open("/proc/stb/vmpeg/0/aspect", "r").read() if aspect_str == "1": # 4:3 - return 1.333333333 + return (4,3) except IOError: pass - return 1.777777778 elif valstr in ("16_9_always", "16_9_letterbox"): # 16:9 - return 1.777777778 + pass elif valstr in ("16_10_letterbox", "16_10_panscan"): # 16:10 - return 1.6 - print "unknown output aspect!" - return 1.0000 + return (16,10) + return (16,9) def getFramebufferScale(self): aspect = self.getOutputAspect() fb_size = getDesktop(0).size() - return aspect / ((1.0 * fb_size.width()) / fb_size.height()) + return (aspect[0] * fb_size.height(), aspect[1] * fb_size.width()) def getAspectRatioSetting(self): valstr = config.av.aspectratio.value diff --git a/lib/python/Plugins/Extensions/PicturePlayer/plugin.py b/lib/python/Plugins/Extensions/PicturePlayer/plugin.py index 7d62d2be..0cdab563 100644 --- a/lib/python/Plugins/Extensions/PicturePlayer/plugin.py +++ b/lib/python/Plugins/Extensions/PicturePlayer/plugin.py @@ -15,7 +15,7 @@ from Components.ConfigList import ConfigList from Components.config import config, ConfigSubsection, ConfigInteger, ConfigSelection, ConfigText, ConfigEnableDisable, KEY_LEFT, KEY_RIGHT, KEY_0, getConfigListEntry -def getAspectforPic(): +def getScale(): return AVSwitch().getFramebufferScale() config.pic = ConfigSubsection() @@ -119,8 +119,9 @@ class picshow(Screen): self.session.openWithCallback(self.callbackView, Pic_Full_View, self.filelist.getFileList(), self.filelist.getSelectionIndex(), self.filelist.getCurrentDirectory()) def setConf(self): + sc = getScale() #0=Width 1=Height 2=Aspect 3=use_cache 4=resize_type 5=Background(#AARRGGBB) - self.picload.setPara([self["thn"].instance.size().width(), self["thn"].instance.size().height(), getAspectforPic(), config.pic.cache.value, int(config.pic.resize.value), "#00000000"]) + self.picload.setPara((self["thn"].instance.size().width(), self["thn"].instance.size().height(), sc[0], sc[1], config.pic.cache.value, int(config.pic.resize.value), "#00000000")) def callbackView(self, val=0): if val > 0: @@ -311,10 +312,10 @@ class Pic_Thumb(Screen): self.ThumbTimer.callback.append(self.showPic) def setPicloadConf(self): - self.picload.setPara([self["thumb0"].instance.size().width(), self["thumb0"].instance.size().height(), getAspectforPic(), config.pic.cache.value, int(config.pic.resize.value), self.color]) + sc = getScale() + self.picload.setPara([self["thumb0"].instance.size().width(), self["thumb0"].instance.size().height(), sc[0], sc[1], config.pic.cache.value, int(config.pic.resize.value), self.color]) self.paintFrame() - - + def paintFrame(self): #print "index=" + str(self.index) if self.maxentry < self.index or self.index < 0: @@ -468,7 +469,8 @@ class Pic_Full_View(Screen): self.onLayoutFinish.append(self.setPicloadConf) def setPicloadConf(self): - self.picload.setPara([self["pic"].instance.size().width(), self["pic"].instance.size().height(), getAspectforPic(), 0, int(config.pic.resize.value), self.bgcolor]) + sc = getScale() + self.picload.setPara([self["pic"].instance.size().width(), self["pic"].instance.size().height(), sc[0], sc[1], 0, int(config.pic.resize.value), self.bgcolor]) self["play_icon"].hide() if config.pic.infoline.value == False: diff --git a/lib/python/Plugins/SystemPlugins/Videomode/VideoHardware.py b/lib/python/Plugins/SystemPlugins/Videomode/VideoHardware.py index 5e38f3e6..02fdf9a5 100644 --- a/lib/python/Plugins/SystemPlugins/Videomode/VideoHardware.py +++ b/lib/python/Plugins/SystemPlugins/Videomode/VideoHardware.py @@ -60,7 +60,7 @@ class VideoHardware: widescreen_modes = set(["720p", "1080i"]) def getOutputAspect(self): - ret = 1.777777778 # 16:9 + ret = (16,9) port = config.av.videoport.value if port not in config.av.videomode: print "current port not available in getOutputAspect!!! force 16:9" @@ -75,16 +75,16 @@ class VideoHardware: else: aspect = {"16_9": "16:9", "16_10": "16:10"}[config.av.aspect.value] if aspect == "16:10": - ret = 1.6 + ret = (16,10) elif is_auto: try: aspect_str = open("/proc/stb/vmpeg/0/aspect", "r").read() if aspect_str == "1": # 4:3 - ret = 1.333333333 + ret = (4,3) except IOError: pass else: # 4:3 - ret = 1.333333333 + ret = (4,3) return ret def __init__(self): -- cgit v1.2.3 From 5cb7cb980986fe89da490d8d5c2a73b935844724 Mon Sep 17 00:00:00 2001 From: Fraxinas Date: Tue, 18 Nov 2008 13:04:38 +0100 Subject: use already translated string --- lib/python/Plugins/Extensions/PicturePlayer/plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/python/Plugins') diff --git a/lib/python/Plugins/Extensions/PicturePlayer/plugin.py b/lib/python/Plugins/Extensions/PicturePlayer/plugin.py index 0cdab563..aeca12dc 100644 --- a/lib/python/Plugins/Extensions/PicturePlayer/plugin.py +++ b/lib/python/Plugins/Extensions/PicturePlayer/plugin.py @@ -202,7 +202,7 @@ class Pic_Exif(Screen): "cancel": self.close }, -1) - exifdesc = [_("Filename:"), "EXIF-Version:", "Make:", "Camera:", "Date/Time:", "Width / Height:", "Flash used:", "Orientation:", "User Comments:", "Metering Mode:", "Exposure Program:", "Light Source:", "CompressedBitsPerPixel:", "ISO Speed Rating:", "X-Resolution:", "Y-Resolution:", "Resolution Unit:", "Brightness:", "Exposure Time:", "Exposure Bias:", "Distance:", "CCD-Width:", "ApertureFNumber:"] + exifdesc = [_("filename")+':', "EXIF-Version:", "Make:", "Camera:", "Date/Time:", "Width / Height:", "Flash used:", "Orientation:", "User Comments:", "Metering Mode:", "Exposure Program:", "Light Source:", "CompressedBitsPerPixel:", "ISO Speed Rating:", "X-Resolution:", "Y-Resolution:", "Resolution Unit:", "Brightness:", "Exposure Time:", "Exposure Bias:", "Distance:", "CCD-Width:", "ApertureFNumber:"] list = [] for x in range(len(exiflist)): -- cgit v1.2.3 From 0753892fd72a1aad2ae5bf9592786ab962622e5d Mon Sep 17 00:00:00 2001 From: Fraxinas Date: Tue, 18 Nov 2008 13:15:33 +0100 Subject: add automatic downloading of latest image and possibility of backing up configuration to the bootable usb sticks --- .../Plugins/SystemPlugins/NFIFlash/downloader.py | 60 ++++++++++++++++++---- 1 file changed, 50 insertions(+), 10 deletions(-) (limited to 'lib/python/Plugins') diff --git a/lib/python/Plugins/SystemPlugins/NFIFlash/downloader.py b/lib/python/Plugins/SystemPlugins/NFIFlash/downloader.py index 7e34d2bb..160620fd 100644 --- a/lib/python/Plugins/SystemPlugins/NFIFlash/downloader.py +++ b/lib/python/Plugins/SystemPlugins/NFIFlash/downloader.py @@ -120,10 +120,10 @@ class NFIDownload(Screen): - - - - + + + + @@ -170,6 +170,7 @@ class NFIDownload(Screen): self.box = HardwareInfo().get_device_name() self.feed_base = "http://www.dreamboxupdate.com/opendreambox/1.5/%s/images/" % self.box self.nfi_filter = "" # "release" # only show NFIs containing this string, or all if "" + self.wizard_mode = False self["actions"] = ActionMap(["OkCancelActions", "ColorActions", "DirectionActions", "EPGSelectActions"], { @@ -206,7 +207,7 @@ class NFIDownload(Screen): self["key_yellow"].text = (_("Change dir.")) else: self["key_yellow"].text = (_("Select image")) - self["key_blue"].text = (_("Fix USB stick")) + self["key_blue"].text = (_("USB stick wizard")) def switchList(self,to_where=None): if self.download or not self["feedlist"].isValid(): @@ -400,7 +401,7 @@ class NFIDownload(Screen): print "couldn't save nfo file " + self.nfofilename pos = self.nfo.find("MD5:") - if pos > 0 and len(self.nfo) >= pos+5+32: + if pos > 0 and len(self.nfo) >= pos+5+32: self["statusbar"].text = ("Please wait for md5 signature verification...") cmd = "md5sum -c -" md5 = self.nfo[pos+5:pos+5+32] + " " + self.nfilocal @@ -416,6 +417,8 @@ class NFIDownload(Screen): else: self["statusbar"].text = "Download completed." self.downloading(False) + if self.wizard_mode: + self.configBackup() def md5ready(self, retval): self.download_container.sendEOF() @@ -424,9 +427,12 @@ class NFIDownload(Screen): print "[md5finished]: " + str(retval) self.download_container.appClosed.remove(self.md5finished) if retval==0: - self["statusbar"].text = _(".NFI file passed md5sum signature check. You can safely flash this image!") - self.switchList(self.LIST_SOURCE) self.downloading(False) + if self.wizard_mode: + self.configBackup() + else: + self["statusbar"].text = _(".NFI file passed md5sum signature check. You can safely flash this image!") + self.switchList(self.LIST_SOURCE) else: self.session.openWithCallback(self.nfi_remove, MessageBox, (_("The md5sum validation failed, the file may be downloaded incompletely or be corrupted!") + "\n" + _("Remove the broken .NFI file?")), MessageBox.TYPE_YESNO) @@ -613,10 +619,11 @@ class NFIDownload(Screen): self["job_progressbar"].value = 1000 self["job_progresslabel"].text = "100.00%" self["statusbar"].text = (".NFI Flasher bootable USB stick successfully created.") - self.session.openWithCallback(self.remove_img, MessageBox, _("The .NFI Image flasher USB stick is now ready to use. Please download an .NFI image file from the feed server and save it on the stick. Then reboot and hold the 'Down' key on the front panel to boot the .NFI flasher from the stick!"), MessageBox.TYPE_INFO) + self.session.openWithCallback(self.flasherFinishedCB, MessageBox, _("The USB stick is now bootable. Do you want to download the latest image from the feed server and save it on the stick?"), type = MessageBox.TYPE_YESNO) self["destlist"].changeDir("/mnt/usb") else: - self.session.openWithCallback(self.remove_img, MessageBox, (self.cmd + " " + _("failed") + ":\n" + str(self.taskstring)), MessageBox.TYPE_ERROR) + self.session.openWithCallback(self.flasherFinishedCB, MessageBox, (self.cmd + " " + _("failed") + ":\n" + str(self.taskstring)), MessageBox.TYPE_ERROR) + self.remove_img(True) def remove_img(self, answer): if fileExists("/tmp/nfiflasher_image.tar.bz2"): @@ -626,6 +633,39 @@ class NFIDownload(Screen): self.downloading(False) self.switchList(self.LIST_SOURCE) + def flasherFinishedCB(self, answer): + if answer == True: + self.wizard_mode = True + self["feedlist"].moveSelection(0) + self["path_bottom"].text = str(self["destlist"].getCurrentDirectory()) + self.nfo_download() + self.nfi_download() + + def configBackup(self): + self.session.openWithCallback(self.runBackup, MessageBox, _("The wizard can backup your current settings. Do you want to do a backup now?")) + + def runBackup(self, result=None): + from Tools.Directories import createDir, isMount, pathExists + from time import localtime + from datetime import date + from Screens.Console import Console + if result: + if isMount("/mnt/usb/"): + if (pathExists("/mnt/usb/backup") == False): + createDir("/mnt/usb/backup", True) + d = localtime() + dt = date(d.tm_year, d.tm_mon, d.tm_mday) + self.backup_file = "backup/" + str(dt) + "_settings_backup.tar.gz" + self.session.open(Console, title = "Backup running", cmdlist = ["tar -czvf " + "/mnt/usb/" + self.backup_file + " /etc/enigma2/ /etc/network/interfaces /etc/wpa_supplicant.conf"], finishedCallback = self.backup_finished, closeOnSuccess = True) + + def backup_finished(self): + wizardfd = open("/mnt/usb/wizard.nfo", "w") + if wizardfd: + wizardfd.write("image: "+self["feedlist"].getNFIname()+'\n') + wizardfd.write("configuration: "+self.backup_file+'\n') + wizardfd.close() + self.session.open(MessageBox, _("To update your Dreambox firmware, please follow these steps:\n1) Turn off your box with the rear power switch and plug in the bootable USB stick.\n2) Turn mains back on and hold the DOWN button on the front panel pressed for 10 seconds.\n3) Wait for bootup and follow instructions of the wizard."), type = MessageBox.TYPE_INFO) + def closeCB(self): if self.download: self.download.stop() -- cgit v1.2.3 From ac28912f03ba943cce61b30df2014f06dd499ba7 Mon Sep 17 00:00:00 2001 From: Fraxinas Date: Wed, 19 Nov 2008 09:58:34 +0100 Subject: fix filelist crash, add necessary import for hotplug --- lib/python/Plugins/Extensions/PicturePlayer/plugin.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'lib/python/Plugins') diff --git a/lib/python/Plugins/Extensions/PicturePlayer/plugin.py b/lib/python/Plugins/Extensions/PicturePlayer/plugin.py index aeca12dc..e9da3e2f 100644 --- a/lib/python/Plugins/Extensions/PicturePlayer/plugin.py +++ b/lib/python/Plugins/Extensions/PicturePlayer/plugin.py @@ -1,7 +1,7 @@ from enigma import ePicLoad, eTimer, getDesktop from Screens.Screen import Screen -from Tools.Directories import resolveFilename, pathExists, SCOPE_MEDIA +from Tools.Directories import resolveFilename, pathExists, fileExists, SCOPE_MEDIA from Plugins.Plugin import PluginDescriptor from Components.Pixmap import Pixmap, MovingPixmap @@ -91,8 +91,9 @@ class picshow(Screen): def showThumb(self): if not self.filelist.canDescent(): - if self.picload.getThumbnail(self.filelist.getCurrentDirectory() + self.filelist.getFilename()) == 1: - self.ThumbTimer.start(500, True) + if self.filelist.getCurrentDirectory() and self.filelist.getFilename(): + if self.picload.getThumbnail(self.filelist.getCurrentDirectory() + self.filelist.getFilename()) == 1: + self.ThumbTimer.start(500, True) def selectionChanged(self): if not self.filelist.canDescent(): -- cgit v1.2.3 From e09c5aad8f93dab13e7b981a75c4d5473ea1376c Mon Sep 17 00:00:00 2001 From: Fraxinas Date: Wed, 19 Nov 2008 12:42:52 +0100 Subject: update MediaPlayer to use new async ePicLoad function for cover artwork. currently no transparent background possible though :/ --- lib/python/Plugins/Extensions/MediaPlayer/plugin.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'lib/python/Plugins') diff --git a/lib/python/Plugins/Extensions/MediaPlayer/plugin.py b/lib/python/Plugins/Extensions/MediaPlayer/plugin.py index babef3e7..981f08cb 100644 --- a/lib/python/Plugins/Extensions/MediaPlayer/plugin.py +++ b/lib/python/Plugins/Extensions/MediaPlayer/plugin.py @@ -1,6 +1,6 @@ from os import path as os_path, remove as os_remove, listdir as os_listdir from time import strftime -from enigma import iPlayableService, eTimer, eServiceCenter, iServiceInformation, loadPic +from enigma import iPlayableService, eTimer, eServiceCenter, iServiceInformation, ePicLoad from ServiceReference import ServiceReference from Screens.Screen import Screen from Screens.HelpMenu import HelpableScreen @@ -171,6 +171,9 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB self.currList = "filelist" self.coverArtFileName = "" + self.picload = ePicLoad() + self.picload.PictureData.get().append(self.paintCoverArtPixmapCB) + self.isAudioCD = False self.AudioCD_albuminfo = {} self.cdAudioTrackFiles = [] @@ -206,6 +209,7 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB config.mediaplayer.defaultDir.setValue(self.filelist.getCurrentDirectory()) config.mediaplayer.defaultDir.save() hotplugNotifier.remove(self.hotplugCB) + del self.picload self.close() def checkSkipShowHideLock(self): @@ -294,9 +298,15 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB new_coverArtFileName = path + filename if self.coverArtFileName != new_coverArtFileName: self.coverArtFileName = new_coverArtFileName - pixmap = loadPic(self.coverArtFileName, 116, 116, AVSwitch().getAspectRatioSetting()/2,1,0,0) - if pixmap is not None: - self["coverArt"].instance.setPixmap(pixmap.__deref__()) + sc = AVSwitch().getFramebufferScale() + #0=Width 1=Height 2=Aspect 3=use_cache 4=resize_type 5=Background(#AARRGGBB) + self.picload.setPara((self["coverArt"].instance.size().width(), self["coverArt"].instance.size().height(), sc[0], sc[1], False, 1, "#ff000000")) + self.picload.startDecode(self.coverArtFileName) + + def paintCoverArtPixmapCB(self, picInfo=None): + ptr = self.picload.getData() + if ptr != None: + self["coverArt"].instance.setPixmap(ptr.__deref__()) def leftDown(self): self.lefttimer = True -- cgit v1.2.3 From 5e6249693c0c59f61dce4a14ad0902fd9d78769a Mon Sep 17 00:00:00 2001 From: Fraxinas Date: Wed, 19 Nov 2008 17:13:33 +0100 Subject: correctly use new ePicLoad. keep "no cover art" pixmap resident the whole time instead of reloading it. move entire cover art functionality into MediaPixmap class. --- .../Plugins/Extensions/MediaPlayer/plugin.py | 83 +++++++++++++--------- 1 file changed, 48 insertions(+), 35 deletions(-) (limited to 'lib/python/Plugins') diff --git a/lib/python/Plugins/Extensions/MediaPlayer/plugin.py b/lib/python/Plugins/Extensions/MediaPlayer/plugin.py index 981f08cb..8477ecc1 100644 --- a/lib/python/Plugins/Extensions/MediaPlayer/plugin.py +++ b/lib/python/Plugins/Extensions/MediaPlayer/plugin.py @@ -35,18 +35,58 @@ class MyPlayList(PlayList): self.oldCurrPlaying = -1 class MediaPixmap(Pixmap): + def __init__(self): + Pixmap.__init__(self) + self.coverArtFileName = "" + self.picload = ePicLoad() + self.picload.PictureData.get().append(self.paintCoverArtPixmapCB) + self.coverFileNames = ["folder.png", "folder.jpg"] + def applySkin(self, desktop, screen): - self.default_pixmap = None + from Tools.LoadPixmap import LoadPixmap if self.skinAttributes is not None: for (attrib, value) in self.skinAttributes: if attrib == "pixmap": - self.default_pixmap = value + noCoverFile = value break - if self.default_pixmap is None: - self.default_pixmap = resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/no_coverArt.png") - self.coverFileNames = ["folder.png", "folder.jpg"] + if noCoverFile is None: + noCoverFile = resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/no_coverArt.png") + self.noCoverPixmap = LoadPixmap(noCoverFile) return Pixmap.applySkin(self, desktop, screen) + def onShow(self): + Pixmap.onShow(self) + sc = AVSwitch().getFramebufferScale() + #0=Width 1=Height 2=Aspect 3=use_cache 4=resize_type 5=Background(#AARRGGBB) + self.picload.setPara((self.instance.size().width(), self.instance.size().height(), sc[0], sc[1], False, 1, "#00000000")) + + def paintCoverArtPixmapCB(self, picInfo=None): + ptr = self.picload.getData() + if ptr != None: + self.instance.setPixmap(ptr.__deref__()) + + def updateCoverArt(self, path): + while not path.endswith("/"): + path = path[:-1] + new_coverArtFileName = None + for filename in self.coverFileNames: + if fileExists(path + filename): + new_coverArtFileName = path + filename + if self.coverArtFileName != new_coverArtFileName: + self.coverArtFileName = new_coverArtFileName + if new_coverArtFileName: + self.picload.startDecode(self.coverArtFileName) + else: + self.showDefaultCover() + + def showDefaultCover(self): + self.instance.setPixmap(self.noCoverPixmap) + + #def destroy(self): + #Pixmap.destroy(self) + #print "mediapixmap ***********+ destroy" + + class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSupport, InfoBarNotifications, InfoBarSubtitleSupport, HelpableScreen): ALLOW_SUSPEND = True ENABLE_RESUME_SUPPORT = True @@ -74,7 +114,6 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB self["filelist"] = self.filelist self.playlist = MyPlayList() - #self.playlist = PlayList() self.is_closing = False self.delname = "" self["playlist"] = self.playlist @@ -169,11 +208,6 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB self.leftKeyTimer.callback.append(self.leftTimerFire) self.currList = "filelist" - - self.coverArtFileName = "" - self.picload = ePicLoad() - self.picload.PictureData.get().append(self.paintCoverArtPixmapCB) - self.isAudioCD = False self.AudioCD_albuminfo = {} self.cdAudioTrackFiles = [] @@ -209,7 +243,7 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB config.mediaplayer.defaultDir.setValue(self.filelist.getCurrentDirectory()) config.mediaplayer.defaultDir.save() hotplugNotifier.remove(self.hotplugCB) - del self.picload + del self["coverArt"].picload self.close() def checkSkipShowHideLock(self): @@ -289,25 +323,6 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB if self[name].getText() != info: self[name].setText(info) - def updateCoverArtPixmap(self, path): - while not path.endswith("/"): - path = path[:-1] - new_coverArtFileName = self["coverArt"].default_pixmap - for filename in self["coverArt"].coverFileNames: - if fileExists(path + filename): - new_coverArtFileName = path + filename - if self.coverArtFileName != new_coverArtFileName: - self.coverArtFileName = new_coverArtFileName - sc = AVSwitch().getFramebufferScale() - #0=Width 1=Height 2=Aspect 3=use_cache 4=resize_type 5=Background(#AARRGGBB) - self.picload.setPara((self["coverArt"].instance.size().width(), self["coverArt"].instance.size().height(), sc[0], sc[1], False, 1, "#ff000000")) - self.picload.startDecode(self.coverArtFileName) - - def paintCoverArtPixmapCB(self, picInfo=None): - ptr = self.picload.getData() - if ptr != None: - self["coverArt"].instance.setPixmap(ptr.__deref__()) - def leftDown(self): self.lefttimer = True self.leftKeyTimer.start(1000) @@ -835,11 +850,9 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB self.unPauseService() if needsInfoUpdate == True: path = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()].getPath() - self.updateCoverArtPixmap(path) + self["coverArt"].updateCoverArt(path) else: - pngname = self["coverArt"].default_pixmap - self.coverArtFileName = pngname - self["coverArt"].instance.setPixmapFromFile(self.coverArtFileName) + self["coverArt"].showDefaultCover() self.readTitleInformation() def updatedSeekState(self): -- cgit v1.2.3 From 5474861f9be0b88428d490b45625d1a65575c020 Mon Sep 17 00:00:00 2001 From: Fraxinas Date: Wed, 19 Nov 2008 17:39:20 +0100 Subject: fix mediascanner list handling, thx to mechatron --- lib/python/Plugins/Extensions/PicturePlayer/plugin.py | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'lib/python/Plugins') diff --git a/lib/python/Plugins/Extensions/PicturePlayer/plugin.py b/lib/python/Plugins/Extensions/PicturePlayer/plugin.py index e9da3e2f..05adb633 100644 --- a/lib/python/Plugins/Extensions/PicturePlayer/plugin.py +++ b/lib/python/Plugins/Extensions/PicturePlayer/plugin.py @@ -452,6 +452,11 @@ class Pic_Full_View(Screen): self.filelist.append(path + x[0][0]) else: self.dirlistcount += 1 + elif len(filelist[0]) == 2: #scanlist + if x[0][1] == False: + self.filelist.append(x[0][0]) + else: + self.dirlistcount += 1 else: # thumbnaillist self.filelist.append(x[T_FULL]) -- cgit v1.2.3 From 5a626462406c008da1c81cf304a448d9abd19576 Mon Sep 17 00:00:00 2001 From: Fraxinas Date: Thu, 20 Nov 2008 12:17:28 +0100 Subject: decode id3 cover art images embedded into mp3 files and show them in mediaplayer --- lib/python/Plugins/Extensions/MediaPlayer/plugin.py | 11 ++++++----- lib/service/servicemp3.cpp | 14 +++++++++++++- 2 files changed, 19 insertions(+), 6 deletions(-) (limited to 'lib/python/Plugins') diff --git a/lib/python/Plugins/Extensions/MediaPlayer/plugin.py b/lib/python/Plugins/Extensions/MediaPlayer/plugin.py index 8477ecc1..b6d87a6e 100644 --- a/lib/python/Plugins/Extensions/MediaPlayer/plugin.py +++ b/lib/python/Plugins/Extensions/MediaPlayer/plugin.py @@ -82,10 +82,10 @@ class MediaPixmap(Pixmap): def showDefaultCover(self): self.instance.setPixmap(self.noCoverPixmap) - #def destroy(self): - #Pixmap.destroy(self) - #print "mediapixmap ***********+ destroy" - + def embeddedCoverArt(self): + print "[embeddedCoverArt] found" + self.coverArtFileName = "/tmp/.id3coverart" + self.picload.startDecode(self.coverArtFileName) class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSupport, InfoBarNotifications, InfoBarSubtitleSupport, HelpableScreen): ALLOW_SUSPEND = True @@ -224,7 +224,8 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB { iPlayableService.evUpdatedInfo: self.__evUpdatedInfo, iPlayableService.evUser+11: self.__evDecodeError, - iPlayableService.evUser+12: self.__evPluginError + iPlayableService.evUser+12: self.__evPluginError, + iPlayableService.evUser+13: self["coverArt"].embeddedCoverArt }) def doNothing(self): diff --git a/lib/service/servicemp3.cpp b/lib/service/servicemp3.cpp index 19b7735b..017c58f0 100644 --- a/lib/service/servicemp3.cpp +++ b/lib/service/servicemp3.cpp @@ -16,6 +16,7 @@ #include /* for subtitles */ #include +#include // eServiceFactoryMP3 @@ -944,6 +945,17 @@ void eServiceMP3::gstBusCall(GstBus *bus, GstMessage *msg) m_audioStreams.push_back(audio); } + GValue *gv_image = gst_tag_list_get_value_index(tags, GST_TAG_IMAGE, 0); + if ( gv_image ) + { + GstBuffer *buf_image; + buf_image = gst_value_get_buffer (gv_image); + int fd = open("/tmp/.id3coverart", O_CREAT|O_WRONLY|O_TRUNC, 0644); + int ret = write(fd, GST_BUFFER_DATA(buf_image), GST_BUFFER_SIZE(buf_image)); + close(fd); + m_event((iPlayableService*)this, evUser+13); + } + gst_tag_list_free(tags); m_event((iPlayableService*)this, evUpdatedInfo); break; @@ -984,7 +996,7 @@ void eServiceMP3::gstBusCall(GstBus *bus, GstMessage *msg) { if ( gst_is_missing_plugin_message(msg) ) { - gchar *description = gst_missing_plugin_message_get_description(msg); + gchar *description = gst_missing_plugin_message_get_description(msg); if ( description ) { m_error_message = "GStreamer plugin " + (std::string)description + " not available!\n"; -- cgit v1.2.3 From 74837aa1b9a2d0ee3cd630b74abcb224272290ab Mon Sep 17 00:00:00 2001 From: Fraxinas Date: Mon, 24 Nov 2008 09:57:14 +0100 Subject: re-introduce consistent EXIT key behaviour. sort "quit" entry to the top though. --- lib/python/Plugins/Extensions/DVDPlayer/plugin.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'lib/python/Plugins') diff --git a/lib/python/Plugins/Extensions/DVDPlayer/plugin.py b/lib/python/Plugins/Extensions/DVDPlayer/plugin.py index 593d4d2e..b7d66a82 100644 --- a/lib/python/Plugins/Extensions/DVDPlayer/plugin.py +++ b/lib/python/Plugins/Extensions/DVDPlayer/plugin.py @@ -489,7 +489,7 @@ class DVDPlayer(Screen, InfoBarBase, InfoBarNotifications, InfoBarSeek, InfoBarP self.doShow() def askLeavePlayer(self): - choices = [(_("Continue playing"), "play"), (_("Exit"), "exit")] + choices = [(_("Exit"), "exit"), (_("Continue playing"), "play")] if not self.physicalDVD: choices.insert(1,(_("Return to file browser"), "browser")) self.session.openWithCallback(self.exitCB, ChoiceBox, title=_("Leave DVD Player?"), list = choices) @@ -590,16 +590,19 @@ class DVDPlayer(Screen, InfoBarBase, InfoBarNotifications, InfoBarSeek, InfoBarP print "cur_dlg", self.session.current_dialog def exitCB(self, answer): - if not answer or answer and answer[1] == "exit": - if self.service: - self.service = None - self.close() - if answer and answer[1] == "browser": + if answer is not None: + if answer[1] == "exit": + if self.service: + self.service = None + self.close() + if answer[1] == "browser": #TODO check here if a paused dvd playback is already running... then re-start it... #else - if self.service: - self.service = None - self.showFileBrowser() + if self.service: + self.service = None + self.showFileBrowser() + else: + pass def __onClose(self): for i in (("/proc/stb/video/aspect", self.old_aspect), ("/proc/stb/video/policy", self.old_policy), ("/proc/stb/denc/0/wss", self.old_wss)): -- cgit v1.2.3 From 4faf769dd3aa03a1ccce0df36beecb4d5f57cffb Mon Sep 17 00:00:00 2001 From: Fraxinas Date: Mon, 24 Nov 2008 19:09:45 +0100 Subject: delete file, shuffle, save & delete playlist and settings screen only for intermediate+ users --- lib/python/Plugins/Extensions/MediaPlayer/plugin.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'lib/python/Plugins') diff --git a/lib/python/Plugins/Extensions/MediaPlayer/plugin.py b/lib/python/Plugins/Extensions/MediaPlayer/plugin.py index b6d87a6e..607294ba 100644 --- a/lib/python/Plugins/Extensions/MediaPlayer/plugin.py +++ b/lib/python/Plugins/Extensions/MediaPlayer/plugin.py @@ -482,17 +482,20 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB else: menu.append((_("add files to playlist"), "copyfiles")) menu.append((_("switch to playlist"), "playlist")) - menu.append((_("delete file"), "deletefile")) + if config.usage.setup_level.index >= 1: # intermediate+ + menu.append((_("delete file"), "deletefile")) else: menu.append((_("switch to filelist"), "filelist")) - menu.append((_("shuffle playlist"), "shuffle")) - menu.append((_("Delete entry"), "deleteentry")) menu.append((_("clear playlist"), "clear")) + menu.append((_("Delete entry"), "deleteentry")) + if config.usage.setup_level.index >= 1: # intermediate+ + menu.append((_("shuffle playlist"), "shuffle")) menu.append((_("hide player"), "hide")); - menu.append((_("save playlist"), "saveplaylist")); menu.append((_("load playlist"), "loadplaylist")); - menu.append((_("delete saved playlist"), "deleteplaylist")); - menu.append((_("Edit settings"), "settings")) + if config.usage.setup_level.index >= 1: # intermediate+ + menu.append((_("save playlist"), "saveplaylist")); + menu.append((_("delete saved playlist"), "deleteplaylist")); + menu.append((_("Edit settings"), "settings")) self.session.openWithCallback(self.menuCallback, ChoiceBox, title="", list=menu) def menuCallback(self, choice): -- cgit v1.2.3 From 9846407eaa878cb717ae15faba55a13079b2c212 Mon Sep 17 00:00:00 2001 From: ghost Date: Mon, 1 Dec 2008 20:30:11 +0100 Subject: graphmultiepg: fix crash when press red on channel without epg --- lib/python/Plugins/Extensions/GraphMultiEPG/GraphMultiEpg.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/python/Plugins') diff --git a/lib/python/Plugins/Extensions/GraphMultiEPG/GraphMultiEpg.py b/lib/python/Plugins/Extensions/GraphMultiEPG/GraphMultiEpg.py index 1af90f13..7f422c96 100644 --- a/lib/python/Plugins/Extensions/GraphMultiEPG/GraphMultiEpg.py +++ b/lib/python/Plugins/Extensions/GraphMultiEPG/GraphMultiEpg.py @@ -489,7 +489,8 @@ class GraphMultiEPG(Screen): if self.zapFunc and self["key_red"].getText() == "Zap": self.closeRecursive = True ref = self["list"].getCurrent()[1] - self.zapFunc(ref.ref) + if ref: + self.zapFunc(ref.ref) def eventSelected(self): self.infoKeyPressed() -- cgit v1.2.3 From 34c1ccf6eaef6f2e8535cb3c0cbe6390835086ef Mon Sep 17 00:00:00 2001 From: ghost Date: Mon, 1 Dec 2008 20:30:34 +0100 Subject: graphmultiepg: also show plugin in extensions menu --- lib/python/Plugins/Extensions/GraphMultiEPG/plugin.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/python/Plugins') diff --git a/lib/python/Plugins/Extensions/GraphMultiEPG/plugin.py b/lib/python/Plugins/Extensions/GraphMultiEPG/plugin.py index 21d1bfe8..0ebcafca 100644 --- a/lib/python/Plugins/Extensions/GraphMultiEPG/plugin.py +++ b/lib/python/Plugins/Extensions/GraphMultiEPG/plugin.py @@ -93,4 +93,5 @@ def main(session, servicelist, **kwargs): def Plugins(**kwargs): name = _("Graphical Multi EPG") descr = _("A graphical EPG for all services of an specific bouquet") - return [ PluginDescriptor(name=name, description=descr, where = PluginDescriptor.WHERE_EVENTINFO, fnc=main) ] + return [ PluginDescriptor(name=name, description=descr, where = PluginDescriptor.WHERE_EVENTINFO, fnc=main), + PluginDescriptor(name=name, description=descr, where = PluginDescriptor.WHERE_EXTENSIONSMENU, fnc=main) ] -- cgit v1.2.3 From 819285a4572823e343f0d1ab88e2c68c2caf2677 Mon Sep 17 00:00:00 2001 From: ghost Date: Tue, 2 Dec 2008 00:14:00 +0100 Subject: add "divx" as known file extension --- lib/python/Components/FileList.py | 1 + lib/python/Plugins/Extensions/MediaPlayer/plugin.py | 2 +- lib/service/servicemp3.cpp | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) (limited to 'lib/python/Plugins') diff --git a/lib/python/Components/FileList.py b/lib/python/Components/FileList.py index e028ec3a..231fde2f 100644 --- a/lib/python/Components/FileList.py +++ b/lib/python/Components/FileList.py @@ -21,6 +21,7 @@ EXTENSIONS = { "bmp": "picture", "ts": "movie", "avi": "movie", + "divx": "movie", "mpg": "movie", "mpeg": "movie", "mkv": "movie", diff --git a/lib/python/Plugins/Extensions/MediaPlayer/plugin.py b/lib/python/Plugins/Extensions/MediaPlayer/plugin.py index 607294ba..41e6ad18 100644 --- a/lib/python/Plugins/Extensions/MediaPlayer/plugin.py +++ b/lib/python/Plugins/Extensions/MediaPlayer/plugin.py @@ -110,7 +110,7 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB # 'None' is magic to start at the list of mountpoints defaultDir = config.mediaplayer.defaultDir.getValue() - self.filelist = FileList(defaultDir, matchingPattern = "(?i)^.*\.(mp2|mp3|ogg|ts|wav|wave|m3u|pls|e2pls|mpg|vob|avi|mkv|mp4|dat|flac)", useServiceRef = True, additionalExtensions = "4098:m3u 4098:e2pls 4098:pls") + self.filelist = FileList(defaultDir, matchingPattern = "(?i)^.*\.(mp2|mp3|ogg|ts|wav|wave|m3u|pls|e2pls|mpg|vob|avi|mkv|mp4|dat|flac|divx)", useServiceRef = True, additionalExtensions = "4098:m3u 4098:e2pls 4098:pls") self["filelist"] = self.filelist self.playlist = MyPlayList() diff --git a/lib/service/servicemp3.cpp b/lib/service/servicemp3.cpp index 017c58f0..9c1972d7 100644 --- a/lib/service/servicemp3.cpp +++ b/lib/service/servicemp3.cpp @@ -37,6 +37,7 @@ eServiceFactoryMP3::eServiceFactoryMP3() extensions.push_back("wave"); extensions.push_back("mkv"); extensions.push_back("avi"); + extensions.push_back("divx"); extensions.push_back("dat"); extensions.push_back("flac"); extensions.push_back("mp4"); @@ -207,7 +208,7 @@ eServiceMP3::eServiceMP3(const char *filename): m_filename(filename), m_pump(eAp sourceinfo.containertype = ctMPEGTS; else if ( strcasecmp(ext, ".mkv") == 0 ) sourceinfo.containertype = ctMKV; - else if ( strcasecmp(ext, ".avi") == 0 ) + else if ( strcasecmp(ext, ".avi") == 0 || strcasecmp(ext, ".divx") == 0) sourceinfo.containertype = ctAVI; else if ( strcasecmp(ext, ".mp4") == 0 ) sourceinfo.containertype = ctMP4; -- cgit v1.2.3 From 0a2edb202a5a94dc97d016457b841b1eb7df1f02 Mon Sep 17 00:00:00 2001 From: Fraxinas Date: Wed, 3 Dec 2008 12:04:12 +0100 Subject: allow hardware playback of M4A (AAC) and MP3 audio streams. --- .../Plugins/Extensions/MediaPlayer/plugin.py | 2 +- lib/service/servicemp3.cpp | 254 ++++++++++++++++----- 2 files changed, 192 insertions(+), 64 deletions(-) (limited to 'lib/python/Plugins') diff --git a/lib/python/Plugins/Extensions/MediaPlayer/plugin.py b/lib/python/Plugins/Extensions/MediaPlayer/plugin.py index 41e6ad18..3d1889b9 100644 --- a/lib/python/Plugins/Extensions/MediaPlayer/plugin.py +++ b/lib/python/Plugins/Extensions/MediaPlayer/plugin.py @@ -110,7 +110,7 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB # 'None' is magic to start at the list of mountpoints defaultDir = config.mediaplayer.defaultDir.getValue() - self.filelist = FileList(defaultDir, matchingPattern = "(?i)^.*\.(mp2|mp3|ogg|ts|wav|wave|m3u|pls|e2pls|mpg|vob|avi|mkv|mp4|dat|flac|divx)", useServiceRef = True, additionalExtensions = "4098:m3u 4098:e2pls 4098:pls") + self.filelist = FileList(defaultDir, matchingPattern = "(?i)^.*\.(mp2|mp3|ogg|ts|wav|wave|m3u|pls|e2pls|mpg|vob|avi|divx|mkv|mp4|m4a|dat|flac)", useServiceRef = True, additionalExtensions = "4098:m3u 4098:e2pls 4098:pls") self["filelist"] = self.filelist self.playlist = MyPlayList() diff --git a/lib/service/servicemp3.cpp b/lib/service/servicemp3.cpp index 9c1972d7..2d217731 100644 --- a/lib/service/servicemp3.cpp +++ b/lib/service/servicemp3.cpp @@ -16,7 +16,6 @@ #include /* for subtitles */ #include -#include // eServiceFactoryMP3 @@ -41,6 +40,7 @@ eServiceFactoryMP3::eServiceFactoryMP3() extensions.push_back("dat"); extensions.push_back("flac"); extensions.push_back("mp4"); + extensions.push_back("m4a"); sc->addServiceFactory(eServiceFactoryMP3::id, this, extensions); } @@ -186,10 +186,8 @@ eServiceMP3::eServiceMP3(const char *filename): m_filename(filename), m_pump(eAp CONNECT(m_seekTimeout->timeout, eServiceMP3::seekTimeoutCB); CONNECT(m_pump.recv_msg, eServiceMP3::gstPoll); GstElement *source = 0; - - GstElement *decoder = 0, *conv = 0, *flt = 0, *sink = 0; /* for audio */ - - GstElement *audio = 0, *switch_audio = 0, *queue_audio = 0, *video = 0, *queue_video = 0, *videodemux = 0; + GstElement *decoder = 0, *conv = 0, *flt = 0, *parser = 0, *sink = 0; /* for audio */ + GstElement *audio = 0, *switch_audio = 0, *queue_audio = 0, *video = 0, *queue_video = 0, *videodemux = 0, *audiodemux = 0; m_state = stIdle; eDebug("SERVICEMP3 construct!"); @@ -202,25 +200,50 @@ eServiceMP3::eServiceMP3(const char *filename): m_filename(filename), m_pump(eAp ext = filename; sourceStream sourceinfo; + sourceinfo.is_video = FALSE; + sourceinfo.audiotype = atUnknown; if ( (strcasecmp(ext, ".mpeg") && strcasecmp(ext, ".mpg") && strcasecmp(ext, ".vob") && strcasecmp(ext, ".bin") && strcasecmp(ext, ".dat") ) == 0 ) + { sourceinfo.containertype = ctMPEGPS; + sourceinfo.is_video = TRUE; + } else if ( strcasecmp(ext, ".ts") == 0 ) + { sourceinfo.containertype = ctMPEGTS; + sourceinfo.is_video = TRUE; + } else if ( strcasecmp(ext, ".mkv") == 0 ) + { sourceinfo.containertype = ctMKV; + sourceinfo.is_video = TRUE; + } else if ( strcasecmp(ext, ".avi") == 0 || strcasecmp(ext, ".divx") == 0) + { sourceinfo.containertype = ctAVI; + sourceinfo.is_video = TRUE; + } else if ( strcasecmp(ext, ".mp4") == 0 ) + { sourceinfo.containertype = ctMP4; + sourceinfo.is_video = TRUE; + } + else if ( strcasecmp(ext, ".m4a") == 0 ) + { + sourceinfo.containertype = ctMP4; + sourceinfo.audiotype = atAAC; + } + else if ( strcasecmp(ext, ".mp3") == 0 ) + sourceinfo.audiotype = atMP3; else if ( (strncmp(filename, "/autofs/", 8) || strncmp(filename+strlen(filename)-13, "/track-", 7) || strcasecmp(ext, ".wav")) == 0 ) sourceinfo.containertype = ctCDA; if ( strcasecmp(ext, ".dat") == 0 ) + { sourceinfo.containertype = ctVCD; + sourceinfo.is_video = TRUE; + } if ( (strncmp(filename, "http://", 7)) == 0 ) sourceinfo.is_streaming = TRUE; - sourceinfo.is_video = ( sourceinfo.containertype && sourceinfo.containertype != ctCDA ); - eDebug("filename=%s, containertype=%d, is_video=%d, is_streaming=%d", filename, sourceinfo.containertype, sourceinfo.is_video, sourceinfo.is_streaming); int all_ok = 0; @@ -252,10 +275,19 @@ eServiceMP3::eServiceMP3(const char *filename): m_filename(filename), m_pump(eAp if (track > 0) g_object_set (G_OBJECT (source), "track", track, NULL); } - else - sourceinfo.containertype = ctNone; } - if ( !sourceinfo.is_streaming && sourceinfo.containertype != ctCDA ) + else if ( sourceinfo.containertype == ctVCD ) + { + int fd = open(filename,O_RDONLY); + char tmp[128*1024]; + int ret = read(fd, tmp, 128*1024); + close(fd); + if ( ret == -1 ) // this is a "REAL" VCD + source = gst_element_factory_make ("vcdsrc", "vcd-source"); + if (source) + g_object_set (G_OBJECT (source), "device", "/dev/cdroms/cdrom0", NULL); + } + if ( !source && !sourceinfo.is_streaming ) { source = gst_element_factory_make ("filesrc", "file-source"); if (source) @@ -271,7 +303,7 @@ eServiceMP3::eServiceMP3(const char *filename): m_filename(filename), m_pump(eAp audio = gst_element_factory_make("dvbaudiosink", "audiosink"); if (!audio) m_error_message += "failed to create Gstreamer element dvbaudiosink\n"; - + video = gst_element_factory_make("dvbvideosink", "videosink"); if (!video) m_error_message += "failed to create Gstreamer element dvbvideosink\n"; @@ -322,35 +354,102 @@ eServiceMP3::eServiceMP3(const char *filename): m_filename(filename), m_pump(eAp } } else /* is audio */ { - - /* filesrc -> decodebin -> audioconvert -> capsfilter -> alsasink */ - decoder = gst_element_factory_make ("decodebin", "decoder"); - if (!decoder) - m_error_message += "failed to create Gstreamer element decodebin\n"; - - conv = gst_element_factory_make ("audioconvert", "converter"); - if (!conv) - m_error_message += "failed to create Gstreamer element audioconvert\n"; - - flt = gst_element_factory_make ("capsfilter", "flt"); - if (!flt) - m_error_message += "failed to create Gstreamer element capsfilter\n"; - - /* for some reasons, we need to set the sample format to depth/width=16, because auto negotiation doesn't work. */ - /* endianness, however, is not required to be set anymore. */ - if (flt) + std::string demux_type; + switch ( sourceinfo.containertype ) { - GstCaps *caps = gst_caps_new_simple("audio/x-raw-int", /* "endianness", G_TYPE_INT, 4321, */ "depth", G_TYPE_INT, 16, "width", G_TYPE_INT, 16, /*"channels", G_TYPE_INT, 2, */NULL); - g_object_set (G_OBJECT (flt), "caps", caps, NULL); - gst_caps_unref(caps); + case ctMP4: + demux_type = "qtdemux"; + break; + default: + break; + } + if ( demux_type.length() ) + { + audiodemux = gst_element_factory_make(demux_type.c_str(), "audiodemux"); + if (!audiodemux) + m_error_message = "GStreamer plugin " + demux_type + " not available!\n"; + } + switch ( sourceinfo.audiotype ) + { + case atMP3: + { + if ( !audiodemux ) + { + parser = gst_element_factory_make("mp3parse", "audioparse"); + if (!parser) + { + m_error_message += "failed to create Gstreamer element mp3parse\n"; + break; + } + } + sink = gst_element_factory_make("dvbaudiosink", "audiosink"); + if ( !sink ) + m_error_message += "failed to create Gstreamer element dvbaudiosink\n"; + else + all_ok = 1; + break; + } + case atAAC: + { + if ( !audiodemux ) + { + m_error_message += "cannot parse raw AAC audio\n"; + break; + } + sink = gst_element_factory_make("dvbaudiosink", "audiosink"); + if (!sink) + m_error_message += "failed to create Gstreamer element dvbaudiosink\n"; + else + all_ok = 1; + break; + } + case atAC3: + { + if ( !audiodemux ) + { + m_error_message += "cannot parse raw AC3 audio\n"; + break; + } + sink = gst_element_factory_make("dvbaudiosink", "audiosink"); + if ( !sink ) + m_error_message += "failed to create Gstreamer element dvbaudiosink\n"; + else + all_ok = 1; + break; + } + default: + { /* filesrc -> decodebin -> audioconvert -> capsfilter -> alsasink */ + decoder = gst_element_factory_make ("decodebin", "decoder"); + if (!decoder) + m_error_message += "failed to create Gstreamer element decodebin\n"; + + conv = gst_element_factory_make ("audioconvert", "converter"); + if (!conv) + m_error_message += "failed to create Gstreamer element audioconvert\n"; + + flt = gst_element_factory_make ("capsfilter", "flt"); + if (!flt) + m_error_message += "failed to create Gstreamer element capsfilter\n"; + + /* for some reasons, we need to set the sample format to depth/width=16, because auto negotiation doesn't work. */ + /* endianness, however, is not required to be set anymore. */ + if (flt) + { + GstCaps *caps = gst_caps_new_simple("audio/x-raw-int", /* "endianness", G_TYPE_INT, 4321, */ "depth", G_TYPE_INT, 16, "width", G_TYPE_INT, 16, /*"channels", G_TYPE_INT, 2, */NULL); + g_object_set (G_OBJECT (flt), "caps", caps, NULL); + gst_caps_unref(caps); + } + + sink = gst_element_factory_make ("alsasink", "alsa-output"); + if (!sink) + m_error_message += "failed to create Gstreamer element alsasink\n"; + + if (source && decoder && conv && sink) + all_ok = 1; + break; + } } - sink = gst_element_factory_make ("alsasink", "alsa-output"); - if (!sink) - m_error_message += "failed to create Gstreamer element alsasink\n"; - - if (source && decoder && conv && sink) - all_ok = 1; } if (m_gst_pipeline && all_ok) { @@ -386,8 +485,9 @@ eServiceMP3::eServiceMP3(const char *filename): m_filename(filename), m_pump(eAp } gst_bin_add_many(GST_BIN(m_gst_pipeline), source, videodemux, audio, queue_audio, video, queue_video, switch_audio, NULL); - if ( sourceinfo.containertype == ctVCD ) + if ( sourceinfo.containertype == ctVCD && gst_bin_get_by_name(GST_BIN(m_gst_pipeline),"file-source") ) { + eDebug("this is a fake video cd... we use filesrc ! cdxaparse !"); GstElement *cdxaparse = gst_element_factory_make("cdxaparse", "cdxaparse"); gst_bin_add(GST_BIN(m_gst_pipeline), cdxaparse); gst_element_link(source, cdxaparse); @@ -403,29 +503,51 @@ eServiceMP3::eServiceMP3(const char *filename): m_filename(filename), m_pump(eAp } else /* is audio*/ { - queue_audio = gst_element_factory_make("queue", "queue_audio"); - - g_signal_connect (decoder, "new-decoded-pad", G_CALLBACK(gstCBnewPad), this); - g_signal_connect (decoder, "unknown-type", G_CALLBACK(gstCBunknownType), this); - - g_object_set (G_OBJECT (sink), "preroll-queue-len", 80, NULL); - - /* gst_bin will take the 'floating references' */ - gst_bin_add_many (GST_BIN (m_gst_pipeline), - source, queue_audio, decoder, NULL); - - /* in decodebin's case we can just connect the source with the decodebin, and decodebin will take care about id3demux (or whatever is required) */ - gst_element_link_many(source, queue_audio, decoder, NULL); - - /* create audio bin with the audioconverter, the capsfilter and the audiosink */ - audio = gst_bin_new ("audiobin"); - - GstPad *audiopad = gst_element_get_static_pad (conv, "sink"); - gst_bin_add_many(GST_BIN(audio), conv, flt, sink, NULL); - gst_element_link_many(conv, flt, sink, NULL); - gst_element_add_pad(audio, gst_ghost_pad_new ("sink", audiopad)); - gst_object_unref(audiopad); - gst_bin_add (GST_BIN(m_gst_pipeline), audio); + if ( decoder ) + { + queue_audio = gst_element_factory_make("queue", "queue_audio"); + + g_signal_connect (decoder, "new-decoded-pad", G_CALLBACK(gstCBnewPad), this); + g_signal_connect (decoder, "unknown-type", G_CALLBACK(gstCBunknownType), this); + + g_object_set (G_OBJECT (sink), "preroll-queue-len", 80, NULL); + + /* gst_bin will take the 'floating references' */ + gst_bin_add_many (GST_BIN (m_gst_pipeline), + source, queue_audio, decoder, NULL); + + /* in decodebin's case we can just connect the source with the decodebin, and decodebin will take care about id3demux (or whatever is required) */ + gst_element_link_many(source, queue_audio, decoder, NULL); + + /* create audio bin with the audioconverter, the capsfilter and the audiosink */ + audio = gst_bin_new ("audiobin"); + + GstPad *audiopad = gst_element_get_static_pad (conv, "sink"); + gst_bin_add_many(GST_BIN(audio), conv, flt, sink, NULL); + gst_element_link_many(conv, flt, sink, NULL); + gst_element_add_pad(audio, gst_ghost_pad_new ("sink", audiopad)); + gst_object_unref(audiopad); + gst_bin_add (GST_BIN(m_gst_pipeline), audio); + } + else + { + gst_bin_add_many (GST_BIN (m_gst_pipeline), source, sink, NULL); + if ( parser ) + { + gst_bin_add (GST_BIN (m_gst_pipeline), parser); + gst_element_link_many(source, parser, sink, NULL); + } + if ( audiodemux ) + { + gst_bin_add (GST_BIN (m_gst_pipeline), audiodemux); + g_signal_connect(audiodemux, "pad-added", G_CALLBACK (gstCBpadAdded), this); + gst_element_link(source, audiodemux); + eDebug("linked source, audiodemux, sink"); + } + audioStream audio; + audio.type = sourceinfo.audiotype; + m_audioStreams.push_back(audio); + } } } else { @@ -1094,8 +1216,14 @@ void eServiceMP3::gstCBpadAdded(GstElement *decodebin, GstPad *pad, gpointer use } else { - gst_pad_link(pad, gst_element_get_static_pad(gst_bin_get_by_name(pipeline,"queue_audio"), "sink")); - _this->m_audioStreams.push_back(audio); + GstElement *queue_audio = gst_bin_get_by_name(pipeline , "queue_audio"); + if ( queue_audio) + { + gst_pad_link(pad, gst_element_get_static_pad(queue_audio, "sink")); + _this->m_audioStreams.push_back(audio); + } + else + gst_pad_link(pad, gst_element_get_static_pad(gst_bin_get_by_name(pipeline , "audiosink"), "sink")); } } if (g_strrstr(type,"video")) -- cgit v1.2.3 From 4dda70dcac6996c8b0a2016c49d6cfbab7128fee Mon Sep 17 00:00:00 2001 From: Fraxinas Date: Wed, 3 Dec 2008 17:53:18 +0100 Subject: initialize noCoverFile in case skin doesn't define it. thx to RitzMo --- lib/python/Plugins/Extensions/MediaPlayer/plugin.py | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/python/Plugins') diff --git a/lib/python/Plugins/Extensions/MediaPlayer/plugin.py b/lib/python/Plugins/Extensions/MediaPlayer/plugin.py index 3d1889b9..c25af780 100644 --- a/lib/python/Plugins/Extensions/MediaPlayer/plugin.py +++ b/lib/python/Plugins/Extensions/MediaPlayer/plugin.py @@ -44,6 +44,7 @@ class MediaPixmap(Pixmap): def applySkin(self, desktop, screen): from Tools.LoadPixmap import LoadPixmap + noCoverFile = None if self.skinAttributes is not None: for (attrib, value) in self.skinAttributes: if attrib == "pixmap": -- cgit v1.2.3 From 188224c032f898f7ddbb347839baba65550b5903 Mon Sep 17 00:00:00 2001 From: ghost Date: Wed, 3 Dec 2008 18:05:47 +0100 Subject: GraphMultiEpg: fix zap to services without events --- lib/python/Plugins/Extensions/GraphMultiEPG/GraphMultiEpg.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/python/Plugins') diff --git a/lib/python/Plugins/Extensions/GraphMultiEPG/GraphMultiEpg.py b/lib/python/Plugins/Extensions/GraphMultiEPG/GraphMultiEpg.py index 7f422c96..aff1c91d 100644 --- a/lib/python/Plugins/Extensions/GraphMultiEPG/GraphMultiEpg.py +++ b/lib/python/Plugins/Extensions/GraphMultiEPG/GraphMultiEpg.py @@ -93,13 +93,13 @@ class EPGList(HTMLComponent, GUIComponent): return event def getCurrent(self): - if self.cur_service is None or self.cur_event is None: + if self.cur_service is None: return ( None, None ) old_service = self.cur_service #(service, service_name, events) events = self.cur_service[2] refstr = self.cur_service[0] - if not events or not len(events): - return ( None, None ) + if self.cur_event is None or not events or not len(events): + return ( None, ServiceReference(refstr) ) event = events[self.cur_event] #(event_id, event_title, begin_time, duration) eventid = event[0] service = ServiceReference(refstr) -- cgit v1.2.3 From 1e1b651652e0f46bebc1c803e289fb84de222690 Mon Sep 17 00:00:00 2001 From: ghost Date: Wed, 3 Dec 2008 19:05:33 +0100 Subject: GraphMultiEpg.py: better readable code (no functional change) --- .../Extensions/GraphMultiEPG/GraphMultiEpg.py | 26 ++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) (limited to 'lib/python/Plugins') diff --git a/lib/python/Plugins/Extensions/GraphMultiEPG/GraphMultiEpg.py b/lib/python/Plugins/Extensions/GraphMultiEPG/GraphMultiEpg.py index aff1c91d..441cb5d8 100644 --- a/lib/python/Plugins/Extensions/GraphMultiEPG/GraphMultiEpg.py +++ b/lib/python/Plugins/Extensions/GraphMultiEPG/GraphMultiEpg.py @@ -204,7 +204,13 @@ class EPGList(HTMLComponent, GUIComponent): def buildEntry(self, service, service_name, events): r1=self.service_rect r2=self.event_rect - res = [ None, MultiContentEntryText(pos = (r1.left(),r1.top()), size = (r1.width(), r1.height()), font = 0, flags = RT_HALIGN_LEFT | RT_VALIGN_CENTER, text = service_name, color = self.foreColorService, backcolor = self.backColorService) ] + res = [ None, MultiContentEntryText( + pos = (r1.left(),r1.top()), + size = (r1.width(), r1.height()), + font = 0, flags = RT_HALIGN_LEFT | RT_VALIGN_CENTER, + text = service_name, + color = self.foreColorService, + backcolor = self.backColorService) ] if events: start = self.time_base+self.offs*self.time_epoch*60 @@ -222,9 +228,16 @@ class EPGList(HTMLComponent, GUIComponent): for ev in events: #(event_id, event_title, begin_time, duration) rec=ev[2] and self.timer.isInTimer(ev[0], ev[2], ev[3], service) > ((ev[3]/10)*8) xpos, ewidth = self.calcEntryPosAndWidthHelper(ev[2], ev[3], start, end, width) - res.append(MultiContentEntryText(pos = (left+xpos, top), size = (ewidth, height), font = 1, flags = RT_HALIGN_CENTER | RT_VALIGN_CENTER | RT_WRAP, text = ev[1], color = foreColor, color_sel = foreColorSelected, backcolor = backColor, backcolor_sel = backColorSelected, border_width = 1, border_color = borderColor)) + res.append(MultiContentEntryText( + pos = (left+xpos, top), size = (ewidth, height), + font = 1, flags = RT_HALIGN_CENTER | RT_VALIGN_CENTER | RT_WRAP, + text = ev[1], color = foreColor, color_sel = foreColorSelected, + backcolor = backColor, backcolor_sel = backColorSelected, border_width = 1, border_color = borderColor)) if rec and ewidth > 23: - res.append(MultiContentEntryPixmapAlphaTest(pos = (left+xpos+ewidth-22, top+height-22), size = (21, 21), png = self.clock_pixmap, backcolor = backColor, backcolor_sel = backColorSelected)) + res.append(MultiContentEntryPixmapAlphaTest( + pos = (left+xpos+ewidth-22, top+height-22), size = (21, 21), + png = self.clock_pixmap, backcolor = backColor, + backcolor_sel = backColorSelected)) return res def selEntry(self, dir, visible=True): @@ -278,8 +291,13 @@ class EPGList(HTMLComponent, GUIComponent): self.time_base = int(stime) test = [ (service.ref.toString(), 0, self.time_base, self.time_epoch) for service in services ] test.insert(0, 'XRnITBD') + print "BEFORE:" + for x in test: + print x epg_data = self.queryEPG(test) - + print "EPG:" + for x in epg_data: + print x self.list = [ ] tmp_list = None service = "" -- cgit v1.2.3 From 282d9e86ee6942a5c557d25cce0899857fab78dd Mon Sep 17 00:00:00 2001 From: ghost Date: Wed, 3 Dec 2008 19:06:21 +0100 Subject: GraphMultiEpg/plugin.py: fix not working zap function when the bouquet is changed with bouquet +/- --- lib/python/Plugins/Extensions/GraphMultiEPG/plugin.py | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/python/Plugins') diff --git a/lib/python/Plugins/Extensions/GraphMultiEPG/plugin.py b/lib/python/Plugins/Extensions/GraphMultiEPG/plugin.py index 0ebcafca..adb7015d 100644 --- a/lib/python/Plugins/Extensions/GraphMultiEPG/plugin.py +++ b/lib/python/Plugins/Extensions/GraphMultiEPG/plugin.py @@ -69,6 +69,7 @@ def changeBouquetCB(direction, epg): bouquet = bouquetSel.getCurrent() services = getBouquetServices(bouquet) if len(services): + global epg_bouquet epg_bouquet = bouquet epg.setServices(services) -- cgit v1.2.3 From e61975a7c2d349bcc5c372c3ca472ce8da28f6fc Mon Sep 17 00:00:00 2001 From: Fraxinas Date: Thu, 4 Dec 2008 11:18:35 +0100 Subject: allow grabbing still frames from movies using seddis AiO Screengrabber V0.8 (needs package aio-grab) for graphical dvd menus --- lib/python/Plugins/Extensions/CutListEditor/plugin.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'lib/python/Plugins') diff --git a/lib/python/Plugins/Extensions/CutListEditor/plugin.py b/lib/python/Plugins/Extensions/CutListEditor/plugin.py index 0d2454e4..c80bff18 100644 --- a/lib/python/Plugins/Extensions/CutListEditor/plugin.py +++ b/lib/python/Plugins/Extensions/CutListEditor/plugin.py @@ -12,6 +12,7 @@ from Components.GUIComponent import GUIComponent from enigma import eListboxPythonMultiContent, eListbox, gFont, iPlayableService, RT_HALIGN_RIGHT from Screens.FixedMenu import FixedMenu from Screens.HelpMenu import HelpableScreen +from ServiceReference import ServiceReference import bisect def CutListEntry(where, what): @@ -42,6 +43,7 @@ class CutListContextMenu(FixedMenu): RET_DELETEMARK = 4 RET_REMOVEBEFORE = 5 RET_REMOVEAFTER = 6 + RET_GRABFRAME = 7 SHOW_STARTCUT = 0 SHOW_ENDCUT = 1 @@ -75,6 +77,7 @@ class CutListContextMenu(FixedMenu): else: menu.append((_("remove this mark"), self.removeMark)) + menu.append((("grab this frame as bitmap"), self.grabFrame)) FixedMenu.__init__(self, session, _("Cut"), menu) self.skinName = "Menu" @@ -99,6 +102,8 @@ class CutListContextMenu(FixedMenu): def removeAfter(self): self.close(self.RET_REMOVEAFTER) + def grabFrame(self): + self.close(self.RET_GRABFRAME) class CutList(GUIComponent): def __init__(self, list): @@ -390,6 +395,8 @@ class CutListEditor(Screen, InfoBarBase, InfoBarSeek, InfoBarCueSheetSupport, He # add 'out' point bisect.insort(self.cut_list, (self.context_position, 1)) self.uploadCuesheet() + elif result == CutListContextMenu.RET_GRABFRAME: + self.grabFrame() # we modify the "play" behavior a bit: # if we press pause while being in slowmotion, we will pause (and not play) @@ -399,6 +406,14 @@ class CutListEditor(Screen, InfoBarBase, InfoBarSeek, InfoBarCueSheetSupport, He else: self.pauseService() + def grabFrame(self): + path = self.session.nav.getCurrentlyPlayingServiceReference().getPath() + from Components.Console import Console + grabConsole = Console() + cmd = 'grab -vblpr%d "%s"' % (180, path.rsplit('.',1)[0] + ".png") + grabConsole.ePopen(cmd) + self.playpauseService() + def main(session, service, **kwargs): session.open(CutListEditor, service) -- cgit v1.2.3 From c69c3febf1582fb1bd170bc4b04132354f574cfc Mon Sep 17 00:00:00 2001 From: Fraxinas Date: Thu, 4 Dec 2008 11:20:12 +0100 Subject: allow fully customizable dvd menu layout, including automatic thumbnail graphic creation (requires package aio-grab) --- .../Plugins/Extensions/DVDBurn/DVDProject.py | 100 ++++++--- lib/python/Plugins/Extensions/DVDBurn/DVDTitle.py | 10 +- .../Extensions/DVDBurn/DreamboxDVD.ddvdp.xml | 14 ++ .../DVDBurn/DreamboxDVDtemplate.ddvdp.xml | 23 -- lib/python/Plugins/Extensions/DVDBurn/Process.py | 249 +++++++++++++-------- .../Plugins/Extensions/DVDBurn/ProjectSettings.py | 34 ++- .../Extensions/DVDBurn/Text menu boat.ddvdm.xml | 35 +++ .../DVDBurn/Thumbs menu clouds.ddvdm.xml | 35 +++ .../Plugins/Extensions/DVDBurn/TitleCutter.py | 7 + lib/python/Plugins/Extensions/DVDBurn/TitleList.py | 4 +- .../Plugins/Extensions/DVDBurn/TitleProperties.py | 45 ++-- .../Plugins/Extensions/DVDBurn/dreamdvd_clouds.jpg | Bin 0 -> 62697 bytes lib/python/Plugins/Extensions/DVDBurn/dvdburn.png | Bin 13 files changed, 381 insertions(+), 175 deletions(-) create mode 100644 lib/python/Plugins/Extensions/DVDBurn/DreamboxDVD.ddvdp.xml delete mode 100644 lib/python/Plugins/Extensions/DVDBurn/DreamboxDVDtemplate.ddvdp.xml create mode 100644 lib/python/Plugins/Extensions/DVDBurn/Text menu boat.ddvdm.xml create mode 100644 lib/python/Plugins/Extensions/DVDBurn/Thumbs menu clouds.ddvdm.xml create mode 100644 lib/python/Plugins/Extensions/DVDBurn/dreamdvd_clouds.jpg mode change 100755 => 100644 lib/python/Plugins/Extensions/DVDBurn/dvdburn.png (limited to 'lib/python/Plugins') diff --git a/lib/python/Plugins/Extensions/DVDBurn/DVDProject.py b/lib/python/Plugins/Extensions/DVDBurn/DVDProject.py index 112a221e..b0b8197a 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/DVDProject.py +++ b/lib/python/Plugins/Extensions/DVDBurn/DVDProject.py @@ -1,18 +1,10 @@ from Tools.Directories import fileExists -from Components.config import config, ConfigSubsection, ConfigInteger, ConfigText, ConfigSelection, getConfigListEntry, ConfigSequence +from Components.config import config, ConfigSubsection, ConfigInteger, ConfigText, ConfigSelection, getConfigListEntry, ConfigSequence, ConfigSubList class ConfigColor(ConfigSequence): def __init__(self): ConfigSequence.__init__(self, seperator = "#", limits = [(0,255),(0,255),(0,255)]) -class ConfigPixelvals(ConfigSequence): - def __init__(self): - ConfigSequence.__init__(self, seperator = ",", limits = [(0,200),(0,200),(0,200)]) - -class ConfigPixelvals(ConfigSequence): - def __init__(self): - ConfigSequence.__init__(self, seperator = ",", limits = [(0,200),(0,200),(0,200)]) - class ConfigFilename(ConfigText): def __init__(self): ConfigText.__init__(self, default = "", fixed_size = True, visible_width = False) @@ -35,19 +27,11 @@ class DVDProject: self.settings.titlesetmode = ConfigSelection(choices = [("single", _("Simple titleset (compatibility for legacy players)")), ("multi", _("Complex (allows mixing audio tracks and aspects)"))], default="multi") self.settings.output = ConfigSelection(choices = [("iso", _("Create DVD-ISO")), ("dvd", _("Burn DVD"))]) self.settings.isopath = ConfigText(fixed_size = False, visible_width = 40) - self.settings.dataformat = ConfigSelection(choices = [("iso9660_1", ("ISO9660 Level 1")), ("iso9660_4", ("ISO9660 version 2")), ("udf", ("UDF"))]) - self.settings.menubg = ConfigFilename() - self.settings.menuaudio = ConfigFilename() - self.settings.titleformat = ConfigText(fixed_size = False, visible_width = 40) - self.settings.subtitleformat = ConfigText(fixed_size = False, visible_width = 40) - self.settings.color_headline = ConfigColor() - self.settings.color_highlight = ConfigColor() - self.settings.color_button = ConfigColor() - self.settings.font_face = ConfigFilename() - self.settings.font_size = ConfigPixelvals() - self.settings.space = ConfigPixelvals() + self.settings.dataformat = ConfigSelection(choices = [("iso9660_1", ("ISO9660 Level 1")), ("iso9660_4", ("ISO9660 version 2")), ("udf", ("UDF"))]) + self.settings.menutemplate = ConfigFilename() self.settings.vmgm = ConfigFilename() - self.filekeys = ["vmgm", "menubg", "menuaudio", "font_face", "isopath"] + self.filekeys = ["vmgm", "isopath", "menutemplate"] + self.menutemplate = MenuTemplate() def addService(self, service): import DVDTitle @@ -65,12 +49,30 @@ class DVDProject: list.append('\t\n') + list.append('/>\n') list.append('\t\n') for title in self.titles: - list.append('\t\t') + list.append('\t\t\n') + list.append('\t\t\t<path>') list.append(stringToXML(title.source.getPath())) list.append('</path>\n') + list.append('\t\t\t<properties ') + audiotracks = [] + for key, val in title.properties.dict().iteritems(): + if type(val) is ConfigSubList: + audiotracks.append('\t\t\t<audiotracks>\n') + for audiotrack in val: + audiotracks.append('\t\t\t\t<audiotrack ') + for subkey, subval in audiotrack.dict().iteritems(): + audiotracks.append( subkey + '="' + str(subval.getValue()) + '" ' ) + audiotracks.append(' />\n') + audiotracks.append('\t\t\t</audiotracks>\n') + else: + list.append( key + '="' + str(val.getValue()) + '" ' ) + list.append('/>\n') + for line in audiotracks: + list.append(line) + list.append('\t\t\n') list.append('\t\n') list.append('\n') @@ -89,6 +91,13 @@ class DVDProject: return False return filename + def load(self, filename): + ret = self.loadProject(filename) + if ret: + ret = self.menutemplate.loadTemplate(self.settings.menutemplate.getValue()) + self.error += self.menutemplate.error + return ret + def loadProject(self, filename): import xml.dom.minidom try: @@ -105,9 +114,9 @@ class DVDProject: if project.nodeType == xml.dom.minidom.Element.nodeType: if project.tagName == 'settings': i = 0 - if project.attributes.length < 11: + if project.attributes.length < len(self.settings.dict()): self.error = "project attributes missing" - raise AttributeError + raise AttributeError while i < project.attributes.length: item = project.attributes.item(i) key = item.name.encode("utf-8") @@ -131,3 +140,44 @@ class DVDProject: self.error += (" in project '%s'") % (filename) return False return True + +class MenuTemplate(DVDProject): + def __init__(self): + self.settings = ConfigSubsection() + self.settings.titleformat = ConfigText(fixed_size = False, visible_width = 40) + self.settings.subtitleformat = ConfigText(fixed_size = False, visible_width = 40) + self.settings.menubg = ConfigFilename() + self.settings.menuaudio = ConfigFilename() + self.settings.dimensions = ConfigSequence(seperator = ',', default = [576,720], limits = [(352,720),(480,576)]) + self.settings.rows = ConfigInteger(default = 4, limits = (1, 10)) + self.settings.cols = ConfigInteger(default = 1, limits = (1, 4)) + self.settings.color_headline = ConfigColor() + self.settings.color_headline = ConfigColor() + self.settings.color_highlight = ConfigColor() + self.settings.color_button = ConfigColor() + self.settings.fontface_headline = ConfigFilename() + self.settings.fontface_title = ConfigFilename() + self.settings.fontface_subtitle = ConfigFilename() + self.settings.fontsize_headline = ConfigInteger(default = 46, limits = (0, 199)) + self.settings.fontsize_title = ConfigInteger(default = 24, limits = (0, 199)) + self.settings.fontsize_subtitle = ConfigInteger(default = 14, limits = (0, 199)) + self.settings.margin_top = ConfigInteger(default = 120, limits = (0, 500)) + self.settings.margin_bottom = ConfigInteger(default = 40, limits = (0, 500)) + self.settings.margin_left = ConfigInteger(default = 56, limits = (0, 500)) + self.settings.margin_right = ConfigInteger(default = 56, limits = (0, 500)) + self.settings.space_rows = ConfigInteger(default = 32, limits = (0, 500)) + self.settings.space_cols = ConfigInteger(default = 24, limits = (0, 500)) + self.settings.prev_page_text = ConfigText(default = "<<<", fixed_size = False) + self.settings.next_page_text = ConfigText(default = ">>>", fixed_size = False) + self.settings.offset_headline = ConfigSequence(seperator = ',', default = [0,0], limits = [(-1,500),(-1,500)]) + self.settings.offset_title = ConfigSequence(seperator = ',', default = [0,0], limits = [(-1,500),(-1,500)]) + self.settings.offset_subtitle = ConfigSequence(seperator = ',', default = [20,0], limits = [(-1,500),(-1,500)]) + self.settings.offset_thumb = ConfigSequence(seperator = ',', default = [40,0], limits = [(-1,500),(-1,500)]) + self.settings.thumb_size = ConfigSequence(seperator = ',', default = [200,158], limits = [(0,576),(-1,720)]) + self.settings.thumb_border = ConfigInteger(default = 2, limits = (0, 20)) + self.filekeys = ["menubg", "menuaudio", "fontface_headline", "fontface_title", "fontface_subtitle"] + + def loadTemplate(self, filename): + ret = DVDProject.loadProject(self, filename) + DVDProject.error = self.error + return ret diff --git a/lib/python/Plugins/Extensions/DVDBurn/DVDTitle.py b/lib/python/Plugins/Extensions/DVDBurn/DVDTitle.py index b1c627aa..660005e6 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/DVDTitle.py +++ b/lib/python/Plugins/Extensions/DVDBurn/DVDTitle.py @@ -51,11 +51,11 @@ class DVDTitle: self.length = info.getLength(service) def initDVDmenuText(self, project, track): - self.properties.menutitle.setValue(self.formatDVDmenuText(project.settings.titleformat.getValue(), track)) - self.properties.menusubtitle.setValue(self.formatDVDmenuText(project.settings.subtitleformat.getValue(), track)) + s = project.menutemplate.settings + self.properties.menutitle.setValue(self.formatDVDmenuText(s.titleformat.getValue(), track)) + self.properties.menusubtitle.setValue(self.formatDVDmenuText(s.subtitleformat.getValue(), track)) def formatDVDmenuText(self, template, track): - properties = self.properties template = template.replace("$i", str(track)) template = template.replace("$t", self.DVBname) template = template.replace("$d", self.DVBdescr) @@ -76,7 +76,7 @@ class DVDTitle: audiolist.append(trackstring) audiostring = ', '.join(audiolist) template = template.replace("$A", audiostring) - + if template.find("$l") >= 0: l = self.length lengthstring = "%d:%02d:%02d" % (l/3600, l%3600/60, l%60) @@ -90,7 +90,7 @@ class DVDTitle: else: template = template.replace("$Y", "").replace("$M", "").replace("$D", "").replace("$T", "") return template - + def produceFinalCuesheet(self): CUT_TYPE_IN = 0 CUT_TYPE_OUT = 1 diff --git a/lib/python/Plugins/Extensions/DVDBurn/DreamboxDVD.ddvdp.xml b/lib/python/Plugins/Extensions/DVDBurn/DreamboxDVD.ddvdp.xml new file mode 100644 index 00000000..2c35e531 --- /dev/null +++ b/lib/python/Plugins/Extensions/DVDBurn/DreamboxDVD.ddvdp.xml @@ -0,0 +1,14 @@ + + + + + diff --git a/lib/python/Plugins/Extensions/DVDBurn/DreamboxDVDtemplate.ddvdp.xml b/lib/python/Plugins/Extensions/DVDBurn/DreamboxDVDtemplate.ddvdp.xml deleted file mode 100644 index 7d8de8ce..00000000 --- a/lib/python/Plugins/Extensions/DVDBurn/DreamboxDVDtemplate.ddvdp.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - diff --git a/lib/python/Plugins/Extensions/DVDBurn/Process.py b/lib/python/Plugins/Extensions/DVDBurn/Process.py index 750e9d9b..d0c9d3c6 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/Process.py +++ b/lib/python/Plugins/Extensions/DVDBurn/Process.py @@ -455,13 +455,13 @@ class ImagePrepareTask(Task): try: from ImageFont import truetype from Image import open as Image_open - s = self.job.project.settings + s = self.job.project.menutemplate.settings + (width, height) = s.dimensions.getValue() self.Menus.im_bg_orig = Image_open(s.menubg.getValue()) - if self.Menus.im_bg_orig.size != (self.Menus.imgwidth, self.Menus.imgheight): - self.Menus.im_bg_orig = self.Menus.im_bg_orig.resize((720, 576)) - self.Menus.fontsizes = s.font_size.getValue() - fontface = s.font_face.getValue() - self.Menus.fonts = [truetype(fontface, self.Menus.fontsizes[0]), truetype(fontface, self.Menus.fontsizes[1]), truetype(fontface, self.Menus.fontsizes[2])] + if self.Menus.im_bg_orig.size != (width, height): + self.Menus.im_bg_orig = self.Menus.im_bg_orig.resize((width, height)) + self.Menus.fontsizes = [s.fontsize_headline.getValue(), s.fontsize_title.getValue(), s.fontsize_subtitle.getValue()] + self.Menus.fonts = [(truetype(s.fontface_headline.getValue(), self.Menus.fontsizes[0])), (truetype(s.fontface_title.getValue(), self.Menus.fontsizes[1])),(truetype(s.fontface_subtitle.getValue(), self.Menus.fontsizes[2]))] Task.processFinished(self, 0) except: Task.processFinished(self, 1) @@ -480,98 +480,158 @@ class MenuImageTask(Task): def run(self, callback): self.callback = callback - try: - import ImageDraw, Image, os - s = self.job.project.settings - fonts = self.Menus.fonts - im_bg = self.Menus.im_bg_orig.copy() - im_high = Image.new("P", (self.Menus.imgwidth, self.Menus.imgheight), 0) - im_high.putpalette(self.Menus.spu_palette) - draw_bg = ImageDraw.Draw(im_bg) - draw_high = ImageDraw.Draw(im_high) - if self.menu_count == 1: - headline = s.name.getValue().decode("utf-8") - textsize = draw_bg.textsize(headline, font=fonts[0]) - if textsize[0] > self.Menus.imgwidth: - offset = (0 , 20) - else: - offset = (((self.Menus.imgwidth-textsize[0]) / 2) , 20) - draw_bg.text(offset, headline, fill=self.Menus.color_headline, font=fonts[0]) - spuxml = """ - - - """ % (self.highlightpngfilename, self.Menus.spu_palette[0], self.Menus.spu_palette[1], self.Menus.spu_palette[2]) - s_top, s_rows, s_left = s.space.getValue() - rowheight = (self.Menus.fontsizes[1]+self.Menus.fontsizes[2]+s_rows) - menu_start_title = (self.menu_count-1)*self.job.titles_per_menu + 1 - menu_end_title = (self.menu_count)*self.job.titles_per_menu + 1 - nr_titles = len(self.job.project.titles) - if menu_end_title > nr_titles: - menu_end_title = nr_titles+1 - menu_i = 0 - for title_no in range( menu_start_title , menu_end_title ): - menu_i += 1 - title = self.job.project.titles[title_no-1] - top = s_top + ( menu_i * rowheight ) - titleText = title.formatDVDmenuText(s.titleformat.getValue(), title_no).decode("utf-8") - draw_bg.text((s_left,top), titleText, fill=self.Menus.color_button, font=fonts[1]) - draw_high.text((s_left,top), titleText, fill=1, font=self.Menus.fonts[1]) - subtitleText = title.formatDVDmenuText(s.subtitleformat.getValue(), title_no).decode("utf-8") - draw_bg.text((s_left,top+36), subtitleText, fill=self.Menus.color_button, font=fonts[2]) - bottom = top+rowheight - if bottom > self.Menus.imgheight: - bottom = self.Menus.imgheight - spuxml += """ -