~screenlets-testing-developers/screenlets/screenlets-testing

« back to all changes in this revision

Viewing changes to build/lib/screenlets/Mplayer.py

  • Committer: Helder
  • Date: 2008-06-04 02:46:43 UTC
  • Revision ID: helder@helder-laptop-20080604024643-ej0gdqejmv3dc3zu
Added files

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
import sys, os, fcntl, gobject, time, re
 
2
 
 
3
STATUS_TIMEOUT = 1000
 
4
 
 
5
#
 
6
#  Provides simple piped I/O to an mplayer process.
 
7
#
 
8
class Mplayer:
 
9
        
 
10
        pymp, mplayerIn, mplayerOut = None, None, None
 
11
        inputHandler, eofHandler, statusQuery = 0, 0, 0
 
12
        paused = False
 
13
        streamTitle = ""
 
14
        streamTitleChangeListeners = []
 
15
        
 
16
        #
 
17
        #  Initializes this Mplayer with the specified Pymp.
 
18
        #
 
19
        def __init__(self, pymp):
 
20
                self.pymp = pymp
 
21
                
 
22
        #
 
23
        #   Plays the specified target.
 
24
        #
 
25
        def play(self, target):
 
26
                
 
27
                mpc = "mplayer -slave -quiet " + target + " 2>/dev/null"
 
28
                
 
29
                self.mplayerIn, self.mplayerOut = os.popen2(mpc)  #open pipe
 
30
                fcntl.fcntl(self.mplayerOut, fcntl.F_SETFL, os.O_NONBLOCK)
 
31
 
 
32
                self.startInputHandler()
 
33
                self.startEofHandler()
 
34
                self.startStatusQuery()
 
35
                
 
36
        #
 
37
        #  Issues command to mplayer.
 
38
        #
 
39
 
 
40
        def record(self, target, savefile):
 
41
                
 
42
                mpc = "mplayer -slave -quiet " + target + " -ao pcm:file=" + savefile
 
43
                
 
44
                self.mplayer_record_In, self.mplayer_record_Out = os.popen2(mpc)  #open pipe
 
45
                fcntl.fcntl(self.mplayer_record_Out, fcntl.F_SETFL, os.O_NONBLOCK)
 
46
 
 
47
                
 
48
        #
 
49
        #  Issues command to mplayer.
 
50
        #
 
51
 
 
52
        def cmd(self, command):
 
53
                
 
54
                if not self.mplayerIn:
 
55
                        return
 
56
                
 
57
                try:
 
58
                        self.mplayerIn.write(command + "\n")
 
59
                        self.mplayerIn.flush()  #flush pipe
 
60
                except StandardError:
 
61
                        return
 
62
                
 
63
        #
 
64
        #  Toggles pausing of the current mplayer job and status query.
 
65
        #
 
66
        def pause(self):
 
67
                if not self.mplayerIn:
 
68
                        return
 
69
                        
 
70
                if self.paused:  #unpause
 
71
                        self.startStatusQuery()
 
72
                        self.paused = False
 
73
                        
 
74
                else:  #pause
 
75
                        self.stopStatusQuery()
 
76
                        self.paused = True
 
77
                        
 
78
                self.cmd("pause")
 
79
                
 
80
        #
 
81
        #  Seeks the amount using the specified mode.  See mplayer docs.
 
82
        #
 
83
        def seek(self, amount, mode=0):
 
84
                pass
 
85
        
 
86
        #
 
87
        #  Cleanly closes any IPC resources to mplayer.
 
88
        #
 
89
        def close(self):
 
90
                self.stopStatusQuery()  #cancel query
 
91
                self.stopEofHandler()  #cancel eof monitor
 
92
                self.stopInputHandler() #cancel input monitor
 
93
                                
 
94
                if self.paused:  #untoggle pause to cleanly quit
 
95
                        self.pause()
 
96
                
 
97
                self.cmd("quit")  #ask mplayer to quit
 
98
                
 
99
                try:                    
 
100
                        self.mplayerIn.close()   #close pipes
 
101
                        self.mplayerOut.close()
 
102
                except StandardError:
 
103
                        pass
 
104
                        
 
105
                self.mplayerIn, self.mplayerOut = None, None
 
106
                #self.pymp.control.setProgress(-1)  #reset bar
 
107
 
 
 
b'\tdef close_record(self):'
 
108
 
 
109
                try:
 
110
                        self.mplayer_record_In.write("quit\n")
 
111
                        self.mplayer_record_In.flush()  #flush pipe
 
112
                except StandardError:
 
113
                        return                  
 
114
 
 
115
                #self.cmd("quit")  #ask mplayer to quit
 
116
                
 
117
                try:                    
 
118
 
 
119
                        self.mplayer_record_In.close()   #close pipes_record_
 
120
                        self.mplayer_record_Out.close()
 
121
                except StandardError:
 
122
                        pass
 
123
                        
 
124
                self.mplayer_record_In, self.mplayer_record_Out = None, None
 
