make some composite strings translatable, changed color.keys to be more standard...
[enigma2-plugins.git] / 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;21" foregroundColor="#ffffff" />
30             <widget name="ServiceInfo" zPosition="4" position="190,52" size="180,21" font="Regular;21" foregroundColor="#cccccc" />
31             <widget name="AC3DelayInfoText" zPosition="4" position="380,52" size="40,21" font="Regular;21" foregroundColor="#ffffff" />
32             <widget name="AC3DelayInfo" zPosition="4" position="430,52" size="50,21" font="Regular;21" foregroundColor="#cccccc" />
33             <widget name="PCMDelayInfoText" zPosition="4" position="490,52" size="40,21" font="Regular;21" foregroundColor="#ffffff" />
34             <widget name="PCMDelayInfo" zPosition="4" position="540,52" size="50,21" font="Regular;21" 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"] = _("Use user delays")
73         self.whichKeyText["User"] = _("Use calc. 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(_("Switch audio"))
93         if self.AC3delay.bIsRecording == True:
94             self["key_green"] = Label(_(" "))
95         else:
96             self["key_green"] = Label(_("Save"))
97         self["key_yellow"] = Label(_("Set user delay"))
98         self["key_blue"] = Label(self.whichKeyText[self.whichKeys])
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"],
112         {
113             "ok": self.keyOk,
114             "back": self.keyCancel,
115             "left": self.keyLeft,
116             "right": self.keyRight,
117             "up": self.keyUp,
118             "down": self.keyDown,
119             "red": self.keyAudioSelection,
120             "green": self.keySaveToLamedb,
121             "yellow": self.keySaveDelayToKey,
122             "blue": self.keySwitchKeyValues,
123             "1": self.keyNumberGlobal,
124             "2": self.keyNumberGlobal,
125             "3": self.keyNumberGlobal,
126             "4": self.keyNumberGlobal,
127             "5": self.keyNumberGlobal,
128             "6": self.keyNumberGlobal,
129             "7": self.keyNumberGlobal,
130             "8": self.keyNumberGlobal,
131             "9": self.keyNumberGlobal,
132             "0": self.keyNumberGlobal
133         }, -1)
134
135     def __onShow(self):
136         for sAudio in lFileDelay.keys():
137             iDelay = self.AC3delay.getFileDelay(sAudio)
138             self[sAudio + "Slider"].setRange([(self.lowerBound), (self.upperBound)])
139             self[sAudio + "Slider"].setValue(iDelay-self.lowerBound)
140             self[sAudio + "SliderText"].setText(_("%i ms") %iDelay)
141             self.savedValue[sAudio] = iDelay
142             self.currentValue[sAudio] = iDelay
143             if self.AC3delay.whichAudio == AC3:
144                 self["AC3DelayText"].setForegroundColorNum(1)
145                 self["PCMDelayText"].setForegroundColorNum(0)
146             else:
147                 self["AC3DelayText"].setForegroundColorNum(0)
148                 self["PCMDelayText"].setForegroundColorNum(1)
149
150     def keyUp(self):
151         self.AC3delay.whichAudio = AC3
152         self["AC3DelayText"].setForegroundColorNum(1)
153         self["PCMDelayText"].setForegroundColorNum(0)
154
155     def keyDown(self):
156         self.AC3delay.whichAudio = PCM
157         self["AC3DelayText"].setForegroundColorNum(0)
158         self["PCMDelayText"].setForegroundColorNum(1)
159
160     def keyLeft(self):
161         sAudio = self.AC3delay.whichAudio
162         iSliderValue = int(self[sAudio+"Slider"].getValue())
163         iSliderValue -= self.arrowStepSize
164         if iSliderValue < 0:
165             iSliderValue = 0
166         self.setSliderInfo(iSliderValue)
167         self.AC3delay.setFileDelay(sAudio, self.currentValue[sAudio])
168
169     def keyRight(self):
170         sAudio = self.AC3delay.whichAudio
171         iSliderValue = int(self[sAudio+"Slider"].getValue())
172         if self.currentValue[sAudio] == 0:
173             iSliderValue = 0
174         iSliderValue += self.arrowStepSize
175         if iSliderValue > self.upperBound:
176             iSliderValue = self.upperBound
177         self.setSliderInfo(iSliderValue)
178         self.AC3delay.setFileDelay(sAudio, self.currentValue[sAudio])
179
180     def keyNumberGlobal(self, number):
181         sAudio = self.AC3delay.whichAudio
182         iNumber = int(number)
183         if iNumber == 0:
184             iSliderValue = 0
185             self.currentValue[sAudio] = 0
186         else:
187             if self.whichKeys == "Computed":
188                 iSliderValue = self.stepSize*iNumber
189             else:
190                 iSliderValue = int(config.plugins.AC3LipSync.keySteps[iNumber].stepSize.getValue())-self.lowerBound
191                 if iSliderValue < 0:
192                     iSliderValue = 0
193         self.setSliderInfo(iSliderValue)
194         self.AC3delay.setFileDelay(sAudio, self.currentValue[sAudio])
195
196     def keyAudioSelection(self):
197         self.audioSelection()
198
199     def keyOk(self):
200         self.close()
201
202     def keyCancel(self):
203         for sAudio in lFileDelay.keys():
204             iSliderValue = self.currentValue[sAudio]
205             if iSliderValue <> self.savedValue[sAudio]:
206                 self.whichAudio = sAudio
207                 self.AC3delay.setFileDelay(sAudio, self.savedValue[sAudio])
208         self.close()
209
210     def keySaveToLamedb(self):
211         if self.AC3delay.bIsRecording == False:
212             keyList = [
213                 (_("Save %s delay")%AC3,"1"),
214                 (_("Save %s delay")%PCM,"2"),
215                 (_("Save both delays"),"3")
216             ]
217
218             self.session.openWithCallback(self.DoSaveLamedb,ChoiceBox,_("Which delays do you want to set"),keyList)
219
220     def DoSaveLamedb(self, answer):
221         sNewLine = ""
222         sResponse = ""
223         bOk = True
224         iType = MessageBox.TYPE_INFO
225         aSetAudio = []
226         if answer is not None:
227             if answer[1] in ("1","2","3"):
228                 bSetAC3 = False
229                 bSetPCM = False
230                 self.AC3delay.initAudio()
231                 if self.AC3delay.iAudioDelay is not None:
232                     if answer[1] in ("1","3"):
233                         iDelay = int( self.AC3delay.getLamedbDelay(AC3) )
234                         aSetAudio.append((AC3,iDelay))
235                         bSetAC3 = True
236                     if answer[1] in ("2","3"):
237                         iDelay = int( self.AC3delay.getLamedbDelay(PCM) )
238                         aSetAudio.append((PCM,iDelay))
239                         bSetPCM = True
240                     for vAudio in aSetAudio:
241                         sAudio = vAudio[0]
242                         iChannelDelay = int(vAudio[1])
243                         iCurDelay = self.currentValue[sAudio]
244                         iNewDelay = iCurDelay
245                         if sAudio == AC3:
246                             self.AC3delay.iAudioDelay.setAC3Delay(iNewDelay)
247                         else:
248                             self.AC3delay.iAudioDelay.setPCMDelay(iNewDelay)
249                         self.AC3delay.lamedbDelay[sAudio] = iNewDelay
250                         sResponse = sResponse + sNewLine + _("Saved %(audio)s value: %(delay)i ms") %dict(audio=sAudio,delay=iNewDelay)
251                         sNewLine = "\n"
252                 self.AC3delay.deleteAudio()
253             else:
254                 sResponse = _("Invalid selection")
255                 iType = MessageBox.TYPE_ERROR
256             if bOk == True:
257                 self.session.open(MessageBox, sResponse , iType)
258         self.setChannelInfoText()
259
260     def setSliderInfo(self, iDelay):
261         sAudio = self.AC3delay.whichAudio
262         if iDelay == 0:
263             if self.currentValue[sAudio] >= self.lowerBound:
264                 self.currentValue[sAudio] = self.lowerBound
265             else:
266                 self.currentValue = 0
267         else:
268             self.currentValue[sAudio] = iDelay + self.lowerBound
269         self[sAudio+"Slider"].setValue(iDelay)
270         iCurDelay = self.currentValue[sAudio]
271         self[sAudio+"SliderText"].setText(_("%i ms")%iCurDelay)
272
273     def setChannelInfoText(self):
274         sActiveAudio = str(self.AC3delay.selectedAudioInfo[0])
275         sBitstreamDelay = _("%i ms") %self.AC3delay.lamedbDelay[AC3]
276         sPCMDelay = ("%i ms") %self.AC3delay.lamedbDelay[PCM]
277
278         self["ServiceInfo"].setText(sActiveAudio)
279         self["AC3DelayInfo"].setText(sBitstreamDelay)
280         self["PCMDelayInfo"].setText(sPCMDelay)
281
282     def keySwitchKeyValues(self):
283         if self.whichKeys == "Computed":
284             self.whichKeys = "User"
285         else:
286             self.whichKeys = "Computed"
287         self["key_blue"].setText(self.whichKeyText[self.whichKeys])
288
289     def keySaveDelayToKey(self):
290         sAudio = self.AC3delay.whichAudio
291         iDelay = self[sAudio+"Slider"].getValue()+self.lowerBound
292         AC3SetCustomValue(self.session,iDelay)
293
294     def audioSelected(self, audio):
295         InfoBarAudioSelection.audioSelected(self, audio)
296         if audio is not None:
297             self.AC3delay.getAudioInformation()
298             self.setChannelInfoText()
299
300 class AC3SetCustomValue:
301     def __init__(self, session, iDelay):
302         self.session = session
303         self.iDelay = iDelay
304         self.session.openWithCallback(self.DoSetCustomValue,ChoiceBox,_("Select the key you want to set"),self.getKeyList())
305
306     def getKeyList(self):
307         keyList = []
308         for i in range(1, 10):
309             keyList.append((_("Key")+" "+str(i),str(i)))
310         return keyList
311
312     def DoSetCustomValue(self,answer):
313         if answer is None:
314             self.session.open(MessageBox,_("Setting key canceled"), MessageBox.TYPE_INFO)
315         else:
316             config.plugins.AC3LipSync.keySteps[int(answer[1])].stepSize.setValue(self.iDelay)
317             config.plugins.AC3LipSync.keySteps.save()
318             self.session.open(MessageBox,_("%(Key)s successfully set to %(delay)i ms") %dict(Key=answer[0],delay=self.iDelay), MessageBox.TYPE_INFO, 5)
319