def add_track_pan_filter(self, track, value): # This method is used for master too, and called with tractor then pan_filter = mlt.Filter(self.profile, "panner") mltrefhold.hold_ref(pan_filter) pan_filter.set("start", value) track.attach(pan_filter) track.pan_filter = pan_filter
def create_file_producer_clip(self, path, new_clip_name=None, novalidate=False, ttl=None): """ Creates MLT Producer and adds attributes to it, but does not add it to track/playlist object. """ producer = mlt.Producer(self.profile, str(path)) # this runs 0.5s+ on some clips if novalidate == True: producer.set("mlt_service", "avformat-novalidate") mltrefhold.hold_ref(producer) producer.path = path producer.filters = [] (dir, file_name) = os.path.split(path) (name, ext) = os.path.splitext(file_name) producer.name = name if new_clip_name != None: producer.name = new_clip_name producer.media_type = get_media_type(path) if producer.media_type == FILE_DOES_NOT_EXIST: print "file does not exist" return None self.add_clip_attr(producer) # Img seq ttl value producer.ttl = ttl if ttl != None: producer.set("ttl", int(ttl)) return producer
def set_track_mute_state(self, track_index, mute_state): track = self.tracks[track_index] track.mute_state = mute_state # Some older projects might get here without a track gain filter existing if not hasattr(track, "gain_filter"): # Create and add gain filter gain_filter = mlt.Filter(self.profile, "volume") mltrefhold.hold_ref(gain_filter) gain_filter.set("gain", str(track.audio_gain)) track.attach(gain_filter) track.gain_filter = gain_filter if mute_state == 2: # TRACK_MUTE_AUDIO if track.id < self.first_video_index: # Audio tracks track.set("hide", 1) track.gain_filter.set("gain", str(0)) else: # Video tracks track.set("hide", 0) track.gain_filter.set("gain", str(0)) elif mute_state == 3: # TRACK_MUTE_ALL track.set("hide", 1) track.gain_filter.set("gain", str(0)) else: # TRACK_MUTE_NOTHING, TRACK_MUTE_VIDEO track.set("hide", int(track.mute_state)) track.gain_filter.set("gain", str(track.audio_gain))
def create_filters_for_keyframes(self, keyframes, mlt_profile): for i in range(0, len(keyframes) - 1): # Theres one less filter parts than keyframes mlt_filter = mlt.Filter(mlt_profile, str(self.info.mlt_service_id)) mltrefhold.hold_ref(mlt_filter) self.mlt_filters.append(mlt_filter)
def create_mlt_producer(self, profile): producer = mlt.Producer(profile, "frei0r.ising0r") producer.set("Temperature", str(self.temp)) producer.set("Border Growth", str(self.bg)) producer.set("Spontaneous Growth", str(self.sg)) mltrefhold.hold_ref(producer) return producer
def _mix_audio_for_track(self, track): # Create and add transition to combine track audios # # Audio transition objects are not saved and are thrown away when track count is changed so we don't # need to hold references to them in Sequence object, mltrefhold stuff is just very # defencsive programming because MLT crashes are most related to deleting stuff, probably not needed at all. transition = mlt.Transition(self.profile, "mix") mltrefhold.hold_ref(transition) # look to remove transition.set("a_track", int(AUDIO_MIX_DOWN_TRACK)) transition.set("b_track", track.id) transition.set("always_active", 1) transition.set("combine", 1) self.field.plant_transition(transition, int(AUDIO_MIX_DOWN_TRACK), track.id) # Create and add gain filter gain_filter = mlt.Filter(self.profile, "volume") mltrefhold.hold_ref(gain_filter) gain_filter.set("gain", str(track.audio_gain)) track.attach(gain_filter) track.gain_filter = gain_filter # Add pan filter if this track is panorated if track.audio_pan != NO_PAN: self.add_track_pan_filter(track, 0.5) track.audio_pan = 0.5
def create_file_producer_clip(self, path, new_clip_name=None, novalidate=False): """ Creates MLT Producer and adds attributes to it, but does not add it to track/playlist object. """ producer = mlt.Producer(self.profile, str(path)) # this runs 0.5s+ on some clips if novalidate == True: producer.set("mlt_service", "avformat-novalidate") mltrefhold.hold_ref(producer) producer.path = path producer.filters = [] (dir, file_name) = os.path.split(path) (name, ext) = os.path.splitext(file_name) producer.name = name if new_clip_name != None: producer.name = new_clip_name producer.media_type = get_media_type(path) if producer.media_type == FILE_DOES_NOT_EXIST: print "file does not exist" return None self.add_clip_attr(producer) return producer
def create_file_producer_clip(self, path, new_clip_name=None, novalidate=False, ttl=None): """ Creates MLT Producer and adds attributes to it, but does not add it to track/playlist object. """ producer = mlt.Producer(self.profile, str(path)) # this runs 0.5s+ on some clips mltrefhold.hold_ref(producer) producer.path = path producer.filters = [] (dir, file_name) = os.path.split(path) (name, ext) = os.path.splitext(file_name) producer.name = name if new_clip_name != None: producer.name = new_clip_name producer.media_type = get_media_type(path) if producer.media_type == FILE_DOES_NOT_EXIST: print("file does not exist") return None self.add_clip_attr(producer) # Img seq ttl value producer.ttl = ttl if ttl != None: producer.set("ttl", int(ttl)) return producer
def add_watermark(self, watermark_file_path): watermark = mlt.Filter(self.profile, "watermark") mltrefhold.hold_ref(watermark) watermark.set("resource",str(watermark_file_path)) watermark.set("composite.always_active", 1) self.tractor.attach(watermark) self.watermark_filter = watermark self.watermark_file_path = watermark_file_path
def create_mlt_producer(self, profile): mlt_color = utils.gdk_color_str_to_mlt_color_str(self.gdk_color_str) producer = mlt.Producer(profile, "colour", mlt_color) mltrefhold.hold_ref(producer) producer.gdk_color_str = self.gdk_color_str return producer
def add_watermark(self, watermark_file_path): watermark = mlt.Filter(self.profile, "watermark") mltrefhold.hold_ref(watermark) watermark.set("resource", str(watermark_file_path)) watermark.set("composite.always_active", 1) self.tractor.attach(watermark) self.watermark_filter = watermark self.watermark_file_path = watermark_file_path
def create_color_producer(profile, gdk_color_str): mlt_color = utils.gdk_color_str_to_mlt_color_str(gdk_color_str) producer = mlt.Producer(profile, "colour", mlt_color) mltrefhold.hold_ref(producer) producer.gdk_color_str = gdk_color_str return producer
def create_mlt_producer(self, profile): producer = mlt.Producer(profile, "count") producer.set("direction", "down") producer.set("style", "seconds") producer.set("sound", "2pop") producer.set("background", "clock") producer.set("drop", "1") mltrefhold.hold_ref(producer) return producer
def create_mlt_producer(self, profile): producer = mlt.Producer(profile, "frei0r.plasma") producer.set("1_speed", str(self.s1)) producer.set("2_speed", str(self.s2)) producer.set("3_speed", str(self.s3)) producer.set("4_speed", str(self.s4)) producer.set("1_move", str(self.m1)) producer.set("2_move", str(self.m2)) mltrefhold.hold_ref(producer) return producer
def create_mlt_transition(self, mlt_profile): transition = mlt.Transition(mlt_profile, str(self.info.mlt_service_id)) mltrefhold.hold_ref(transition) self.mlt_transition = transition self.set_default_values() # PROP_EXPR values may have keywords that need to be replaced with # numerical values that depend on the profile we have. These need # to be replaced now that we have profile and we are ready to connect this. propertyparse.replace_value_keywords(self.properties, mlt_profile) self.update_editable_mlt_properties()
def create_mlt_producer(self, profile): width = profile.width() height = profile.height() surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height) cr = cairo.Context(surface) cr.set_source_rgb(*utils.gdk_color_str_to_cairo_rgb(self.gdk_color_str)) cr.rectangle(0, 0, width + 1, height+ 1) cr.fill() file_name = md5.new(self.gdk_color_str + str(width) + str(height)).hexdigest() write_file_path = utils.get_hidden_user_dir_path() + appconsts.RENDERED_CLIPS_DIR + "/" + file_name + ".png" surface.write_to_png(write_file_path) producer = mlt.Producer(profile, write_file_path) mltrefhold.hold_ref(producer) return producer
def create_mlt_producer(self, profile): width = profile.width() height = profile.height() surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height) cr = cairo.Context(surface) cr.set_source_rgb(*utils.gdk_color_str_to_cairo_rgb(self.gdk_color_str)) cr.rectangle(0, 0, width + 1, height+ 1) cr.fill() file_name = hashlib.md5((self.gdk_color_str + str(width) + str(height)).encode('utf-8')).hexdigest() write_file_path = userfolders.get_render_dir() + "/" + file_name + ".png" surface.write_to_png(write_file_path) producer = mlt.Producer(profile, write_file_path) mltrefhold.hold_ref(producer) return producer
def create_mlt_producer(self, profile): width = profile.width() height = profile.height() surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height) cr = cairo.Context(surface) cr.set_source_rgb( *utils.gdk_color_str_to_cairo_rgb(self.gdk_color_str)) cr.rectangle(0, 0, width + 1, height + 1) cr.fill() file_name = md5.new(self.gdk_color_str + str(width) + str(height)).hexdigest() write_file_path = utils.get_hidden_user_dir_path( ) + appconsts.RENDERED_CLIPS_DIR + "/" + file_name + ".png" surface.write_to_png(write_file_path) producer = mlt.Producer(profile, write_file_path) mltrefhold.hold_ref(producer) return producer
def _mix_audio_for_track(self, track): # Create and add transition to combine track audios transition = mlt.Transition(self.profile, "mix") mltrefhold.hold_ref(transition) transition.set("a_track", int(AUDIO_MIX_DOWN_TRACK)) transition.set("b_track", track.id) transition.set("always_active", 1) transition.set("combine", 1) self.field.plant_transition(transition, int(AUDIO_MIX_DOWN_TRACK), track.id) # Create and ad gain filter gain_filter = mlt.Filter(self.profile, "volume") mltrefhold.hold_ref(gain_filter) gain_filter.set("gain", str(track.audio_gain)) track.attach(gain_filter) track.gain_filter = gain_filter # Add pan filter if this track is panorated if track.audio_pan != NO_PAN: self.add_track_pan_filter(track, 0.5) track.audio_pan = 0.5
def create_slowmotion_producer(self, path, speed): """ Creates MLT Producer and adds attributes to it, but does not add it to track/playlist object. """ fr_path = "framebuffer:" + path + "?" + str(speed) producer = mlt.Producer(self.profile, None, str(fr_path)) # this runs 0.5s+ on some clips mltrefhold.hold_ref(producer) (folder, file_name) = os.path.split(path) (name, ext) = os.path.splitext(file_name) producer.name = name producer.path = path producer.speed = speed producer.media_type = get_media_type(path) if producer.media_type == FILE_DOES_NOT_EXIST: return None self.add_clip_attr(producer) return producer
def init_mlt_objects(self): # MLT objects for multitrack sequence self.tractor = mlt.Tractor() self.tractor.mark_in = -1 self.tractor.mark_out = -1 # Only create and add pan filter if actual pan is applied # This method gets called on load and we only want to add a filter then if pan is applied, # and not on initial creation. # audiomonitoring.py calls add_track_pan_filter() when pan turned on for initial creation if self.master_audio_pan != NO_PAN: self.add_track_pan_filter(self.tractor, self.master_audio_pan) # Create and add gain filter gain_filter = mlt.Filter(self.profile, "volume") mltrefhold.hold_ref(gain_filter) gain_filter.set("gain", str(self.master_audio_gain)) self.tractor.attach(gain_filter) self.tractor.gain_filter = gain_filter self.field = self.tractor.field() self.multitrack = self.tractor.multitrack() self.vectorscope = mlt.Filter(self.profile, "frei0r.vectorscope") mltrefhold.hold_ref(self.vectorscope) # ?? is this just some anti-crash hack attempt that was not removed self.vectorscope.set("mix", str(SCOPE_MIX_VALUES[_scope_over_lay_mix])) self.vectorscope.set("overlay sides", "0.0") self.rgbparade = mlt.Filter(self.profile, "frei0r.rgbparade") mltrefhold.hold_ref(self.rgbparade) # ?? is this just some anti-crash hack attempt that was not removed self.rgbparade.set("mix", str(SCOPE_MIX_VALUES[_scope_over_lay_mix])) self.rgbparade.set("overlay sides", "0.0") self.outputfilter = None
def init_mlt_objects(self): # MLT objects for multitrack sequence self.tractor = mlt.Tractor() self.tractor.mark_in = -1 self.tractor.mark_out = -1 # Only create and add pan filter if actual pan is applied # This method gets called on load and we only want to add a filter then if pan is applied, # and not on initial creation. # audiomonitoring.py calls add_track_pan_filter() when pan turned on for initial creation if self.master_audio_pan != NO_PAN: self.add_track_pan_filter(self.tractor, self.master_audio_pan) # Create and ad gain filter gain_filter = mlt.Filter(self.profile, "volume") mltrefhold.hold_ref(gain_filter) gain_filter.set("gain", str(self.master_audio_gain)) self.tractor.attach(gain_filter) self.tractor.gain_filter = gain_filter self.field = self.tractor.field() self.multitrack = self.tractor.multitrack() self.vectorscope = mlt.Filter(self.profile, "frei0r.vectorscope") mltrefhold.hold_ref(self.vectorscope) # ?? is this just some anti-crash hack attempt that was not removed self.vectorscope.set("mix", "0.5") self.vectorscope.set("overlay sides", "0.0") self.rgbparade = mlt.Filter(self.profile, "frei0r.rgbparade") mltrefhold.hold_ref(self.rgbparade) # ?? is this just some anti-crash hack attempt that was not removed self.rgbparade.set("mix", "0.4") self.rgbparade.set("overlay sides", "0.0") self.outputfilter = None
def create_file_producer_clip(self, path, new_clip_name=None): """ Creates MLT Producer and adds attributes to it, but does not add it to track/playlist object. """ producer = mlt.Producer(self.profile, str(path)) # this runs 0.5s+ on some clips mltrefhold.hold_ref(producer) producer.path = path producer.filters = [] (dir, file_name) = os.path.split(path) (name, ext) = os.path.splitext(file_name) producer.name = name if new_clip_name != None: producer.name = new_clip_name producer.media_type = get_media_type(path) if producer.media_type == FILE_DOES_NOT_EXIST: print "file does not exist" return None self.add_clip_attr(producer) return producer
def create_mlt_producer(self, profile): producer = mlt.Producer(profile, "frei0r.nois0r") mltrefhold.hold_ref(producer) return producer
def create_mlt_producer(self, profile): producer = mlt.Producer(profile, respaths.PATTERN_PRODUCER_PATH + "ebubars.png") mltrefhold.hold_ref(producer) return producer
def _create_noise_producer(profile): producer = mlt.Producer(profile, "frei0r.nois0r") mltrefhold.hold_ref(producer) return producer
def _add_audio_level_filter(producer, profile): audio_level_filter = mlt.Filter(profile, "audiolevel") mltrefhold.hold_ref(audio_level_filter) producer.attach(audio_level_filter) return audio_level_filter
def get_rendered_transition_tractor(current_sequence, orig_from, orig_to, action_from_out, action_from_in, action_to_out, action_to_in, transition_type_selection_index, wipe_luma_sorted_keys_index, gdk_color_str): name, transition_type = rendered_transitions[transition_type_selection_index] # New from clip if orig_from.media_type != appconsts.PATTERN_PRODUCER: from_clip = current_sequence.create_file_producer_clip(orig_from.path, None, False, orig_from.ttl)# File producer else: from_clip = current_sequence.create_pattern_producer(orig_from.create_data) # pattern producer current_sequence.clone_clip_and_filters(orig_from, from_clip) # New to clip if not(transition_type == RENDERED_FADE_IN or transition_type == RENDERED_FADE_OUT): # fades to not use to_clip if orig_to.media_type != appconsts.PATTERN_PRODUCER: to_clip = current_sequence.create_file_producer_clip(orig_to.path, None, False, orig_to.ttl)# File producer else: to_clip = current_sequence.create_pattern_producer(orig_to.create_data) # pattern producer current_sequence.clone_clip_and_filters(orig_to, to_clip) # Create tractor and tracks tractor = mlt.Tractor() multitrack = tractor.multitrack() track0 = mlt.Playlist() track1 = mlt.Playlist() multitrack.connect(track0, 0) multitrack.connect(track1, 1) # we'll set in and out points for images and pattern producers. if not(transition_type == RENDERED_FADE_IN or transition_type == RENDERED_FADE_OUT): # fades to not use to_clip or some other data used here if from_clip.media_type == appconsts.IMAGE or from_clip.media_type == appconsts.PATTERN_PRODUCER: length = action_from_out - action_from_in from_clip.clip_in = 0 from_clip.clip_out = length if to_clip.media_type == appconsts.IMAGE or to_clip.media_type == appconsts.PATTERN_PRODUCER: length = action_to_out - action_to_in to_clip.clip_in = 0 to_clip.clip_out = length else: length = action_from_out if from_clip.media_type == appconsts.IMAGE or from_clip.media_type == appconsts.PATTERN_PRODUCER: from_clip.clip_in = 0 from_clip.clip_out = length # Add clips to tracks and create keyframe string for mixing if transition_type == RENDERED_DISSOLVE or transition_type == RENDERED_WIPE: # Add clips. Images and pattern producers always fill full track. if from_clip.media_type != appconsts.IMAGE and from_clip.media_type != appconsts.PATTERN_PRODUCER: track0.insert(from_clip, 0, action_from_in, action_from_out) else: track0.insert(from_clip, 0, 0, action_from_out - action_from_in) if to_clip.media_type != appconsts.IMAGE and to_clip.media_type != appconsts.PATTERN_PRODUCER: track1.insert(to_clip, 0, action_to_in, action_to_out) else: track1.insert(to_clip, 0, 0, action_to_out - action_to_in) kf_str = "0=0/0:100%x100%:0.0;"+ str(tractor.get_length() - 1) + "=0/0:100%x100%:100.0" elif transition_type == RENDERED_COLOR_DIP: length = action_from_out - action_from_in first_clip_length = length // 2 second_clip_length = length - first_clip_length color_clip = patternproducer.create_color_producer(current_sequence.profile, gdk_color_str) track0.insert(color_clip, 0, 0, length) track1.insert(from_clip, 0, action_from_in, action_from_in + first_clip_length) track1.insert(to_clip, 1, action_to_out - second_clip_length, action_to_out) kf_str = "0=0/0:100%x100%:100.0;"+ str(first_clip_length) + "=0/0:100%x100%:0.0;" + str(tractor.get_length() - 1) + "=0/0:100%x100%:100.0" elif (transition_type == RENDERED_FADE_IN or transition_type == RENDERED_FADE_OUT): color_clip = patternproducer.create_color_producer(current_sequence.profile, gdk_color_str) track0.insert(color_clip, 0, 0, length) if transition_type == RENDERED_FADE_IN: track1.insert(from_clip, 0, orig_from.clip_in, orig_from.clip_in + length) kf_str = "0=0/0:100%x100%:0.0;"+ str(length) + "=0/0:100%x100%:100.0" else: # transition_type == RENDERED_FADE_OUT track1.insert(from_clip, 0, orig_from.clip_out - length, orig_from.clip_out) kf_str = "0=0/0:100%x100%:100.0;"+ str(length) + "=0/0:100%x100%:0.0" # Create transition transition = mlt.Transition(current_sequence.profile, "region") mltrefhold.hold_ref(transition) transition.set("composite.geometry", str(kf_str)) # controls mix over time transition.set("composite.automatic",1) transition.set("composite.aligned", 0) transition.set("composite.deinterlace",0) transition.set("composite.distort",0) transition.set("composite.fill",1) transition.set("composite.operator","over") transition.set("composite.luma_invert",0) transition.set("composite.progressive",1) transition.set("composite.softness",0) transition.set("in", 0) transition.set("out", tractor.get_length() - 1) transition.set("a_track", 0) transition.set("b_track", 1) # Setting luma resource file turns dissolve into wipe if transition_type == RENDERED_WIPE: wipe_resource_path = get_wipe_resource_path_for_sorted_keys_index(wipe_luma_sorted_keys_index) transition.set("composite.luma", str(wipe_resource_path)) # Add transition field = tractor.field() field.plant_transition(transition, 0,1) return tractor
def _render_frame_buffer_clip_dialog_callback(dialog, response_id, fb_widgets, media_file): if response_id == Gtk.ResponseType.ACCEPT: # speed, filename folder speed = float(int(fb_widgets.hslider.get_value())) / 100.0 file_name = fb_widgets.file_name.get_text() filenames = fb_widgets.out_folder.get_filenames() folder = filenames[0] write_file = folder + "/"+ file_name + fb_widgets.extension_label.get_text() if os.path.exists(write_file): primary_txt = _("A File with given path exists!") secondary_txt = _("It is not allowed to render Motion Files with same paths as existing files.\nSelect another name for file.") dialogutils.warning_message(primary_txt, secondary_txt, dialog) return # Profile profile_index = fb_widgets.out_profile_combo.get_active() if profile_index == 0: # project_profile is first selection in combo box profile = PROJECT().profile else: profile = mltprofiles.get_profile_for_index(profile_index - 1) # Render consumer properties encoding_option_index = fb_widgets.encodings_cb.get_active() quality_option_index = fb_widgets.quality_cb.get_active() # Range range_selection = fb_widgets.render_range.get_active() dialog.destroy() # Create motion producer fr_path = "framebuffer:" + media_file.path + "?" + str(speed) motion_producer = mlt.Producer(profile, None, str(fr_path)) mltrefhold.hold_ref(motion_producer) # Create sequence and add motion producer into it seq = sequence.Sequence(profile) seq.create_default_tracks() track = seq.tracks[seq.first_video_index] track.append(motion_producer, 0, motion_producer.get_length() - 1) print "motion clip render starting..." consumer = renderconsumer.get_render_consumer_for_encoding_and_quality(write_file, profile, encoding_option_index, quality_option_index) # start and end frames start_frame = 0 end_frame = motion_producer.get_length() - 1 wait_for_producer_stop = True if range_selection == 1: start_frame = int(float(media_file.mark_in) * (1.0 / speed)) end_frame = int(float(media_file.mark_out + 1) * (1.0 / speed)) + int(1.0 / speed) #+ 40 # I'm unable to get this frame perfect. # +40 is to make sure rendering stops after mark out. if end_frame > motion_producer.get_length() - 1: end_frame = motion_producer.get_length() - 1 wait_for_producer_stop = False # consumer wont stop automatically and needs to stopped explicitly # Launch render global motion_renderer, motion_progress_update motion_renderer = renderconsumer.FileRenderPlayer(write_file, seq.tractor, consumer, start_frame, end_frame) motion_renderer.wait_for_producer_end_stop = wait_for_producer_stop motion_renderer.start() title = _("Rendering Motion Clip") text = "<b>Motion Clip File: </b>" + write_file progress_bar = Gtk.ProgressBar() dialog = rendergui.clip_render_progress_dialog(_FB_render_stop, title, text, progress_bar, gui.editor_window.window) motion_progress_update = renderconsumer.ProgressWindowThread(dialog, progress_bar, motion_renderer, _FB_render_stop) motion_progress_update.start() else: dialog.destroy()
def create_mlt_filter(self, mlt_profile): self.mlt_filter = mlt.Filter(mlt_profile, str(self.info.mlt_service_id)) mltrefhold.hold_ref(self.mlt_filter) self.update_mlt_filter_properties_all()
def _render_reverse_clip_dialog_callback(dialog, response_id, fb_widgets, media_file): if response_id == Gtk.ResponseType.ACCEPT: # speed, filename folder speed = float(int(fb_widgets.hslider.get_value())) / 100.0 file_name = fb_widgets.file_name.get_text() filenames = fb_widgets.out_folder.get_filenames() folder = filenames[0] write_file = folder + "/"+ file_name + fb_widgets.extension_label.get_text() if os.path.exists(write_file): primary_txt = _("A File with given path exists!") secondary_txt = _("It is not allowed to render Motion Files with same paths as existing files.\nSelect another name for file.") dialogutils.warning_message(primary_txt, secondary_txt, dialog) return # Profile profile_index = fb_widgets.out_profile_combo.get_active() if profile_index == 0: # project_profile is first selection in combo box profile = PROJECT().profile else: profile = mltprofiles.get_profile_for_index(profile_index - 1) # Render consumer properties encoding_option_index = fb_widgets.encodings_cb.get_active() quality_option_index = fb_widgets.quality_cb.get_active() # Range range_selection = fb_widgets.render_range.get_active() dialog.destroy() # Create motion producer source_path = media_file.path if media_file.is_proxy_file == True: source_path = media_file.second_file_path motion_producer = mlt.Producer(profile, None, str("timewarp:" + str(speed) + ":" + str(source_path))) mltrefhold.hold_ref(motion_producer) # Create sequence and add motion producer into it seq = sequence.Sequence(profile) seq.create_default_tracks() track = seq.tracks[seq.first_video_index] track.append(motion_producer, 0, motion_producer.get_length() - 1) print "motion clip render starting..." consumer = renderconsumer.get_render_consumer_for_encoding_and_quality(write_file, profile, encoding_option_index, quality_option_index) # start and end frames start_frame = 0 end_frame = motion_producer.get_length() - 1 wait_for_producer_stop = True if range_selection == 1: start_frame = int(float(media_file.length - media_file.mark_out - 1) * (1.0 / -speed)) end_frame = int(float(media_file.length - media_file.mark_out + (media_file.mark_out - media_file.mark_in) + 1) * (1.0 / -speed)) + int(1.0 / -speed) if end_frame > motion_producer.get_length() - 1: end_frame = motion_producer.get_length() - 1 if start_frame < 0: start_frame = 0 wait_for_producer_stop = False # consumer wont stop automatically and needs to stopped explicitly # Launch render global motion_renderer, motion_progress_update motion_renderer = renderconsumer.FileRenderPlayer(write_file, seq.tractor, consumer, start_frame, end_frame) motion_renderer.wait_for_producer_end_stop = wait_for_producer_stop motion_renderer.start() title = _("Rendering Reverse Clip") text = "<b>Motion Clip File: </b>" + write_file progress_bar = Gtk.ProgressBar() dialog = rendergui.clip_render_progress_dialog(_FB_render_stop, title, text, progress_bar, gui.editor_window.window) motion_progress_update = renderconsumer.ProgressWindowThread(dialog, progress_bar, motion_renderer, _REVERSE_render_stop) motion_progress_update.start() else: dialog.destroy()
def get_rendered_transition_tractor(current_sequence, orig_from, orig_to, action_from_out, action_from_in, action_to_out, action_to_in, transition_type_selection_index, wipe_luma_sorted_keys_index, gdk_color_str): name, transition_type = rendered_transitions[transition_type_selection_index] # New from clip if orig_from.media_type != appconsts.PATTERN_PRODUCER: from_clip = current_sequence.create_file_producer_clip(orig_from.path)# File producer else: from_clip = current_sequence.create_pattern_producer(orig_from.create_data) # pattern producer current_sequence.clone_clip_and_filters(orig_from, from_clip) # New to clip if not(transition_type == RENDERED_FADE_IN or transition_type == RENDERED_FADE_OUT): # fades to not use to_clip if orig_to.media_type != appconsts.PATTERN_PRODUCER: to_clip = current_sequence.create_file_producer_clip(orig_to.path)# File producer else: to_clip = current_sequence.create_pattern_producer(orig_to.create_data) # pattern producer current_sequence.clone_clip_and_filters(orig_to, to_clip) # Create tractor and tracks tractor = mlt.Tractor() multitrack = tractor.multitrack() track0 = mlt.Playlist() track1 = mlt.Playlist() multitrack.connect(track0, 0) multitrack.connect(track1, 1) # we'll set in and out points for images and pattern producers. if not(transition_type == RENDERED_FADE_IN or transition_type == RENDERED_FADE_OUT): # fades to not use to_clip or some other data used here if from_clip.media_type == appconsts.IMAGE or from_clip.media_type == appconsts.PATTERN_PRODUCER: length = action_from_out - action_from_in from_clip.clip_in = 0 from_clip.clip_out = length if to_clip.media_type == appconsts.IMAGE or to_clip.media_type == appconsts.PATTERN_PRODUCER: length = action_to_out - action_to_in to_clip.clip_in = 0 to_clip.clip_out = length else: length = action_from_out if from_clip.media_type == appconsts.IMAGE or from_clip.media_type == appconsts.PATTERN_PRODUCER: from_clip.clip_in = 0 from_clip.clip_out = length # Add clips to tracks and create keyframe string to contron mixing if transition_type == RENDERED_DISSOLVE or transition_type == RENDERED_WIPE: # Add clips. Images and pattern producers always fill full track. if from_clip.media_type != appconsts.IMAGE and from_clip.media_type != appconsts.PATTERN_PRODUCER: track0.insert(from_clip, 0, action_from_in, action_from_out) else: track0.insert(from_clip, 0, 0, action_from_out - action_from_in) if to_clip.media_type != appconsts.IMAGE and to_clip.media_type != appconsts.PATTERN_PRODUCER: track1.insert(to_clip, 0, action_to_in, action_to_out) else: track1.insert(to_clip, 0, 0, action_to_out - action_to_in) kf_str = "0=0/0:100%x100%:0.0;"+ str(tractor.get_length() - 1) + "=0/0:100%x100%:100.0" elif transition_type == RENDERED_COLOR_DIP: length = action_from_out - action_from_in first_clip_length = length / 2 second_clip_length = length - first_clip_length color_clip = patternproducer.create_color_producer(current_sequence.profile, gdk_color_str) track0.insert(color_clip, 0, 0, length) track1.insert(from_clip, 0, action_from_in, action_from_in + first_clip_length) track1.insert(to_clip, 1, action_to_out - second_clip_length, action_to_out) kf_str = "0=0/0:100%x100%:100.0;"+ str(first_clip_length) + "=0/0:100%x100%:0.0;" + str(tractor.get_length() - 1) + "=0/0:100%x100%:100.0" elif (transition_type == RENDERED_FADE_IN or transition_type == RENDERED_FADE_OUT): color_clip = patternproducer.create_color_producer(current_sequence.profile, gdk_color_str) track0.insert(color_clip, 0, 0, length) if transition_type == RENDERED_FADE_IN: track1.insert(from_clip, 0, orig_from.clip_in, orig_from.clip_in + length) kf_str = "0=0/0:100%x100%:0.0;"+ str(length) + "=0/0:100%x100%:100.0" else: # transition_type == RENDERED_FADE_OUT track1.insert(from_clip, 0, orig_from.clip_out - length, orig_from.clip_out) kf_str = "0=0/0:100%x100%:100.0;"+ str(length) + "=0/0:100%x100%:0.0" # Create transition transition = mlt.Transition(current_sequence.profile, "region") mltrefhold.hold_ref(transition) transition.set("composite.geometry", str(kf_str)) # controls mix over time transition.set("composite.automatic",1) transition.set("composite.aligned", 0) transition.set("composite.deinterlace",0) transition.set("composite.distort",0) transition.set("composite.fill",1) transition.set("composite.operator","over") transition.set("composite.luma_invert",0) transition.set("composite.progressive",1) transition.set("composite.softness",0) transition.set("in", 0) transition.set("out", tractor.get_length() - 1) transition.set("a_track", 0) transition.set("b_track", 1) # Setting luma resource file turns dissolve into wipe if transition_type == RENDERED_WIPE: wipe_resource_path = get_wipe_resource_path_for_sorted_keys_index(wipe_luma_sorted_keys_index) transition.set("composite.luma", str(wipe_resource_path)) # Add transition field = tractor.field() field.plant_transition(transition, 0,1) return tractor
def run(self): items = 1 global progress_window start = time.time() elapsed = 0 proxy_w, proxy_h = _get_proxy_dimensions(self.proxy_profile, editorstate.PROJECT().proxy_data.size) proxy_encoding = _get_proxy_encoding() self.current_render_file_path = None print "proxy render started, items: " + str(len(self.files_to_render)) + ", dim: " + str(proxy_w) + "x" + str(proxy_h) for media_file in self.files_to_render: if self.aborted == True: break # Create render objects proxy_file_path = media_file.create_proxy_path(proxy_w, proxy_h, proxy_encoding.extension) self.current_render_file_path = proxy_file_path consumer = renderconsumer.get_render_consumer_for_encoding( proxy_file_path, self.proxy_profile, proxy_encoding) # Bit rates for proxy files are counted using 2500kbs for # PAL size image as starting point. pal_pix_count = 720.0 * 576.0 pal_proxy_rate = 2500.0 proxy_pix_count = float(proxy_w * proxy_h) proxy_rate = pal_proxy_rate * (proxy_pix_count / pal_pix_count) proxy_rate = int(proxy_rate / 100) * 100 # Make proxy rate even hundred # There are no practical reasons to have bitrates lower than 500kbs. if proxy_rate < 500: proxy_rate = 500 consumer.set("vb", str(int(proxy_rate)) + "k") consumer.set("rescale", "nearest") file_producer = mlt.Producer(self.proxy_profile, str(media_file.path)) mltrefhold.hold_ref(file_producer) stop_frame = file_producer.get_length() - 1 # Create and launch render thread global render_thread render_thread = renderconsumer.FileRenderPlayer(None, file_producer, consumer, 0, stop_frame) render_thread.start() # Render view update loop self.thread_running = True self.aborted = False while self.thread_running: if self.aborted == True: break render_fraction = render_thread.get_render_fraction() now = time.time() elapsed = now - start gtk.gdk.threads_enter() progress_window.update_render_progress(render_fraction, media_file.name, items, len(self.files_to_render), elapsed) gtk.gdk.threads_leave() render_thread.producer.get_length() if render_thread.producer.frame() >= stop_frame: self.thread_running = False media_file.add_proxy_file(proxy_file_path) if self.set_as_proxy_immediately: # When proxy mode is USE_PROXY_MEDIA all proxy files are used all the time media_file.set_as_proxy_media_file() self.current_render_file_path = None else: time.sleep(0.1) if not self.aborted: items = items + 1 gtk.gdk.threads_enter() progress_window.update_render_progress(0, media_file.name, items, len(self.files_to_render), elapsed) gtk.gdk.threads_leave() else: print "proxy render aborted" render_thread.shutdown() break render_thread.shutdown() gtk.gdk.threads_enter() _proxy_render_stopped() gtk.gdk.threads_leave() # Remove unfinished proxy files if self.current_render_file_path != None: os.remove(self.current_render_file_path) # If we're currently proxy editing, we need to update # all the clips on the timeline to use proxy media. if editorstate.PROJECT().proxy_data.proxy_mode == appconsts.USE_PROXY_MEDIA: _auto_renconvert_after_proxy_render_in_proxy_mode() print "proxy render done"
def run(self): items = 1 global progress_window start = time.time() elapsed = 0 proxy_w, proxy_h = _get_proxy_dimensions( self.proxy_profile, editorstate.PROJECT().proxy_data.size) proxy_encoding = _get_proxy_encoding() self.current_render_file_path = None print "proxy render started, items: " + str(len( self.files_to_render)) + ", dim: " + str(proxy_w) + "x" + str( proxy_h) for media_file in self.files_to_render: if self.aborted == True: break if media_file.type == appconsts.IMAGE_SEQUENCE: self._create_img_seq_proxy(media_file, proxy_w, proxy_h, items, start) continue # Create render objects proxy_file_path = media_file.create_proxy_path( proxy_w, proxy_h, proxy_encoding.extension) self.current_render_file_path = proxy_file_path renderconsumer.performance_settings_enabled = False consumer = renderconsumer.get_render_consumer_for_encoding( proxy_file_path, self.proxy_profile, proxy_encoding) renderconsumer.performance_settings_enabled = True # Bit rates for proxy files are counted using 2500kbs for # PAL size image as starting point. pal_pix_count = 720.0 * 576.0 pal_proxy_rate = 2500.0 proxy_pix_count = float(proxy_w * proxy_h) proxy_rate = pal_proxy_rate * (proxy_pix_count / pal_pix_count) proxy_rate = int( proxy_rate / 100) * 100 # Make proxy rate even hundred # There are no practical reasons to have bitrates lower than 500kbs. if proxy_rate < 500: proxy_rate = 500 consumer.set("vb", str(int(proxy_rate)) + "k") consumer.set("rescale", "nearest") file_producer = mlt.Producer(self.proxy_profile, str(media_file.path)) mltrefhold.hold_ref( file_producer ) # this may or may not be needed to avoid crashes stop_frame = file_producer.get_length() - 1 # Create and launch render thread global render_thread render_thread = renderconsumer.FileRenderPlayer( None, file_producer, consumer, 0, stop_frame) render_thread.start() # Render view update loop self.thread_running = True self.aborted = False while self.thread_running: if self.aborted == True: break render_fraction = render_thread.get_render_fraction() now = time.time() elapsed = now - start Gdk.threads_enter() progress_window.update_render_progress( render_fraction, media_file.name, items, len(self.files_to_render), elapsed) Gdk.threads_leave() render_thread.producer.get_length() if render_thread.producer.frame() >= stop_frame: self.thread_running = False media_file.add_proxy_file(proxy_file_path) if self.set_as_proxy_immediately: # When proxy mode is USE_PROXY_MEDIA all proxy files are used all the time media_file.set_as_proxy_media_file() self.current_render_file_path = None else: time.sleep(0.1) if not self.aborted: items = items + 1 Gdk.threads_enter() progress_window.update_render_progress( 0, media_file.name, items, len(self.files_to_render), elapsed) Gdk.threads_leave() else: print "proxy render aborted" render_thread.shutdown() break render_thread.shutdown() Gdk.threads_enter() _proxy_render_stopped() Gdk.threads_leave() # Remove unfinished proxy files if self.current_render_file_path != None: os.remove(self.current_render_file_path) # If we're currently proxy editing, we need to update # all the clips on the timeline to use proxy media. if editorstate.PROJECT( ).proxy_data.proxy_mode == appconsts.USE_PROXY_MEDIA: _auto_re_convert_after_proxy_render_in_proxy_mode() print "proxy render done"