def _find_all_outputs(self): from dayu_ffmpeg.network import Output, OutputHolder from dayu_ffmpeg.errors.base import DayuFFmpegException if self.max_output_num == 0: all_outputs = [ n for n in self.inside_nodes if isinstance(n, Output) ] if not all_outputs: raise DayuFFmpegException( 'there is no output node, cannot generate cmd! ' 'please attach some output node') else: all_outputs = [] for n in self.inside_nodes: if isinstance(n, Output): all_outputs.append(n) if isinstance(n, OutputHolder): out = next((o for o in n.traverse_outputs() if isinstance(o, Output)), None) if not out: raise DayuFFmpegException( 'an OutputHolder not connect to a Output node, ' 'please make sure every OutputHolder is connected.' ) all_outputs.append(out) return all_outputs
def _ensure_ad_hoc(self): from dayu_ffmpeg.errors.base import DayuFFmpegException for n in self.traverse_inputs(): if n.max_input_num > 1: raise DayuFFmpegException('{} input count is not 1, not supported in ad-hoc mode'.format(n)) if self.validate() is False: raise DayuFFmpegException('{} is not validate, may missing input'.format(n))
def __rshift__(self, other): from dayu_ffmpeg.network import AbstractHolder, BaseGroupNode from dayu_ffmpeg.errors.base import DayuFFmpegException if not isinstance(other, BaseNode): raise DayuFFmpegException('{} not a BaseNode!'.format(other)) if other.order_score < self.order_score and other.order_score != 0: raise DayuFFmpegException( '{} should be on the left of {}, order error'.format( other, self)) if isinstance(other, (AbstractHolder, BaseGroupNode)): raise DayuFFmpegException( '{} not support in ad-hoc mode, use complex mode instead!'. format(other)) if self.max_output_num != 1: raise DayuFFmpegException( '{}\'s output num is not 1, ' 'so not support in ad-hoc mode, use complex mode instead!'. format(self)) if other.max_input_num != 1: raise DayuFFmpegException( '{}\'s input num is not 1, ' 'so not support in ad-hoc mode, use complex mode instead!'. format(other)) other.set_input(self) return other
def _ensure_all_nodes_are_connected(self, all_outputs): for o in all_outputs: for n in o.traverse_inputs(): if n.validate() is False: from dayu_ffmpeg.errors.base import DayuFFmpegException raise DayuFFmpegException( '{} has unconnected input'.format(n))
def _find_all_complex_filters(self): cf_group = next( (n for n in self.inside_nodes if isinstance(n, ComplexFilterGroup)), None) if not cf_group: from dayu_ffmpeg.errors.base import DayuFFmpegException raise DayuFFmpegException( 'root should have one and only one complex filter group!') all_complex_filters = list(cf_group.traverse_children(recursive=True)) return all_complex_filters
def __call__(self, input_list=None, output_list=None): from dayu_ffmpeg.errors.base import DayuFFmpegException if self.max_input_num == 0 and self.max_output_num == 0: raise DayuFFmpegException( 'this Root node has no inputholder and outputholder, ' 'maybe be a self-contain network, ' 'use .run() instead.') if len(input_list) < self.max_input_num or len( output_list) < self.max_output_num: raise DayuFFmpegException( 'this Root node has {} inputs and {} outputs, ' 'but only provide {} inputs and {} outputs'.format( self.max_input_num, self.max_output_num, len(input_list), len(output_list))) for index in range(self.max_input_num): self.set_input(input_list[index], index) for index in range(self.max_output_num): output_list[index].set_input(self, output_index=index) return self
def run(self): import subprocess import re import time self.progress = { 'render_frame': None, 'render_fps': None, 'render_speed': None, 'elapse_time': None } frame_regex = re.compile(r'^frame=\s*?(\d+)') fps_regex = re.compile(r'.*?fps=\s*?(\d+)') time_regex = re.compile(r'.*?time=\s*?(.*?)\s') speed_regex = re.compile(r'.*?speed=\s*?(.*?)x') start_time = time.time() _cmd = self.cmd() print _cmd shell_cmd = subprocess.Popen(_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) while True: if shell_cmd.poll() is not None: break message = shell_cmd.stderr.readline() self.progress['elapse_time'] = round(time.time() - start_time, 2) frame_match = frame_regex.match(message) fps_match = fps_regex.match(message) time_match = time_regex.match(message) speed_match = speed_regex.match(message) if frame_match and fps_match and time_regex and speed_regex: self.progress['render_frame'] = float(frame_match.group(1)) self.progress['render_fps'] = float(fps_match.group(1)) self.progress['render_speed'] = float(speed_match.group(1)) yield self.progress if shell_cmd.returncode != 0: from dayu_ffmpeg.errors.base import DayuFFmpegException raise DayuFFmpegException('transcode failed: {}'.format( shell_cmd.stderr.readlines()))