def create_gif_thumb(sequence, ext='gif', width='100', height='x100', do_height=True, verbose=True): if do_height: res = height else: res = width path_object = PathObject(sequence) new_res = 'gif' path_object_output = path_object.copy(resolution=new_res) output_dir = os.path.dirname(path_object_output.path_root) out_seq = '' command = '' if not os.path.exists(output_dir): CreateProductionData(path_object=output_dir, project_management=False) if '####' in sequence: in_seq = '%s*.%s' % (split_sequence(sequence), path_object.ext) out_seq = '%s/%sthumb.%s' % ( output_dir, os.path.basename(split_sequence(sequence)), ext) command = '%s %s -resize %s %s' % (CONFIG['magick'], in_seq, res, out_seq) if command: cgl_execute(command, verbose=verbose) return out_seq
def extract_wav_from_movie(filein, fileout=None, processing_method='local', dependent_job=None): """ extracts audio from a video file. :param filein: location of video file to extract from. :param fileout: location of .wav file to be created :param processing_method: local, smedge, or deadline processing. :param dependent_job: :return: """ # check if the input is an approved video format. file_, ext = os.path.splitext(filein) if ext in ext_map.keys(): if ext_map[ext] == 'movie': if not fileout: fileout = '%s.wav' % file_ if not fileout.endswith('.wav'): print("%s is not a .wav file, aborting wav extraction") return command = '%s -i %s -acodec pcm_s16le -ac 2 %s' % (PATHS['ffmpeg'], filein, fileout) cgl_execute(command, command_name='Audio Extraction', methodology=processing_method, WaitForJobID=dependent_job, new_window=True) return fileout else: print( 'Extension %s not cataloged in globals, please add it to the ext_map dictionary' % ext)
def make_full_res_jpg(input_file, preview_path=None): if not preview_path: # preview_path = PathParser.preview_path_from_frame_path(input_file, file_type='image') preview_path = PathObject(path_object=input_file).preview_path if not os.path.isdir(os.path.split(preview_path)[0]): os.makedirs(os.path.split(preview_path)[0]) command = r"%s %s --ch R,G,B -o %s" % (CONFIG['magick'], input_file, preview_path) if command: cgl_execute(command, verbose=True) return preview_path
def create_movie_thumb(input_file, output_file, processing_method='local', command_name='create_movie_thumb()', dependent_job=None, new_window=False): """ creates thumbnail for a movie file. :param input_file: input sequence string, formatted with (#, %04d, *) :param output_file: output sequence string, formatted with (####, %04d, *) :param processing_method: how will this be processed? (local, smedge, deadline) :param dependent_job: job_id of any dependencies :param command_name: this is the command name that will be sent to the render farm :return: """ if not output_file: print('No output_file specified, cancelling thumbnail generation') return res = settings['resolution']['thumb_cine'].replace('x', ':') prep_for_output(output_file) if processing_method == 'smedge': pyfile = '%s.py' % os.path.splitext(__file__)[0] command = r'python %s -i %s -o %s -t thumb -ft movie' % ( pyfile, input_file, output_file) process_info = cgl_execute(command, command_name=command_name, methodology='smedge', WaitForJobID=dependent_job) process_info['file_out'] = output_file try: write_to_cgl_data(process_info) except ValueError: print('Error writing to cgl_data for: %s' % output_file) return process_info if processing_method == 'local': command = '%s -i %s -vf "thumbnail,scale=%s" ' \ '-frames:v 1 %s' % (PATHS['ffmpeg'], input_file, res, output_file) process_info = cgl_execute(command, verbose=True, methodology='local', command_name=command_name, new_window=True, WaitForJobID=dependent_job) process_info['file_out'] = output_file try: write_to_cgl_data(process_info) except ValueError: print('Error writing to cgl_data for: %s' % output_file) return process_info
def create_prores_mov(input_file, output_file=None, processing_method='local', dependent_job=None, quality=0, new_window=False, command_name="create_prores_mov()"): """ create a prores mov from specified input sequence, and save it to output. :param input_file: input sequence string, formatted with (#, %04d, *) :param output: output string :return: """ if quality == 0: description = 'proxy' elif quality == 1: description = 'low' elif quality == 2: description = 'standard' elif quality == 3: description = 'high' if not command_name: command_name = "create_prores_mov(%s)" % description file_, ext = os.path.splitext(input_file) file_type = ext_map[ext] if not output_file: output_file = '%s_prores_%s.mov' % (file_, description) if file_type == 'movie': if processing_method == 'local': command = '%s -i %s -c:v prores_ks -qscale:v 1 -profile:v %s -c:a copy %s' % ( PATHS['ffmpeg'], input_file, quality, output_file) cgl_execute(command, command_name='Create Prores', methodology=processing_method, WaitForJobID=dependent_job, new_window=new_window) return output_file elif processing_method == 'smedge': filename = "%s.py" % os.path.splitext(__file__)[0] command = r'python %s -i %s -o %s -t prores -ft movie -q %s' % ( filename, input_file, output_file, quality) process_info = cgl_execute(command, command_name=command_name, methodology='smedge', WaitForJobID=dependent_job) process_info['file_out'] = output_file return process_info else: print('File type: %s not supported with create_prores_mov()' % file_type)
def create_proxy(sequence, ext='jpg', verbose=True, methodology='local'): """ Creates a Jpeg proxy resolution based off the resolution of the given path. :param sequence: :param ext: :param project_management: :return: """ out_seq = '' path_object = PathObject(sequence) start_frame = get_start_frame(sequence) new_res = '%s%s' % (path_object.resolution, 'Proxy') path_object_output = path_object.copy(resolution=new_res, ext='jpg') output_dir = os.path.dirname(path_object_output.path_root) if not os.path.exists(output_dir): CreateProductionData(path_object=output_dir, project_management=False) if '####' in sequence: # replace ### with "*" number = hash_to_number(sequence)[-1] in_seq = '%s*.%s' % (split_sequence(sequence), path_object.ext) out_seq = '%s/%s%s.%s' % (output_dir, os.path.basename( split_sequence(sequence)), number, ext) command = '%s %s -scene %s %s' % (CONFIG['magick'], in_seq, start_frame, out_seq) run_dict = cgl_execute(command, methodology=methodology, verbose=verbose) run_dict['file_out'] = out_seq write_to_cgl_data(run_dict) return run_dict
def get_info(input_file): if get_file_type(input_file) == 'movie': ffprobe_cmd = "%s -v error -show_format -show_streams -of default=noprint_wrappers=1 %s"\ % (CONFIG['ffprobe'], input_file) return cgl_execute(ffprobe_cmd, verbose=True) elif get_file_type(input_file) == 'sequence': _, middle, _ = get_first_frame(input_file) return get_image_info(middle)
def create_title(file_path='sample_image.png', title_text="Sample Title Text", size='1920x1080', bg='transparent', font_color='ffffff', font='Arial', font_size='120', processing_method='local', dependent_job=None): command = '%s convert -background %s -fill #%s -size %s -gravity center ' \ '-font %s -pointsize %s label:"%s" %s' % (PATHS['magick'], bg, font_color, size, font, font_size, title_text, file_path) cgl_execute(command, command_name='Create Title', methodology=processing_method, WaitForJobID=dependent_job, new_window=False)
def make_images_from_pdf(input_file, preview_path=None): """ Creates jpg images from a pdf :param input_file: :param preview_path: :return: """ # This requires imagemagick as well as ghostscript. this is on hold until i understand better how # the licensing for ghostscript works and how we'd package it. if not preview_path: preview_path = PathObject(input_file).preview_path if not os.path.exists(os.path.split(preview_path)[0]): os.makedirs(os.path.split(preview_path)[0]) name = os.path.splitext(os.path.split(input_file)[-1])[0] output_file = name + '.%04d.jpg' command = r"%s -density 300 %s %s/%s" % (CONFIG['imagemagick'], input_file, os.path.split(input_file)[0], output_file) if command: cgl_execute(command, verbose=True) return True
def get_meta_data2(filein, tool='exiftool'): """ Due to issues with the exiftool module this is provided as a way to parse output directly from exiftool through the system commands and cglexecute. For the moment it's only designed to get the metadata for a single file. :param filein: :return: dictionary containing metadata from exiftool """ d = {} if tool == 'exiftool': command = r'exiftool %s' % filein output = cgl_execute(command=command, verbose=False) for each in output['printout']: key, value = re.split("\s+:\s+", each) d[key] = value return d elif tool == 'ffprobe': command = r'%s %s' % ('ffprobe', filein) output = cgl_execute(command=command) for each in output['printout']: try: values = re.split(":\s+", each) key = values[0] values.pop(0) if 'Stream' in key: split_v = values[1].split(',') d['Image Size'] = split_v[2].split()[0] d['Source Image Width'], d['Source Image Height'] = d[ 'Image Size'].split('x') d['Video Frame Rate'] = split_v[4].split( ' fps')[0].replace(' ', '') if 'Duration' in key: d['Track Duration'] = '%s s' % values[0].split(',')[0] value = ' '.join(values) d[key] = value except ValueError: print 'skipping %s' % each return d
def convert_to_webm(filein, fileout=None, processing_method='local', dependent_job=None): """ creates a .mp4 file specifically to be used in amazon's transcription services. :param filein: :param fileout: :param processing_method: :param dependent_job: :return: """ if not fileout: fileout = change_extension(filein, 'mp4') vcodec = ' -pix_fmt yuv420p -vcodec libvpx -vf "scale=trunc((a*oh)/2)*2:720" -g 30 -b:v 2000k -vpre 720p -quality realtime -cpu-used 0 -qmin 10 -qmax 42' acodec = "-acodec libvorbis -aq 60 -ac 2" command = "%s -i %s %s %s -f webm %s" % (PATHS['ffmpeg'], filein, acodec, vcodec, fileout) cgl_execute(command, command_name='convert to webm', methodology=processing_method, WaitForJobID=dependent_job, new_window=True) return fileout
def get_image_info(input_file): # TODO - can we replace this with the metadata module i created? command = "%s --info %s" % (CONFIG['oiiotool'], input_file) return cgl_execute(command, verbose=True)
def convert_to_mp4(filein, fileout=None, processing_method='local', dependent_job=None, audio_only=False, new_window=False, command_name='convert_to_mp4()', delete_existing=True): """ creates a .mp4 file specifically to be used in amazon's transcription services. :param filein: :param fileout: :param processing_method: :param dependent_job: :return: """ if not fileout: fileout = change_extension(filein, 'mp4') print(fileout) if os.path.exists(fileout): print('deleting fileout: %s' % fileout) if delete_existing: print('deleting existing file: %s' % fileout) os.remove(fileout) # 'scale=trunc((a*oh)/2)*2:720' vcodec = '-vcodec libx264 -pix_fmt yuv420p -vf "scale=trunc((a*oh)/2)*2:720" -g 30 -b:v 2000k -vprofile high -bf 0' acodec = "-strict experimental -acodec aac -ab 160k -ac 2" process_info = {'file_out': fileout, 'job_id': 0} if audio_only: if not fileout.endswith('_audio.mp4'): fileout = fileout.replace('.mp4', '_audio.mp4') print(fileout) if os.path.exists(fileout): print('deleting fileout: %s' % fileout) if delete_existing: print('deleting existing file: %s' % fileout) os.remove(fileout) if processing_method == 'local': command = "%s -i %s -vn %s %s" % (PATHS['ffmpeg'], filein, acodec, fileout) cgl_execute(command, command_name=command_name, methodology='local', WaitForJobID=dependent_job) process_info['file_out'] = fileout return process_info elif processing_method == 'smedge': filename = "%s.py" % os.path.splitext(__file__)[0] command = r'python %s -i %s -o %s -t audio -ft movie' % ( filename, filein, fileout) process_info = cgl_execute(command, command_name=command_name, methodology='smedge', WaitForJobID=dependent_job) process_info['file_out'] = fileout return process_info else: if processing_method == 'local': command = "%s -i %s %s %s -f mp4 %s" % (PATHS['ffmpeg'], filein, acodec, vcodec, fileout) cgl_execute(command, command_name='Convert to mp4', methodology=processing_method, WaitForJobID=dependent_job, new_window=new_window) process_info['file_out'] = fileout elif processing_method == 'smedge': filename = "%s.py" % os.path.splitext(__file__)[0] command = r'python %s -i %s -o %s -t mp4 -ft movie' % ( filename, filein, fileout) process_info = cgl_execute(command, command_name=command_name, methodology='smedge', WaitForJobID=dependent_job) process_info['file_out'] = fileout return process_info return process_info
def create_hd_proxy(sequence, output=None, mov=None, ext='jpg', width='1920', height='x1080', do_height=False, start_frame=None, verbose=True, methodology='local', dependent_job=None): """ Create HD Proxy Sequence from a givein image sequence. :param sequence: :param output: :param mov: :param ext: :param width: :param height: :param do_height: :param start_frame: :param verbose: :param methodology: :param dependent_job: :return: """ if do_height: res = height else: res = width path_object = PathObject(sequence) path_object.set_file_type() hashes = '' fileout = '' out_seq = '' command = '' number = '' if not output: logging.info('No output defined for create_hd_proxy') else: path_object_output = None output_dir = os.path.dirname(output) if path_object.file_type == 'sequence': # replace ### with "*" if '##' in sequence: hashes, number = hash_to_number(sequence) elif '%0' in sequence: hashes, number = number_to_hash(sequence) in_seq = '%s*.%s' % (split_sequence(sequence), path_object.ext) out_seq = '%s/%s%s.%s' % (output_dir, os.path.basename( split_sequence(sequence)), number, ext) fileout = out_seq.replace(number, hashes) elif path_object.file_type == 'image': sequence = sequence try: path_object_output.set_attr(ext='jpg') fileout = path_object_output.path_root except AttributeError: this_ = os.path.splitext(output)[0] fileout = this_ + '.jpg' command = '%s %s -resize %s %s' % (CONFIG['magick'], sequence, res, fileout) if methodology == 'smedge': print "I'm sending this to smedge to start after %s" % dependent_job command = r'python %s -i %s' % (__file__, sequence) # set_process_time = r'"python %s -e True -j %s -k farm_processing_end"' % (util_file, '%SMEDGE_JOB_ID%') # run_dict = cgl_execute(command, command_name='create_hd_proxy', methodology=methodology, # Wait=dependent_job, WorkPostExecuteSuccessfulEvt=set_process_time) run_dict = cgl_execute(command, command_name='%s_%s: create_hd_proxy' % (path_object.seq, path_object.shot), methodology='smedge', Wait=dependent_job) run_dict['file_out'] = fileout write_to_cgl_data(run_dict) return run_dict if not start_frame: start_frame = get_start_frame(sequence) if path_object.file_type == 'sequence': command = '%s %s -scene %s -resize %s %s' % (CONFIG['magick'], in_seq, start_frame, res, out_seq) if not os.path.exists(output_dir): CreateProductionData(path_object=output_dir, project_management='lumbermill') run_dict = cgl_execute(command, verbose=verbose, methodology=methodology, command_name='%s_%s: create_hd_proxy' % (path_object.seq, path_object.shot), Wait=dependent_job) run_dict['file_out'] = fileout write_to_cgl_data(run_dict) print 'file_out: %s' % fileout return run_dict
def create_proxy_sequence(input_sequence, output_sequence, width='1920', height='1080', do_height=False, processing_method='local', dependent_job=None, copy_input_padding=True, command_name='create_proxy_sequence()', new_window=False, ext=None): """ Create a proxy jpeg sequence in sRGB color space from the given input sequence. :param input_sequence: input sequence string, formatted with (#, %04d, *) :param output_sequence: output sequence string, formatted with (####, %04d, *) :param width: width in pixels :param height: height in pixels :param do_height: this is when you want to specifically use both parts of the width/height. y default we only use width and scale from there. :param processing_method: how will this be processed? (local, smedge, deadline) :param dependent_job: job_id of any dependencies :param copy_input_padding: if True use the same padding as the input file, if False, use studio wide padding setting :param command_name: this is the command name that will be sent to the render farm :param new_window: Puts the processing of the job into a new shell :param ext: if none i'll use what's in the output. :return: """ from cgl.core.path import Sequence, PathObject if ' ' in input_sequence: input_sequence, frange = input_sequence.split(' ') input_sequence.replace('/', '\\') input_ = Sequence(input_sequence) if not input_.is_valid_sequence(): logging.error('%s is not a valid sequence' % input_sequence) filein = input_.star_sequence if copy_input_padding: padding = input_.padding else: padding = PADDING output_sequence = output_sequence.replace('/', '\\') output_ = Sequence(output_sequence, padding=padding) if not output_.is_valid_sequence(): logging.error('%s is not a valid sequence' % output_sequence) fileout = output_.num_sequence out_dir = os.path.dirname(fileout) out_obj = PathObject(out_dir) if out_obj.context == 'source': out_obj.set_attr(context='render') else: out_obj.set_attr(context='source') if not os.path.exists(out_dir): os.makedirs(out_dir) if not os.path.exists(out_obj.path_root): os.makedirs(out_obj.path_root) process_info = None if do_height: res = 'x%s' % height else: res = width start_frame = input_.start_frame if processing_method == 'smedge': pyfile = '%s.py' % os.path.splitext(__file__)[0] command = r'python %s -i %s -o %s -w %s -h %s -ft sequence -t proxy' % ( pyfile, filein, fileout, width, height) # probably good to write a custom imagemagick command for smedge for this. process_info = cgl_execute(command, command_name=command_name, methodology='smedge', WaitForJobID=dependent_job) elif processing_method == 'local': dirname, filename = os.path.split(filein) match = filename.split('*')[0] for each in os.listdir(os.path.dirname(filein)): if match in each: file_ = os.path.join(os.path.dirname(filein), each) SEQ_SPLIT = "\d{3,}\.\w{2,4}$" frange = re.search(SEQ_SPLIT, each) if frange: num = os.path.splitext(frange.group(0))[0] filename, ext_ = fileout.split('%') if not ext: ext = os.path.splitext(ext_)[-1].replace('.', '') file_out = '%s%s.%s' % (filename, num, ext) command = '%s %s -resize %s %s' % (PATHS['magick'], file_, res, file_out) process_info = cgl_execute(command, methodology='local', command_name=command_name, verbose=True, new_window=new_window) if process_info: process_info['file_out'] = fileout print(fileout) print('-----------') print(process_info) try: write_to_cgl_data(process_info) except ValueError: print('Skipping write to cgl_data: %s' % process_info) return process_info else: print('----------------------------') print('process_info not defined')
def create_web_mov(input_sequence, output, framerate=settings['frame_rate'], output_frame_rate=None, res=settings['resolution']['video_review'], processing_method='local', dependent_job=None, command_name='create_web_mov()', new_window=False): """ create a web optimized h264 mp4 from an specified input_sequence to a specified output.mp4 This assumes an sRGB jpg sequence as input :param input_sequence: input sequence string, formatted with (#, %04d, *) :param output: output mp4 string :param framerate: frame rate for input sequence :param output_frame_rate: if None frame rate for input movie is used, if defined this frame rate is used for output movie :param res: resolution 1920x1080 :param processing_method: local, smedge, deadline :param dependent_job: job_id of dependencies :param command_name: this is the command name that will be sent to the render farm :return: """ from cgl.core.path import Sequence if not output: logging.error('No Output Defined') return input_ = Sequence(input_sequence) start_frame = None if input_.ext != '.jpg': logging.error('%s is not a valid ext for input sequences' % input_.ext) if not input_.is_valid_sequence(): logging.error('%s is not a valid sequence for web quicktimes' % input_sequence) return else: start_frame = input_.start_frame file_type = 'sequence' filein = input_.num_sequence fileout = output prep_for_output(fileout) process_info = None if processing_method == 'smedge': filename = "%s.py" % os.path.splitext(__file__)[0] command = r'python %s -i %s -o %s -t web_preview -ft sequence' % ( filename, filein, fileout) process_info = cgl_execute(command, command_name=command_name, methodology='smedge', WaitForJobID=dependent_job) process_info['file_out'] = fileout try: write_to_cgl_data(process_info) except ValueError: print('Skipping creation of cgl_data for %s:' % process_info) return process_info ffmpeg_cmd = '' if not output_frame_rate: output_frame_rate = framerate encoder = "libx264" profile = 'high' constant_rate_factor = "24" # i need to test this with stuff that's not created at 24fps - pixel_format = 'yuv420p' gamma = 1 width, height = res.split('x') vcodec = "-vcodec libx264 -pix_fmt yuv420p -vf 'scale=trunc((a*oh)/2)*2:720' -g 30 -b:v 2000k -vprofile high -bf 0" acodec = "-strict experimental -acodec aac -ab 160k -ac 2" filter_arg = r' -filter:v "scale=iw*min($width/iw\,$height/ih):ih*min($width/iw\,$height/ih),' \ r' pad=$width:$height:($width-iw*min($width/iw\,$height/ih))/2:' \ r'($height-ih*min($width/iw\,$height/ih))/2" '.replace('$width', width).replace('$height', height) if file_type == 'sequence': ffmpeg_cmd = r'%s -start_number %s -framerate %s -gamma %s -i %s -s:v %s -b:v 50M -c:v %s -profile:v %s' \ r' -crf %s -pix_fmt %s -r %s %s %s' % (PATHS['ffmpeg'], start_frame, framerate, gamma, filein, res, encoder, profile, constant_rate_factor, pixel_format, output_frame_rate, filter_arg, fileout) elif file_type == 'movie': ffmpeg_cmd = r'%s -gamma %s -i %s -s:v %s -b:v 50M -c:v %s -profile:v %s' \ r' -crf %s -pix_fmt %s -r %s %s %s' % (PATHS['ffmpeg'], gamma, filein, res, encoder, profile, constant_rate_factor, pixel_format, output_frame_rate, filter_arg, fileout) if ffmpeg_cmd: process_info = cgl_execute(ffmpeg_cmd, verbose=True, command_name=command_name, WaitForJobID=dependent_job, new_window=new_window) process_info['file_out'] = fileout try: write_to_cgl_data(process_info) except ValueError: print('Skipping creation of cgl_data for %s' % fileout) return process_info
def create_mov(sequence, output=None, framerate=settings['frame_rate'], output_frame_rate=None, res=settings['resolution']['video_review'], methodology='local', dependent_job=None): path_object = PathObject(sequence) output_file = '' input_file = '' if output: if path_object.file_type == 'sequence': input_file = prep_seq_delimiter(sequence, replace_with='%') output_file = output if not os.path.exists(os.path.dirname(output_file)): os.makedirs(os.path.dirname(output_file)) else: print('Nothing defined for %s' % path_object.file_type) else: print 2 output_file = path_object.preview_path if path_object.file_type == 'sequence': if not output: output_file = output_file.split('#')[0] if output_file.endswith('.'): output_file = '%smp4' % output_file else: output_file = '%s.mp4' % output_file filename = os.path.basename(output_file) if methodology == 'smedge': command = r'python %s -i %s -t %s' % (__file__, sequence, 'mov') run_dict = cgl_execute(command, command_name='%s_%s: create_mov' % (path_object.seq, path_object.shot), methodology='smedge', Wait=dependent_job) run_dict['file_out'] = output_file write_to_cgl_data(run_dict) return run_dict print output_file, 'output file' if path_object.file_type == 'sequence': input_file = prep_seq_delimiter(sequence, replace_with='%') if os.path.exists(output_file): os.remove(output_file) if os.path.splitext(input_file)[-1] == '.exr' or os.path.splitext( input_file)[-1] == '.dpx': logging.info('applying gamma 2.2 to linear sequence') gamma = 2.2 else: gamma = 1 if not output_frame_rate: output_frame_rate = framerate encoder = "libx264" profile = 'high' constant_rate_factor = "24" # i need to test this with stuff that's not created at 24fps - pixel_format = 'yuv420p' res_list = res.split('x') width = res_list[0] height = res_list[1] if methodology == 'smedge': filter_arg = r' -filter:v \"scale=iw*min($width/iw\,$height/ih):ih*min($width/iw\,$height/ih),' \ r' pad=$width:$height:($width-iw*min($width/iw\,$height/ih))/2:' \ r'($height-ih*min($width/iw\,$height/ih))/2\" '.replace('$width', width).replace('$height', height) else: filter_arg = r' -filter:v "scale=iw*min($width/iw\,$height/ih):ih*min($width/iw\,$height/ih),' \ r' pad=$width:$height:($width-iw*min($width/iw\,$height/ih))/2:' \ r'($height-ih*min($width/iw\,$height/ih))/2" '.replace('$width', width).replace('$height', height) ffmpeg_cmd = '' if path_object.file_type == 'sequence': start_frame = get_first_frame(sequence)[0] ffmpeg_cmd = r'%s -start_number %s -framerate %s -gamma %s -i %s -s:v %s -b:v 50M -c:v %s -profile:v %s' \ r' -crf %s -pix_fmt %s -r %s %s %s' % (CONFIG['ffmpeg'], start_frame, framerate, gamma, input_file, res, encoder, profile, constant_rate_factor, pixel_format, output_frame_rate, filter_arg, output_file) elif path_object.file_type == 'movie': print 4 ffmpeg_cmd = r'%s -gamma %s -i %s -s:v %s -b:v 50M -c:v %s -profile:v %s' \ r' -crf %s -pix_fmt %s -r %s %s %s' % (CONFIG['ffmpeg'], gamma, input_file, res, encoder, profile, constant_rate_factor, pixel_format, output_frame_rate, filter_arg, output_file) if ffmpeg_cmd: print 5 run_dict = cgl_execute(ffmpeg_cmd, verbose=True, methodology=methodology, command_name='%s_%s: create_mov' % (path_object.seq, path_object.shot), Wait=dependent_job) run_dict['file_out'] = output_file write_to_cgl_data(run_dict) create_movie_thumb(sequence, methodology=methodology, dependent_job=run_dict['job_id']) return run_dict
def create_movie_thumb(input_file, output_file=None, frame='middle', thumb=True, methodology='local', dependent_job=None): """ Create a thumbnail from a movie file. :param input_file: path to mov :param output_file: output file (jpg) :param frame: first, middle, or last :param thumb: Default value is True, this pulls the thumbnail resolution from the settings. :return: """ path_object = PathObject(input_file) if not output_file: if '.preview' in input_file: output_file.replace('.preview', '.thumb') else: output_file = PathObject(path_object=input_file).copy( resolution='thumb', ext='jpg').path_root if not output_file.endswith('.jpg'): file_ = os.path.splitext(output_file)[0] output_file = '%s.%s' % (file_, 'jpg') if os.path.exists(output_file): os.remove(output_file) if not os.path.exists(os.path.dirname(output_file)): CreateProductionData(os.path.dirname(output_file), project_management='lumbermill') if get_file_type(input_file) == 'movie': if thumb: res = get_thumb_res(input_file) res.replace('x', ':') if not res: logging.warning('problem with thumbnail resolution algorithm') res = settings['resolution']['thumb_cine'] else: res = settings['resolution']['image_review'].replace('x', ':') # This command will just use ffmpeg's default thumbnail generator command = '%s -i %s -vf "thumbnail,scale=%s" ' \ '-frames:v 1 %s' % (CONFIG['ffmpeg'], input_file, res, output_file) if command: run_dict = cgl_execute(command, verbose=True, methodology=methodology, command_name='%s_%s: create_mov_thumb' % (path_object.seq, path_object.shot), Wait=dependent_job) run_dict['file_out'] = output_file write_to_cgl_data(run_dict) return run_dict else: if get_file_type(input_file) == 'sequence': first_frame, middle_frame, end_frame = get_first_frame(input_file) if frame == 'middle': input_file = middle_frame elif frame == 'first': input_file = first_frame elif frame == 'last': input_file = end_frame # create the thumbnail # output_file = output_file.replace('####', 'seq') if thumb: res = thumb_res else: res = settings['resolution']['image_review'] # command = r"%s %s --fit %s --ch R,G,B -o %s" % (CONFIG['oiiotool'], input_file, res, output_file) command = '%s %s -resize %s %s' % (CONFIG['magick'], input_file, res, output_file) run_dict = cgl_execute(command, verbose=True, methodology=methodology, Wait=dependent_job) run_dict['file_out'] = output_file write_to_cgl_data(run_dict) return run_dict