updated on Wed Jan 25 00:20:47 UTC 2012
[aur-mirror.git] / pyvnc2swf / pyvnc2swf-0.9.5-setup.diff
blob9d856c5100f1985888cb85ff8dd5077f6cbc1b18
1 diff -Naur pyvnc2swf-0.9.5.old/setup.py pyvnc2swf-0.9.5/setup.py
2 --- pyvnc2swf-0.9.5.old/setup.py 1969-12-31 18:00:00.000000000 -0600
3 +++ pyvnc2swf-0.9.5/setup.py 2008-12-18 06:10:12.000000000 -0600
4 @@ -0,0 +1,21 @@
5 +#!/usr/bin/env python
6 +# -*- coding: ISO-8859-1 -*-
8 +from distutils.core import setup, Extension
10 +pkgs = ['pyvnc2swf']
11 +docs = ['docs/pyvnc2swf.html', 'docs/recordwin.html']
12 +data = [('share/doc/pyvnc2swf', docs)]
13 +bins = ['bin/recordwin', 'bin/pyvnc2swf', 'bin/pyvnc2swf-edit', 'bin/pyvnc2swf-play']
15 +setup(
16 + name = 'pyvnc2swf',
17 + version = '0.9.5',
18 + author = 'Yusuke Shinyama',
19 + author_email = 'yusuke at cs dot nyu dot edu',
20 + license = 'GPL',
21 + url = 'http://www.unixuser.org/~euske/vnc2swf/pyvnc2swf.html',
22 + packages = pkgs,
23 + data_files = data,
24 + scripts = bins
26 diff -Naur pyvnc2swf-0.9.5.old/bin/pyvnc2swf pyvnc2swf-0.9.5/bin/pyvnc2swf
27 --- pyvnc2swf-0.9.5.old/bin/pyvnc2swf 1969-12-31 18:00:00.000000000 -0600
28 +++ pyvnc2swf-0.9.5/bin/pyvnc2swf 2008-12-18 06:07:48.000000000 -0600
29 @@ -0,0 +1,611 @@
30 +#!/usr/bin/env python
31 +##
32 +## pyvnc2swf - vnc2swf.py
33 +##
34 +## $Id: vnc2swf.py,v 1.7 2008/11/16 02:39:40 euske Exp $
35 +##
36 +## Copyright (C) 2005 by Yusuke Shinyama (yusuke at cs . nyu . edu)
37 +## All Rights Reserved.
38 +##
39 +## This is free software; you can redistribute it and/or modify
40 +## it under the terms of the GNU General Public License as published by
41 +## the Free Software Foundation; either version 2 of the License, or
42 +## (at your option) any later version.
43 +##
44 +## This software is distributed in the hope that it will be useful,
45 +## but WITHOUT ANY WARRANTY; without even the implied warranty of
46 +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
47 +## GNU General Public License for more details.
48 +##
49 +## You should have received a copy of the GNU General Public License
50 +## along with this software; if not, write to the Free Software
51 +## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
52 +## USA.
53 +##
55 +import sys, os, os.path, time, socket, re
56 +import Tkinter, tkFileDialog, tkMessageBox, tempfile, shutil
57 +from tkSimpleDialog import Dialog
58 +from struct import pack, unpack
59 +import threading
61 +from pyvnc2swf.movie import SWFInfo
62 +from pyvnc2swf.output import StreamFactory
63 +from pyvnc2swf.rfb import RFBError, RFBNetworkClient, RFBFileParser, RFBNetworkClientForRecording, RFBStreamConverter
64 +stderr = sys.stderr
67 +## tkPasswordDialog
68 +##
69 +class tkPasswordDialog(Dialog):
71 + def __init__(self, title, prompt, master=None):
72 + if not master:
73 + master = Tkinter._default_root
74 + self.prompt = prompt
75 + Dialog.__init__(self, master, title)
76 + return
78 + def destroy(self):
79 + self.entry = None
80 + Dialog.destroy(self)
81 + return
83 + def body(self, master):
84 + w = Tkinter.Label(master, text=self.prompt, justify=Tkinter.LEFT)
85 + w.grid(row=0, padx=5, sticky=Tkinter.W)
86 + self.entry = Tkinter.Entry(master, name="entry", show="*")
87 + self.entry.grid(row=1, padx=5, sticky=Tkinter.W+Tkinter.E)
88 + return self.entry
90 + def validate(self):
91 + self.result = self.entry.get()
92 + return 1
95 +## tkEntryDialog
96 +##
97 +class tkEntryDialog(Dialog):
99 + def __init__(self, title, prompt, pattern=None, default=None, master=None):
100 + if not master:
101 + master = Tkinter._default_root
102 + self.prompt = prompt
103 + self.default = default
104 + self.pattern = re.compile(pattern)
105 + Dialog.__init__(self, master, title)
106 + return
108 + def destroy(self):
109 + self.entry = None
110 + Dialog.destroy(self)
111 + return
113 + def body(self, master):
114 + w = Tkinter.Label(master, text=self.prompt, justify=Tkinter.LEFT)
115 + w.grid(row=0, padx=5, sticky=Tkinter.W)
116 + self.entry = Tkinter.Entry(master, name="entry")
117 + self.entry.grid(row=1, padx=5, sticky=Tkinter.W+Tkinter.E)
118 + if self.default:
119 + self.entry.insert(0, self.default)
120 + return self.entry
122 + def validate(self):
123 + self.result = self.entry.get()
124 + if self.pattern and not self.pattern.match(self.result):
125 + return 0
126 + return 1
129 +## RFBNetworkClientWithTkMixin
131 +class RFBNetworkClientWithTkMixin:
133 + def tk_init(self, root):
134 + self.root = root
135 + self.doloop = True
136 + return
138 + def interrupt(self):
139 + self.doloop = False
140 + return
142 + def loop(self):
143 + self.doloop = True
144 + while self.doloop:
145 + self.root.update()
146 + if not self.loop1(): break
147 + self.finish_update()
148 + return self
150 + def getpass(self):
151 + return tkPasswordDialog('Login',
152 + 'Password for %s:%d' % (self.host, self.port),
153 + self.root).result
155 +class RFBNetworkClientWithTk(RFBNetworkClientWithTkMixin, RFBNetworkClient): pass
156 +class RFBNetworkClientForRecordingWithTk(RFBNetworkClientWithTkMixin, RFBNetworkClientForRecording): pass
159 +## VNC2SWFWithTk
161 +class VNC2SWFWithTk:
163 + FILE_TYPES = [
164 + ('Flash(v5)', 'swf5', 'Macromedia Flash Files', '.swf'), # 0
165 + ('Flash(v7)', 'swf7', 'Macromedia Flash Files', '.swf'), # 1
166 + ('FLV', 'flv', 'Macromedia Flash Video Files', '.flv'), # 3
167 + ('MPEG', 'mpeg', 'MPEG Files', '.mpeg'), # 2
168 + ('VNCRec', 'vnc', 'VNCRec Files', '.vnc'), # 4
171 + def __init__(self, tempdir, info,
172 + outtype='swf5', host='localhost', port=5900,
173 + preferred_encoding=(0,), subprocess=None, pwdfile=None,
174 + debug=0):
175 + self.tempdir = tempdir
176 + self.moviefile = info.filename
177 + self.info = info
178 + self.debug = debug
179 + self.preferred_encoding = preferred_encoding
180 + self.subprocess = subprocess
181 + self.pwdfile = pwdfile
182 + self.outtype = outtype
183 + self.host = host
184 + self.port = port
185 + self.recording = False
186 + self.exit_immediately = False
187 + self.root = Tkinter.Tk()
188 + self.root.title('vnc2swf.py')
189 + self.root.wm_protocol('WM_DELETE_WINDOW', self.file_exit)
190 + self.toggle_button = Tkinter.Button(master=self.root)
191 + self.toggle_button.pack(side=Tkinter.LEFT)
192 + self.status_label = Tkinter.Label(master=self.root, justify=Tkinter.LEFT)
193 + self.status_label.pack(side=Tkinter.LEFT)
194 + self.setup_menubar()
195 + self.file_new(True)
196 + return
198 + def frames(self):
199 + return self.stream and self.stream.output_frames
201 + # Set up the GUI components.
202 + def setup_menubar(self):
204 + def option_server():
205 + x = tkEntryDialog('Server', 'Server? (host:port)', pattern='^([^:/]+(:\d+)?|)$',
206 + default='%s:%d' % (self.host, self.port), master=self.root).result
207 + if not x: return
208 + m = re.match(r'^([^:/]*)(:(\d+))?', x)
209 + if not m:
210 + tkMessageBox.showerror('Invalid address: %s' % x)
211 + return
212 + (host, port) = (m.group(1) or 'localhost', int(m.group(3) or '5900'))
213 + if host != self.host or port != self.port and self.file_new_ask():
214 + (self.host, self.port) = (host, port)
215 + self.file_new(True)
216 + return
218 + def option_framerate():
219 + x = tkEntryDialog('Framerate', 'Framerate? (fps)', pattern='^([1-9][.0-9]+|)$',
220 + default=self.info.framerate, master=self.root).result
221 + if not x: return
222 + framerate = float(x)
223 + if framerate != self.info.framerate and self.file_new_ask():
224 + self.info.framerate = framerate
225 + self.file_new(True)
226 + return
228 + def option_clipping():
229 + try:
230 + s = self.info.get_clipping()
231 + except ValueError:
232 + s = ''
233 + x = tkEntryDialog('Clipping', 'Clipping? (ex. 640x480+0+0)',
234 + pattern='^(\d+x\d+\+\d+\+\d+|)$',
235 + default=s, master=self.root).result
236 + if not x: return
237 + if x != s and self.file_new_ask():
238 + self.info.set_clipping(x)
239 + self.file_new(True)
240 + return
242 + record_type = Tkinter.StringVar(self.root)
243 + record_type.set(self.outtype)
244 + def option_type():
245 + if record_type.get() != self.outtype and self.file_new_ask():
246 + self.outtype = record_type.get()
247 + self.file_new()
248 + else:
249 + record_type.set(self.outtype)
250 + return
252 + menubar = Tkinter.Menu(self.root)
253 + self.file_menu = Tkinter.Menu(menubar, tearoff=0)
254 + self.file_menu.add_command(label="New...", underline=0, command=self.file_new, accelerator='Alt-N')
255 + self.file_menu.add_command(label="Save as...", underline=0, command=self.file_saveas, accelerator='Alt-S')
256 + self.file_menu.add_separator()
257 + self.file_menu.add_command(label="Exit", underline=1, command=self.file_exit)
258 + self.option_menu = Tkinter.Menu(menubar, tearoff=0)
259 + self.option_menu.add_command(label="Server...", underline=0, command=option_server)
260 + self.option_menu.add_command(label="Clipping...", underline=0, command=option_clipping)
261 + self.option_menu.add_command(label="Framerate...", underline=0, command=option_framerate)
262 + type_submenu = Tkinter.Menu(self.option_menu, tearoff=0)
263 + for (k,v,_,_) in self.FILE_TYPES:
264 + type_submenu.add_radiobutton(label=k, value=v, variable=record_type, command=option_type)
265 + self.option_menu.add_cascade(label="Type", underline=0, menu=type_submenu)
266 + menubar.add_cascade(label="File", underline=0, menu=self.file_menu)
267 + menubar.add_cascade(label="Option", underline=0, menu=self.option_menu)
268 + self.root.config(menu=menubar)
269 + self.root.bind('<Alt-n>', lambda e: self.file_new())
270 + self.root.bind('<Alt-s>', lambda e: self.file_saveas())
271 + return
273 + # Change the current status of UI.
274 + def set_status(self):
276 + def enable_menus(state):
277 + self.file_menu.entryconfig(0, state=state) # "File->New..."
278 + self.option_menu.entryconfig(0, state=state) # "Option->Server..."
279 + self.option_menu.entryconfig(1, state=state) # "Option->Clipping..."
280 + self.option_menu.entryconfig(2, state=state) # "Option->Framerate..."
281 + self.option_menu.entryconfig(3, state=state) # "Option->Type"
282 + return
284 + # "File->Save As..."
285 + if not self.recording and self.frames():
286 + self.file_menu.entryconfig(1, state='normal')
287 + else:
288 + self.file_menu.entryconfig(1, state='disabled')
290 + s = []
291 + if not self.recording:
292 + s.append('Ready (%d frames recorded).' % (self.frames() or 0))
293 + self.toggle_button.config(text='Start', underline=0)
294 + self.toggle_button.config(background='#80ff80', activebackground='#00ff00')
295 + self.toggle_button.config(command=self.record)
296 + self.root.bind('<s>', lambda e: self.record())
297 + self.root.bind('<space>', lambda e: self.record())
298 + enable_menus('normal')
299 + else:
300 + s.append('Recording.')
301 + self.toggle_button.config(text='Stop', underline=0)
302 + self.toggle_button.config(background='#ff8080', activebackground='#ff0000')
303 + self.toggle_button.config(command=self.client.interrupt)
304 + self.root.bind('<s>', lambda e: self.client.interrupt())
305 + self.root.bind('<space>', lambda e: self.client.interrupt())
306 + enable_menus('disabled')
307 + if self.host != 'localhost' or self.port != 5900:
308 + s.append('Server: %s:%d' % (self.host, self.port))
309 + if self.info.clipping:
310 + s.append('Clipping: %s' % self.info.get_clipping())
311 + if self.info.framerate:
312 + s.append('Framerate: %s' % self.info.framerate)
313 + self.status_label.config(text='\n'.join(s))
314 + return
316 + # File->New
317 + def file_new_ask(self):
318 + if self.frames():
319 + if not tkMessageBox.askokcancel('New file', 'Discard the current session?'):
320 + return False
321 + return True
323 + def file_new(self, force=False):
324 + if self.recording or (not force and not self.file_new_ask()): return
325 + ext = dict([ (t,ext) for (_,t,desc,ext) in self.FILE_TYPES ])[self.outtype]
326 + if self.moviefile:
327 + moviefile = self.moviefile
328 + else:
329 + moviefile = os.path.join(self.tempdir, 'pyvnc2swf-%d%s' % (os.getpid(), ext))
330 + self.info.filename = moviefile
331 + self.fp = None
332 + if self.outtype == 'vnc':
333 + self.fp = file(self.info.filename, 'wb')
334 + self.client = RFBNetworkClientForRecordingWithTk(
335 + self.host, self.port, self.fp, pwdfile=self.pwdfile,
336 + preferred_encoding=self.preferred_encoding)
337 + self.stream = None
338 + else:
339 + self.stream = StreamFactory(self.outtype)(self.info)
340 + self.client = RFBNetworkClientWithTk(
341 + self.host, self.port, RFBStreamConverter(self.info, self.stream),
342 + pwdfile=self.pwdfile,
343 + preferred_encoding=self.preferred_encoding)
344 + self.set_status()
345 + return True
347 + # File->SaveAs
348 + def file_saveas(self):
349 + if self.recording or not self.frames(): return
350 + (ext,desc) = dict([ (t,(ext,desc)) for (_,t,desc,ext) in self.FILE_TYPES ])[self.outtype]
351 + filename = tkFileDialog.asksaveasfilename(
352 + master=self.root, title='Vnc2swf Save As', defaultextension=ext,
353 + filetypes=[(desc,'*'+ext), ("All Files", "*")]
355 + if not filename: return
356 + if self.stream:
357 + # Finish the movie.
358 + self.stream.close()
359 + self.stream = None
360 + if self.fp:
361 + self.fp.close()
362 + self.fp = None
363 + shutil.move(self.info.filename, filename)
364 + self.info.write_html(filename=filename)
365 + self.set_status()
366 + return
368 + # File->Exit
369 + def file_exit(self):
370 + if self.recording:
371 + self.client.interrupt()
372 + self.exit_immediately = True
373 + else:
374 + if self.frames():
375 + if not tkMessageBox.askokcancel('Exit', 'Discard the current session?'):
376 + return
377 + self.root.destroy()
378 + return
380 + # Do recording.
381 + def record(self):
382 + self.client.tk_init(self.root)
383 + try:
384 + self.client.init().auth().start()
385 + except socket.error, e:
386 + return self.error('Socket error', e)
387 + except RFBError, e:
388 + return self.error('RFB protocol error', e)
389 + if self.debug:
390 + print >>stderr, 'start recording'
391 + self.recording = True
392 + self.set_status()
393 + if self.subprocess:
394 + self.subprocess.start()
395 + try:
396 + self.client.loop()
397 + except socket.error, e:
398 + return self.error('Socket error', e)
399 + except RFBError, e:
400 + return self.error('RFB protocol error', e)
401 + if self.debug:
402 + print >>stderr, 'stop recording'
403 + if self.subprocess:
404 + self.subprocess.stop()
405 + self.client.close()
406 + self.recording = False
407 + self.set_status()
408 + if self.exit_immediately:
409 + self.file_exit()
410 + return
412 + # Displays an error message.
413 + def error(self, msg, arg):
414 + print >>stderr, arg
415 + tkMessageBox.showerror('vnc2swf: %s' % msg, str(arg))
416 + return
418 + # Runs Tk mainloop.
419 + def run(self):
420 + self.root.mainloop()
421 + return
424 +## vnc2swf - CLI routine
426 +def vnc2swf(info, outtype='swf5', host='localhost', port=5900,
427 + preferred_encoding=(0,), subprocess=None, pwdfile=None, vncfile=None,
428 + debug=0, merge=False):
429 + fp = None
430 + if outtype == 'vnc':
431 + if info.filename == '-':
432 + fp = sys.stdout
433 + else:
434 + fp = file(info.filename, 'wb')
435 + client = RFBNetworkClientForRecording(host, port, fp, pwdfile=pwdfile,
436 + preferred_encoding=preferred_encoding, debug=debug)
437 + else:
438 + stream = StreamFactory(outtype)(info, debug=debug)
439 + converter = RFBStreamConverter(info, stream, debug=debug)
440 + if vncfile:
441 + client = RFBFileParser(vncfile, converter, debug=debug)
442 + else:
443 + client = RFBNetworkClient(host, port, converter, pwdfile=pwdfile,
444 + preferred_encoding=preferred_encoding, debug=debug)
445 + try:
446 + client.init().auth().start()
447 + except socket.error, e:
448 + print >>stderr, 'Socket error:', e
449 + except RFBError, e:
450 + print >>stderr, 'RFB error:', e
451 + if debug:
452 + print >>stderr, 'start recording'
453 + if subprocess:
454 + subprocess.start()
455 + try:
456 + client.loop()
457 + except KeyboardInterrupt:
458 + pass
459 + except socket.error, e:
460 + print >>stderr, 'Socket error:', e
461 + except RFBError, e:
462 + print >>stderr, 'RFB error:', e
463 + if debug:
464 + print >>stderr, 'stop recording'
465 + if subprocess:
466 + subprocess.stop()
467 + client.close()
468 + stream.close()
469 + info.write_html()
470 + if fp:
471 + fp.close()
472 + # Contributed by David Fraser
473 + if merge:
474 + tmpfile = os.tempnam(os.path.dirname(info.filename), "vncmerge-") + os.path.basename(info.filename)
475 + print >>stderr, "renaming %s to %s for merge" % (info.filename, tmpfile)
476 + if os.path.exists(tmpfile):
477 + os.remove(tmpfile)
478 + os.rename( info.filename, tmpfile )
479 + try:
480 + # TODO: sort out getting outputfilename properly
481 + audiofilename = subprocess.outputfile
482 + import edit
483 + args = ["-d", "-o", info.filename, "-a", audiofilename, tmpfile]
484 + if not edit.main(args):
485 + print >>stderr, "Error doing merge..."
486 + finally:
487 + origexists, tmpexists = os.path.exists(info.filename), os.path.exists(tmpfile)
488 + print >>stderr, "origexists %r, tmpexists %r" % (origexists, tmpexists)
489 + if origexists and tmpexists:
490 + try:
491 + os.remove(tmpfile)
492 + except OSError, e:
493 + print >>stderr, "Could not remove temporary file: %s" % e
494 + elif tmpexists:
495 + print >>stderr, "only tmpfile remains after merge, renaming to original (but will not contain sound)"
496 + os.rename( tmpfile, info.filename )
497 + return
500 +# Thread management
501 +class RecordingThread:
502 + def __init__(self, outputfile):
503 + try:
504 + import record_sound
505 + except ImportError, e:
506 + print >>stderr, "unable to use pymedia?:", e
507 + raise
508 + self.outputfile = outputfile
509 + self.recorder = record_sound.voiceRecorder(self.outputfile)
510 + self.thread = threading.Thread(target=self.recorder.run)
512 + def start(self):
513 + self.thread.start()
515 + def stop(self):
516 + self.recorder.finished = True
517 + self.thread.join()
519 +# Subprocess management
520 +class Subprocess:
522 + def __init__(self, s):
523 + try:
524 + import subprocess
525 + except ImportError:
526 + print >>stderr, '-S option requires Python 2.4 or newer.'
527 + sys.exit(111)
528 + if not hasattr(os, 'kill'):
529 + print >>stderr, '-S option works only on Unix or Mac OS X.'
530 + sys.exit(111)
531 + self.args = s.split(' ')
532 + self.popen = None
533 + return
535 + def start(self):
536 + import subprocess
537 + self.popen = subprocess.Popen(self.args)
538 + return
540 + def stop(self):
541 + import signal
542 + os.kill(self.popen.pid, signal.SIGINT)
543 + self.popen.wait()
544 + return
547 +# main
548 +# ./vnc2swf.py -S 'arecord -t wav -c 1 -r 22050 out.wav' -n -o out.swf
549 +def main(argv):
550 + import getopt
551 + def usage():
552 + print ('usage: %s [-d] [-n] [-o filename] [-t {flv|mpeg|swf5|swf7|vnc}]'
553 + ' [-e encoding] [-N] [-C clipping] [-r framerate] [-s scaling] [-z] [-m] [-a] [-V]'
554 + ' [-S subprocess] [-P pwdfile] [host[:display] [port]]' % argv[0])
555 + return 100
556 + try:
557 + (opts, args) = getopt.getopt(argv[1:], 'dno:t:e:NC:r:S:P:s:zmaV')
558 + except getopt.GetoptError:
559 + return usage()
560 + (debug, console, outtype, subprocess, merge, pwdfile, isfile) = (0, False, None, None, False, None, False)
561 + (cursor, host, port, preferred_encoding) = (True, 'localhost', 5900, (0,))
562 + info = SWFInfo()
563 + for (k, v) in opts:
564 + if k == '-d': debug += 1
565 + elif k == '-n': console = True
566 + elif k == '-t': outtype = v
567 + elif k == '-e': preferred_encoding = tuple([ int(i) for i in v.split(',') ])
568 + elif k == '-N': cursor = False
569 + elif k == '-S': subprocess = Subprocess(v)
570 + elif k == '-a': subprocess = RecordingThread(v)
571 + elif k == '-m': merge = True
572 + elif k == '-P': pwdfile = v
573 + elif k == '-V': isfile = True
574 + elif k == '-o':
575 + info.filename = v
576 + elif k == '-C':
577 + try:
578 + info.set_clipping(v)
579 + except ValueError:
580 + print 'Invalid clipping specification:', v
581 + return usage()
582 + elif k == "-r":
583 + info.framerate = int(v)
584 + elif k == "-z":
585 + info.set_scalable(True)
586 + elif k == '-s':
587 + info.scaling = float(v)
588 + assert 0 < info.scaling and info.scaling <= 1.0, 'Invalid scaling.'
589 + if not outtype:
590 + if info.filename:
591 + if info.filename.endswith('.vnc'):
592 + outtype = 'vnc'
593 + elif info.filename.endswith('.swf'):
594 + outtype = 'swf5'
595 + elif info.filename.endswith('.mpg') or info.filename.endswith('.mpeg'):
596 + outtype = 'mpeg'
597 + elif info.filename.endswith('.flv'):
598 + outtype = 'flv'
599 + else:
600 + outtype = 'swf5'
601 + if outtype not in ('swf5','swf7','vnc','mpeg','flv'):
602 + print 'Please specify the output type or file extension.'
603 + return usage()
604 + if cursor:
605 + preferred_encoding += (-232,-239,)
606 + if 1 <= len(args):
607 + if ':' in args[0]:
608 + i = args[0].index(':')
609 + host = args[0][:i] or 'localhost'
610 + port = int(args[0][i+1:])+5900
611 + else:
612 + host = args[0]
613 + if 2 <= len(args):
614 + port = int(args[1])
615 + if console:
616 + if not info.filename:
617 + print 'Please specify the output filename.'
618 + return usage()
619 + vncfile = None
620 + if isfile:
621 + vncfile = sys.stdin
622 + if args:
623 + vncfile = file(args[0], 'rb')
624 + vnc2swf(info, outtype, host, port,
625 + preferred_encoding=preferred_encoding,
626 + subprocess=subprocess, pwdfile=pwdfile, vncfile=vncfile,
627 + merge=merge, debug=debug)
628 + else:
629 + tempdir = os.path.join(tempfile.gettempdir(), 'pyvnc2swf')
630 + try:
631 + os.mkdir(tempdir)
632 + except OSError:
633 + pass
634 + VNC2SWFWithTk(tempdir, info, outtype, host, port,
635 + preferred_encoding=preferred_encoding,
636 + subprocess=subprocess, pwdfile=pwdfile,
637 + debug=debug).run()
638 + return
640 +if __name__ == "__main__": sys.exit(main(sys.argv))
641 diff -Naur pyvnc2swf-0.9.5.old/bin/pyvnc2swf-edit pyvnc2swf-0.9.5/bin/pyvnc2swf-edit
642 --- pyvnc2swf-0.9.5.old/bin/pyvnc2swf-edit 1969-12-31 18:00:00.000000000 -0600
643 +++ pyvnc2swf-0.9.5/bin/pyvnc2swf-edit 2008-12-18 06:07:56.000000000 -0600
644 @@ -0,0 +1,248 @@
645 +#!/usr/bin/env python
647 +## pyvnc2swf - edit.py
649 +## $Id: edit.py,v 1.6 2008/11/16 02:39:40 euske Exp $
651 +## Copyright (C) 2005 by Yusuke Shinyama (yusuke at cs . nyu . edu)
652 +## All Rights Reserved.
654 +## This is free software; you can redistribute it and/or modify
655 +## it under the terms of the GNU General Public License as published by
656 +## the Free Software Foundation; either version 2 of the License, or
657 +## (at your option) any later version.
659 +## This software is distributed in the hope that it will be useful,
660 +## but WITHOUT ANY WARRANTY; without even the implied warranty of
661 +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
662 +## GNU General Public License for more details.
664 +## You should have received a copy of the GNU General Public License
665 +## along with this software; if not, write to the Free Software
666 +## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
667 +## USA.
670 +import sys, re
671 +from pyvnc2swf.movie import SWFInfo, MovieContainer
672 +from pyvnc2swf.output import FLVVideoStream, MPEGVideoStream, SWFVideoStream, \
673 + SWFShapeStream, ImageSequenceStream, MovieBuilder
674 +stderr = sys.stderr
677 +# range2list: converts strings like "1,5-8" to [1,5,6,7,8].
678 +class RangeError(ValueError): pass
679 +def range2list(s, n0, n1, step=1):
680 + PAT_RANGE = re.compile(r'^([0-9]*)-([0-9]*)$')
681 + r = []
682 + for i in s.split(','):
683 + i = i.strip()
684 + if not i: continue
685 + if i.isdigit():
686 + n = int(i)
687 + if n0 <= n and n <= n1:
688 + r.append(n)
689 + else:
690 + raise RangeError('%d: must be in %d...%d' % (n,n0,n1))
691 + else:
692 + m = PAT_RANGE.match(i.strip())
693 + if not m:
694 + raise RangeError('%r: illegal number' % i)
695 + b = n0
696 + if m.group(1):
697 + b = int(m.group(1))
698 + e = n1
699 + if m.group(2):
700 + e = int(m.group(2))
701 + if e < b:
702 + (b,e) = (e,b)
703 + if b < n0:
704 + raise RangeError('%d: must be in %d...%d' % (b,n0,n1))
705 + if n1 < e:
706 + raise RangeError('%d: must be in %d...%d' % (e,n0,n1))
707 + r.extend(xrange(b,e+1,step))
708 + return r
711 +# reorganize
712 +def reorganize(info, stream, moviefiles, range_str='-',
713 + loop=True, seekbar=True,
714 + step=1, kfinterval=0,
715 + mp3seek=True, mp3skip=0,
716 + debug=0):
717 + movie = MovieContainer(info)
718 + for fname in moviefiles:
719 + if fname.endswith('.swf'):
720 + # vnc2swf file
721 + movie.parse_vnc2swf(fname, True, debug=debug)
722 + elif fname.endswith('.flv'):
723 + # flv file
724 + movie.parse_flv(fname, True, debug=debug)
725 + elif fname.endswith('.vnc'):
726 + # vncrec file
727 + movie.parse_vncrec(fname, debug=debug)
728 + else:
729 + raise ValueError('unsupported format: %r' % fname)
730 + r = range2list(range_str, 0, movie.nframes-1, step)
731 + if movie.info.mp3:
732 + if isinstance(mp3skip, float):
733 + mp3skip = int(mp3skip * movie.info.mp3.sample_rate)
734 + movie.info.mp3.set_initial_skip(mp3skip)
735 + builder = MovieBuilder(movie, stream, mp3seek=mp3seek, kfinterval=kfinterval, debug=debug)
736 + builder.build(r)
737 + stream.close()
738 + movie.info.write_html(seekbar=seekbar, loop=loop)
739 + return 0
742 +# main
743 +def main(argv):
744 + import getopt
745 + def usage():
746 + print >>stderr, '''usage: %s
747 + [-d] [-c] [-t type] [-f|-F frames] [-a mp3file] [-r framerate]
748 + [-S mp3sampleskip] [-C WxH+X+Y] [-B blocksize] [-K keyframe]
749 + [-R framestep] [-s scaling]
750 + -o outfile.swf file1 file2 ...
752 + Specify one output filename from the following:
753 + *.swf: generate a SWF movie.
754 + *.flv: generate a FLV movie.
755 + *.mpg: generate a MPEG movie.
756 + *.png|*.bmp: save snapshots of given frames as "X-nnn.png"
758 + -d: debug mode.
759 + -c: compression.
760 + -t {swf5,swf7,flv,mpeg,png,bmp}: specify the output movie type.
761 + -f(-F) frames: frames to extract. e.g. 1-2,100-300,310,500-
762 + -F disables seeking audio.
763 + -R framestep: frame resampling step (default: 1)
764 + -s scaling: scale factor (default: 1.0)
765 + -a filename: attach MP3 file(s). (multiple files can be specified)
766 + -r framerate: override framerate.
767 + -B blocksize: (SWF7 and FLV mode only) blocksize of video packet (must be a multiple of 16)
768 + -K keyframe: keyframe interval
769 + -S N[s]: skip the first N samples (or N seconds) of the sound when the movie starts.
770 + -C WxH+X+Y: crop a specific area of the movie.
771 + -b: disable seekbar.
772 + -l: disable loop.
773 + -z: make the movie scalable.
774 + ''' % argv[0]
775 + return 100
776 + try:
777 + (opts, args) = getopt.getopt(argv[1:], 'dr:o:t:cHa:S:C:B:K:f:F:R:s:blz')
778 + except getopt.GetoptError:
779 + return usage()
781 + debug = 0
782 + info = SWFInfo()
783 + range_str = '-'
784 + step = 1
785 + streamtype = None
786 + kfinterval = 0
787 + mp3skip = 0
788 + mp3seek = True
789 + loop = True
790 + seekbar = True
791 + for (k, v) in opts:
792 + if k == '-d':
793 + debug += 1
794 + elif k == '-r':
795 + info.set_framerate(float(v))
796 + elif k == '-o':
797 + info.filename = v
798 + elif k == '-t':
799 + v = v.lower()
800 + if v not in ('swf5','swf7','mpeg','mpg','flv','png','bmp','gif'):
801 + print >>stderr, 'Invalid output type:', v
802 + return usage()
803 + streamtype = v
804 + elif k == '-a':
805 + fp = file(v, 'rb')
806 + print >>stderr, 'Reading mp3 file: %s...' % v
807 + info.reg_mp3blocks(fp)
808 + fp.close()
809 + elif k == '-S':
810 + if v.endswith('s'):
811 + mp3skip = float(v[:-1])
812 + else:
813 + mp3skip = int(v)
814 + elif k == '-C':
815 + try:
816 + info.set_clipping(v)
817 + except ValueError:
818 + print >>stderr, 'Invalid clipping specification:', v
819 + return usage()
820 + elif k == '-B':
821 + blocksize = int(v)
822 + assert 0 < blocksize and blocksize <= 256 and blocksize % 16 == 0, 'Invalid block size.'
823 + info.blocksize = blocksize
824 + elif k == '-K':
825 + kfinterval = int(v)
826 + elif k == '-c':
827 + info.compression = True
828 + elif k == '-f':
829 + range_str = v
830 + elif k == '-F':
831 + range_str = v
832 + mp3seek = False
833 + elif k == '-R':
834 + step = int(v)
835 + mp3seek = False
836 + elif k == '-s':
837 + info.scaling = float(v)
838 + assert 0 < info.scaling and info.scaling <= 1.0, 'Invalid scaling.'
839 + elif k == '-b':
840 + seekbar = False
841 + elif k == '-l':
842 + loop = False
843 + elif k == '-z':
844 + info.set_scalable(True)
845 + if not args:
846 + print >>stderr, 'Specify at least one input movie.'
847 + return usage()
848 + if not info.filename:
849 + print >>stderr, 'Specify exactly one output file.'
850 + return usage()
851 + if not streamtype:
852 + v = info.filename
853 + if v.endswith('.swf'):
854 + streamtype = 'swf5'
855 + elif v.endswith('.png'):
856 + streamtype = 'png'
857 + elif v.endswith('.bmp'):
858 + streamtype = 'bmp'
859 + elif v.endswith('.gif'):
860 + streamtype = 'gif'
861 + elif v.endswith('.mpg') or v.endswith('.mpeg'):
862 + streamtype = 'mpeg'
863 + elif v.endswith('.flv'):
864 + streamtype = 'flv'
865 + else:
866 + print >>stderr, 'Unknown stream type.'
867 + return 100
868 + if streamtype == 'mpeg' and not MPEGVideoStream:
869 + print >>stderr, 'MPEGVideoStream is not supported.'
870 + return 100
871 + stream = None
872 + if streamtype == 'swf5':
873 + stream = SWFShapeStream(info, debug=debug)
874 + elif streamtype == 'swf7':
875 + stream = SWFVideoStream(info, debug=debug)
876 + elif streamtype in ('mpg', 'mpeg'):
877 + stream = MPEGVideoStream(info, debug=debug)
878 + elif streamtype == 'flv':
879 + stream = FLVVideoStream(info, debug=debug)
880 + else:
881 + stream = ImageSequenceStream(info, debug=debug)
882 + try:
883 + return reorganize(info, stream, args, range_str,
884 + loop=loop, seekbar=seekbar,
885 + step=step, kfinterval=kfinterval,
886 + mp3seek=mp3seek, mp3skip=mp3skip,
887 + debug=debug)
888 + except RangeError, e:
889 + print >>stderr, 'RangeError:', e
890 + return 100
892 +if __name__ == "__main__": sys.exit(main(sys.argv))
893 diff -Naur pyvnc2swf-0.9.5.old/bin/pyvnc2swf-play pyvnc2swf-0.9.5/bin/pyvnc2swf-play
894 --- pyvnc2swf-0.9.5.old/bin/pyvnc2swf-play 1969-12-31 18:00:00.000000000 -0600
895 +++ pyvnc2swf-0.9.5/bin/pyvnc2swf-play 2008-12-18 06:08:06.000000000 -0600
896 @@ -0,0 +1,275 @@
897 +#!/usr/bin/env python
899 +## pyvnc2swf - play.py
901 +## $Id: play.py,v 1.6 2008/11/16 02:39:40 euske Exp $
903 +## Copyright (C) 2005 by Yusuke Shinyama (yusuke at cs . nyu . edu)
904 +## All Rights Reserved.
906 +## This is free software; you can redistribute it and/or modify
907 +## it under the terms of the GNU General Public License as published by
908 +## the Free Software Foundation; either version 2 of the License, or
909 +## (at your option) any later version.
911 +## This software is distributed in the hope that it will be useful,
912 +## but WITHOUT ANY WARRANTY; without even the implied warranty of
913 +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
914 +## GNU General Public License for more details.
916 +## You should have received a copy of the GNU General Public License
917 +## along with this software; if not, write to the Free Software
918 +## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
919 +## USA.
922 +import sys, os.path, subprocess
923 +import pygame
924 +from pyvnc2swf.image import create_image_from_string_argb
925 +from pyvnc2swf.movie import SWFInfo, MovieContainer
926 +from pyvnc2swf.output import SWFScreen, MovieOutputStream, MovieBuilder
927 +lowerbound = max
928 +upperbound = min
929 +stderr = sys.stderr
932 +## PygameMoviePlayer
934 +class PygameMoviePlayer(MovieOutputStream):
936 + """
937 + A simple movie player using Pygame.
938 + """
940 + font_size = 24
942 + def __init__(self, movie, debug=0):
943 + MovieOutputStream.__init__(self, movie.info, debug)
944 + self.builder = MovieBuilder(movie, self, debug)
945 + self.movie = movie
946 + return
948 + # MovieOuputStream methods
950 + def open(self):
951 + MovieOutputStream.open(self)
952 + # open window
953 + (x,y,w,h) = self.info.clipping
954 + self.imagesize = ( int(w*(self.info.scaling or 1)), int(h*(self.info.scaling or 1)) )
955 + self.screen = SWFScreen(x, y, w, h)
956 + (self.winwidth, self.winheight) = self.imagesize
957 + self.font = pygame.font.SysFont(pygame.font.get_default_font(), self.font_size)
958 + (fw1,fh1) = self.font.size('00000 ')
959 + (fw2,fh2) = self.font.size('[>] ')
960 + self.panel_x0 = 0
961 + self.panel_x1 = fw1
962 + self.panel_x2 = fw1+fw2
963 + self.panel_y0 = self.winheight
964 + self.panel_y1 = self.winheight + fh1/2
965 + self.panel_h = fh1
966 + self.panel_w = lowerbound(64, self.winwidth-fw1-fw2-4)
967 + self.slide_h = fh1/2
968 + self.slide_w = 8
969 + self.actualwidth = self.panel_w+fw1+fw2+4
970 + pygame.display.set_caption(self.info.filename, self.info.filename)
971 + self.window = pygame.display.set_mode((self.actualwidth, self.winheight+self.panel_h))
972 + self.cursor_image = None
973 + self.cursor_pos = None
974 + self.playing = True
975 + self.mp3_out = self.mp3_dec = None
976 + #import pymedia
977 + #self.mp3_out = subprocess.Popen(['mpg123','-q','-'], stdin=subprocess.PIPE)
978 + #self.mp3_dec = pymedia.audio.acodec.Decoder('mp3')
979 + #self.mp3_out = pymedia.audio.sound.Output(44100,2,pymedia.audio.sound.AFMT_S16_LE)
980 + return
982 + def paint_frame(self, (images, othertags, cursor_info)):
983 + for ((x0,y0), (w,h,data)) in images:
984 + self.screen.paint_image(x0, y0, w, h, data)
985 + if cursor_info:
986 + (cursor_image, cursor_pos) = cursor_info
987 + if cursor_image:
988 + (w, h, dx, dy, data) = cursor_image
989 + self.cursor_offset = (dx, dy)
990 + self.cursor_image = create_image_from_string_argb(w, h, data)
991 + if cursor_pos:
992 + self.cursor_pos = cursor_pos
993 + return
995 + def preserve_frame(self):
996 + img = pygame.Surface(self.screen.buf.get_size())
997 + img.blit(self.screen.buf, (0,0))
998 + return img
1000 + def recover_frame(self, img):
1001 + self.screen.buf.blit(img, (0,0))
1002 + return
1004 + # additional methods
1006 + def show_status(self):
1007 + f = self.current_frame
1008 + n = self.movie.nframes
1009 + s = '%05d' % f
1010 + self.window.fill((0,0,0), (0, self.panel_y0, self.actualwidth, self.panel_h))
1011 + self.window.blit(self.font.render(s, 0, (255,255,255)), (0, self.panel_y0))
1012 + if self.playing:
1013 + self.window.blit(self.font.render('[>]', 0, (0,255,0)), (self.panel_x1, self.panel_y0))
1014 + else:
1015 + self.window.blit(self.font.render('[||]', 0, (255,0,0)), (self.panel_x1, self.panel_y0))
1016 + self.window.fill((255,255,255), (self.panel_x2, self.panel_y1, self.panel_w, 1))
1017 + x = self.panel_x2 + self.panel_w*f/n - self.slide_w/2
1018 + y = self.panel_y1 - self.slide_h/2
1019 + self.window.fill((255,255,255), (x, y, self.slide_w, self.slide_h))
1020 + return
1022 + def update(self):
1023 + surface = self.screen.buf
1024 + if self.info.scaling:
1025 + # rotozoom is still very unstable... it sometime causes segfault :(
1026 + # in case it doesn't work, use scale instead.
1027 + # surface = pygame.transform.scale(surface, self.imagesize)
1028 + # surface.set_alpha()
1029 + surface = pygame.transform.rotozoom(surface, 0, self.info.scaling)
1030 + self.window.blit(surface, (0,0))
1031 + if self.cursor_image and self.cursor_pos:
1032 + (x, y) = self.cursor_pos
1033 + (dx, dy) = self.cursor_offset
1034 + self.window.blit(self.cursor_image, (x-dx, y-dy))
1035 + self.show_status()
1036 + pygame.display.update()
1037 + if self.mp3_out and self.info.mp3:
1038 + t = (self.current_frame+1) / self.info.framerate
1039 + (nsamples, seeksamples, mp3frames) = self.info.mp3.get_frames_until(t)
1040 + r = self.mp3_dec.decode(''.join(mp3frames))
1041 + self.mp3_out.play(r.data)
1042 + return
1044 + def toggle_playing(self):
1045 + self.playing = not self.playing
1046 + if self.playing and self.movie.nframes-1 <= self.current_frame:
1047 + self.current_frame = 0
1048 + return
1050 + def seek(self, goal):
1051 + self.current_frame = upperbound(lowerbound(goal, 0), self.movie.nframes-1)
1052 + self.builder.seek(self.current_frame)
1053 + self.playing = False
1054 + self.update()
1055 + return
1057 + def play(self):
1058 + drag = False
1059 + loop = True
1060 + ticks0 = 0
1061 + self.current_frame = 0
1062 + self.builder.start()
1063 + while loop:
1064 + if self.playing:
1065 + events = pygame.event.get()
1066 + else:
1067 + events = [pygame.event.wait()]
1068 + for e in events:
1069 + if e.type in (pygame.MOUSEBUTTONDOWN, pygame.MOUSEMOTION):
1070 + (x,y) = e.pos
1071 + if (e.type == pygame.MOUSEBUTTONDOWN and y < self.panel_y0):
1072 + # the screen clicked
1073 + self.toggle_playing()
1074 + elif (self.panel_y0 < y and (e.type == pygame.MOUSEBUTTONDOWN or drag)):
1075 + # slide bar dragging
1076 + drag = True
1077 + (x,y) = e.pos
1078 + self.seek((x-self.panel_x2)*self.movie.nframes/self.panel_w)
1079 + elif e.type == pygame.MOUSEBUTTONUP:
1080 + drag = False
1081 + elif e.type == pygame.KEYDOWN:
1082 + if e.key in (13, 32): # space or enter
1083 + self.toggle_playing()
1084 + elif e.key in (113, 27): # 'q'uit, esc
1085 + loop = False
1086 + elif e.key in (115, 83): # 's'napshot
1087 + (root, ext) = os.path.splitext(self.info.filename)
1088 + fname = '%s-%05d.bmp' % (root, self.current_frame)
1089 + pygame.image.save(self.screen.buf, fname)
1090 + print >>stderr, 'Save:', fname
1091 + elif e.key == 275: # right
1092 + self.current_frame += 1
1093 + self.seek(self.current_frame)
1094 + elif e.key == 276: # left
1095 + self.current_frame -= 1
1096 + self.seek(self.current_frame)
1097 + else:
1098 + print >>stderr, 'Unknown key:', e
1099 + elif e.type == pygame.QUIT:
1100 + # window close attmpt
1101 + loop = False
1102 + if self.playing:
1103 + self.builder.seek(self.current_frame)
1104 + if self.movie.nframes-1 <= self.current_frame:
1105 + # reach the end.
1106 + self.playing = False
1107 + else:
1108 + self.current_frame += 1
1109 + ticks1 = pygame.time.get_ticks()
1110 + d = lowerbound(int(1000.0/self.info.framerate), ticks0-ticks1)
1111 + ticks0 = ticks1
1112 + pygame.time.wait(d)
1113 + self.update()
1114 + # loop end
1115 + self.builder.finish()
1116 + self.close()
1117 + return
1120 +# play
1121 +def play(moviefiles, info, debug=0):
1122 + movie = MovieContainer(info)
1123 + for fname in moviefiles:
1124 + if fname.endswith('.swf'):
1125 + # vnc2swf file
1126 + movie.parse_vnc2swf(fname, True, debug=debug)
1127 + elif fname.endswith('.flv'):
1128 + # flv file
1129 + movie.parse_flv(fname, True, debug=debug)
1130 + elif fname.endswith('.vnc'):
1131 + # vncrec file
1132 + movie.parse_vncrec(fname, debug=debug)
1133 + else:
1134 + raise ValueError('unsupported format: %r' % fname)
1135 + info.filename = os.path.basename(fname)
1136 + PygameMoviePlayer(movie, debug=debug).play()
1137 + return
1139 +# main
1140 +def main(argv):
1141 + import getopt, re
1142 + def usage():
1143 + print 'usage: %s [-d] [-r framerate] [-C WxH+X+Y] [-s scaling] file1 file2 ...' % argv[0]
1144 + return 100
1145 + try:
1146 + (opts, args) = getopt.getopt(argv[1:], 'dr:C:s:')
1147 + except getopt.GetoptError:
1148 + return usage()
1150 + debug = 0
1151 + info = SWFInfo()
1152 + for (k, v) in opts:
1153 + if k == '-d':
1154 + debug += 1
1155 + elif k == '-r':
1156 + info.set_framerate(float(v))
1157 + elif k == '-C':
1158 + m = re.match(r'^(\d+)x(\d+)\+(\d+)\+(\d+)$', v)
1159 + if not m:
1160 + print >>stderr, 'Invalid clipping specification:', v
1161 + return usage()
1162 + x = map(int, m.groups())
1163 + info.clipping = (x[2],x[3], x[0],x[1])
1164 + elif k == '-s':
1165 + info.scaling = float(v)
1166 + if not args:
1167 + print >>stderr, 'Specify at least one input movie.'
1168 + return usage()
1169 + return play(args, info, debug=debug)
1171 +if __name__ == "__main__": sys.exit(main(sys.argv))
1172 diff -Naur pyvnc2swf-0.9.5.old/bin/recordwin pyvnc2swf-0.9.5/bin/recordwin
1173 --- pyvnc2swf-0.9.5.old/bin/recordwin 1969-12-31 18:00:00.000000000 -0600
1174 +++ pyvnc2swf-0.9.5/bin/recordwin 2008-11-15 20:39:40.000000000 -0600
1175 @@ -0,0 +1,60 @@
1176 +#!/bin/sh
1178 +## recordwin.sh
1179 +## $Id: recordwin.sh,v 1.3 2008/11/16 02:39:40 euske Exp $
1181 +## Quick recording script for UNIX.
1183 +## usage:
1184 +## recordwin.sh [-display disp] [-name winname] [-id winid] output.swf
1186 +## Requires: x11vnc, xwininfo, awk
1189 +PYTHON=python
1190 +VNC2SWF=pyvnc2swf/vnc2swf.py
1191 +X11VNC=x11vnc
1192 +XWININFO=xwininfo
1193 +AWK=awk
1195 +usage() {
1196 + echo "usage: $0 [-all] [-display display] [-name windowname] [-id windowid] [-type filetype] outfile"
1197 + exit 100
1200 +vncopts=
1201 +xwopts=
1202 +desktop=
1203 +display="$DISPLAY"
1204 +while [ $# -gt 1 ]; do
1205 + case "$1" in
1206 + -all|-a) desktop=1;;
1207 + -name) shift; xwopts="$xwopts -name $1";;
1208 + -id) shift; xwopts="$xwopts -id $1";;
1209 + -display|-d) shift; display="$1"; xwopts="$xwopts -display $1";;
1210 + -type|-t) shift; vncopts="$vncopts -t $1";;
1211 + -*) usage;;
1212 + esac
1213 + shift
1214 +done
1216 +if [ $# -lt 1 ]; then usage; fi
1218 +outfile="$1"
1219 +if [ "X$desktop" = "X" ]; then
1220 + info=`$XWININFO $xwopts 2>/dev/null`
1221 + if [ "X$info" = "X" ]; then
1222 + echo "Window $xwopts not found!"
1223 + exit 2
1224 + fi
1225 + geometry="-C `echo "$info" |
1226 + $AWK '/Absolute upper-left X:/{x=$4}
1227 + /Absolute upper-left Y:/{y=$4}
1228 + /Width:/{w=$2} /Height:/{h=$2}
1229 + END {printf "%dx%d+%d+%d",w,h,x,y}' `"
1230 + echo $geometry
1233 +# launch x11vnc and vnc2swf
1234 +$X11VNC -quiet -bg -nopw -display "$display" -viewonly -localhost -cursor -wait 10 -defer 10 &&
1235 + $PYTHON $VNC2SWF -n $vncopts -o "$outfile" $geometry
1236 diff -Naur pyvnc2swf-0.9.5.old/bin/recordwin.sh pyvnc2swf-0.9.5/bin/recordwin.sh
1237 --- pyvnc2swf-0.9.5.old/bin/recordwin.sh 2008-12-18 06:06:38.000000000 -0600
1238 +++ pyvnc2swf-0.9.5/bin/recordwin.sh 1969-12-31 18:00:00.000000000 -0600
1239 @@ -1,60 +0,0 @@
1240 -#!/bin/sh
1242 -## recordwin.sh
1243 -## $Id: recordwin.sh,v 1.3 2008/11/16 02:39:40 euske Exp $
1245 -## Quick recording script for UNIX.
1247 -## usage:
1248 -## recordwin.sh [-display disp] [-name winname] [-id winid] output.swf
1250 -## Requires: x11vnc, xwininfo, awk
1253 -PYTHON=python
1254 -VNC2SWF=pyvnc2swf/vnc2swf.py
1255 -X11VNC=x11vnc
1256 -XWININFO=xwininfo
1257 -AWK=awk
1259 -usage() {
1260 - echo "usage: $0 [-all] [-display display] [-name windowname] [-id windowid] [-type filetype] outfile"
1261 - exit 100
1264 -vncopts=
1265 -xwopts=
1266 -desktop=
1267 -display="$DISPLAY"
1268 -while [ $# -gt 1 ]; do
1269 - case "$1" in
1270 - -all|-a) desktop=1;;
1271 - -name) shift; xwopts="$xwopts -name $1";;
1272 - -id) shift; xwopts="$xwopts -id $1";;
1273 - -display|-d) shift; display="$1"; xwopts="$xwopts -display $1";;
1274 - -type|-t) shift; vncopts="$vncopts -t $1";;
1275 - -*) usage;;
1276 - esac
1277 - shift
1278 -done
1280 -if [ $# -lt 1 ]; then usage; fi
1282 -outfile="$1"
1283 -if [ "X$desktop" = "X" ]; then
1284 - info=`$XWININFO $xwopts 2>/dev/null`
1285 - if [ "X$info" = "X" ]; then
1286 - echo "Window $xwopts not found!"
1287 - exit 2
1288 - fi
1289 - geometry="-C `echo "$info" |
1290 - $AWK '/Absolute upper-left X:/{x=$4}
1291 - /Absolute upper-left Y:/{y=$4}
1292 - /Width:/{w=$2} /Height:/{h=$2}
1293 - END {printf "%dx%d+%d+%d",w,h,x,y}' `"
1294 - echo $geometry
1297 -# launch x11vnc and vnc2swf
1298 -$X11VNC -quiet -bg -nopw -display "$display" -viewonly -localhost -cursor -wait 10 -defer 10 &&
1299 - $PYTHON $VNC2SWF -n $vncopts -o "$outfile" $geometry