📄 vb.py
字号:
#! /usr/bin/env python# Video bag of tricks: record video(+audio) in various formats and modes# XXX To do:# - audio# - improve user interface# - help button?# - command line options to set initial settings# - save settings in a file# - ...?import sysimport timeimport getoptimport stringimport ossts = os.system('makemap') # Must be before "import fl" to workimport sgiimport glimport GLimport DEVICEimport flimport FLimport flpimport watchcursorimport svimport SVimport VFileimport VGrabberimport imageopsys.path.append('/ufs/jack/src/av/vcr')import VCRtry: import clexcept ImportError: cl = NoneARROW = 0WATCH = 1watchcursor.defwatch(WATCH)def main():## fl.set_graphics_mode(0, 1) vb = VideoBagOfTricks() while 1: dummy = fl.do_forms() [dummy]StopCapture = 'StopCapture'VideoFormatLabels = ['Video off', 'rgb8', 'grey8', 'grey4', 'grey2', \ 'grey2 dith', 'mono dith', 'mono thresh', 'rgb24', 'rgb24-jpeg', \ 'compress']VideoFormats = ['', 'rgb8', 'grey', 'grey4', 'grey2', \ 'grey2', 'mono', 'mono', 'rgb', 'jpeg', 'compress']VideoModeLabels = ['Continuous', 'Burst', 'Single frame', 'VCR sync'][VM_CONT, VM_BURST, VM_SINGLE, VM_VCR] = range(1, 5)AudioFormatLabels = ['Audio off', \ '16 bit mono', '16 bit stereo', '8 bit mono', '8 bit stereo'][A_OFF, A_16_MONO, A_16_STEREO, A_8_MONO, A_8_STEREO] = range(1, 6)VcrSpeedLabels = ['normal', '1/3', '1/5', '1/10', '1/30', 'single-step']VcrSpeeds = [None, 5, 4, 3, 2, 1, 0]RgbSizeLabels = ['full', 'quarter', 'sixteenth']# init file stuff:if os.environ.has_key('HOME'): HOME=os.environ['HOME']else: HOME='.'VB_INIT_FILE=HOME + '/.Vb_init'VB_INIT_KEYS=['vfile', 'vmode', 'mono_thresh', 'vformat', 'comp_scheme', \ 'rgb24_size', 'afile', 'aformat']class VideoBagOfTricks: # Init/close stuff def __init__(self): self.window = None formdef = flp.parse_form('VbForm', 'form') flp.create_full_form(self, formdef) self.setdefaults() if self.vmode <> VM_CONT: self.g_cont.hide_object() if self.vmode <> VM_BURST: self.g_burst.hide_object() if self.vmode <> VM_SINGLE: self.g_single.hide_object() if self.vmode <> VM_VCR: self.g_vcr.hide_object() if self.vformat <> 'compress': self.g_compress.hide_object() self.openvideo() self.makewindow() self.bindvideo() if self.use_24: self.optfullsizewindow() self.showform() fl.set_event_call_back(self.do_event) def close(self): self.close_video() self.close_audio() self.savedefaults() raise SystemExit, 0 def showform(self): # Get position of video window gl.winset(self.window) x, y = gl.getorigin() width, height = gl.getsize() # Calculate position of form window x1 = x + width + 10 x2 = x1 + int(self.form.w) - 1 y2 = y + height - 1 y1 = y2 - int(self.form.h) + 1 # Position and show form window gl.prefposition(x1, x2, y1, y2) self.form.show_form(FL.PLACE_FREE, FL.TRUE, 'Vb Control') def getdefaultdefaults(self): # Video defaults self.vfile = 'film.video' self.vmode = VM_CONT self.mono_thresh = 128 self.vformat = 'rgb8' self.comp_scheme = 'Uncompressed' self.rgb24_size = 1 # Missing: drop, rate, maxmem, nframes, rate, vcrspeed # Audio defaults: self.afile = 'film.aiff' self.aformat = A_OFF def getdefaults(self): self.getdefaultdefaults() # XXXX Read defaults file and override. try: fp = open(VB_INIT_FILE, 'r') except IOError: print 'Vb: no init file' self.initcont = {} return data = fp.read(1000000) try: self.initcont = eval(data) except: print 'Vb: Ill-formatted init file' self.initcont = {} for k in self.initcont.keys(): if hasattr(self, k): setattr(self, k, self.initcont[k]) def savedefaults(self): newdb = {} for k in VB_INIT_KEYS: newdb[k] = getattr(self, k) if newdb <> self.initcont: try: fp = open(VB_INIT_FILE, 'w') except IOError: print 'Vb: Cannot create', VB_INIT_FILE return fp.write(`newdb`) fp.close() def setdefaults(self): self.getdefaults() self.vcr = None self.vout = None self.capturing = 0 self.c_vformat.clear_choice() for label in VideoFormatLabels: self.c_vformat.addto_choice(label) self.c_vformat.set_choice(1 + VideoFormats.index(self.vformat)) self.c_vmode.clear_choice() for label in VideoModeLabels: self.c_vmode.addto_choice(label) self.c_vmode.set_choice(self.vmode) self.get_vformat() self.b_drop.set_button(1) self.in_rate.set_input('2') self.in_maxmem.set_input('1.0') self.in_nframes.set_input('0') self.in_nframes_vcr.set_input('1') self.in_rate_vcr.set_input('1') self.c_vcrspeed.clear_choice() for label in VcrSpeedLabels: self.c_vcrspeed.addto_choice(label) self.c_vcrspeed.set_choice(4) self.c_rgb24_size.clear_choice() for label in RgbSizeLabels: self.c_rgb24_size.addto_choice(label) self.c_rgb24_size.set_choice(self.rgb24_size) if cl: algs = cl.QueryAlgorithms(cl.VIDEO) self.all_comp_schemes = [] for i in range(0, len(algs), 2): if algs[i+1] in (cl.COMPRESSOR, cl.CODEC): self.all_comp_schemes.append(algs[i]) self.c_cformat.clear_choice() for label in self.all_comp_schemes: self.c_cformat.addto_choice(label) i = self.all_comp_schemes.index(self.comp_scheme) self.c_cformat.set_choice(i+1) # Audio defaults self.aout = None self.aport = None self.c_aformat.clear_choice() for label in AudioFormatLabels: self.c_aformat.addto_choice(label) self.c_aformat.set_choice(self.aformat) self.get_aformat() def openvideo(self): try: self.video = sv.OpenVideo() except sv.error, msg: print 'Error opening video:', msg self.video = None param = [SV.BROADCAST, SV.PAL] if self.video: self.video.GetParam(param) if param[1] == SV.PAL: x = SV.PAL_XMAX y = SV.PAL_YMAX elif param[1] == SV.NTSC: x = SV.NTSC_XMAX y = SV.NTSC_YMAX else: print 'Unknown video standard:', param[1] sys.exit(1) self.maxx, self.maxy = x, y self.curx = 256 self.cury = 256*3/4 def makewindow(self): x, y = self.maxx, self.maxy gl.foreground() gl.maxsize(x, y) gl.keepaspect(x, y) gl.stepunit(8, 6) width = self.curx height = self.cury if width and height: # Place the window at (150, 150) from top left # (the video board likes this location...) x1 = 150 x2 = x1+width-1 SCRHEIGHT = 768 y2 = SCRHEIGHT-1-150 y1 = y2-height+1 gl.prefposition(x1, x2, y1, y2) self.window = gl.winopen('Vb video') self.settitle() if width: gl.maxsize(x, y) gl.keepaspect(x, y) gl.stepunit(8, 6) gl.winconstraints() gl.qdevice(DEVICE.LEFTMOUSE) gl.qdevice(DEVICE.WINQUIT) gl.qdevice(DEVICE.WINSHUT) def optfullsizewindow(self): if not self.window: return gl.winset(self.window) if self.use_24: x, y = self.maxx, self.maxy else: x, y = self.curx, self.cury left, bottom = gl.getorigin() width, height = gl.getsize() bottom = bottom+height-y gl.prefposition(left, left+x-1, bottom, bottom+y-1) gl.winconstraints() if not self.use_24: gl.keepaspect(x, y) gl.stepunit(8, 6) gl.maxsize(self.maxx, self.maxy) gl.winconstraints() self.bindvideo() def bindvideo(self): if not self.video: return x, y = gl.getsize() if not self.use_24: self.curx, self.cury = x, y self.video.SetSize(x, y) drop = self.b_drop.get_button() if drop: param = [SV.FIELDDROP, 1, SV.GENLOCK, SV.GENLOCK_OFF] else: param = [SV.FIELDDROP, 0, SV.GENLOCK, SV.GENLOCK_ON] if self.rgb: param = param+[SV.COLOR, SV.DEFAULT_COLOR, \ SV.DITHER, 1, \ SV.INPUT_BYPASS, 0] else: param = param+[SV.COLOR, SV.MONO, SV.DITHER, 0, \ SV.INPUT_BYPASS, 1] self.video.BindGLWindow(self.window, SV.IN_REPLACE) self.video.SetParam(param) def rebindvideo(self): gl.winset(self.window) self.bindvideo() def reset(self): self.close_video() self.close_audio() if self.vcr: try: ok = self.vcr.still() except VCR.error: pass self.vcr = None self.b_capture.set_button(0) # Event handler (catches resize of video window) def do_event(self, dev, val): #print 'Event:', dev, val if dev in (DEVICE.WINSHUT, DEVICE.WINQUIT): self.close() if dev == DEVICE.REDRAW and val == self.window: self.rebindvideo() self.settitle() # Video controls: format, mode, file def cb_vformat(self, *args): self.reset() self.get_vformat() if self.mono_use_thresh: s = `self.mono_thresh` s = fl.show_input('Please enter mono threshold', s) if s: try: self.mono_thresh = string.atoi(s) except string.atoi_error: fl.show_message('Bad input, using', \ `self.mono_thresh`, '') self.rebindvideo() def cb_cformat(self, *args): i = self.c_cformat.get_choice() self.comp_scheme = self.all_comp_schemes[i-1] def cb_vmode(self, *args): if self.vcr: self.vcr = None self.vmode = self.c_vmode.get_choice() self.form.freeze_form() self.g_cont.hide_object() self.g_burst.hide_object() self.g_single.hide_object() self.g_vcr.hide_object() if self.vmode == VM_CONT: self.g_cont.show_object() elif self.vmode == VM_BURST: self.g_burst.show_object() elif self.vmode == VM_SINGLE: self.g_single.show_object() elif self.vmode == VM_VCR: self.g_vcr.show_object() self.form.unfreeze_form() def cb_vfile(self, *args): filename = self.vfile hd, tl = os.path.split(filename) filename = fl.file_selector('Video save file:', hd, '', tl) if filename: self.reset() hd, tl = os.path.split(filename) if hd == os.getcwd(): filename = tl self.vfile = filename # Video mode specific video controls def cb_rate(self, *args): pass def cb_drop(self, *args): self.rebindvideo() def cb_maxmem(self, *args): pass def cb_nframes(self, *args): pass def cb_fps(self, *args): pass def cb_nframes_vcr(self, *args): pass def cb_rate_vcr(self, *args): pass def cb_vcrspeed(self, *args): pass def cb_rgb24_size(self, *args): i = self.c_rgb24_size.get_choice() if i: self.rgb24_size = i # Audio controls: format, file def cb_aformat(self, *args): self.get_aformat() def cb_afile(self, *args): filename = self.afile hd, tl = os.path.split(filename) filename = fl.file_selector('Audio save file:', hd, '', tl) if filename: self.reset() hd, tl = os.path.split(filename) if hd == os.getcwd(): filename = tl self.afile = filename # General controls: capture, reset, play, quit def cb_capture(self, *args): if self.capturing: raise StopCapture if not self.b_capture.get_button(): return if not self.video or not self.vformat: gl.ringbell() return if self.vmode == VM_CONT: self.cont_capture() elif self.vmode == VM_BURST: self.burst_capture() elif self.vmode == VM_SINGLE: self.single_capture(None, None) elif self.vmode == VM_VCR: self.vcr_capture() def cb_reset(self, *args): self.reset() def cb_play(self, *args): self.reset() sts = os.system('Vplay -q ' + self.vfile + ' &') def cb_quit(self, *args): self.close() # Capture routines def burst_capture(self): self.setwatch() gl.winset(self.window) x, y = gl.getsize() if self.use_24: fl.show_message('Sorry, no 24 bit continuous capture yet', '', '') return vformat = SV.RGB8_FRAMES nframes = self.getint(self.in_nframes, 0) if nframes == 0: maxmem = self.getint(self.in_maxmem, 1.0) memsize = int(maxmem * 1024 * 1024) nframes = self.calcnframes(memsize) info = (vformat, x, y, nframes, 1) try: info2, data, bitvec = self.video.CaptureBurst(info) except sv.error, msg: self.b_capture.set_button(0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -