new:
[enigma2-plugins.git] / automaticvolumeadjustment / src / AutomaticVolumeAdjustment.py
1 # -*- coding: utf-8 -*-
2 #
3 #  AutomaticVolumeAdjustment E2
4 #
5 #  $Id$
6 #
7 #  Coded by Dr.Best (c) 2010
8 #  Support: www.dreambox-tools.info
9 #
10 #  This plugin is licensed under the Creative Commons 
11 #  Attribution-NonCommercial-ShareAlike 3.0 Unported 
12 #  License. To view a copy of this license, visit
13 #  http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter to Creative
14 #  Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
15 #
16 #  Alternatively, this plugin may be distributed and executed on hardware which
17 #  is licensed by Dream Multimedia GmbH.
18
19 #  This plugin is NOT free software. It is open source, you are allowed to
20 #  modify it (if you keep the license), but it may not be commercially 
21 #  distributed other than under the conditions noted above.
22 #
23 from Screens.Screen import Screen
24 from Components.ActionMap import ActionMap
25 from Components.Sources.StaticText import StaticText
26 from Components.config import config
27 from Components.ServiceEventTracker import ServiceEventTracker
28 from enigma import iPlayableService, iServiceInformation, eDVBVolumecontrol, eServiceCenter, eServiceReference
29 from ServiceReference import ServiceReference
30 from Components.VolumeControl import VolumeControl
31 from AutomaticVolumeAdjustmentConfig import AutomaticVolumeAdjustmentConfig
32
33 class AutomaticVolumeAdjustment(Screen):
34         instance = None
35         def __init__(self, session):
36                 self.session = session
37                 Screen.__init__(self, session)
38                 print "[AutomaticVolumeAdjustment] Starting AutomaticVolumeAdjustment..."
39                 self.__event_tracker = ServiceEventTracker(screen = self, eventmap =
40                         {
41                                 iPlayableService.evUpdatedInfo: self.__evUpdatedInfo,
42                                 iPlayableService.evStart: self.__evStart,
43                                 iPlayableService.evEnd: self.__evEnd
44                         })
45                 self.newService = False # switching flag
46                 self.pluginStarted = False # is plugin started?
47                 self.lastAdjustedValue = 0 # remember delta from last automatic volume up/down
48                 self.currentVolume = 0 # only set when AC3 or DTS is available
49                 self.enabled = False # AutomaticVolumeAdjustment enabled in setup?
50                 self.serviceList = { } # values from config
51                 configVA = AutomaticVolumeAdjustmentConfig() # get config values
52                 assert not AutomaticVolumeAdjustment.instance, "only one AutomaticVolumeAdjustment instance is allowed!"
53                 AutomaticVolumeAdjustment.instance = self # set instance
54                 self.volumeControlInstance = None # VolumeControlInstance
55                 self.currentAC3DTS = False # current service = AC3||DTS?
56                 self.initializeConfigValues(configVA, False)
57                 self.volctrl = eDVBVolumecontrol.getInstance()
58
59         def initializeConfigValues(self, configVA, fromOutside):
60                 print "[AutomaticVolumeAdjustment] initialize config values..."
61                 self.serviceList = { }
62                 for c in configVA.config.Entries:
63                         self.serviceList[c.servicereference.value] = int(c.adjustvalue.value)
64                 self.defaultValue = int(configVA.config.adustvalue.value)
65                 self.enabled = configVA.config.enable.value
66                 self.maxMPEGVolume = configVA.config.mpeg_max_volume.value
67                 self.showVolumeBar = configVA.config.show_volumebar.value
68                 VolumeControlInit(self.enabled, self.maxMPEGVolume) # overwrite VolumeControl Class, when max MPEG Volume was set (<> 100)
69                 if not self.pluginStarted and self.enabled and fromOutside:
70                         self.newService = True
71                         self.__evUpdatedInfo()
72                 
73         def __evEnd(self):
74                 if self.pluginStarted and self.enabled:
75                         # if played service had AC3||DTS audio and volume value was changed with RC, take new delta value from the config
76                         if self.currentVolume and self.volctrl.getVolume() != self.currentVolume:
77                                 self.lastAdjustedValue = self.serviceList.get(self.session.nav.getCurrentlyPlayingServiceReference().toString(), self.defaultValue)
78                                         
79         def __evStart(self):
80                 self.newService = True
81
82         def __evUpdatedInfo(self):
83                 if self.newService and self.session.nav.getCurrentlyPlayingServiceReference() and self.enabled:
84                         print "[AutomaticVolumeAdjustment] service changed"
85                         self.newService = False
86                         self.currentVolume = 0 # init
87                         self.currentAC3DTS = self.isCurrentAudioAC3DTS()
88                         if self.pluginStarted:
89                                 if self.currentAC3DTS: # ac3 dts?
90                                         vol = self.volctrl.getVolume()
91                                         currentvol = vol # remember current vol
92                                         vol -= self.lastAdjustedValue # go back to origin value first
93                                         ref = self.session.nav.getCurrentlyPlayingServiceReference()
94                                         if ref.getPath(): # check if a movie is playing
95                                                 # it is , get the eServicereference if available
96                                                 self.serviceHandler = eServiceCenter.getInstance()
97                                                 info = self.serviceHandler.info(ref)
98                                                 if info:
99                                                         ref = eServiceReference(info.getInfoString(ref, iServiceInformation.sServiceref)) # get new eServicereference from meta file
100                                         ajvol = self.serviceList.get(ref.toString(), self.defaultValue) # get delta from config
101                                         if vol >= 100 - ajvol: # check if delta + vol < 100
102                                                 ajvol = 100 - vol # correct delta value
103                                         self.lastAdjustedValue = ajvol # save delta value
104                                         if (ajvol !=0 or self.defaultValue == 0) and (vol+ajvol != currentvol): # only adjust volume when delta != 0 and current vol != new volume
105                                                 if ajvol == 0:
106                                                         ajvol = vol+self.lastAdjustedValue - currentvol # correction for debug -print only
107                                                 self.volctrl.setVolume(vol+self.lastAdjustedValue, vol+self.lastAdjustedValue)
108                                                 if self.volumeControlInstance is not None:
109                                                         self.volumeControlInstance.volumeDialog.setValue(vol+self.lastAdjustedValue)
110                                                         if self.showVolumeBar:
111                                                                 self.volumeControlInstance.volumeDialog.show()
112                                                                 self.volumeControlInstance.hideVolTimer.start(3000, True)
113                                                 print "[AutomaticVolumeAdjustment] Change volume for service: %s (+%d) to %d"%(ServiceReference(ref).getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', ''), ajvol, self.volctrl.getVolume())
114                                         self.currentVolume = self.volctrl.getVolume() # ac3||dts service , save current volume
115                                 else:
116                                         # mpeg or whatever audio
117                                         if self.lastAdjustedValue != 0:
118                                                 # go back to origin value
119                                                 vol = self.volctrl.getVolume()
120                                                 ajvol = vol-self.lastAdjustedValue
121                                                 if ajvol > self.maxMPEGVolume:
122                                                                 ajvol = self.maxMPEGVolume
123                                                 self.volctrl.setVolume(ajvol, ajvol)
124                                                 if self.volumeControlInstance is not None:
125                                                         self.volumeControlInstance.volumeDialog.setValue(ajvol)
126                                                         if self.showVolumeBar:
127                                                                 self.volumeControlInstance.volumeDialog.show()
128                                                                 self.volumeControlInstance.hideVolTimer.start(3000, True)
129                                                 print "[AutomaticVolumeAdjustment] Change volume for service: %s (-%d) to %d"%(ServiceReference(self.session.nav.getCurrentlyPlayingServiceReference()).getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', ''), vol-ajvol, self.volctrl.getVolume())
130                                                 self.lastAdjustedValue = 0 # mpeg audio, no delta here
131                                 # save new volume in config
132                                 config.audio.volume.value = self.volctrl.getVolume()
133                                 config.audio.volume.save()
134                         else:
135                                 # starting plugin, if service audio is ac3 or dts --> get delta from config...volume value is set by enigma2-system at start
136                                 if self.currentAC3DTS:
137                                         self.lastAdjustedValue = self.serviceList.get(self.session.nav.getCurrentlyPlayingServiceReference().toString(), self.defaultValue)
138                                         self.currentVolume = self.volctrl.getVolume() # ac3||dts service , save current volume
139                                 # only images >= 05.08.2010, must use try/except
140                                 try: self.volumeControlInstance = VolumeControl.instance
141                                 except: pass
142                                 self.pluginStarted = True # plugin started...
143
144         def isCurrentAudioAC3DTS(self):
145                 service = self.session.nav.getCurrentService()
146                 audio = service.audioTracks()
147                 if audio:
148                         try: # uhh, servicemp3 leads sometimes to OverflowError Error
149                                 tracknr = audio.getCurrentTrack()
150                                 i = audio.getTrackInfo(tracknr)
151                                 description = i.getDescription();
152                                 if "AC3" in description or "DTS" in description:
153                                         return True
154                         except:
155                                 return False
156                 return False
157
158
159 # VolumeControl Class --> overwrite setVolume
160 # only for max. mpeg-volume restriction
161 baseVolumeControl_setVolume = None
162                 
163 def VolumeControlInit(enabled, maxVolume):
164         global baseVolumeControl_setVolume
165         if baseVolumeControl_setVolume is None:
166                 baseVolumeControl_setVolume = VolumeControl.setVolume
167         if enabled and maxVolume <> 100:
168                 VolumeControl.setVolume = AVA_setVolume
169                 VolumeControl.maxVolume = maxVolume
170         else:
171                 VolumeControl.setVolume = baseVolumeControl_setVolume
172                 baseVolumeControl_setVolume = None
173
174 def AVA_setVolume(self, direction):
175         ok = True
176         if direction > 0:
177                 oldvol = self.volctrl.getVolume()
178                 if not AutomaticVolumeAdjustment.instance.currentAC3DTS:        
179                         if oldvol+1 > self.maxVolume:
180                                 ok = False
181                                 self.volumeDialog.setValue(oldvol)
182                                 self.volumeDialog.show()
183                                 self.hideVolTimer.start(3000, True)
184         if ok:
185                 baseVolumeControl_setVolume(self, direction)