Package screenlets :: Package plugins :: Module Mplayer
[hide private]
[frames] | no frames]

Source Code for Module screenlets.plugins.Mplayer

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