3adf1428763a8ad43cedc5f2d9b4d23d20582e8a
[vuplus_dvbapp-plugin] / ac3lipsync / src / AC3main.py
1 from AC3utils import AC3, PCM, AC3PCM, lFileDelay, dec2hex, hex2dec
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="60,420" size="600,100" title="AC3 Lip Sync" zPosition="1" >
21             <widget name="AC3DelayText" 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="AC3Slider" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/AC3LipSync/img/AC3LipSyncBar.png" zPosition="3" position="190,0" size="370,21" transparent="1" />
24             <widget name="AC3SliderText" zPosition="4" position="190,0" size="370,21" font="Regular;18" halign="center" valign="center" transparent="1" />
25             <widget name="PCMDelayText" zPosition="2" position="5,26" size="180,21" font="Regular;21" foregroundColors="#ffffff,#ffa323" />
26             <ePixmap pixmap="/usr/lib/enigma2/python/Plugins/Extensions/AC3LipSync/img/AC3LipSyncBarBG.png" zPosition="2" position="190,26" size="370,21" alphatest="on" transparent="1" />
27             <widget name="PCMSlider" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/AC3LipSync/img/AC3LipSyncBar.png" zPosition="3" position="190,26" size="370,21" transparent="1" />
28             <widget name="PCMSliderText" zPosition="4" position="190,26" size="370,21" font="Regular;18" halign="center" valign="center" transparent="1" />
29             <widget name="ServiceInfoText" zPosition="4" position="5,52" size="180,21" font="Regular;18" foregroundColor="#ffffff" />
30             <widget name="ServiceInfo" zPosition="4" position="190,52" size="180,21" font="Regular;18" foregroundColor="#cccccc" />
31             <widget name="AC3DelayInfoText" zPosition="4" position="380,52" size="48,21" font="Regular;18" foregroundColor="#ffffff" />
32             <widget name="AC3DelayInfo" zPosition="4" position="430,52" size="50,21" font="Regular;18" foregroundColor="#cccccc" />
33             <widget name="PCMDelayInfoText" zPosition="4" position="490,52" size="48,21" font="Regular;18" foregroundColor="#ffffff" />
34             <widget name="PCMDelayInfo" zPosition="4" position="540,52" size="50,21" font="Regular;18" foregroundColor="#cccccc" />
35             <ePixmap pixmap="/usr/lib/enigma2/python/Plugins/Extensions/AC3LipSync/img/key-red.png" position="5,78" zPosition="5" size="20,20" transparent="1" alphatest="on" />
36             <ePixmap pixmap="/usr/lib/enigma2/python/Plugins/Extensions/AC3LipSync/img/key-green.png" position="150,78" zPosition="5" size="20,20" transparent="1" alphatest="on" />
37             <ePixmap pixmap="/usr/lib/enigma2/python/Plugins/Extensions/AC3LipSync/img/key-yellow.png" position="295,78" zPosition="5" size="20,20" transparent="1" alphatest="on" />
38             <ePixmap pixmap="/usr/lib/enigma2/python/Plugins/Extensions/AC3LipSync/img/key-blue.png" position="440,78" zPosition="5" size="20,20" transparent="1" alphatest="on" />
39             <widget name="key_red" position="30,78" zPosition="1" size="115,21"
40                 font="Regular;16" valign="center" halign="left" transparent="1"
41                 shadowColor="#000000" shadowOffset="-1,-1" />
42             <widget name="key_green" position="175,78" zPosition="1" size="115,21"
43                 font="Regular;16" valign="center" halign="left" transparent="1"
44                 shadowColor="#000000" shadowOffset="-1,-1" />
45             <widget name="key_yellow" position="320,78" zPosition="1" size="115,21"
46                 font="Regular;16" valign="center" halign="left" transparent="1"
47                 shadowColor="#000000" shadowOffset="-1,-1" />
48             <widget name="key_blue" position="465,78" zPosition="1" size="115,21"
49                 font="Regular;16" valign="center" halign="left" transparent="1"
50             shadowColor="#000000" shadowOffset="-1,-1" />
51         </screen>"""
52
53     def __init__(self, session, args = None):
54         Screen.__init__(self, session)
55         self.onShow.append(self.__onShow)
56
57         #Initialisiere Infobargenerics
58         InfoBarAudioSelection.__init__(self)
59
60         # Configuration values
61         self.lowerBound = int(config.plugins.AC3LipSync.lowerBound.getValue())
62         self.upperBound = int(config.plugins.AC3LipSync.upperBound.getValue())
63         self.arrowStepSize = int(config.plugins.AC3LipSync.arrowStepSize.getValue())
64         self.stepSize = int(config.plugins.AC3LipSync.stepSize.getValue())
65
66         # AC3delay instance
67         self.AC3delay = AC3delay(self.session)
68
69         #Which Values do the number keys use
70         self.whichKeys = "Computed" # Computed = computed Values of keys, User = User set values of keys
71         self.whichKeyText = {}
72         self.whichKeyText["Computed"] = _("Switch to user key- delays")
73         self.whichKeyText["User"] = _("Switch to calculated key- delays")
74
75         #Screen elements
76
77         #Slider
78
79         for sAudio in AC3PCM:
80             self[sAudio+"Slider"] = ProgressBar()
81             self[sAudio+"SliderText"] = Label(_("%i ms")%0)
82             self[sAudio+"DelayText"] = MultiColorLabel( _("%s delay:")%sAudio)
83             self[sAudio+"DelayInfoText"] = Label( _("%s:")%sAudio)
84             self[sAudio+"DelayInfo"] = Label(_("%i ms")%0)
85
86         #Service Information
87         self["ServiceInfoText"] = Label(_("Channel audio:"))
88         self["ServiceInfo"] = Label()
89         self.setChannelInfoText()
90
91         # Buttons
92         self["key_red"] = Label(_("Cancel"))
93         self["key_green"] = Label(_("OK"))
94         self["key_yellow"] = Label(_("Switch audio"))
95         if self.AC3delay.bIsRecording == True:
96             self["key_blue"] = Label("")
97         else:
98             self["key_blue"] = Label(_("Save"))
99
100         # Last saved values
101         self.savedValue = {}
102         self.savedValue[AC3] = 0
103         self.savedValue[PCM] = 0
104
105         # Current Values
106         self.currentValue = {}
107         self.currentValue[AC3] = 0
108         self.currentValue[PCM] = 0
109
110         # Actions
111         self["actions"] = NumberActionMap(["WizardActions", "NumberActions", "ColorActions", "MenuActions"],
112         {
113             "menu": self.keyMenu,
114             "ok": self.keyOk,
115             "back": self.keyCancel,
116             "left": self.keyLeft,
117             "right": self.keyRight,
118             "up": self.keyUp,
119             "down": self.keyDown,
120             "red": self.keyCancel,
121             "green": self.keyOk,
122             "yellow": self.keyAudioSelection,
123             "blue": self.keySaveToLamedb,
124             "1": self.keyNumberGlobal,
125             "2": self.keyNumberGlobal,
126             "3": self.keyNumberGlobal,
127             "4": self.keyNumberGlobal,
128             "5": self.keyNumberGlobal,
129             "6": self.keyNumberGlobal,
130             "7": self.keyNumberGlobal,
131             "8": self.keyNumberGlobal,
132             "9": self.keyNumberGlobal,
133             "0": self.keyNumberGlobal
134         }, -1)
135
136     def __onShow(self):
137         for sAudio in lFileDelay.keys():
138             iDelay = self.AC3delay.getFileDelay(sAudio)
139             self[sAudio + "Slider"].setRange([(self.lowerBound), (self.upperBound)])
140             self[sAudio + "Slider"].setValue(iDelay-self.lowerBound)
141             self[sAudio + "SliderText"].setText(_("%i ms") %iDelay)
142             self.savedValue[sAudio] = iDelay
143             self.currentValue[sAudio] = iDelay
144             if self.AC3delay.whichAudio == AC3:
145                 self["AC3DelayText"].setForegroundColorNum(1)
146                 self["PCMDelayText"].setForegroundColorNum(0)
147             else:
148                 self["AC3DelayText"].setForegroundColorNum(0)
149                 self["PCMDelayText"].setForegroundColorNum(1)
150
151     def keyUp(self):
152         self.AC3delay.whichAudio = AC3
153         self["AC3DelayText"].setForegroundColorNum(1)
154         self["PCMDelayText"].setForegroundColorNum(0)
155
156     def keyDown(self):
157         self.AC3delay.whichAudio = PCM
158         self["AC3DelayText"].setForegroundColorNum(0)
159         self["PCMDelayText"].setForegroundColorNum(1)
160
161     def keyLeft(self):
162         sAudio = self.AC3delay.whichAudio
163         iSliderValue = int(self[sAudio+"Slider"].getValue())
164         iSliderValue -= self.arrowStepSize
165         if iSliderValue < 0:
166             iSliderValue = 0
167         self.setSliderInfo(iSliderValue)
168         self.AC3delay.setFileDelay(sAudio, self.currentValue[sAudio], True)
169
170     def keyRight(self):
171         sAudio = self.AC3delay.whichAudio
172         iSliderValue = int(self[sAudio+"Slider"].getValue())
173         if self.currentValue[sAudio] == 0:
174             iSliderValue = 0
175         iSliderValue += self.arrowStepSize
176         if iSliderValue > self.upperBound:
177             iSliderValue = self.upperBound
178         self.setSliderInfo(iSliderValue)
179         self.AC3delay.setFileDelay(sAudio, self.currentValue[sAudio], True)
180
181     def keyNumberGlobal(self, number):
182         sAudio = self.AC3delay.whichAudio
183         iNumber = int(number)
184         if iNumber == 0:
185             iSliderValue = 0
186             self.currentValue[sAudio] = 0
187         else:
188             if self.whichKeys == "Computed":
189                 iSliderValue = self.stepSize*iNumber
190             else:
191                 iSliderValue = int(config.plugins.AC3LipSync.keySteps[iNumber].stepSize.getValue())-self.lowerBound
192                 if iSliderValue < 0:
193                     iSliderValue = 0
194         self.setSliderInfo(iSliderValue)
195         self.AC3delay.setFileDelay(sAudio, self.currentValue[sAudio], True)
196
197     def keyAudioSelection(self):
198         self.audioSelection()
199
200     def keyOk(self):
201         self.close()
202
203     def keyCancel(self):
204         for sAudio in lFileDelay.keys():
205             iSliderValue = self.currentValue[sAudio]
206             if iSliderValue <> self.savedValue[sAudio]:
207                 self.AC3delay.whichAudio = sAudio
208                 self.AC3delay.setFileDelay(sAudio, self.savedValue[sAudio], False)
209         self.close()
210
211     def keyMenu(self):
212         sAudio = self.AC3delay.whichAudio
213         iDelay = self[sAudio+"Slider"].getValue()+self.lowerBound
214         keyList = [
215             (_("Save current %(audio)s delay of %(delay)i ms to key") %dict(audio=sAudio , delay=iDelay),"1"),
216             (self.whichKeyText[self.whichKeys],"2")
217         ]
218
219         self.session.openWithCallback(self.DoShowMenu,ChoiceBox,_("Menu"),keyList)
220
221     def DoShowMenu(self, answer):
222         if answer is not None:
223             if answer[1] == "1":
224                 self.menuSaveDelayToKey()
225             elif answer[1] == "2":
226                 self.menuSwitchKeyValues()
227             else:
228                 sResponse = _("Invalid selection")
229                 iType = MessageBox.TYPE_ERROR
230                 self.session.open(MessageBox, sResponse , iType)
231                 
232     def menuSwitchKeyValues(self):
233         if self.whichKeys == "Computed":
234             self.whichKeys = "User"
235         else:
236             self.whichKeys = "Computed"
237         self["key_blue"].setText(self.whichKeyText[self.whichKeys])
238
239     def menuSaveDelayToKey(self):
240         sAudio = self.AC3delay.whichAudio
241         iDelay = self[sAudio+"Slider"].getValue()+self.lowerBound
242         AC3SetCustomValue(self.session,iDelay)
243
244     def keySaveToLamedb(self):
245         if self.AC3delay.bIsRecording == False:
246             keyList = [
247                 (_("Save %s delay")%AC3,"1"),
248                 (_("Save %s delay")%PCM,"2"),
249                 (_("Save both delays"),"3")
250             ]
251
252             self.session.openWithCallback(self.DoSaveLamedb,ChoiceBox,_("Which delays do you want to set"),keyList)
253
254     def DoSaveLamedb(self, answer):
255         sNewLine = ""
256         sResponse = ""
257         bOk = True
258         iType = MessageBox.TYPE_INFO
259         aSetAudio = []
260         if answer is not None:
261             if answer[1] in ("1","2","3"):
262                 bSetAC3 = False
263                 bSetPCM = False
264                 self.AC3delay.initAudio()
265                 if self.AC3delay.iAudioDelay is not None:
266                     if answer[1] in ("1","3"):
267                         iDelay = int( self.AC3delay.getLamedbDelay(AC3) )
268                         aSetAudio.append((AC3,iDelay))
269                         bSetAC3 = True
270                     if answer[1] in ("2","3"):
271                         iDelay = int( self.AC3delay.getLamedbDelay(PCM) )
272                         aSetAudio.append((PCM,iDelay))
273                         bSetPCM = True
274                     for vAudio in aSetAudio:
275                         sAudio = vAudio[0]
276                         iChannelDelay = int(vAudio[1])
277                         iCurDelay = self.currentValue[sAudio]
278                         iNewDelay = iCurDelay
279                         if sAudio == AC3:
280                             self.AC3delay.iAudioDelay.setAC3Delay(iNewDelay)
281                         else:
282                             self.AC3delay.iAudioDelay.setPCMDelay(iNewDelay)
283                         self.AC3delay.lamedbDelay[sAudio] = iNewDelay
284                         sResponse = sResponse + sNewLine + _("Saved %(audio)s value: %(delay)i ms") %dict(audio=sAudio,delay=iNewDelay)
285                         sNewLine = "\n"
286                 self.AC3delay.deleteAudio()
287             else:
288                 sResponse = _("Invalid selection")
289                 iType = MessageBox.TYPE_ERROR
290             if bOk == True:
291                 self.session.open(MessageBox, sResponse , iType)
292         self.setChannelInfoText()
293
294     def setSliderInfo(self, iDelay):
295         sAudio = self.AC3delay.whichAudio
296         if iDelay == 0:
297             if self.currentValue[sAudio] >= self.lowerBound:
298                 self.currentValue[sAudio] = self.lowerBound
299             else:
300                 self.currentValue = 0
301         else:
302             self.currentValue[sAudio] = iDelay + self.lowerBound
303         self[sAudio+"Slider"].setValue(iDelay)
304         iCurDelay = self.currentValue[sAudio]
305         self[sAudio+"SliderText"].setText(_("%i ms")%iCurDelay)
306
307     def setChannelInfoText(self):
308         sActiveAudio = str(self.AC3delay.selectedAudioInfo[0])
309         sBitstreamDelay = _("%i ms") %self.AC3delay.lamedbDelay[AC3]
310         sPCMDelay = _("%i ms") %self.AC3delay.lamedbDelay[PCM]
311
312         self["ServiceInfo"].setText(sActiveAudio)
313         self["AC3DelayInfo"].setText(sBitstreamDelay)
314         self["PCMDelayInfo"].setText(sPCMDelay)
315
316     def audioSelected(self, audio):
317         InfoBarAudioSelection.audioSelected(self, audio)
318         if audio is not None:
319             self.AC3delay.getAudioInformation()
320             self.setChannelInfoText()
321
322 class AC3SetCustomValue:
323     def __init__(self, session, iDelay):
324         self.session = session
325         self.iDelay = iDelay
326         self.session.openWithCallback(self.DoSetCustomValue,ChoiceBox,_("Select the key you want to set to %i ms") %(iDelay),self.getKeyList())
327
328     def getKeyList(self):
329         keyList = []
330         for i in range(1, 10):
331             iValue = int(config.plugins.AC3LipSync.keySteps[i].stepSize.getValue())
332             keyList.append((_("Key %(key)i (current value: %(value)i ms)") %dict(key=i, value=iValue),str(i)))
333         return keyList
334
335     def DoSetCustomValue(self,answer):
336         if answer is None:
337             self.session.open(MessageBox,_("Setting key canceled"), MessageBox.TYPE_INFO)
338         else:
339             config.plugins.AC3LipSync.keySteps[int(answer[1])].stepSize.setValue(self.iDelay)
340             config.plugins.AC3LipSync.keySteps.save()
341             self.session.open(MessageBox,_("%(Key)s successfully set to %(delay)i ms") %dict(Key=answer[0],delay=self.iDelay), MessageBox.TYPE_INFO, 5)
342