def exec_subprocess(self, script_file): """Reimplemented from BasicWorker. Args: script_file (str): path to execution py Returns: (any): app launch result """ # Get launcher arguments for psylaunch print '[worker] EXEC MAYA SUBPROCESS' _app_name = self.payload.get("app_name", "mayapy") _app_ver = self.payload.get("app_version") _args = [script_file] # Launch and wait for maya batch process. print '[worker] LAUNCHING MAYA', _app_name, _app_ver, _args _result = psylaunch.launch_app(_app_name, version=_app_ver, args=_args, wait=True) print '[worker] LAUNCHED APP', _result return _result
def _seq_to_mov_ffmpeg(seq, mov, fps): """Generate a mov using ffmpeg. Args: seq (Seq): input sequence mov (str): output mov fps (float): mov frame rate """ from psyhive import pipe _start, _end = seq.find_range(force=True) _mov = Movie(get_path(mov)) assert not _mov.exists() assert _mov.extn.lower() in ['mov', 'mp4'] _mov.test_dir() # Use ffmpeg through psylaunch if pipe.LOCATION == 'psy': import psylaunch _args = [ '-r', str(fps), '-f', 'image2', '-i', seq.path, '-vcodec', 'libx264', '-crf', '25', '-pix_fmt', 'yuv420p', _mov.path ] print 'launch ffmpeg --', ' '.join(_args) psylaunch.launch_app('ffmpeg', args=_args, wait=True) # Use ffmpeg directly else: _args = [ 'ffmpeg', '-r', str(fps), '-f', 'image2', '-i', '"{}"'.format(seq.path), '-vcodec', 'libx264', '-crf', '25', '-pix_fmt', 'yuv420p', '"{}"'.format(_mov.path) ] if _start != 1: _idx = _args.index('-i') _args.insert(_idx, '-start_number') _args.insert(_idx + 1, str(_start)) _cmd = ' '.join(_args) print _cmd os.system(_cmd) if not _mov.exists(): raise RuntimeError("Failed to generate " + _mov.path)
def _get_ref_jpgs(mov, start, secs): """Get reference mov jpg sequence. If no reference mov was found, None is returns. Otherwise, the section of the reference mov relating to this work (based on ref_movs.data spreadsheet) is baked out to a tmp jpg sequence. Args: mov (str): path to mov to extract start (float): start seconds secs (float): duration of section to bake Returns: (Seq|None): tmp reference jpgs (if any) """ print ' - MOV', start, mov # Prepare tmp seq _ref_tmp_jpgs = Seq( abs_path('{}/ref_tmp/images.%04d.jpg'.format(tempfile.gettempdir()))) _ref_tmp_jpgs.test_dir() _ref_tmp_jpgs.delete(force=True) # Run ffmpeg _args = [ '-i', mov, '-vf', "fps=30,select='between(t,{:.02f},{:.02f})'".format( start, start + secs), '-vsync', '0', _ref_tmp_jpgs.path, ] print 'launch ffmpeg --', ' '.join(_args) psylaunch.launch_app('ffmpeg', args=_args, wait=True) print ' - WROTE TO', _ref_tmp_jpgs.path print ' - REF JPGS {} {}'.format(_ref_tmp_jpgs.find_range(force=True), _ref_tmp_jpgs.path) return _ref_tmp_jpgs
def process_movs_for_review(src_dir): """Search dir for groups of 3 input movs to comp into review mov. Args: src_dir (str): dir to search for input movs """ print 'SRC DIR', src_dir _tmp_py = abs_path('{}/process_movs_for_review.py'.format( tempfile.gettempdir())) print ' - TMP PY', _tmp_py _py = '\n'.join([ 'import nuke', 'import psyhive', 'from nuke_psyhive.shows import frasier', 'frasier.process_review_movs(dir_="{dir}")' ]).format(dir=src_dir) print print _py print File(_tmp_py).write_text(_py, force=True) psylaunch.launch_app('nuke', args=['-t', _tmp_py], wait=True)
def edit(self, line_n=None, verbose=0): """Edit this file in a text editor. Args: line_n (int): line of the file to open verbose (int): print process data """ from ..misc import lprint from .p_tools import abs_path _arg = self.path if line_n: _arg += ':{:d}'.format(line_n) # Try using sublime executable _subl_exe = os.environ.get('SUBLIME_EXE') if not _subl_exe: for _exe in [ 'C:/Program Files/Sublime Text 3/subl.exe', 'C:/Program Files (x86)/Sublime Text 3/subl.exe', ]: if os.path.exists(_exe): _subl_exe = abs_path(_exe, win=os.name == 'nt') break lprint('MISSING EXE', _exe, verbose=verbose) if _subl_exe: lprint('EXE', _subl_exe, verbose=verbose) _cmds = [_subl_exe, _arg] system(_cmds, verbose=verbose, result=False) return # Try using psylaunch dprint('Using psylaunch sublime - it may be quicker to install it ' 'locally on your machine.') import psylaunch psylaunch.launch_app('sublimetext', args=[_arg])
def _view_seq(path, viewer=None, verbose=0): """View an image sequence or movie file. Args: path (str): path to images/movie to view viewer (str): viewer to use verbose (int): print process data """ _viewer = viewer or os.environ.get('VIEWER', 'rv') print 'VIEW SEQ', path, _viewer if _viewer == 'djv_view': _path = path.replace("%04d", "#") _cmd = 'djv_view "{}" &'.format(_path) lprint(_cmd, verbose=verbose) os.system(_cmd) elif _viewer == 'rv': import psylaunch dprint('Launching psylaunch rv') psylaunch.launch_app('rv', args=[path, '-play']) else: raise ValueError(_viewer)
def _generate_blast_comp_mov(work, ref_imgs=True, comp_imgs=True, margin=20, thumb_aspect=0.75): """Generate blast comp mov file for the given work. Args: work (FrasierWork): work file to comp images for ref_imgs (bool): generate ref jpgs (disable for debugging) comp_imgs (bool): generate comp jpgs (disable for debugging) margin (int): face ref/blast overlay margin in pixels thumb_aspect (float): aspect ration of face ref/blast overlay """ print 'WORK', work.path assert work.blast.exists() assert work.face_blast.exists() assert not work.blast_comp.exists() _start, _end = work.blast.find_range() _dur_secs = 1.0 * (_end - _start + 1) / 30 print ' - BLAST COMP', work.blast_comp.path print ' - RANGE {:d}-{:d} ({:.02f}s)'.format(_start, _end, _dur_secs) # Generate tmp ref jpgs if ref_imgs and work.get_ref_mov(): _mov, _start = work.get_ref_data() _ref_tmp_jpgs = _get_ref_jpgs(mov=_mov, start=_start, secs=_dur_secs) else: _ref_tmp_jpgs = Seq( abs_path('{}/ref_tmp/images.%04d.jpg'.format( tempfile.gettempdir()))) _ref_tmp_jpgs.delete(force=True) print ' - REF JPG', _ref_tmp_jpgs # Build comp jpgs _comp_tmp_jpgs = Seq( abs_path('{}/comp_tmp/images.%04d.jpg'.format(tempfile.gettempdir()))) if comp_imgs: _comp_tmp_jpgs.test_dir() _comp_tmp_jpgs.delete(force=True) for _idx, _src_frame in qt.progress_bar(enumerate( work.blast.get_frames()), 'Comping {:d} images', stack_key='FrasierBlastComp', col='GreenYellow'): _out = qt.HPixmap(work.blast[_src_frame]) _face = qt.HPixmap(work.face_blast[_src_frame]) _thumb_w = (1.0 * _out.width() / 3 - margin * 3) / 2 _thumb_size = qt.get_size(_thumb_w, _thumb_w / thumb_aspect) # Add ref overlay if _ref_tmp_jpgs: _ref = qt.HPixmap(_ref_tmp_jpgs[_idx + 1]) _ref = _ref.resize(_thumb_size) _out.add_overlay(_ref, pos=(_out.width() * 2 / 3 + margin, margin)) # Add face blast overlay _face_size = qt.get_size(_face.height() * thumb_aspect, _face.height()) _face = _face.copy(_face.width() / 2 - _face_size.width() / 2, 0, _face_size.width(), _face_size.height()) _face = _face.resize(_thumb_size) _out.add_overlay(_face, pos=(_out.width() - margin, margin), anchor="TR") _out.save(_comp_tmp_jpgs[_idx + 1]) print ' - WROTE TMP IMAGES', _comp_tmp_jpgs.path print ' - COMP IMAGES {} {}'.format(_comp_tmp_jpgs.find_range(force=True), _comp_tmp_jpgs.path) # Compile out mov work.blast_comp.test_dir() _args = [ '-r', '30', '-f', 'image2', '-i', _comp_tmp_jpgs.path, '-vcodec', 'libx264', '-crf', '25', '-pix_fmt', 'yuv420p', work.blast_comp.path ] print 'launch ffmpeg --', ' '.join(_args) psylaunch.launch_app('ffmpeg', args=_args, wait=True) assert work.blast_comp.exists() print ' - WROTE MOV', work.blast_comp.path