def load(): """ If docs fail to load, new ones are created and saved. """ prefs_file_path = utils.get_hidden_user_dir_path() + PREFS_DOC recents_file_path = utils.get_hidden_user_dir_path() + RECENT_DOC global prefs, recent_projects try: f = open(prefs_file_path) prefs = pickle.load(f) except: prefs = EditorPreferences() write_file = file(prefs_file_path, "wb") pickle.dump(prefs, write_file) try: f = open(recents_file_path) recent_projects = pickle.load(f) except: recent_projects = utils.EmptyClass() recent_projects.projects = [] write_file = file(recents_file_path, "wb") pickle.dump(recent_projects, write_file) # version of program may have different prefs objects and # we may need to to update prefs on disk if user has e.g. # installed later version of Flowblade current_prefs = EditorPreferences() if len(prefs.__dict__) != len(current_prefs.__dict__): current_prefs.__dict__.update(prefs.__dict__) prefs = current_prefs write_file = file(prefs_file_path, "wb") pickle.dump(prefs, write_file) print "prefs updated to new version, new param count:", len(prefs.__dict__)
def load(): """ If docs fail to load, new ones are created and saved. """ prefs_file_path = utils.get_hidden_user_dir_path() + PREFS_DOC recents_file_path = utils.get_hidden_user_dir_path() + RECENT_DOC global prefs, recent_projects try: f = open(prefs_file_path) prefs = pickle.load(f) except: prefs = EditorPreferences() write_file = file(prefs_file_path, "wb") pickle.dump(prefs, write_file) # Override deprecated preferences to default values. prefs.delta_overlay = True prefs.auto_play_in_clip_monitor = False prefs.empty_click_exits_trims = True prefs.quick_enter_trims = True prefs.remember_monitor_clip_frame = True try: f = open(recents_file_path) recent_projects = pickle.load(f) except: recent_projects = utils.EmptyClass() recent_projects.projects = [] write_file = file(recents_file_path, "wb") pickle.dump(recent_projects, write_file) # Remove non-existing projects from recents list remove_list = [] for proj_path in recent_projects.projects: if os.path.isfile(proj_path) == False: remove_list.append(proj_path) if len(remove_list) > 0: for proj_path in remove_list: recent_projects.projects.remove(proj_path) write_file = file(recents_file_path, "wb") pickle.dump(recent_projects, write_file) # Versions of program may have different prefs objects and # we may need to to update prefs on disk if user has e.g. # installed later version of Flowblade. current_prefs = EditorPreferences() if len(prefs.__dict__) != len(current_prefs.__dict__): current_prefs.__dict__.update(prefs.__dict__) prefs = current_prefs write_file = file(prefs_file_path, "wb") pickle.dump(prefs, write_file) print "prefs updated to new version, new param count:", len(prefs.__dict__)
def run(self): start_time = time.time() b_switch = "-b" w_switch = "-w" writer = "Write1" if self.is_preview == False: range_str = _animation_instance.get_frame_range_str() render_frame = _window.get_render_frame() else: range_str = str(_animation_instance.frame()) render_frame = utils.get_hidden_user_dir_path() + appconsts.NATRON_DIR + "/session_" + _session_id + "/preview####.png" print render_frame Gdk.threads_enter() _window.preview_info.set_markup("<small>" + _("Rendering preview for frame ") + range_str + "..." + "</small>") Gdk.threads_leave() l_switch = "-l" param_mod_script = respaths.ROOT_PATH + "/tools/NatronRenderModify.py" natron_project = _animation_instance.get_project_file_path() render_command = "NatronRenderer " + b_switch + " " + w_switch + " " + writer + " " + \ range_str + " " + render_frame + " " + l_switch + " " + param_mod_script + " " + natron_project print "Starting Natron render, command: ", render_command FLOG = open(utils.get_hidden_user_dir_path() + "log_natron_render", 'w') p = subprocess.Popen(render_command, shell=True, stdin=FLOG, stdout=FLOG, stderr=FLOG) p.wait() FLOG.close() if _progress_updater != None: _progress_updater.stop_thread() # Render complete GUI updates Gdk.threads_enter() if self.is_preview == False: _window.render_percentage.set_markup("<small>" + _("Render complete.") + "</small>") else: render_time = time.time() - start_time time_str = "{0:.2f}".format(round(render_time,2)) _window.preview_info.set_markup("<small>" + _("Preview for frame: ") + range_str + \ _(", render time: ") + time_str + "</small>" ) global _current_preview_surface preview_frame_path = utils.get_hidden_user_dir_path() + appconsts.NATRON_DIR + "/session_" + _session_id + "/preview" + str(_animation_instance.frame()).zfill(4) + ".png" _current_preview_surface = cairo.ImageSurface.create_from_png(preview_frame_path) _window.preview_monitor.queue_draw() Gdk.threads_leave() print "Natron render done."
def save(): """ Write out prefs and recent_projects files """ prefs_file_path = utils.get_hidden_user_dir_path() + PREFS_DOC recents_file_path = utils.get_hidden_user_dir_path() + RECENT_DOC write_file = file(prefs_file_path, "wb") pickle.dump(prefs, write_file) write_file = file(recents_file_path, "wb") pickle.dump(recent_projects, write_file)
def run(self): start_time = time.time() try: # For the case the render fails shutil.copyfile(get_current_frame_file(), get_preview_file()) except IOError: # No we have failed to extract a png file from source file Gdk.threads_enter() _window.out_view.override_color((Gtk.StateFlags.NORMAL and Gtk.StateFlags.ACTIVE), Gdk.RGBA(red=1.0, green=0.0, blue=0.0)) _window.out_view.get_buffer().set_text("Extracting PNG frames from this file failed!") Gdk.threads_leave() return Gdk.threads_enter() _window.preview_info.set_markup("<small>" + _("Rendering preview...") + "</small>" ) buf = _window.script_view.get_buffer() view_text = buf.get_text(buf.get_start_iter(), buf.get_end_iter(), False) Gdk.threads_leave() script_str = "gmic " + get_current_frame_file() + " " + view_text + " -output " + get_preview_file() print "Render preview:", script_str 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() global _current_preview_surface _current_preview_surface = cairo.ImageSurface.create_from_png(get_preview_file()) Gdk.threads_enter() 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)) else: _window.out_view.override_color((Gtk.StateFlags.NORMAL and Gtk.StateFlags.ACTIVE), None) _window.out_view.get_buffer().set_text(out + "Return code:" + str(p.returncode)) render_time = time.time() - start_time time_str = "{0:.2f}".format(round(render_time,2)) _window.preview_info.set_markup("<small>" + _("Preview for frame: ") + \ utils.get_tc_string_with_fps(_player.current_frame(), _current_fps) + _(", render time: ") + time_str + "</small>" ) _window.preview_monitor.queue_draw() Gdk.threads_leave()
def set_waveform_displayer_clip_from_popup(data): clip, track, item_id, item_data = data global frames_cache if clip.path in frames_cache: frame_levels = frames_cache[clip.path] clip.waveform_data = frame_levels return cache_file_path = utils.get_hidden_user_dir_path() + appconsts.AUDIO_LEVELS_DIR + _get_unique_name_for_media(clip.path) if os.path.isfile(cache_file_path): f = open(cache_file_path) frame_levels = pickle.load(f) frames_cache[clip.path] = frame_levels clip.waveform_data = frame_levels return progress_bar = Gtk.ProgressBar() title = _("Audio Levels Data Render") text = "<b>Media File: </b>" + clip.path dialog = _waveform_render_progress_dialog(_waveform_render_abort, title, text, progress_bar, gui.editor_window.window) dialog.progress_bar = progress_bar global waveform_thread waveform_thread = WaveformCreator(clip, track.height, dialog) waveform_thread.start()
def launch_phantom(): respaths.PHANTOM_JAR if _phantom_found == False: info_row = guiutils.get_centered_box([Gtk.Label(_("Phantom2D tool has not been installed on your system."))]) link_info_row = guiutils.get_centered_box([Gtk.Label(_("Install instructions:"))]) link = Gtk.LinkButton.new("https://github.com/jliljebl/phantom2D") link_row = guiutils.get_centered_box([link]) dir_info_row = guiutils.get_centered_box([Gtk.Label(_("Install directory for Phantom2D tool:"))]) dir_label = Gtk.Label(respaths.PHANTOM_JAR.rstrip("/Phantom2D.jar")) dir_label.set_selectable(True) dir_row = guiutils.get_centered_box([Gtk.Label(respaths.PHANTOM_JAR.rstrip("/Phantom2D.jar"))]) dir_row.set_margin_top(8) panel = Gtk.VBox() panel.pack_start(info_row, False, False, 0) panel.pack_start(guiutils.pad_label(12, 24), False, False, 0) panel.pack_start(link_info_row, False, False, 0) panel.pack_start(link_row, False, False, 0) panel.pack_start(guiutils.pad_label(12, 24), False, False, 0) panel.pack_start(dir_info_row, False, False, 0) panel.pack_start(dir_row, False, False, 0) dialogutils.panel_ok_dialog(_("Phantom2D not found"), panel) return FLOG = open(utils.get_hidden_user_dir_path() + "log_phantom", 'w') subprocess.Popen([str(respaths.LAUNCH_DIR + "flowbladephantom") + " " + str(respaths.PHANTOM_JAR) \ + " profile" + " " + _get_underscored_profile() \ + " cachefolder " + utils.get_phantom_disk_cache_folder()], shell=True, stdin=FLOG, stdout=FLOG, stderr=FLOG) print "Phantom2D launched"
def load_render_items(self): self.queue = [] self.error_status = None user_dir = utils.get_hidden_user_dir_path() data_files_dir = user_dir + DATAFILES_DIR data_files = [ f for f in listdir(data_files_dir) if isfile(join(data_files_dir,f)) ] for data_file_name in data_files: try: data_file_path = data_files_dir + data_file_name data_file = open(data_file_path) render_item = pickle.load(data_file) self.queue.append(render_item) except Exception as e: if self.error_status == None: self.error_status = [] self.error_status.append((data_file_name, _(" datafile load failed with ") + str(e))) try: render_file = open(render_item.get_project_filepath()) except Exception as e: if self.error_status == None: self.error_status = [] self.error_status.append((render_item.get_project_filepath(), _(" project file load failed with ") + str(e))) if self.error_status != None: for file_path, error_str in self.error_status: identifier = get_identifier_from_path(file_path) destroy_for_identifier(identifier) for render_item in self.queue: if render_item.matches_identifier(identifier): self.queue.remove(render_item) break # Latest added items displayed on top self.queue.sort(key=lambda item: item.timestamp) self.queue.reverse()
def _auto_renconvert_after_proxy_render_in_proxy_mode(): # Save to temp to convert to using original media project = editorstate.PROJECT() project.proxy_data.proxy_mode = appconsts.CONVERTING_TO_USE_ORIGINAL_MEDIA conv_temp_project_path = utils.get_hidden_user_dir_path() + "proxy_conv.flb" persistance.save_project(editorstate.PROJECT(), conv_temp_project_path) project.proxy_data.proxy_mode = appconsts.USE_ORIGINAL_MEDIA # Load saved temp original media project persistance.show_messages = False project = persistance.load_project(conv_temp_project_path) # Save to temp to convert back to using proxy media project.proxy_data.proxy_mode = appconsts.CONVERTING_TO_USE_PROXY_MEDIA persistance.save_project(project, conv_temp_project_path) project.proxy_data.proxy_mode = appconsts.USE_PROXY_MEDIA # Load saved temp proxy project project = persistance.load_project(conv_temp_project_path) # Open saved temp project app.stop_autosave() gtk.gdk.threads_enter() app.open_project(project) gtk.gdk.threads_leave() app.start_autosave() editorstate.update_current_proxy_paths() persistance.show_messages = True
def run(self): # 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() # Delete old preview frames folder = get_clip_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 frame_name = "frrrrame" frames_range_writer = gmicplayer.FramesRangeWriter(_current_path, self.frames_update) frames_range_writer.write_frames(get_clip_frames_dir() + "/", frame_name, mark_in, mark_out) # 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) Gdk.threads_leave() clip_frames = os.listdir(folder) frame_count = 1 for clip_frame in clip_frames: update_info = "Render effect frame " + str(frame_count) + "/" + str(self.length) Gdk.threads_enter() _window.render_percentage.set_text(update_info) Gdk.threads_leave() frame_count = frame_count + 1 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 print script_str 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 """
def launch_batch_rendering(): bus = dbus.SessionBus() if bus.name_has_owner('flowblade.movie.editor.batchrender'): print "flowblade.movie.editor.batchrender dbus service exists, batch rendering already running" _show_single_instance_info() else: FLOG = open(utils.get_hidden_user_dir_path() + "log_batch_render", 'w') subprocess.Popen([sys.executable, respaths.LAUNCH_DIR + "flowbladebatch"], stdin=FLOG, stdout=FLOG, stderr=FLOG)
def init_dirs_if_needed(): user_dir = utils.get_hidden_user_dir_path() if not os.path.exists(user_dir + BATCH_DIR): os.mkdir(user_dir + BATCH_DIR) if not os.path.exists(get_datafiles_dir()): os.mkdir(get_datafiles_dir()) if not os.path.exists(get_projects_dir()): os.mkdir(get_projects_dir())
def _convert_to_original_media_project(): editorstate.PROJECT().proxy_data.proxy_mode = appconsts.CONVERTING_TO_USE_ORIGINAL_MEDIA conv_temp_project_path = utils.get_hidden_user_dir_path() + "proxy_conv.flb" manager_window.convert_progress_bar.set_text(_("Converting to Use Original Media")) persistance.save_project(editorstate.PROJECT(), conv_temp_project_path) global load_thread load_thread = ProxyProjectLoadThread(conv_temp_project_path, manager_window.convert_progress_bar) load_thread.start()
def start_autosave(): global autosave_timeout_id time_min = 1 # hard coded, probably no need to make configurable autosave_delay_millis = time_min * 60 * 1000 print "Autosave started..." autosave_timeout_id = GObject.timeout_add(autosave_delay_millis, do_autosave) autosave_file = utils.get_hidden_user_dir_path() + get_instance_autosave_file() persistance.save_project(editorstate.PROJECT(), autosave_file)
def write_image(self): """ Writes thumbnail image from file producer """ clip_path = self.clip.path # Create consumer matchframe_new_path = utils.get_hidden_user_dir_path() + appconsts.MATCH_FRAME_NEW consumer = mlt.Consumer(PROJECT().profile, "avformat", matchframe_new_path) consumer.set("real_time", 0) consumer.set("vcodec", "png") # Create one frame producer producer = mlt.Producer(PROJECT().profile, str(clip_path)) producer = producer.cut(int(self.clip_frame), int(self.clip_frame)) # Delete new match frame try: os.remove(matchframe_new_path) except: # This fails when done first time ever pass # Connect and write image consumer.connect(producer) consumer.run() # Wait until new file exists while os.path.isfile(matchframe_new_path) != True: time.sleep(0.1) # Copy to match frame matchframe_path = utils.get_hidden_user_dir_path() + appconsts.MATCH_FRAME shutil.copyfile(matchframe_new_path, matchframe_path) # Update timeline data # Get frame of clip.clip_in_in on timeline. clip_index = self.track.clips.index(self.clip) clip_start_in_tline = self.track.clip_start(clip_index) tline_match_frame = clip_start_in_tline + (self.clip_frame - self.clip.clip_in) tlinewidgets.set_match_frame(tline_match_frame, self.track.id, self.display_on_right) # Update view updater.repaint_tline()
def autosave_dialog_callback(dialog, response): dialog.destroy() autosave_file = utils.get_hidden_user_dir_path() + AUTOSAVE_DIR + get_autosave_files()[0] if response == Gtk.ResponseType.OK: global loaded_autosave_file loaded_autosave_file = autosave_file projectaction.actually_load_project(autosave_file, True) else: os.remove(autosave_file) start_autosave()
def run(self): # Launch render process and wait for it to end FLOG = open(utils.get_hidden_user_dir_path() + "log_audio_levels_render", 'w') process = subprocess.Popen([sys.executable, respaths.LAUNCH_DIR + "flowbladeaudiorender", \ self.rendered_media, self.profile_desc, respaths.ROOT_PATH], \ stdin=FLOG, stdout=FLOG, stderr=FLOG) process.wait() Gdk.threads_enter() updater.repaint_tline() Gdk.threads_leave()
def __init__(self, clip, track_height, dialog): threading.Thread.__init__(self) self.clip = clip self.temp_clip = self._get_temp_producer(clip) self.file_cache_path = utils.get_hidden_user_dir_path() + appconsts.AUDIO_LEVELS_DIR + _get_unique_name_for_media(clip.path) self.track_height = track_height self.abort = False self.clip_media_length = PROJECT().get_media_file_for_path(self.clip.path).length self.last_rendered_frame = 0 self.stopped = False self.dialog = dialog
def launch_gmic(): if _gmic_found == False: primary_txt = _("G'Mic not found!") secondary_txt = _("G'Mic binary was not present at <b>/usr/bin/gmic</b>.\nInstall G'MIC to use this tool.") dialogutils.info_message(primary_txt, secondary_txt, gui.editor_window.window) return print "Launch gmic..." gui.save_current_colors() FLOG = open(utils.get_hidden_user_dir_path() + "log_gmic", 'w') subprocess.Popen([sys.executable, respaths.LAUNCH_DIR + "flowbladegmic"], stdin=FLOG, stdout=FLOG, stderr=FLOG)
def _convert_to_proxy_project(): editorstate.PROJECT().proxy_data.proxy_mode = appconsts.CONVERTING_TO_USE_PROXY_MEDIA conv_temp_project_path = utils.get_hidden_user_dir_path() + "proxy_conv.flb" manager_window.convert_progress_bar.set_text(_("Converting Project to Use Proxy Media")) mark_in = editorstate.PROJECT().c_seq.tractor.mark_in mark_out = editorstate.PROJECT().c_seq.tractor.mark_out persistance.save_project(editorstate.PROJECT(), conv_temp_project_path) global load_thread load_thread = ProxyProjectLoadThread(conv_temp_project_path, manager_window.convert_progress_bar, mark_in, mark_out) load_thread.start()
def remove_non_existing_recent_projects(): # Remove non-existing projects from recents list recents_file_path = utils.get_hidden_user_dir_path() + RECENT_DOC remove_list = [] for proj_path in recent_projects.projects: if os.path.isfile(proj_path) == False: remove_list.append(proj_path) if len(remove_list) > 0: for proj_path in remove_list: recent_projects.projects.remove(proj_path) write_file = file(recents_file_path, "wb") pickle.dump(recent_projects, write_file)
def _not_matching_media_info_callback(dialog, response_id, media_file): dialog.destroy() if response_id == Gtk.ResponseType.ACCEPT: # Save in hidden and open match_profile_index = mltprofiles.get_closest_matching_profile_index(media_file.info) profile = mltprofiles.get_profile_for_index(match_profile_index) path = utils.get_hidden_user_dir_path() + "/" + PROJECT().name persistance.save_project(PROJECT(), path, profile.description()) #<----- HERE actually_load_project(path)
def _write_offsets(video_file_path, audio_file_path, completed_callback): print "Starting clapperless analysis..." fps = str(int(utils.fps() + 0.5)) idstr = _get_offset_file_idstr(video_file_path, audio_file_path) FLOG = open(utils.get_hidden_user_dir_path() + "log_clapperless", 'w') # clapperless.py computes offsets and writes them to file clapperless.OFFSETS_DATA_FILE p = subprocess.Popen([sys.executable, respaths.LAUNCH_DIR + "flowbladeclapperless", video_file_path, audio_file_path, "--rate", fps, "--idstr", idstr], stdin=FLOG, stdout=FLOG, stderr=FLOG) p.wait() # Offsets are now available GLib.idle_add(completed_callback, (video_file_path, audio_file_path, idstr))
def run(self): start_time = time.time() shutil.copyfile(get_current_frame_file(), get_preview_file()) Gdk.threads_enter() _window.preview_info.set_markup("<small>" + _("Rendering preview...") + "</small>" ) buf = _window.script_view.get_buffer() view_text = buf.get_text(buf.get_start_iter(), buf.get_end_iter(), False) Gdk.threads_leave() script_str = "gmic " + get_current_frame_file() + " " + view_text + " -output " + get_preview_file() print "Render preview:", script_str 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() global _current_preview_surface _current_preview_surface = cairo.ImageSurface.create_from_png(get_preview_file()) Gdk.threads_enter() _window.out_view.get_buffer().set_text(out) render_time = time.time() - start_time time_str = "{0:.2f}".format(round(render_time,2)) _window.preview_info.set_markup("<small>" + _("Preview for frame: ") + \ utils.get_tc_string_with_fps(_player.current_frame(), _current_fps) + ", render time: " + time_str + "</small>" ) _window.preview_monitor.queue_draw() Gdk.threads_leave()
def export_clip(clip): # Write export data file natron_dir = utils.get_hidden_user_dir_path() + appconsts.NATRON_DIR + "/" file_path = natron_dir + "clipexport_" + md5.new(str(os.urandom(32))).hexdigest() data_text = clip.path + " " + str(clip.clip_in) + " " + str(clip.clip_out + 1) export_data_file = open(file_path, "w") export_data_file.write(data_text) export_data_file.close() # Launch Natron print "Launch Natron..." args = [str(respaths.LAUNCH_DIR + "natron_clip_export_start.sh"), str(respaths.LAUNCH_DIR)] subprocess.Popen(args)
def launch_natron_animations_tool(): if _natron_found == False: primary_txt = _("Natron not found!") secondary_txt = _("Natron was not present in the system.") # TODO: more info dialogutils.info_message(primary_txt, secondary_txt, gui.editor_window.window) return gui.save_current_colors() current_profile_name = PROJECT().profile.description().replace(" ", "_") print current_profile_name print "Launch Natron tool..." FLOG = open(utils.get_hidden_user_dir_path() + "log_natron_tool", 'w') subprocess.Popen([sys.executable, respaths.LAUNCH_DIR + "flowbladenatron", current_profile_name], stdin=FLOG, stdout=FLOG, stderr=FLOG)
def _read_offsets(idstr): offsets_file = utils.get_hidden_user_dir_path() + clapperless.OFFSETS_DATA_FILE + "_"+ idstr with open(offsets_file) as f: file_lines = f.readlines() file_lines = [x.rstrip("\n") for x in file_lines] _files_offsets = {} for line in file_lines: tokens = line.split(" ") _files_offsets[tokens[0]] = tokens[1] os.remove(offsets_file) return _files_offsets
def autosaves_many_recovery_dialog(): autosaves_file_names = get_autosave_files() now = time.time() autosaves = [] for a_file_name in autosaves_file_names: autosave_path = utils.get_hidden_user_dir_path() + AUTOSAVE_DIR + a_file_name autosave_object = utils.EmptyClass() autosave_object.age = now - os.stat(autosave_path).st_mtime autosave_object.path = autosave_path autosaves.append(autosave_object) autosaves = sorted(autosaves, key=lambda autosave_object: autosave_object.age) dialogs.autosaves_many_recovery_dialog(autosaves_many_dialog_callback, autosaves, gui.editor_window.window) return False
def set_default_values_for_widgets(movie_name_too=False): if len(renderconsumer.encoding_options) == 0:# this won't work if no encoding options available return # but we don't want crash, so that we can inform user widgets.encoding_panel.encoding_selector.widget.set_active(0) if movie_name_too == True: widgets.file_panel.movie_name.set_text("movie") # SvdB - Render Folder from Preferences is not copied to Render panel #337 # Default render path is ~/.flowblade/rendered_clips. If this is not changed by the user # we will use the HOME directory if editorpersistance.prefs.render_folder != str(utils.get_hidden_user_dir_path()) + appconsts.RENDERED_CLIPS_DIR: widgets.file_panel.out_folder.set_current_folder(editorpersistance.prefs.render_folder) else: widgets.file_panel.out_folder.set_current_folder(os.path.expanduser("~") + "/") widgets.args_panel.use_args_check.set_active(False) widgets.profile_panel.use_project_profile_check.set_active(True)
def main(): args = cl_parser() print args.idstr offsets_output = process_files(args) # Write out offsets data out_str = "" for file_offset in offsets_output: f, offset = file_offset out_str = out_str + f + " " + str(offset) + "\n" output_file = utils.get_hidden_user_dir_path() + OFFSETS_DATA_FILE + "_"+ args.idstr f = open(output_file, 'w') f.write(out_str) f.close()
def _get_levels_file_path(media_file_path, profile): return utils.get_hidden_user_dir_path( ) + appconsts.AUDIO_LEVELS_DIR + utils.get_unique_name_for_audio_levels_file( media_file_path, profile)
import os import threading import time from gi.repository import Gdk import appconsts import dialogutils import editorpersistance import editorstate import guiutils import utils _jack_frequencies = [22050, 32000, 44100, 48000, 88200, 96000, 192000] _jack_failsafe_path = utils.get_hidden_user_dir_path() + "/jack_fail_safe" _dialog = None def start_up(): pass def use_jack_clicked(window): jackstart_thread = JackStartThread(window) jackstart_thread.start() class JackChangeThread(threading.Thread): def __init__(self, window):
def _colors_data_path(): return utils.get_hidden_user_dir_path() + _CURRENT_THEME_COLORS_FILE
def get_edl_temp_xml_path(): return utils.get_hidden_user_dir_path() + "edl_temp_xml.xml"
def run(self): start_time = time.time() b_switch = "-b" w_switch = "-w" writer = "Write1" if self.is_preview == False: range_str = _animation_instance.get_frame_range_str() render_frame = _window.get_render_frame() else: range_str = str(_animation_instance.frame()) render_frame = utils.get_hidden_user_dir_path( ) + appconsts.NATRON_DIR + "/session_" + _session_id + "/preview####.png" print render_frame Gdk.threads_enter() _window.preview_info.set_markup("<small>" + _("Rendering preview for frame ") + range_str + "..." + "</small>") Gdk.threads_leave() l_switch = "-l" param_mod_script = respaths.ROOT_PATH + "/tools/NatronRenderModify.py" natron_project = _animation_instance.get_project_file_path() render_command = "NatronRenderer " + b_switch + " " + w_switch + " " + writer + " " + \ range_str + " " + render_frame + " " + l_switch + " " + param_mod_script + " " + natron_project print "Starting Natron render, command: ", render_command FLOG = open(utils.get_hidden_user_dir_path() + "log_natron_render", 'w') p = subprocess.Popen(render_command, shell=True, stdin=FLOG, stdout=FLOG, stderr=FLOG) p.wait() FLOG.close() if _progress_updater != None: _progress_updater.stop_thread() # Render complete GUI updates Gdk.threads_enter() if self.is_preview == False: _window.render_percentage.set_markup("<small>" + _("Render complete.") + "</small>") else: render_time = time.time() - start_time time_str = "{0:.2f}".format(round(render_time, 2)) _window.preview_info.set_markup("<small>" + _("Preview for frame: ") + range_str + \ _(", render time: ") + time_str + "</small>" ) global _current_preview_surface preview_frame_path = utils.get_hidden_user_dir_path( ) + appconsts.NATRON_DIR + "/session_" + _session_id + "/preview" + str( _animation_instance.frame()).zfill(4) + ".png" _current_preview_surface = cairo.ImageSurface.create_from_png( preview_frame_path) _window.preview_monitor.queue_draw() Gdk.threads_leave() print "Natron render done."
def file_lines(self): with open(utils.get_hidden_user_dir_path() + "log_natron_render", "r") as f: for i, l in enumerate(f): pass return i + 1
def get_session_folder(): return utils.get_hidden_user_dir_path() + appconsts.NATRON_DIR + "/session_" + str(_session_id)
def get_projects_dir(): return utils.get_hidden_user_dir_path() + PROJECTS_DIR
def _get_match_frame_path(): return utils.get_hidden_user_dir_path( ) + appconsts.TRIM_VIEW_DIR + "/" + MATCH_FRAME
def get_modify_exec_data_file_path(self): return utils.get_hidden_user_dir_path( ) + appconsts.NATRON_DIR + "/mod_data_" + self.uid
def get_render_session_id_file_path(self): return utils.get_hidden_user_dir_path( ) + appconsts.NATRON_DIR + "/LATEST_RENDER_INSTANCE_ID"
def _get_assets_file(): return utils.get_hidden_user_dir_path() + MEDIA_ASSETS_IMPORT_FILE
def do_autosave(): autosave_file = utils.get_hidden_user_dir_path( ) + get_instance_autosave_file() persistance.save_project(editorstate.PROJECT(), autosave_file) return True
def get_autosave_files(): autosave_dir = utils.get_hidden_user_dir_path() + AUTOSAVE_DIR return os.listdir(autosave_dir)
def main(root_path): """ Called at application start. Initializes application with a default project. """ # DEBUG: Direct output to log file if log file set if _log_file != None: log_print_output_to_file() # Print OS, Python version and GTK+ version try: os_release_file = open("/etc/os-release", "r") os_text = os_release_file.read() s_index = os_text.find("PRETTY_NAME=") e_index = os_text.find("\n", s_index) print "OS: " + os_text[s_index + 13:e_index - 1] except: pass print "Python", sys.version gtk_version = "%s.%s.%s" % (Gtk.get_major_version(), Gtk.get_minor_version(), Gtk.get_micro_version()) print "GTK+ version:", gtk_version editorstate.gtk_version = gtk_version try: editorstate.mlt_version = mlt.LIBMLT_VERSION except: editorstate.mlt_version = "0.0.99" # magic string for "not found" print "SDL version:", str(editorstate.get_sdl_version()) # passing -xdg as a flag will change the user_dir location with XDG_CONFIG_HOME # For full xdg-app support all the launch processes need to add this too, currently not impl. for arg in sys.argv: if arg.lower() == "-xdg": editorstate.use_xdg = True # Create hidden folders if not present user_dir = utils.get_hidden_user_dir_path() print "User dir:", user_dir if not os.path.exists(user_dir): os.mkdir(user_dir) if not os.path.exists(user_dir + mltprofiles.USER_PROFILES_DIR): os.mkdir(user_dir + mltprofiles.USER_PROFILES_DIR) if not os.path.exists(user_dir + AUTOSAVE_DIR): os.mkdir(user_dir + AUTOSAVE_DIR) if not os.path.exists(user_dir + BATCH_DIR): os.mkdir(user_dir + BATCH_DIR) if not os.path.exists(user_dir + appconsts.AUDIO_LEVELS_DIR): os.mkdir(user_dir + appconsts.AUDIO_LEVELS_DIR) if not os.path.exists(utils.get_hidden_screenshot_dir_path()): os.mkdir(utils.get_hidden_screenshot_dir_path()) if not os.path.exists(user_dir + appconsts.GMIC_DIR): os.mkdir(user_dir + appconsts.GMIC_DIR) if not os.path.exists(user_dir + appconsts.MATCH_FRAME_DIR): os.mkdir(user_dir + appconsts.MATCH_FRAME_DIR) if not os.path.exists(user_dir + appconsts.TRIM_VIEW_DIR): os.mkdir(user_dir + appconsts.TRIM_VIEW_DIR) if not os.path.exists(user_dir + appconsts.NATRON_DIR): os.mkdir(user_dir + appconsts.NATRON_DIR) # Set paths. respaths.set_paths(root_path) # Load editor prefs and list of recent projects editorpersistance.load() if editorpersistance.prefs.dark_theme == True: respaths.apply_dark_theme() if editorpersistance.prefs.display_all_audio_levels == False: editorstate.display_all_audio_levels = False editorpersistance.create_thumbs_folder_if_needed(user_dir) editorpersistance.create_rendered_clips_folder_if_needed(user_dir) editorpersistance.save() # Init translations module with translations data translations.init_languages() translations.load_filters_translations() mlttransitions.init_module() # Apr-2017 - SvdB - Keyboard shortcuts shortcuts.load_shortcut_files() shortcuts.load_shortcuts() # RHEL7/CentOS compatibility fix if gtk_version == "3.8.8": GObject.threads_init() # Init gtk threads Gdk.threads_init() Gdk.threads_enter() # Request dark theme if so desired if editorpersistance.prefs.dark_theme == True: Gtk.Settings.get_default().set_property( "gtk-application-prefer-dark-theme", True) # Load drag'n'drop images dnd.init() # Adjust gui parameters for smaller screens scr_w = Gdk.Screen.width() scr_h = Gdk.Screen.height() editorstate.SCREEN_WIDTH = scr_w editorstate.SCREEN_HEIGHT = scr_h print scr_w, scr_h print "Small height:", editorstate.screen_size_small_height() print "Small width:", editorstate.screen_size_small_width() _set_draw_params() # Refuse to run on too small screen. if scr_w < 1151 or scr_h < 767: _too_small_screen_exit() return # Splash screen if editorpersistance.prefs.display_splash_screen == True: show_splash_screen() # Init MLT framework repo = mlt.Factory().init() # 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) # Replace some services if better replacements available mltfilters.replace_services(mltenv.services) # Create list of available mlt profiles mltprofiles.load_profile_list() # Save assoc file path if found in arguments global assoc_file_path assoc_file_path = get_assoc_file_path() # There is always a project open, so at startup we create a default project. # Set default project as the project being edited. editorstate.project = projectdata.get_default_project() check_crash = True # Audiomonitoring being available needs to be known before GUI creation audiomonitoring.init(editorstate.project.profile) # Set trim view mode to current default value editorstate.show_trim_view = editorpersistance.prefs.trim_view_default # Check for tools and init tools integration gmic.test_availablity() toolnatron.init() toolsintegration.init() #toolsintegration.test() # Create player object create_player() # Create main window and set widget handles in gui.py for more convenient reference. create_gui() # Inits widgets with project data init_project_gui() # Inits widgets with current sequence data init_sequence_gui() # Launch player now that data and gui exist launch_player() # Editor and modules need some more initializing init_editor_state() # Tracks need to be recentered if window is resized. # Connect listener for this now that the tline panel size allocation is sure to be available. global window_resize_id, window_state_id window_resize_id = gui.editor_window.window.connect( "size-allocate", lambda w, e: updater.window_resized()) window_state_id = gui.editor_window.window.connect( "window-state-event", lambda w, e: updater.window_resized()) # Get existing autosave files autosave_files = get_autosave_files() # Clear splash if ((editorpersistance.prefs.display_splash_screen == True) and len(autosave_files) == 0): global splash_timeout_id splash_timeout_id = GLib.timeout_add(2600, destroy_splash_screen) splash_screen.show_all() appconsts.SAVEFILE_VERSION = projectdata.SAVEFILE_VERSION # THIS IS A QUESTIONABLE IDEA TO SIMPLIFY IMPORTS, NOT DRY. WHEN DOING TOOLS THAT RUN IN ANOTHER PROCESSES AND SAVE PROJECTS, THIS LINE NEEDS TO BE THERE ALSO. # Every running instance has unique autosave file which is deleted at exit set_instance_autosave_id() # Existance of autosave file hints that program was exited abnormally if check_crash == True and len(autosave_files) > 0: if len(autosave_files) == 1: GObject.timeout_add(10, autosave_recovery_dialog) else: GObject.timeout_add(10, autosaves_many_recovery_dialog) else: start_autosave() # We prefer to monkeypatch some callbacks into some modules, usually to # maintain a simpler and/or non-circular import structure monkeypatch_callbacks() # File in assoc_file_path is opened after very short delay if not (check_crash == True and len(autosave_files) > 0): if assoc_file_path != None: print "Launch assoc file:", assoc_file_path global assoc_timeout_id assoc_timeout_id = GObject.timeout_add(10, open_assoc_file) # SDL 2 consumer needs to created after Gtk.main() has run enough for window to be visble if editorstate.get_sdl_version( ) == editorstate.SDL_2: # needs more state considerion still print "SDL2 timeout launch" global sdl2_timeout_id sdl2_timeout_id = GObject.timeout_add(1500, create_sdl_2_consumer) # Launch gtk+ main loop Gtk.main() Gdk.threads_leave()
def _get_pid_file_path(): user_dir = utils.get_hidden_user_dir_path() return user_dir + PID_FILE
def get_datafiles_dir(): return utils.get_hidden_user_dir_path() + DATAFILES_DIR
def get_modify_exec_data_file_path(self, uid): return utils.get_hidden_user_dir_path( ) + appconsts.NATRON_DIR + "/session_" + uid + "/mod_data"