125
        #
 
126
        #  Triggered when mplayer's stdout reaches EOF.
 
127
        #
 
128
        def handleEof(self, source, condition):
 
129
                
 
130
                self.stopStatusQuery()  #cancel query
 
131
                
 
132
                self.mplayerIn, self.mplayerOut = None, None
 
133
                
 
134
        #       if self.pymp.playlist.continuous:  #play next target
 
135
        #               self.pymp.playlist.next(None, None)
 
136
        #       else:  #reset progress bar
 
137
        #               self.pymp.control.setProgress(-1)
 
138
                        
 
139
                return False
 
140
        
 
141
        #
 
142
        #  Triggered when mplayer's stdout reaches EOF.
 
143
        #
 
144
        def handleInput(self, source, condition):
 
145
                try:
 
146
                    for line in self.mplayerOut:
 
147
                        self.lookForStreamTitle(line)
 
148
                finally:
 
149
                        return True
 
150
        
 
151
        #
 
152
        #  Triggered when mplayer prints something stdout.
 
153
        #
 
154
        def lookForStreamTitle(self, line):
 
155
                matches = re.search("(?<=StreamTitle=\')(.*)(\';StreamUrl=)", line)
 
156
                if matches:
 
157
                        self.streamTitle = matches.group(1)
 
158
                        for listener in self.streamTitleChangeListeners:
 
159
                                keepListener = listener(self, self.streamTitle)
 
160
                                if not keepListener:
 
161
                                        self.streamTitleChangeListeners.remove(listener)
 
162
        
 
163
        #
 
164
        #  Queries mplayer's playback status and upates the progress bar.
 
165
        #
 
166
        def queryStatus(self):
 
167
                
 
168
                self.cmd("get_percent_pos")  #submit status query
 
169
                self.cmd("get_time_pos")
 
170
                
 
171
                time.sleep(0.05)  #allow time for output
 
172
                
 
173
                line, percent, seconds = None, -1, -1
 
174
                
 
175
                while True:
 
176
                        try:  #attempt to fetch last line of output
 
177
                                line = self.mplayerOut.readline()
 
178
                        except StandardError, detail:
 
179
                                break
 
180
                                
 
181
                        if not line: break
 
182
                        
 
183
                        if line.startswith("ANS_PERCENT_POSITION"):
 
184
                                percent = int(line.replace("ANS_PERCENT_POSITION=", ""))
 
185
                        
 
186
                        if line.startswith("ANS_TIME_POSITION"):
 
187
                                seconds = float(line.replace("ANS_TIME_POSITION=", ""))
 
188
                
 
189
                #self.pymp.control.setProgress(percent, seconds)
 
190
                return True
 
191
                
 
192
        #
 
193
        #  Add a listener that will be called every time a change in stream title is detected.
 
194
        #  The signature of the callback should be:
 
195
        #       def callback(source, newStreamTitle)
 
196
        #
 
197
        def addStreamTitleChangeListener(self, callback):
 
198
                self.streamTitleChangeListeners.append(callback)
 
199
        
 
200
        #
 
201
        #  Removes a stream title change listener.
 
202
        #
 
203
        def removeStreamTitleChangeListener(self, callback):
 
204
                self.streamTitleChangeListeners.remove(callback)
 
205
        
 
206
        #
 
207
        #  Inserts the status query monitor.
 
208
        #
 
209
        def startStatusQuery(self):
 
210
                self.statusQuery = gobject.timeout_add(STATUS_TIMEOUT, self.queryStatus)
 
211
                
 
212
        #
 
213
        #  Removes the status query monitor.
 
214
        #
 
215
        def stopStatusQuery(self):
 
216
                if self.statusQuery:
 
217
                        gobject.source_remove(self.statusQuery)
 
218
                self.statusQuery = 0
 
219
                
 
220
        #
 
221
        #  Inserts the EOF monitor.
 
222
        #
 
223
        def startEofHandler(self):
 
224
                self.eofHandler = gobject.io_add_watch(self.mplayerOut, gobject.IO_HUP, self.handleEof)
 
225
        
 
226
        #
 
227
        #  Removes the EOF monitor.
 
228
        #
 
229
        def stopEofHandler(self):
 
230
                if self.eofHandler:
 
231
                        gobject.source_remove(self.eofHandler)
 
232
                self.eofHandler = 0
 
233
        
 
234
        #
 
235
        #  Inserts the input monitoy.
 
236
        #
 
237
        def startInputHandler(self):
 
238
                self.inputHandler = gobject.io_add_watch(self.mplayerOut, gobject.IO_IN, self.handleInput)
 
239
        
 
240
        #
 
241
        #  Removes the EOF monitor.
 
242
        #
 
243
        def stopInputHandler(self):
 
244
                if self.inputHandler:
 
245
                        gobject.source_remove(self.inputHandler)
 
246
                self.inputHandler = 0
 
247
                
 
248
#End of file