--- /dev/null
+#
+# AutomaticVolumeAdjustment E2
+#
+# $Id$
+#
+# Coded by Dr.Best (c) 2010
+# Support: www.dreambox-tools.info
+#
+# This plugin is licensed under the Creative Commons
+# Attribution-NonCommercial-ShareAlike 3.0 Unported
+# License. To view a copy of this license, visit
+# http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter to Creative
+# Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
+#
+# Alternatively, this plugin may be distributed and executed on hardware which
+# is licensed by Dream Multimedia GmbH.
+
+# This plugin is NOT free software. It is open source, you are allowed to
+# modify it (if you keep the license), but it may not be commercially
+# distributed other than under the conditions noted above.
+#
+from Plugins.Plugin import PluginDescriptor
+from Screens.Screen import Screen
+from Components.ActionMap import ActionMap
+from Components.Sources.StaticText import StaticText
+from Components.config import config
+from setup import AutomaticVolumeAdjustmentConfigScreen, AutomaticVolumeAdjustmentConfig
+from Components.ServiceEventTracker import ServiceEventTracker
+from enigma import iPlayableService, iServiceInformation, eDVBVolumecontrol, eServiceCenter, eServiceReference
+from ServiceReference import ServiceReference
+
+automaticvolumeadjustment = None # global, so setup can use method initializeConfigValues and enable/disable the plugin without gui restart
+
+class AutomaticVolumeAdjustment(Screen):
+ def __init__(self, session):
+ self.session = session
+ Screen.__init__(self, session)
+ print "[AutomaticVolumeAdjustment] Starting AutomaticVolumeAdjustment..."
+ self.__event_tracker = ServiceEventTracker(screen = self, eventmap =
+ {
+ iPlayableService.evUpdatedInfo: self.__evUpdatedInfo,
+ iPlayableService.evStart: self.__evStart,
+ iPlayableService.evEnd: self.__evEnd
+ })
+ self.newService = False # switching flag
+ self.pluginStarted = False # is plugin started?
+ self.lastAdjustedValue = 0 # remember delta from last automatic volume up/down
+ self.currentVolume = 0 # only set when AC3 or DTS is available
+ self.enabled = False # AutomaticVolumeAdjustment enabled in setup?
+ self.serviceList = { } # values from config
+ configVA = AutomaticVolumeAdjustmentConfig()
+ self.initializeConfigValues(configVA, False)
+ self.volctrl = eDVBVolumecontrol.getInstance()
+
+ def initializeConfigValues(self, configVA, fromOutside):
+ print "[AutomaticVolumeAdjustment] initialize config values..."
+ self.serviceList = { }
+ for c in configVA.config.Entries:
+ self.serviceList[c.servicereference.value] = int(c.adjustvalue.value)
+ self.defaultValue = int(configVA.config.adustvalue.value)
+ self.enabled = configVA.config.enable.value
+ if not self.pluginStarted and self.enabled and fromOutside:
+ self.newService = True
+ self.__evUpdatedInfo()
+
+ def __evEnd(self):
+ if self.pluginStarted and self.enabled:
+ # if played service had AC3||DTS audio and volume value was changed with RC, take new delta value from the config
+ if self.currentVolume and self.volctrl.getVolume() != self.currentVolume:
+ self.lastAdjustedValue = self.serviceList.get(self.session.nav.getCurrentlyPlayingServiceReference().toString(), self.defaultValue)
+
+ def __evStart(self):
+ self.newService = True
+
+ def __evUpdatedInfo(self):
+ if self.newService and self.session.nav.getCurrentlyPlayingServiceReference() and self.enabled:
+ print "[AutomaticVolumeAdjustment] service changed"
+ self.newService = False
+ self.currentVolume = 0 # init
+ currentAC3DTS = self.isCurrentAudioAC3DTS()
+ if self.pluginStarted:
+ if currentAC3DTS: # ac3 dts?
+ vol = self.volctrl.getVolume()
+ currentvol = vol # remember current vol
+ vol -= self.lastAdjustedValue # go back to origin value first
+ ref = self.session.nav.getCurrentlyPlayingServiceReference()
+ if ref.getPath(): # check if a moving is playing
+ # it is , get the eServicereference if available
+ self.serviceHandler = eServiceCenter.getInstance()
+ info = self.serviceHandler.info(ref)
+ if info:
+ ref = eServiceReference(info.getInfoString(ref, iServiceInformation.sServiceref)) # set new eServicereference
+ ajvol = self.serviceList.get(ref.toString(), self.defaultValue) # get delta from config
+ if vol >= 100 - ajvol: # check if delta + vol < 100
+ ajvol = 100 - vol # correct delta value
+ self.lastAdjustedValue = ajvol # save delta value
+ if ajvol !=0 and (vol+ajvol != currentvol): # only adjust volume when delta != 0 or current vol != new volume
+ self.volctrl.setVolume(vol+self.lastAdjustedValue, vol+self.lastAdjustedValue)
+ print "[AutomaticVolumeAdjustment] Change volume for service: %s (+%d) to %d"%(ServiceReference(ref).getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', ''), ajvol, self.volctrl.getVolume())
+ self.currentVolume = self.volctrl.getVolume() # ac3||dts service , save current volume
+ else:
+ # mpeg or whatever audio
+ if self.lastAdjustedValue != 0:
+ # go back to origin value
+ vol = self.volctrl.getVolume()
+ self.volctrl.setVolume(vol-self.lastAdjustedValue, vol-self.lastAdjustedValue)
+ print "[AutomaticVolumeAdjustment] Change volume for service: %s (-%d) to %d"%(ServiceReference(self.session.nav.getCurrentlyPlayingServiceReference()).getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', ''), self.lastAdjustedValue, self.volctrl.getVolume())
+ self.lastAdjustedValue = 0 # mpeg audio, no delta here
+ # save new volume in config
+ config.audio.volume.value = self.volctrl.getVolume()
+ config.audio.volume.save()
+ else:
+ # starting plugin, if service audio is ac3 or dts --> get delta from config...volume value is set by enigma2-system at start
+ if currentAC3DTS:
+ self.lastAdjustedValue = self.serviceList.get(self.session.nav.getCurrentlyPlayingServiceReference().toString(), self.defaultValue)
+ self.currentVolume = self.volctrl.getVolume() # ac3||dts service , save current volume
+ self.pluginStarted = True # plugin started...
+
+ def isCurrentAudioAC3DTS(self):
+ service = self.session.nav.getCurrentService()
+ audio = service.audioTracks()
+ if audio:
+ try: # uhh, servicemp3 leads sometimes to OverflowError Error
+ tracknr = audio.getCurrentTrack()
+ i = audio.getTrackInfo(tracknr)
+ description = i.getDescription();
+ if "AC3" in description or "DTS" in description:
+ return True
+ except:
+ return False
+ return False
+
+def autostart(reason, **kwargs):
+ if "session" in kwargs and automaticvolumeadjustment is None:
+ global automaticvolumeadjustment
+ session = kwargs["session"]
+ automaticvolumeadjustment = AutomaticVolumeAdjustment(session)
+
+def setup(session, **kwargs):
+ session.open(AutomaticVolumeAdjustmentConfigScreen) # start setup
+
+def startSetup(menuid):
+ if menuid != "system": # show setup only in system level menu
+ return []
+ return [(_("Automatic Volume Adjustment"), setup, "AutomaticVolumeAdjustment", 46)]
+
+def Plugins(**kwargs):
+ return [PluginDescriptor(where = [PluginDescriptor.WHERE_SESSIONSTART], fnc = autostart), PluginDescriptor(name="Automatic Volume Adjustment", description=_("Automatic Volume Adjustment"), where = PluginDescriptor.WHERE_MENU, fnc=startSetup) ]
+
--- /dev/null
+# -*- coding: utf-8 -*-
+#
+# AutomaticVolumeAdjustment E2
+#
+# $Id$
+#
+# Coded by Dr.Best (c) 2009
+# Support: www.dreambox-tools.info
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+
+from enigma import eListboxPythonMultiContent, gFont, RT_HALIGN_LEFT, \
+ RT_VALIGN_CENTER
+from Screens.Screen import Screen
+from Screens.MessageBox import MessageBox
+from Components.MenuList import MenuList
+from Components.Sources.StaticText import StaticText
+from Components.ActionMap import ActionMap
+from Components.ConfigList import ConfigList, ConfigListScreen
+from Components.config import ConfigSubsection, ConfigText, \
+ getConfigListEntry, config, ConfigInteger, Config, ConfigSubList, ConfigDirectory, NoSave, ConfigYesNo
+from os import path as os_path, open as os_open, close as os_close, O_RDWR as os_O_RDWR, O_CREAT as os_O_CREAT
+from Screens.ChannelSelection import SimpleChannelSelection
+from enigma import eServiceReference
+from ServiceReference import ServiceReference
+
+import plugin as AutomaticVolumeAdjustmentPlugin # import to submit config-values
+
+class AutomaticVolumeAdjustmentConfig():
+ def __init__(self):
+ self.CONFIG_FILE = '/usr/lib/enigma2/python/Plugins/SystemPlugins/AutomaticVolumeAdjustment/config'
+ # load config file
+ self.loadConfigFile()
+
+ # load config file and initialize
+ def loadConfigFile(self):
+ print "[AutomaticVolumeAdjustmentConfig] Loading config file..."
+ self.config = Config()
+ if not os_path.exists(self.CONFIG_FILE):
+ fd = os_open( self.CONFIG_FILE, os_O_RDWR|os_O_CREAT)
+ os_close( fd )
+ self.config.loadFromFile(self.CONFIG_FILE)
+ self.config.entriescount = ConfigInteger(0)
+ self.config.Entries = ConfigSubList()
+ self.config.enable = ConfigYesNo(default = False)
+ self.config.adustvalue = ConfigInteger(default=25, limits=(0,50))
+ self.initConfig()
+
+ def initConfig(self):
+ count = self.config.entriescount.value
+ if count != 0:
+ i = 0
+ while i < count:
+ self.initEntryConfig()
+ i += 1
+ print "[AutomaticVolumeAdjustmentConfig] Loaded %s entries from config file..." % count
+
+ def initEntryConfig(self):
+ self.config.Entries.append(ConfigSubsection())
+ i = len(self.config.Entries) - 1
+ self.config.Entries[i].servicereference = ConfigText(default = "")
+ self.config.Entries[i].name = NoSave(ConfigDirectory(default = _("Press OK to select a service")))
+ self.config.Entries[i].adjustvalue = ConfigInteger(default=25, limits=(5,50))
+ return self.config.Entries[i]
+
+ def remove(self, configItem):
+ self.config.entriescount.value = self.config.entriescount.value - 1
+ self.config.entriescount.save()
+ self.config.Entries.remove(configItem)
+ self.config.Entries.save()
+ self.save()
+
+ def save(self):
+ print "[AutomaticVolumeAdjustmentConfig] saving config file..."
+ self.config.saveToFile(self.CONFIG_FILE)
+
+class AutomaticVolumeAdjustmentConfigScreen(ConfigListScreen, Screen):
+ skin = """
+ <screen name="AutomaticVolumeAdjustmentConfigScreen" position="center,center" size="550,400">
+ <widget name="config" position="20,10" size="520,330" scrollbarMode="showOnDemand" />
+ <ePixmap position="0,350" zPosition="4" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" />
+ <ePixmap position="140,350" zPosition="4" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" />
+ <ePixmap position="280,350" zPosition="4" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" />
+ <ePixmap position="420,350" zPosition="4" size="140,40" pixmap="skin_default/buttons/blue.png" transparent="1" alphatest="on" />
+
+ <widget source="key_red" render="Label" position="0,350" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+ <widget source="key_green" render="Label" position="140,350" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+ <widget render="Label" source="key_blue" position="420,350" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+ </screen>"""
+
+ def __init__(self, session):
+ Screen.__init__(self, session)
+ self.title = _("Automatic Volume Adjustment - Config")
+ self["actions"] = ActionMap(["SetupActions", "ColorActions"],
+ {
+ "green": self.keySave,
+ "red": self.keyCancel,
+ "blue": self.blue,
+ "cancel": self.keyCancel,
+ }, -2)
+ self["key_red"] = StaticText(_("Cancel"))
+ self["key_green"] = StaticText(_("OK"))
+ self["key_blue"] = StaticText(_("Services"))
+ self.configVA = AutomaticVolumeAdjustmentConfig()
+ self.list = []
+ self.list.append(getConfigListEntry(_("Enable"), self.configVA.config.enable))
+ self.list.append(getConfigListEntry(_("Default volume adjustment value for AC3/DTS"), self.configVA.config.adustvalue))
+ ConfigListScreen.__init__(self, self.list, session)
+
+ def blue(self):
+ self.session.open(AutomaticVolumeAdjustmentEntriesListConfigScreen, self.configVA)
+
+ def keySave(self):
+ for x in self["config"].list:
+ x[1].save()
+ self.configVA.save()
+ if AutomaticVolumeAdjustmentPlugin.automaticvolumeadjustment is not None:
+ AutomaticVolumeAdjustmentPlugin.automaticvolumeadjustment.initializeConfigValues(self.configVA, True) # submit config values
+ self.close()
+
+ def keyCancel(self):
+ ConfigListScreen.cancelConfirm(self, True)
+
+
+class AutomaticVolumeAdjustmentEntriesListConfigScreen(Screen):
+ skin = """
+ <screen position="center,center" size="550,400">
+ <widget render="Label" source="name" position="5,0" size="350,50" font="Regular;20" halign="left"/>
+ <widget render="Label" source="adjustvalue" position="355,0" size="200,50" font="Regular;20" halign="left"/>
+ <widget name="entrylist" position="0,50" size="550,300" scrollbarMode="showOnDemand"/>
+ <widget render="Label" source="key_red" position="0,350" size="140,40" zPosition="5" valign="center" halign="center" backgroundColor="red" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+ <widget source="key_green" render="Label" position="140,350" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+ <widget render="Label" source="key_yellow" position="280,350" size="140,40" zPosition="5" valign="center" halign="center" backgroundColor="yellow" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+ <widget render="Label" source="key_blue" position="420,350" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+ <ePixmap position="0,350" zPosition="4" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" />
+ <ePixmap position="140,350" zPosition="4" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" />
+ <ePixmap position="280,350" zPosition="4" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" />
+ <ePixmap position="420,350" zPosition="4" size="140,40" pixmap="skin_default/buttons/blue.png" transparent="1" alphatest="on" />
+ </screen>"""
+
+ def __init__(self, session, configVA):
+ Screen.__init__(self, session)
+ self.title = _("Automatic Volume Adjustment - Service Config")
+ self["name"] = StaticText(_("Servicename"))
+ self["adjustvalue"] = StaticText(_("Adjustment value"))
+ self["key_red"] = StaticText(_("Add"))
+ self["key_green"] = StaticText(_("OK"))
+ self["key_yellow"] = StaticText(_("Edit"))
+ self["key_blue"] = StaticText(_("Delete"))
+ self["entrylist"] = AutomaticVolumeAdjustmentEntryList([])
+ self["actions"] = ActionMap(["WizardActions","MenuActions","ShortcutActions"],
+ {
+ "ok" : self.keyOK,
+ "back" : self.keyClose,
+ "red" : self.keyRed,
+ "green": self.keyClose,
+ "yellow": self.keyYellow,
+ "blue": self.keyDelete,
+ }, -1)
+ self["entrylist"].setConfig(configVA)
+ self.updateList()
+
+ def updateList(self):
+ self["entrylist"].buildList()
+
+ def keyClose(self):
+ self.close(-1, None)
+
+ def keyRed(self):
+ self.session.openWithCallback(self.updateList,AutomaticVolumeAdjustmentEntryConfigScreen,None, self["entrylist"].configVA)
+
+ def keyOK(self):
+ try:sel = self["entrylist"].l.getCurrentSelection()[0]
+ except: sel = None
+ self.close(self["entrylist"].getCurrentIndex(), sel)
+
+ def keyYellow(self):
+ try:sel = self["entrylist"].l.getCurrentSelection()[0]
+ except: sel = None
+ if sel is None:
+ return
+ self.session.openWithCallback(self.updateList,AutomaticVolumeAdjustmentEntryConfigScreen,sel, self["entrylist"].configVA)
+
+ def keyDelete(self):
+ try:sel = self["entrylist"].l.getCurrentSelection()[0]
+ except: sel = None
+ if sel is None:
+ return
+ self.session.openWithCallback(self.deleteConfirm, MessageBox, _("Do you really want to delete this entry?"))
+
+ def deleteConfirm(self, result):
+ if not result:
+ return
+ sel = self["entrylist"].l.getCurrentSelection()[0]
+ self["entrylist"].configVA.remove(sel)
+ if AutomaticVolumeAdjustmentPlugin.automaticvolumeadjustment is not None:
+ AutomaticVolumeAdjustmentPlugin.automaticvolumeadjustment.initializeConfigValues(self["entrylist"].configVA, True) # submit config values
+ self.updateList()
+
+class AutomaticVolumeAdjustmentEntryList(MenuList):
+ def __init__(self, list, enableWrapAround = True):
+ MenuList.__init__(self, list, enableWrapAround, eListboxPythonMultiContent)
+ self.l.setFont(0, gFont("Regular", 20))
+ self.l.setFont(1, gFont("Regular", 18))
+ self.configVA = None
+
+ def postWidgetCreate(self, instance):
+ MenuList.postWidgetCreate(self, instance)
+ instance.setItemHeight(20)
+
+ def getCurrentIndex(self):
+ return self.instance.getCurrentIndex()
+
+ def setConfig(self, configVA):
+ self.configVA = configVA
+
+ def buildList(self):
+ list = []
+ for c in self.configVA.config.Entries:
+ c.name.value = ServiceReference(eServiceReference(c.servicereference.value)).getServiceName()
+ res = [
+ c,
+ (eListboxPythonMultiContent.TYPE_TEXT, 5, 0, 350, 20, 1, RT_HALIGN_LEFT|RT_VALIGN_CENTER, c.name.value),
+ (eListboxPythonMultiContent.TYPE_TEXT, 355, 0,200, 20, 1, RT_HALIGN_LEFT|RT_VALIGN_CENTER, str(c.adjustvalue.value)),
+ ]
+ list.append(res)
+ self.list = list
+ self.l.setList(list)
+ self.moveToIndex(0)
+
+class AutomaticVolumeAdjustmentEntryConfigScreen(ConfigListScreen, Screen):
+ skin = """
+ <screen name="AutomaticVolumeAdjustmentEntryConfigScreen" position="center,center" size="550,400">
+ <widget name="config" position="20,10" size="520,330" scrollbarMode="showOnDemand" />
+ <ePixmap position="0,350" zPosition="4" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" />
+ <ePixmap position="140,350" zPosition="4" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" />
+ <ePixmap position="280,350" zPosition="4" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" />
+ <ePixmap position="420,350" zPosition="4" size="140,40" pixmap="skin_default/buttons/blue.png" transparent="1" alphatest="on" />
+
+ <widget source="key_red" render="Label" position="0,350" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+ <widget source="key_green" render="Label" position="140,350" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
+ </screen>"""
+
+ def __init__(self, session, entry, configVA):
+ Screen.__init__(self, session)
+ self.title = _("Automatic Volume Adjustment - Entry Config")
+ self["actions"] = ActionMap(["SetupActions", "ColorActions"],
+ {
+ "green": self.keySave,
+ "red": self.keyCancel,
+ "cancel": self.keyCancel,
+ "ok": self.keySelect,
+ }, -2)
+ self["key_red"] = StaticText(_("Cancel"))
+ self["key_green"] = StaticText(_("OK"))
+ self.configVA = configVA
+ if entry is None:
+ self.newmode = 1
+ self.current = self.configVA.initEntryConfig()
+ else:
+ self.newmode = 0
+ self.current = entry
+ self.list = [ ]
+ self.service = getConfigListEntry(_("Servicename"), self.current.name)
+ self.list.append(self.service)
+ self.list.append(getConfigListEntry(_("Adjustment value"), self.current.adjustvalue))
+ ConfigListScreen.__init__(self, self.list, session)
+
+ def keySelect(self):
+ cur = self["config"].getCurrent()
+ if cur == self.service:
+ self.session.openWithCallback(self.channelSelected, ConfigChannelSelection)
+
+ def channelSelected(self, ref = None):
+ if ref:
+ self.current.name.value = ServiceReference(ref).getServiceName()
+ self.current.servicereference.value = ref.toString()
+ self.current.save()
+
+ def keySave(self):
+ if self.current.servicereference.value:
+ if self.newmode == 1:
+ self.configVA.config.entriescount.value = self.configVA.config.entriescount.value + 1
+ self.configVA.config.entriescount.save()
+ for x in self["config"].list:
+ x[1].save()
+ self.configVA.save()
+ if AutomaticVolumeAdjustmentPlugin.automaticvolumeadjustment is not None:
+ AutomaticVolumeAdjustmentPlugin.automaticvolumeadjustment.initializeConfigValues(self.configVA, True) # submit config values
+ self.close()
+ else:
+ self.session.open(MessageBox, _("You must select a valid service!"), type = MessageBox.TYPE_INFO)
+
+ def keyCancel(self):
+ if self.newmode == 1:
+ self.configVA.remove(self.current)
+ ConfigListScreen.cancelConfirm(self, True)
+
+class ConfigChannelSelection(SimpleChannelSelection):
+ def __init__(self, session):
+ SimpleChannelSelection.__init__(self, session, _("Channel Selection"))
+ self.skinName = ["SimpleChannelSelection"]
+ self["ChannelSelectEPGActions"] = ActionMap(["ChannelSelectEPGActions"],
+ {
+ "showEPGList": self.channelSelected
+ })
+
+ def channelSelected(self):
+ ref = self.getCurrentSelection()
+ if (ref.flags & 7) == 7:
+ self.enterPath(ref)
+ elif not (ref.flags & eServiceReference.isMarker):
+ self.close(ref)
\ No newline at end of file