Version 0.9: Correct issue, when global delay was set. Removed all the filehandling...
[enigma2-plugins.git] / ac3lipsync / src / AC3main.py
1 from AC3utils import AC3, PCM, AC3PCM
2 from AC3delay import AC3delay
3 from Components.ActionMap import ActionMap, NumberActionMap
4 from Components.Button import Button
5 from Components.ConfigList import ConfigListScreen
6 from Components.Label import Label,MultiColorLabel
7 from Components.ProgressBar import ProgressBar
8 from Components.config import config
9 from enigma import eDVBDB
10 from Screens.ChoiceBox import ChoiceBox
11 from Screens.MessageBox import MessageBox
12 from Screens.Screen import Screen
13 from Screens.InfoBarGenerics import InfoBarAudioSelection
14 from ServiceReference import ServiceReference
15 from __init__ import _
16 import os
17
18 class AC3LipSync(Screen,InfoBarAudioSelection):
19     skin = """
20         <screen position="center,472" size="600,74" title="AC3 Lip Sync" zPosition="1" >
21             <widget name="AudioDelayText" zPosition="2" position="5,0" size="180,21" font="Regular;21" foregroundColors="#ffffff,#ffa323" />
22             <ePixmap pixmap="/usr/lib/enigma2/python/Plugins/Extensions/AC3LipSync/img/AC3LipSyncBarBG.png" zPosition="2" position="190,0" size="370,21" alphatest="on" transparent="1" />
23             <widget name="AudioSlider" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/AC3LipSync/img/AC3LipSyncBar.png" zPosition="3" position="190,0" size="370,21" transparent="1" />
24             <widget name="AudioSliderText" zPosition="4" position="190,0" size="370,21" font="Regular;18" halign="center" valign="center" transparent="1" />
25             <widget name="ServiceInfoText" zPosition="4" position="5,26" size="180,21" font="Regular;18" foregroundColor="#ffffff" />
26             <widget name="ServiceInfo" zPosition="4" position="190,26" size="180,21" font="Regular;18" foregroundColor="#cccccc" />
27             <widget name="AC3DelayInfoText" zPosition="4" position="380,26" size="48,21" font="Regular;18" foregroundColor="#ffffff" />
28             <widget name="AC3DelayInfo" zPosition="4" position="430,26" size="50,21" font="Regular;18" foregroundColor="#cccccc" />
29             <widget name="PCMDelayInfoText" zPosition="4" position="490,26" size="48,21" font="Regular;18" foregroundColor="#ffffff" />
30             <widget name="PCMDelayInfo" zPosition="4" position="540,26" size="50,21" font="Regular;18" foregroundColor="#cccccc" />
31             <ePixmap pixmap="/usr/lib/enigma2/python/Plugins/Extensions/AC3LipSync/img/key-red.png" position="5,52" zPosition="5" size="20,20" transparent="1" alphatest="on" />
32             <ePixmap pixmap="/usr/lib/enigma2/python/Plugins/Extensions/AC3LipSync/img/key-green.png" position="150,52" zPosition="5" size="20,20" transparent="1" alphatest="on" />
33             <ePixmap pixmap="/usr/lib/enigma2/python/Plugins/Extensions/AC3LipSync/img/key-yellow.png" position="295,52" zPosition="5" size="20,20" transparent="1" alphatest="on" />
34             <ePixmap pixmap="/usr/lib/enigma2/python/Plugins/Extensions/AC3LipSync/img/key-blue.png" position="440,52" zPosition="5" size="20,20" transparent="1" alphatest="on" />
35             <widget name="key_red" position="30,52" zPosition="1" size="115,21"
36                 font="Regular;16" valign="center" halign="left" transparent="1"
37                 shadowColor="#000000" shadowOffset="-1,-1" />
38             <widget name="key_green" position="175,52" zPosition="1" size="115,21"
39                 font="Regular;16" valign="center" halign="left" transparent="1"
40                 shadowColor="#000000" shadowOffset="-1,-1" />
41             <widget name="key_yellow" position="320,52" zPosition="1" size="115,21"
42                 font="Regular;16" valign="center" halign="left" transparent="1"
43                 shadowColor="#000000" shadowOffset="-1,-1" />
44             <widget name="key_blue" position="465,52" zPosition="1" size="115,21"
45                 font="Regular;16" valign="center" halign="left" transparent="1"
46             shadowColor="#000000" shadowOffset="-1,-1" />
47         </screen>"""
48
49     def __init__(self, session, args = None):
50         Screen.__init__(self, session)
51         self.onShow.append(self.__onShow)
52
53         #Initialisiere Infobargenerics
54         InfoBarAudioSelection.__init__(self)
55
56         # Configuration values
57         self.upperBound = int(config.plugins.AC3LipSync.outerBounds.getValue())
58         self.lowerBound = -1 * self.upperBound
59         self.arrowStepSize = int(config.plugins.AC3LipSync.arrowStepSize.getValue())
60         self.stepSize = {}
61         self.stepSize["3"] = int(config.plugins.AC3LipSync.stepSize13.getValue())
62         self.stepSize["1"] = -1 * self.stepSize["3"]
63         self.stepSize["6"] = int(config.plugins.AC3LipSync.stepSize46.getValue())
64         self.stepSize["4"] = -1 * self.stepSize["6"]
65         self.stepSize["9"] = int(config.plugins.AC3LipSync.stepSize79.getValue())
66         self.stepSize["7"] = -1 * self.stepSize["9"]
67         self.keyStep = {}
68         self.keyStep["0"] = 0
69         self.keyStep["2"] = int(config.plugins.AC3LipSync.absoluteStep2.getValue()) 
70         self.keyStep["5"] = int(config.plugins.AC3LipSync.absoluteStep5.getValue()) 
71         self.keyStep["8"] = int(config.plugins.AC3LipSync.absoluteStep8.getValue()) 
72
73         # AC3delay instance
74         self.AC3delay = AC3delay()
75
76         #Screen elements
77
78         #Slider
79
80         for sAudio in AC3PCM:
81             self[sAudio+"Slider"] = ProgressBar()
82             self[sAudio+"SliderText"] = Label(_("%i ms")%0)
83             self[sAudio+"DelayText"] = MultiColorLabel( _("%s delay:")%sAudio)
84             self[sAudio+"DelayInfoText"] = Label( _("%s:")%sAudio)
85             self[sAudio+"DelayInfo"] = Label(_("%i ms")%0)
86
87         self["AudioSlider"] = ProgressBar()
88         self["AudioSliderText"] = Label(_("%i ms")%0)
89         self["AudioDelayText"] = MultiColorLabel( _("%s delay:")%self.AC3delay.whichAudio)
90         
91         #Service Information
92         self["ServiceInfoText"] = Label(_("Channel audio:"))
93         self["ServiceInfo"] = Label()
94         self.setChannelInfoText()
95
96         # Buttons
97         self["key_red"] = Label(_("Cancel"))
98         self["key_green"] = Label(_("OK"))
99         self["key_yellow"] = Label(_("Switch audio"))
100         self["key_blue"] = Label("")
101
102         # Last saved values
103         self.savedValue = {}
104         self.savedValue[AC3] = 0
105         self.savedValue[PCM] = 0
106
107         # Current Values
108         self.currentValue = {}
109         self.currentValue[AC3] = 0
110         self.currentValue[PCM] = 0
111
112         # Actions
113         self["actions"] = NumberActionMap(["WizardActions", "NumberActions", "ColorActions", "MenuActions"],
114         {
115             "menu": self.keyMenu,
116             "ok": self.keyOk,
117             "back": self.keyCancel,
118             "left": self.keyLeft,
119             "right": self.keyRight,
120             "up": self.keyUp,
121             "down": self.keyDown,
122             "red": self.keyCancel,
123             "green": self.keyOk,
124             "yellow": self.keyAudioSelection,
125             "1": self.keyNumberRelative,
126             "3": self.keyNumberRelative,
127             "4": self.keyNumberRelative,
128             "6": self.keyNumberRelative,
129             "7": self.keyNumberRelative,
130             "9": self.keyNumberRelative,
131             "0": self.keyNumberAbsolute,
132             "2": self.keyNumberAbsolute,
133             "5": self.keyNumberAbsolute,
134             "8": self.keyNumberAbsolute
135         }, -1)
136
137     def __onShow(self):
138         for sAudio in AC3PCM:
139             iDelay = self.AC3delay.getLamedbDelay(sAudio)
140             self[sAudio + "Slider"].setRange([(self.lowerBound), (self.upperBound)])
141             self[sAudio + "Slider"].setValue(iDelay-self.lowerBound)
142             self[sAudio + "SliderText"].setText(_("%i ms") %iDelay)
143             self.savedValue[sAudio] = iDelay
144             self.currentValue[sAudio] = iDelay
145             if sAudio == self.AC3delay.whichAudio: 
146                 self["AudioSlider"].setRange([(self.lowerBound), (self.upperBound)])
147                 self["AudioSlider"].setValue(iDelay-self.lowerBound)
148                 self["AudioSliderText"].setText(_("%i ms")%iDelay)
149
150     def keyUp(self):
151         self.AC3delay.whichAudio = AC3
152         self.setActiveSlider(AC3)
153
154     def keyDown(self):
155         self.AC3delay.whichAudio = PCM
156         self.setActiveSlider(PCM)
157
158     def setActiveSlider(self,sAudio):
159         if self.AC3delay.whichAudio == AC3:
160             self["AC3DelayText"].setForegroundColorNum(1)
161             self["PCMDelayText"].setForegroundColorNum(0)
162         else:
163             self["AC3DelayText"].setForegroundColorNum(0)
164             self["PCMDelayText"].setForegroundColorNum(1)                        
165         iDelay = self[sAudio+"Slider"].getValue()
166         iCurDelay = iDelay + self.lowerBound
167         self["AudioSlider"].setValue(iDelay)
168         self["AudioSliderText"].setText(_("%i ms")%iCurDelay)
169         self["AudioDelayText"].setText(_("%s delay:")%sAudio)
170
171     def keyLeft(self):
172         self.changeSliderValue(-1 * self.arrowStepSize)
173         
174     def keyRight(self):
175         self.changeSliderValue(self.arrowStepSize)
176
177     def keyNumberAbsolute(self, number):
178         sAudio = self.AC3delay.whichAudio
179         sNumber = str(number)
180         iSliderValue = self.keyStep[sNumber]-self.lowerBound
181         self.setSliderInfo(iSliderValue)
182         self.AC3delay.setLamedbDelay(sAudio, self.currentValue[sAudio], True)
183
184     def keyNumberRelative(self, number):
185         sNumber = str(number)
186         self.changeSliderValue(self.stepSize[sNumber])
187
188     def changeSliderValue(self,iValue):
189         sAudio = self.AC3delay.whichAudio
190         iSliderValue = int(self[sAudio+"Slider"].getValue())
191         iSliderValue += iValue
192         if iSliderValue < 0:
193             iSliderValue = 0
194         elif iSliderValue > (self.upperBound - self.lowerBound):
195             iSliderValue = (self.upperBound - self.lowerBound)
196         self.setSliderInfo(iSliderValue)
197         self.AC3delay.setLamedbDelay(sAudio, self.currentValue[sAudio], True)        
198
199     def keyAudioSelection(self):
200         self.audioSelection()
201
202     def keyOk(self):
203         self.close()
204
205     def keyCancel(self):
206         for sAudio in AC3PCM:
207             iSliderValue = self.currentValue[sAudio]
208             if iSliderValue <> self.savedValue[sAudio]:
209                 self.AC3delay.whichAudio = sAudio
210                 self.AC3delay.setLamedbDelay(sAudio, self.savedValue[sAudio], False)
211         self.close()
212
213     def keyMenu(self):
214         sAudio = self.AC3delay.whichAudio
215         iDelay = self[sAudio+"Slider"].getValue()+self.lowerBound
216         keyList = [
217             (_("Save current %(audio)s delay of %(delay)i ms to key") %dict(audio=sAudio , delay=iDelay),"1")
218         ]
219
220         self.session.openWithCallback(self.DoShowMenu,ChoiceBox,_("Menu"),keyList)
221     
222     def DoShowMenu(self, answer):
223         if answer is not None:
224             if answer[1] == "1":
225                 self.menuSaveDelayToKey()
226             else:
227                 sResponse = _("Invalid selection")
228                 iType = MessageBox.TYPE_ERROR
229                 self.session.open(MessageBox, sResponse , iType)
230                 
231     def menuSaveDelayToKey(self):
232         sAudio = self.AC3delay.whichAudio
233         iDelay = self[sAudio+"Slider"].getValue()+self.lowerBound
234
235         AC3SetCustomValue(self.session,iDelay,self.keyStep)
236
237     def setSliderInfo(self, iDelay):
238         sAudio = self.AC3delay.whichAudio
239         self.currentValue[sAudio] = iDelay + self.lowerBound
240         iCurDelay = self.currentValue[sAudio]
241         self[sAudio+"Slider"].setValue(iDelay)
242         self[sAudio+"SliderText"].setText(_("%i ms")%iCurDelay)
243         self["AudioSlider"].setValue(iDelay)
244         self["AudioSliderText"].setText(_("%i ms")%iCurDelay)
245
246     def setChannelInfoText(self):
247         sActiveAudio = str(self.AC3delay.selectedAudioInfo[0])
248         sBitstreamDelay = _("%i ms") %self.AC3delay.lamedbDelay[AC3]
249         sPCMDelay = _("%i ms") %self.AC3delay.lamedbDelay[PCM]
250
251         self["ServiceInfo"].setText(sActiveAudio)
252         self["AC3DelayInfo"].setText(sBitstreamDelay)
253         self["PCMDelayInfo"].setText(sPCMDelay)
254
255     def audioSelected(self, audio):
256         InfoBarAudioSelection.audioSelected(self, audio)
257         if audio is not None:
258             self.AC3delay.getAudioInformation()
259             self.setChannelInfoText()
260             self.setActiveSlider(self.AC3delay.whichAudio)
261             
262 class AC3SetCustomValue:
263     def __init__(self, session, iDelay, keyStep):
264         self.keyStep = keyStep
265         self.session = session
266         self.iDelay = iDelay
267         self.session.openWithCallback(self.DoSetCustomValue,ChoiceBox,_("Select the key you want to set to %i ms") %(iDelay),self.getKeyList())
268
269     def getKeyList(self):
270         keyList = []
271         for i,iValue in self.keyStep.iteritems():
272             if i != "0":
273                 keyList.append((_("Key %(key)s (current value: %(value)i ms)") %dict(key=i, value=iValue),i))
274         return keyList
275
276     def DoSetCustomValue(self,answer):
277         if answer is None:
278             self.session.open(MessageBox,_("Setting key canceled"), MessageBox.TYPE_INFO)
279         elif answer[1] in ("2" , "5" , "8"):
280             if answer[1] == "2":
281                 config.plugins.AC3LipSync.absoluteStep2.setValue(self.iDelay)
282                 config.plugins.AC3LipSync.absoluteStep2.save()
283             elif  answer[1] == "5":
284                 config.plugins.AC3LipSync.absoluteStep5.setValue(self.iDelay)
285                 config.plugins.AC3LipSync.absoluteStep5.save()
286             elif  answer[1] == "8":
287                 config.plugins.AC3LipSync.absoluteStep8.setValue(self.iDelay)
288                 config.plugins.AC3LipSync.absoluteStep8.save()
289             self.keyStep[answer[1]] = self.iDelay
290             self.session.open(MessageBox,_("Key %(Key)s successfully set to %(delay)i ms") %dict(Key=answer[1],delay=self.iDelay), MessageBox.TYPE_INFO, 5)
291         else:
292             self.session.open(MessageBox,_("Invalid selection"), MessageBox.TYPE_ERROR, 5)