b25338aacae04d20484ed21494521af5010eccb2
[vuplus_dvbapp-plugin] / ac3lipsync / src / AC3delay.py
1 from AC3utils import AC3, PCM, AC3PCM, lFileDelay, dec2hex, hex2dec
2 from Components.config import config
3 from enigma import eTimer
4 from Tools.ISO639 import LanguageCodes
5 from Tools.HardwareInfo import HardwareInfo
6 import os
7 import NavigationInstance
8
9 class AC3delay:
10     def __init__(self, session):
11         self.iService = None
12         self.iServiceReference = None
13         self.iAudioDelay = None
14         self.channelAudio = AC3
15         self.whichAudio = AC3
16         self.bIsRecording = False
17
18         # Current audio- delay
19         self.lamedbDelay = {}
20
21         self.getAudioInformation()
22
23         self.activateTimer = eTimer()
24         self.activateTimer.callback.append(self.activateDelay)
25         self.activateWait = config.plugins.AC3LipSync.activationDelay.getValue()
26         
27         # Current value for movie start behaviour
28         self.movieStart = config.usage.on_movie_start.getValue()
29
30         # find out box type
31         self.oHWInfo = HardwareInfo()
32         if self.oHWInfo.get_device_name() in ("dm800","dm8000"):
33             self.bHasToRestartService = False
34         else:
35             self.bHasToRestartService = True
36         
37     def initAudio(self):
38         self.iService = NavigationInstance.instance.getCurrentService()
39         self.iServiceReference = NavigationInstance.instance.getCurrentlyPlayingServiceReference()
40         self.iAudioDelay = self.iService and self.iService.audioDelay()
41         self.iSeek = self.iService and self.iService.seek()
42
43     def deleteAudio(self):
44         self.iService = None
45         self.iAudioDelay = None
46         self.iSeek = None
47
48     def setChannelAudio(self, sAudio):
49         self.channelAudio = sAudio
50
51     def delayedActivateDelay(self):
52         if self.activateTimer.isActive:
53             self.activateTimer.stop()
54         self.activateTimer.start(self.activateWait, False)
55
56     def activateDelay(self):
57         if self.activateTimer.isActive:
58             self.activateTimer.stop()
59         if self.bHasToRestartService == True:
60             bInitialized = False
61             if self.iService == None:
62                 self.initAudio()
63                 bInitialized = True
64             if self.iServiceReference is not None:
65                 lCurPosition = self.cueGetCurrentPosition()
66                 self.deleteAudio()
67                 if self.whichAudio == self.channelAudio:
68                     config.usage.on_movie_start.setValue("beginning")
69                     NavigationInstance.instance.stopService()
70                     NavigationInstance.instance.playService(self.iServiceReference)
71                     config.usage.on_movie_start.setValue(self.movieStart)
72                     if lCurPosition is not None:
73                         self.lCurPosition = lCurPosition
74                         self.timer = eTimer()
75                         self.timer.callback.append(self.seekAfterWait)
76                         self.timer.start(200, False)
77             else:
78                 self.deleteAudio()
79         
80     def seekAfterWait(self):
81         self.timer.stop()
82         self.initAudio()
83         if self.iSeek is not None:
84             self.iSeek.seekTo(self.lCurPosition)
85         self.deleteAudio()
86
87     def cueGetCurrentPosition(self):
88         if self.iSeek is None:
89             return None
90         r = self.iSeek.getPlayPosition()
91         if r[0]:
92             return None
93         return long(r[1])
94
95     def getLamedbDelay(self, sAudio):
96         bInitialized = False
97         if self.iService == None:
98             self.initAudio()
99             bInitialized = True
100         iDelay = 0
101         if self.iAudioDelay is not None:
102             if sAudio == AC3:
103                 iDelay = self.iAudioDelay.getAC3Delay()
104             else:
105                 iDelay = self.iAudioDelay.getPCMDelay()
106             if iDelay == -1:
107                 iDelay = 0
108         if bInitialized == True:
109             self.deleteAudio()
110         return iDelay
111
112     def getFileDelay(self, sAudio):
113         sFileName = lFileDelay[sAudio]
114         if os.path.exists(sFileName) == True:
115             delayfile = open(sFileName,"r")
116             delay = 0
117             delay = delayfile.readline()
118             delayfile.close()
119             iDelay = hex2dec(delay)/90
120         else:
121             iDelay = 0
122         return int(iDelay)
123
124     def setLamedbDelay(self, sAudio, iDelay):
125         self.initAudio()
126         if self.iAudioDelay is not None:
127             if iDelay == 0:
128                 iDelay = -1
129             if sAudio == AC3:
130                 self.iAudioDelay.setAC3Delay(iDelay)
131             else:
132                 self.iAudioDelay.setPCMDelay(iDelay)
133
134     def setFileDelay(self, sAudio, iDelay, bDelayStart):
135         hDelay = dec2hex(iDelay*90)
136         sFileName = lFileDelay[sAudio]
137         if os.path.exists(sFileName) == True:
138             delayfile = open(lFileDelay[sAudio],"w")
139             delayfile.write("%s\0" % hDelay)
140             delayfile.close()
141             if bDelayStart == True:
142                 self.delayedActivateDelay()
143             else:
144                 self.activateDelay()
145
146     def getAudioInformation(self):
147         bInitialized = False
148         if self.iService == None:
149             self.initAudio()
150             bInitialized = True
151
152         # check if we are in a recording
153         lCurPosition = self.cueGetCurrentPosition()
154         if lCurPosition is not None:
155             self.bIsRecording = True
156             
157         # check if downmix is enabled
158         try:
159             bDownmixEnabled = config.av.downmix_ac3.value
160         except:
161             bDownmixEnabled = False
162
163         oAudioTracks = self.iService and self.iService.audioTracks()
164         n = oAudioTracks and oAudioTracks.getNumberOfTracks() or 0
165         tlist = []
166         self.selectedAudioIndex = oAudioTracks.getCurrentTrack()
167         if n >= 0:
168             for x in range(n):
169                 i = oAudioTracks.getTrackInfo(x)
170                 language = i.getLanguage()
171                 description = i.getDescription()
172                 if LanguageCodes.has_key(language):
173                     language = LanguageCodes[language][0]
174                 if len(description):
175                     description += " (" + language + ")"
176                 else:
177                     description = language
178
179                 tlist.append((description, x))
180                 if x == self.selectedAudioIndex:
181                     if (description.find("AC3") != -1 and not bDownmixEnabled) or description.find("DTS") != -1:
182                         self.whichAudio = AC3
183                         self.channelAudio = AC3
184                     else:
185                         self.whichAudio = PCM
186                         self.channelAudio = PCM
187                     self.selectedAudioInfo = (description, x)
188             tlist.sort(key=lambda x: x[0])
189
190             self.audioTrackList = tlist
191         for sAudio in AC3PCM:
192             self.lamedbDelay[sAudio]=self.getLamedbDelay(sAudio)
193         del oAudioTracks
194         if bInitialized == True:
195             self.deleteAudio()
196