def load_filters_xml(services): """ Load filters document and save filters nodes as FilterInfo objects in array. Save them also as array of tuples of names and arrays of FilterInfo objects that represent named groups of filters as displayd to user. """ _load_icons() print "Loading filters..." global filters_doc filters_doc = xml.dom.minidom.parse(respaths.FILTERS_XML_DOC) load_groups = {} filter_nodes = filters_doc.getElementsByTagName(FILTER) for f_node in filter_nodes: filter_info = FilterInfo(f_node) if filter_info.mlt_drop_version != "": if editorstate.mlt_version_is_equal_or_greater(filter_info.mlt_drop_version): print filter_info.name + " dropped, MLT version too high for this filter." continue if filter_info.mlt_min_version != "": if not editorstate.mlt_version_is_equal_or_greater(filter_info.mlt_min_version): print filter_info.name + " dropped, MLT version too low for this filter." continue if (not filter_info.mlt_service_id in services) and len(services) > 0: print "MLT service " + filter_info.mlt_service_id + " not found." global not_found_filters not_found_filters.append(filter_info) continue if filter_info.mlt_service_id == "volume": # we need this filter to do mutes so save reference to it global _volume_filter_info _volume_filter_info = filter_info # Add filter compositor filters or filter groups if filter_info.group == COMPOSITOR_FILTER_GROUP: global compositor_filters compositor_filters[filter_info.name] = filter_info else: translated_group_name = _translate_group_name(filter_info.group) try: group = load_groups[translated_group_name] group.append(filter_info) except: load_groups[translated_group_name] = [filter_info] # We used translated group names as keys in load_groups # Now we sort them and use them to place data in groups array in the same # order as it will be presented to user, so selection indexes in gui components will match # group array indexes here. sorted_keys = sorted(load_groups.keys()) global groups for gkey in sorted_keys: group = load_groups[gkey] add_group = sorted(group, key=lambda finfo: translations.get_filter_name(finfo.name)) groups.append((gkey, add_group))
def load_filters_xml(services): """ Load filters document and save filters nodes as FilterInfo objects in array. Save them also as array of tuples of names and arrays of FilterInfo objects that represent named groups of filters as displayd to user. """ _load_icons() print "Loading filters..." global filters_doc filters_doc = xml.dom.minidom.parse(respaths.FILTERS_XML_DOC) load_groups = {} filter_nodes = filters_doc.getElementsByTagName(FILTER) for f_node in filter_nodes: filter_info = FilterInfo(f_node) if filter_info.mlt_drop_version != "": if editorstate.mlt_version_is_equal_or_greater(filter_info.mlt_drop_version): print filter_info.name + " dropped, MLT version too high for this filter." continue if filter_info.mlt_min_version != "": if not editorstate.mlt_version_is_equal_or_greater(filter_info.mlt_min_version): print filter_info.name + " dropped, MLT version too low for this filter." continue if (not filter_info.mlt_service_id in services) and len(services) > 0: print "MLT service " + filter_info.mlt_service_id + " not found." global not_found_filters not_found_filters.append(filter_info) continue if filter_info.mlt_service_id == "volume": # we need this filter to do mutes so save reference to it global _volume_filter_info _volume_filter_info = filter_info # Add filter compositor filters or filter groups if filter_info.group == COMPOSITOR_FILTER_GROUP: global compositor_filters compositor_filters[filter_info.name] = filter_info else: translated_group_name = _translate_group_name(filter_info.group) try: group = load_groups[translated_group_name] group.append(filter_info) except: load_groups[translated_group_name] = [filter_info] # We used translated group names as keys in load_groups # Now we sort them and use them to place data in groups array in the same # order as it will be presented to user, so selection indexes in gui components will match # group array indexes here. sorted_keys = sorted(load_groups.keys()) global groups for gkey in sorted_keys: group = load_groups[gkey] add_group = sorted(group, key=lambda finfo: translations.get_filter_name(finfo.name) ) groups.append((gkey, add_group))
def _select_relink_path_dialog_callback(file_select, response_id, media_asset): filenames = file_select.get_filenames() file_select.destroy() if response_id != Gtk.ResponseType.OK: return if len(filenames) == 0: return media_asset.relink_path = filenames[0] folder, file_name = os.path.split(filenames[0]) global last_media_dir last_media_dir = folder # Relink all the files in a same directory for med_asset in media_assets: med_link_name = os.path.basename(med_asset.orig_path) link_path = os.path.join(folder, med_link_name) if os.path.isfile(link_path): if med_asset.media_type == appconsts.IMAGE_SEQUENCE: # img seqs need formatted path if editorstate.mlt_version_is_equal_or_greater("0.8.5"): new_style = True else: new_style = False resource_name_str = utils.get_img_seq_resource_name( link_path, new_style) med_asset.relink_path = folder + "/" + resource_name_str else: med_asset.relink_path = link_path linker_window.relink_list.fill_data_model()
def _add_image_sequence_callback(dialog, response_id, data): if response_id == Gtk.ResponseType.CANCEL: dialog.destroy() return file_chooser, spin = data frame_file = file_chooser.get_filename() dialog.destroy() if frame_file == None: dialogutils.info_message(_("No file was selected"), _("Select a numbered file to add an Image Sequence to Project."), gui.editor_window.window) return (folder, file_name) = os.path.split(frame_file) try: number_parts = re.findall("[0-9]+", file_name) number_part = number_parts[-1] # we want the last number part except: dialogutils.info_message(_("Not a sequence file!"), _("Selected file does not have a number part in it,\nso it can't be an image sequence file."), gui.editor_window.window) return # Create resource name with MLT syntax for MLT producer number_index = file_name.find(number_part) path_name_part = file_name[0:number_index] end_part = file_name[number_index + len(number_part):len(file_name)] # The better version with "?begin=xxx" only available after 0.8.7 if editorstate.mlt_version_is_equal_or_greater("0.8.5"): resource_name_str = utils.get_img_seq_resource_name(frame_file, True) else: resource_name_str = utils.get_img_seq_resource_name(frame_file, False) # detect highest file # FIX: this fails if two similarily numbered sequences in same dir and both have same substring in frame name onlyfiles = [ f for f in listdir(folder) if isfile(join(folder,f)) ] highest_number_part = int(number_part) for f in onlyfiles: try: file_number_part = int(re.findall("[0-9]+", f)[-1]) # -1, we want the last number part except: continue if f.find(path_name_part) == -1: continue if file_number_part > highest_number_part: highest_number_part = file_number_part dialog.destroy() resource_path = folder + "/" + resource_name_str length = highest_number_part - int(number_part) PROJECT().add_image_sequence_media_object(resource_path, file_name + "(img_seq)", length) gui.media_list_view.fill_data_model() gui.bin_list_view.fill_data_model() editorpersistance.prefs.last_opened_media_dir = os.path.dirname(resource_path) editorpersistance.save()
def _select_relink_path_dialog_callback(file_select, response_id, media_asset): filenames = file_select.get_filenames() file_select.destroy() if response_id != Gtk.ResponseType.OK: return if len(filenames) == 0: return media_asset.relink_path = filenames[0] if media_asset.media_type == appconsts.IMAGE_SEQUENCE: # img seqs need formatted path if editorstate.mlt_version_is_equal_or_greater("0.8.5"): new_style = True else: new_style = False resource_name_str = utils.get_img_seq_resource_name(filenames[0], new_style) folder, file_name = os.path.split(filenames[0]) media_asset.relink_path = folder + "/" + resource_name_str linker_window.relink_list.fill_data_model()
def _select_relink_path_dialog_callback(file_select, response_id, media_asset): filenames = file_select.get_filenames() file_select.destroy() if response_id != Gtk.ResponseType.OK: return if len(filenames) == 0: return media_asset.relink_path = filenames[0] if media_asset.media_type == appconsts.IMAGE_SEQUENCE: # img seqs need formatted path if editorstate.mlt_version_is_equal_or_greater("0.8.5"): new_style = True else: new_style = False resource_name_str = utils.get_img_seq_resource_name( filenames[0], new_style) folder, file_name = os.path.split(filenames[0]) media_asset.relink_path = folder + "/" + resource_name_str linker_window.relink_list.fill_data_model()
def main(root_path, session_id, project_path, range_in, range_out, profile_desc): project_path = utils.escape_shell_path(project_path) try: editorstate.mlt_version = mlt.LIBMLT_VERSION except: editorstate.mlt_version = "0.0.99" # magic string for "not found" # Set paths. respaths.set_paths(root_path) userfolders.init() editorpersistance.load() # Init translations module with translations data translations.init_languages() translations.load_filters_translations() mlttransitions.init_module() repo = mlt.Factory().init() processutils.prepare_mlt_repo(repo) # Set numeric locale to use "." as radix, MLT initilizes this to OS locale and this causes bugs locale.setlocale(locale.LC_NUMERIC, 'C') # Check for codecs and formats on the system mltenv.check_available_features(repo) renderconsumer.load_render_profiles() # Load filter and compositor descriptions from xml files. mltfilters.load_filters_xml(mltenv.services) mlttransitions.load_compositors_xml(mltenv.transitions) # Create list of available mlt profiles mltprofiles.load_profile_list() ccrutils.init_session_folders(session_id) ccrutils.load_render_data() log_path = GLib.get_user_cache_dir() + "/blenderrenderlog" FLOG = open(log_path, 'w') render_setup_script = respaths.ROOT_PATH + "/tools/blenderrendersetup.py" blender_launch = "/usr/bin/blender -b " + project_path + " -P " + utils.escape_shell_path( render_setup_script) global _start_time _start_time = time.monotonic() render_data = ccrutils.get_render_data() # Delete old rendered frames for non-preview renders. if render_data.is_preview_render == False: rendered_frames_folder = ccrutils.rendered_frames_folder() for frame_file in os.listdir(rendered_frames_folder): file_path = os.path.join(rendered_frames_folder, frame_file) os.remove(file_path) else: # For preview render delete preview frames preview_frames_folder = ccrutils.preview_frames_folder() for frame_file in os.listdir(preview_frames_folder): file_path = os.path.join(preview_frames_folder, frame_file) os.remove(file_path) p = subprocess.Popen(blender_launch, shell=True, stdin=FLOG, stdout=FLOG, stderr=FLOG, preexec_fn=os.setsid) manager_thread = ProgressPollingThread(range_in, range_out, p, render_data.is_preview_render) manager_thread.start() p.wait() if manager_thread.abort == True: return # Render video if render_data.do_video_render == True: # Change file numbering to start from 0000 to please ffmpeg rendered_folder = ccrutils.rendered_frames_folder() + "/" files = [ f for f in listdir(rendered_folder) if isfile(join(rendered_folder, f)) ] files.sort(key=lambda var: [ int(x) if x.isdigit() else x for x in re.findall(r'[^0-9]|[0-9]+', var) ]) number = 0 for rendered_file in files: source_file = rendered_folder + rendered_file file_number = '{0:04d}'.format(number) dst_file = rendered_folder + "videoframe" + file_number + ".png" Path(source_file).rename(dst_file) number += 1 # Render consumer args_vals_list = toolsencoding.get_args_vals_list_for_render_data( render_data) profile = mltprofiles.get_profile_for_index(render_data.profile_index) if ccrutils.get_render_data().save_internally == True: file_path = ccrutils.session_folder( ) + "/" + appconsts.CONTAINER_CLIP_VIDEO_CLIP_NAME + render_data.file_extension else: file_path = render_data.render_dir + "/" + render_data.file_name + render_data.file_extension consumer = renderconsumer.get_mlt_render_consumer( file_path, profile, args_vals_list) # Render producer rendered_frames_folder = ccrutils.rendered_frames_folder() frames_info = gmicplayer.FolderFramesInfo(rendered_frames_folder) frame_file = frames_info.get_lowest_numbered_file() if editorstate.mlt_version_is_equal_or_greater("0.8.5"): resource_name_str = utils.get_img_seq_resource_name( frame_file, True) else: resource_name_str = utils.get_img_seq_resource_name( frame_file, False) resource_path = rendered_frames_folder + "/" + resource_name_str producer = mlt.Producer(profile, str(resource_path)) frames_length = len(os.listdir(rendered_frames_folder)) render_player = renderconsumer.FileRenderPlayer( "", producer, consumer, 0, frames_length - 1) render_player.wait_for_producer_end_stop = False render_player.start() abort = False while render_player.stopped == False and abort == False: abort = ccrutils.abort_requested() if abort == True: render_player.shutdown() return else: fraction = render_player.get_render_fraction() elapsed = time.monotonic() - _start_time msg = "2 " + str(fraction) + " " + str(elapsed) ccrutils.write_status_message(msg) time.sleep(1.0) else: manager_thread.abort = True # to exit while loop and end thread ccrutils.write_completed_message() print("Blender render complete.")
def run(self): self.render_player = None self.frames_range_writer = None self.abort = False # Refuse to render into user home folder out_folder = _window.out_folder.get_filenames()[0] + "/" if out_folder == (os.path.expanduser("~") + "/"): print "home folder" return start_time = time.time() Gdk.threads_enter() _window.render_status_info.set_markup("") _window.set_widgets_sensitive(False) _window.render_percentage.set_sensitive(True) _window.render_status_info.set_sensitive(True) _window.render_progress_bar.set_sensitive(True) _window.stop_button.set_sensitive(True) _window.render_button.set_sensitive(False) _window.close_button.set_sensitive(False) _window.encode_settings_button.set_sensitive(False) _window.encode_desc.set_sensitive(False) _window.hamburger_launcher.widget.set_sensitive(False) _window.load_button.set_sensitive(False) Gdk.threads_leave() # Delete old preview frames folder = get_render_frames_dir() for frame_file in os.listdir(folder): file_path = os.path.join(folder, frame_file) os.remove(file_path) # Render clipm frames for range mark_in = _player.producer.mark_in mark_out = _player.producer.mark_out self.length = mark_out - mark_in + 1 self.mark_in = mark_in self.mark_out = mark_out frame_name = _window.frame_name.get_text() # jotain controllii frame_namelle self.frames_range_writer = gmicplayer.FramesRangeWriter(_current_path, self.frames_update) self.frames_range_writer.write_frames(get_render_frames_dir() + "/", frame_name, mark_in, mark_out) if self.abort == True: return # Render effect for frames # Get user script Gdk.threads_enter() buf = _window.script_view.get_buffer() user_script = buf.get_text(buf.get_start_iter(), buf.get_end_iter(), False) _window.render_percentage.set_markup("<small>" + _("Waiting for frames write to complete...") + "</small>") Gdk.threads_leave() while len(os.listdir(folder)) != self.length: time.sleep(0.5) clip_frames = os.listdir(folder) frame_count = 1 for clip_frame in clip_frames: if self.abort == True: return update_info = _("Rendering frame: ") + str(frame_count) + "/" + str(self.length) Gdk.threads_enter() _window.render_percentage.set_markup("<small>" + update_info + "</small>") _window.render_progress_bar.set_fraction(float(frame_count)/float(self.length)) Gdk.threads_leave() file_numbers_list = re.findall(r'\d+', clip_frame) filled_number_str = str(file_numbers_list[0]).zfill(3) clip_frame_path = os.path.join(folder, clip_frame) rendered_file_path = out_folder + frame_name + "_" + filled_number_str + ".png" script_str = "gmic " + clip_frame_path + " " + user_script + " -output " + rendered_file_path if frame_count == 1: # first frame displays shell output and does error checking FLOG = open(utils.get_hidden_user_dir_path() + "log_gmic_preview", 'w') p = subprocess.Popen(script_str, shell=True, stdin=FLOG, stdout=FLOG, stderr=FLOG) p.wait() FLOG.close() # read log f = open(utils.get_hidden_user_dir_path() + "log_gmic_preview", 'r') out = f.read() f.close() Gdk.threads_enter() _window.out_view.get_buffer().set_text(out + "Return code:" + str(p.returncode)) if p.returncode != 0: _window.out_view.override_color((Gtk.StateFlags.NORMAL and Gtk.StateFlags.ACTIVE), Gdk.RGBA(red=1.0, green=0.0, blue=0.0)) _window.render_percentage.set_text(_("Render error!")) Gdk.threads_leave() return else: _window.out_view.override_color((Gtk.StateFlags.NORMAL and Gtk.StateFlags.ACTIVE), None) Gdk.threads_leave() else: FLOG = open(utils.get_hidden_user_dir_path() + "log_gmic_preview", 'w') p = subprocess.Popen(script_str, shell=True, stdin=FLOG, stdout=FLOG, stderr=FLOG) p.wait() FLOG.close() frame_count = frame_count + 1 # Render video if _window.encode_check.get_active() == True: # Render consumer args_vals_list = toolsencoding.get_args_vals_list_for_render_data(_render_data) profile = mltprofiles.get_profile_for_index(_current_profile_index) file_path = _render_data.render_dir + "/" + _render_data.file_name + _render_data.file_extension consumer = renderconsumer.get_mlt_render_consumer(file_path, profile, args_vals_list) # Render producer frame_file = out_folder + frame_name + "_0000.png" if editorstate.mlt_version_is_equal_or_greater("0.8.5"): resource_name_str = utils.get_img_seq_resource_name(frame_file, True) else: resource_name_str = utils.get_img_seq_resource_name(frame_file, False) resource_path = out_folder + "/" + resource_name_str producer = mlt.Producer(profile, str(resource_path)) self.render_player = renderconsumer.FileRenderPlayer("", producer, consumer, 0, len(clip_frames) - 1) self.render_player.wait_for_producer_end_stop = False self.render_player.start() while self.render_player.stopped == False: if self.abort == True: return fraction = self.render_player.get_render_fraction() update_info = _("Rendering video, ") + str(int(fraction * 100)) + _("% done") Gdk.threads_enter() _window.render_percentage.set_markup("<small>" + update_info + "</small>") _window.render_progress_bar.set_fraction(fraction) Gdk.threads_leave() time.sleep(0.3) Gdk.threads_enter() _window.render_percentage.set_markup("<small>" + _("Render complete!") + "</small>") self.set_render_stopped_gui_state() Gdk.threads_leave()
def run(self): self.start_time = time.monotonic() self.render_player = None self.frames_range_writer = None self.script_renderer = None if self.render_data.save_internally == True: frame_name = "frame" else: frame_name = self.render_data.frame_name clip_frames_folder = ccrutils.clip_frames_folder() rendered_frames_folder = ccrutils.rendered_frames_folder() profile = mltprofiles.get_profile(self.profile_desc) # Delete old frames for frame_file in os.listdir(clip_frames_folder): file_path = os.path.join(clip_frames_folder, frame_file) os.remove(file_path) # Delete old frames for frame_file in os.listdir(rendered_frames_folder): file_path = os.path.join(rendered_frames_folder, frame_file) os.remove(file_path) self.frames_range_writer = gmicplayer.FramesRangeWriter( self.clip_path, self.frames_update, profile) self.frames_range_writer.write_frames(clip_frames_folder + "/", frame_name, self.range_in, self.range_out) if self.abort == True: return script_file = open(self.script_path) user_script = script_file.read() while len(os.listdir(clip_frames_folder)) != self.length: time.sleep(0.5) # Render frames with gmic script self.script_renderer = gmicplayer.FolderFramesScriptRenderer( user_script, clip_frames_folder, rendered_frames_folder + "/", frame_name, self.script_render_update_callback, self.script_render_output_callback, 10, False, # this is not useful until we get MLT to fin frames sequences not startin from 0001 0) self.script_renderer.write_frames() ccrutils.delete_clip_frames() if self.abort == True: return # Render video if self.render_data.do_video_render == True: # Render consumer args_vals_list = toolsencoding.get_args_vals_list_for_render_data( self.render_data) profile = mltprofiles.get_profile_for_index( self.render_data.profile_index) if self.render_data.save_internally == True: file_path = ccrutils.session_folder( ) + "/" + appconsts.CONTAINER_CLIP_VIDEO_CLIP_NAME + self.render_data.file_extension else: file_path = self.render_data.render_dir + "/" + self.render_data.file_name + self.render_data.file_extension consumer = renderconsumer.get_mlt_render_consumer( file_path, profile, args_vals_list) # Render producer frame_file = rendered_frames_folder + "/" + frame_name + "_0000.png" if editorstate.mlt_version_is_equal_or_greater("0.8.5"): resource_name_str = utils.get_img_seq_resource_name( frame_file, True) else: resource_name_str = utils.get_img_seq_resource_name( frame_file, False) resource_path = rendered_frames_folder + "/" + resource_name_str producer = mlt.Producer(profile, str(resource_path)) frames_length = len(os.listdir(rendered_frames_folder)) self.render_player = renderconsumer.FileRenderPlayer( "", producer, consumer, 0, frames_length - 1) self.render_player.wait_for_producer_end_stop = False self.render_player.start() while self.render_player.stopped == False: self.abort_requested() if self.abort == True: self.render_player.shutdown() return fraction = self.render_player.get_render_fraction() self.video_render_update_callback(fraction) time.sleep(0.3) ccrutils.delete_rendered_frames() # Write out completed flag file. ccrutils.write_completed_message()