def _do_create_proxy_files(media_files, retry_from_render_folder_select=False): if editorpersistance.prefs.render_folder == None: if retry_from_render_folder_select == True: return dialogs.select_rendred_clips_dir( _create_proxy_render_folder_select_callback, gui.editor_window.window, editorpersistance.prefs.render_folder, media_files) return # Create proxies dir if does not exist proxies_dir = _get_proxies_dir() if not os.path.exists(proxies_dir): os.mkdir(proxies_dir) proxy_profile = _get_proxy_profile(editorstate.PROJECT()) proxy_w, proxy_h = _get_proxy_dimensions( proxy_profile, editorstate.PROJECT().proxy_data.size) proxy_file_extension = _get_proxy_encoding().extension files_to_render = [] not_video_files = 0 already_have_proxies = [] is_proxy_file = 0 other_project_proxies = [] for f in media_files: #f = w.media_file if f.is_proxy_file == True: # Can't create a proxy file for a proxy file is_proxy_file = is_proxy_file + 1 continue if f.type != appconsts.VIDEO: # only video files can have proxy files not_video_files = not_video_files + 1 continue if f.has_proxy_file == True: # no need to to create proxy files again, unless forced by user if os.path.exists(f.second_file_path): already_have_proxies.append(f) continue path_for_size_and_encoding = f.create_proxy_path( proxy_w, proxy_h, proxy_file_extension) if os.path.exists( path_for_size_and_encoding ): # A proxy for media file has been created by other projects. Get user to confirm overwrite other_project_proxies.append(f) continue files_to_render.append(f) if len(already_have_proxies) > 0 or len( other_project_proxies ) > 0 or not_video_files > 0 or is_proxy_file > 0 or len( files_to_render) == 0: global proxy_render_issues_window proxy_render_issues_window = ProxyRenderIssuesWindow( files_to_render, already_have_proxies, not_video_files, is_proxy_file, other_project_proxies, proxy_w, proxy_h, proxy_file_extension) return _create_proxy_files(files_to_render)
def log_range_clicked(): media_file = editorstate.MONITOR_MEDIA_FILE() if media_file == None: return if media_file.type == appconsts.PATTERN_PRODUCER: # INFOWINDOW ??? return if media_file.mark_in == -1 or media_file.mark_out == -1: return file_path = media_file.path if PROJECT().proxy_data.proxy_mode == appconsts.USE_PROXY_MEDIA: if media_file.second_file_path != None: file_path = media_file.second_file_path # proxy file exists else: file_path = media_file.path # no proxy file created log_event = MediaLogEvent(appconsts.MEDIA_LOG_MARKS_SET, media_file.mark_in, media_file.mark_out, media_file.name, file_path) log_event.ttl = media_file.ttl editorstate.PROJECT().media_log.append(log_event) editorstate.PROJECT().add_to_group(_get_current_group_index(), [log_event]) _update_list_view(log_event)
def _do_create_proxy_files(media_files, retry_from_render_folder_select=False): proxy_profile = _get_proxy_profile(editorstate.PROJECT()) proxy_w, proxy_h = _get_proxy_dimensions( proxy_profile, editorstate.PROJECT().proxy_data.size) proxy_file_extension = _get_proxy_encoding().extension files_to_render = [] not_video_files = 0 already_have_proxies = [] is_proxy_file = 0 other_project_proxies = [] for f in media_files: if f.is_proxy_file == True: # Can't create a proxy file for a proxy file is_proxy_file = is_proxy_file + 1 continue if f.type != appconsts.VIDEO and f.type != appconsts.IMAGE_SEQUENCE: # only video files and img seqs can have proxy files not_video_files = not_video_files + 1 continue if f.container_data != None: not_video_files = not_video_files + 1 continue if f.has_proxy_file == True: # no need to to create proxy files again, unless forced by user if os.path.exists(f.second_file_path): already_have_proxies.append(f) continue p_folder, p_file = os.path.split(f.second_file_path) if os.path.isdir(p_folder): already_have_proxies.append(f) continue path_for_size_and_encoding = f.create_proxy_path( proxy_w, proxy_h, proxy_file_extension) if os.path.exists( path_for_size_and_encoding ): # A proxy for media file (with these exact settings) has been created by other projects. # Get user to confirm overwrite other_project_proxies.append(f) continue if f.type == appconsts.IMAGE_SEQUENCE: p_folder, p_file = os.path.split(path_for_size_and_encoding) if os.path.isdir(p_folder): other_project_proxies.append(f) continue files_to_render.append(f) if len(already_have_proxies) > 0 or len( other_project_proxies ) > 0 or not_video_files > 0 or is_proxy_file > 0 or len( files_to_render) == 0: global proxy_render_issues_window proxy_render_issues_window = ProxyRenderIssuesWindow( files_to_render, already_have_proxies, not_video_files, is_proxy_file, other_project_proxies, proxy_w, proxy_h, proxy_file_extension) return _create_proxy_files(files_to_render)
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() Gdk.threads_enter() app.open_project(project) Gdk.threads_leave() app.start_autosave() editorstate.update_current_proxy_paths() persistance.show_messages = True
def launch_audio_levels_rendering(file_names): # Only render audio levels for media that does not have existing levels file rendered_media = "" for media_file in file_names: levels_file_path = _get_levels_file_path(media_file, editorstate.PROJECT().profile) if os.path.isfile(levels_file_path): continue else: global _render_already_requested if not (media_file in _render_already_requested): _render_already_requested.append(media_file) rendered_media = rendered_media + FILE_SEPARATOR + media_file if rendered_media == "": return profile_desc = editorstate.PROJECT().profile_desc # This is called from GTK thread, so we need to launch process from another thread to # clean-up properly and not block GTK thread/GUI global single_render_launch_thread single_render_launch_thread = AudioRenderLaunchThread( rendered_media, profile_desc) single_render_launch_thread.start()
def run(self): proxy_w, proxy_h = _get_proxy_dimensions( self.proxy_profile, editorstate.PROJECT().proxy_data.size) enc_index = editorstate.PROJECT().proxy_data.encoding proxy_render_items = [] for media_file in self.files_to_render: if media_file.type != appconsts.IMAGE_SEQUENCE: proxy_encoding = renderconsumer.proxy_encodings[enc_index] proxy_file_path = media_file.create_proxy_path( proxy_w, proxy_h, proxy_encoding.extension) # 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 item_data = ProxyRenderItemData( media_file.id, proxy_w, proxy_h, enc_index, proxy_file_path, proxy_rate, media_file.path, self.proxy_profile.description(), None) else: asset_folder, asset_file_name = os.path.split(media_file.path) lookup_filename = utils.get_img_seq_glob_lookup_name( asset_file_name) lookup_path = asset_folder + "/" + lookup_filename proxy_file_path = media_file.create_proxy_path( proxy_w, proxy_h, None) # media_file.path, proxy_file_path, proxy_w, proxy_h, lookup_path item_data = ProxyRenderItemData( media_file.id, proxy_w, proxy_h, -1, proxy_file_path, -1, media_file.path, self.proxy_profile.description(), lookup_path) proxy_render_items.append(item_data) Gdk.threads_enter() for proxy_render_data_item in proxy_render_items: session_id = hashlib.md5(str( os.urandom(32)).encode('utf-8')).hexdigest() job_queue_object = jobs.ProxyRenderJobQueueObject( session_id, proxy_render_data_item) job_queue_object.add_to_queue() Gdk.threads_leave()
def _get_default_fades_lengths(property_klass): if property_klass in _dissolve_property_klasses: fade_in_length = editorstate.PROJECT().get_project_property(appconsts.P_PROP_DISSOLVE_GROUP_FADE_IN) fade_out_length = editorstate.PROJECT().get_project_property(appconsts.P_PROP_DISSOLVE_GROUP_FADE_OUT) else: fade_in_length = editorstate.PROJECT().get_project_property(appconsts.P_PROP_ANIM_GROUP_FADE_IN) fade_out_length = editorstate.PROJECT().get_project_property(appconsts.P_PROP_ANIM_GROUP_FADE_OUT) return (fade_in_length, fade_out_length)
def _shutdown_dialog_callback(dialog, response_id): dialog.destroy() if response_id == Gtk.ResponseType.CLOSE:# "Don't Save" pass elif response_id == Gtk.ResponseType.YES:# "Save" if editorstate.PROJECT().last_save_path != None: persistance.save_project(editorstate.PROJECT(), editorstate.PROJECT().last_save_path) else: dialogutils.warning_message(_("Project has not been saved previously"), _("Save project with File -> Save As before closing."), gui.editor_window.window) return else: # "Cancel" return # --- APP SHUT DOWN --- # print "Exiting app..." # Sep-2018 - SvdB - Stop wave form threads for thread_termination in threading.enumerate(): # We only terminate threads with a 'process', as these are launched # by the audiowaveformrenderer try: thread_termination.process.terminate() except: None # No more auto saving stop_autosave() # Save window dimensions on exit alloc = gui.editor_window.window.get_allocation() x, y, w, h = alloc.x, alloc.y, alloc.width, alloc.height editorpersistance.prefs.exit_allocation = (w, h) if gui.editor_window.window2 != None: alloc = gui.editor_window.window2.get_allocation() pos_x, pos_y = gui.editor_window.window2.get_position() editorpersistance.prefs.exit_allocation_window_2 = (alloc.width, alloc.height, pos_x, pos_y) editorpersistance.prefs.app_v_paned_position = gui.editor_window.app_v_paned.get_position() editorpersistance.prefs.top_paned_position = gui.editor_window.top_paned.get_position() try: # This fails if preference for top row layout changed, we just ignore saving these values then. if editorwindow.top_level_project_panel() == True: editorpersistance.prefs.mm_paned_position = 200 # This is not used until user sets preference to not have top level project panel else: editorpersistance.prefs.mm_paned_position = gui.editor_window.mm_paned.get_position() except: pass editorpersistance.save() # Block reconnecting consumer before setting window not visible updater.player_refresh_enabled = False gui.editor_window.window.set_visible(False) if gui.editor_window.window2 != None: gui.editor_window.window2.set_visible(False) # Close and destroy app when gtk finds time to do it after hiding window GLib.idle_add(_app_destroy)
def _convert_to_original_media_project(): editorstate.PROJECT().proxy_data.proxy_mode = appconsts.CONVERTING_TO_USE_ORIGINAL_MEDIA conv_temp_project_path = userfolders.get_cache_dir() + "proxy_conv.flb" manager_window.convert_progress_bar.set_text(_("Converting to Use Original 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 _create_proxy_files(media_files_to_render): proxy_profile = _get_proxy_profile(editorstate.PROJECT()) if editorstate.PROJECT().proxy_data.proxy_mode == appconsts.USE_ORIGINAL_MEDIA: set_as_proxy_immediately = False else: set_as_proxy_immediately = True global progress_window, runner_thread progress_window = ProxyRenderProgressDialog() runner_thread = ProxyRenderRunnerThread(proxy_profile, media_files_to_render, set_as_proxy_immediately) runner_thread.start()
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 _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 create_proxy_files_pressed(render_all=False): media_files = [] if render_all == False: media_file_widgets = gui.media_list_view.get_selected_media_objects() if len(media_file_widgets) == 0: return for w in media_file_widgets: media_files.append(w.media_file) else: for item_id in editorstate.PROJECT().media_files: media_files.append(editorstate.PROJECT().media_files[item_id]) _do_create_proxy_files(media_files)
def _shutdown_dialog_callback(dialog, response_id): dialog.destroy() if response_id == Gtk.ResponseType.CLOSE: # "Don't Save" pass elif response_id == Gtk.ResponseType.YES: # "Save" if editorstate.PROJECT().last_save_path != None: persistance.save_project(editorstate.PROJECT(), editorstate.PROJECT().last_save_path) else: dialogutils.warning_message( _("Project has not been saved previously"), _("Save project with File -> Save As before closing."), gui.editor_window.window) return else: # "Cancel" return # --- APP SHUT DOWN --- # print "Exiting app..." # No more auto saving stop_autosave() # Save window dimensions on exit alloc = gui.editor_window.window.get_allocation() x, y, w, h = alloc.x, alloc.y, alloc.width, alloc.height editorpersistance.prefs.exit_allocation = (w, h) if gui.editor_window.window2 != None: alloc = gui.editor_window.window2.get_allocation() pos_x, pos_y = gui.editor_window.window2.get_position() editorpersistance.prefs.exit_allocation_window_2 = (alloc.width, alloc.height, pos_x, pos_y) editorpersistance.prefs.app_v_paned_position = gui.editor_window.app_v_paned.get_position( ) editorpersistance.prefs.top_paned_position = gui.editor_window.top_paned.get_position( ) editorpersistance.prefs.mm_paned_position = gui.editor_window.mm_paned.get_position( ) editorpersistance.save() # Block reconnecting consumer before setting window not visible updater.player_refresh_enabled = False gui.editor_window.window.set_visible(False) if gui.editor_window.window2 != None: gui.editor_window.window2.set_visible(False) # Close and destroy app when gtk finds time to do it after hiding window GLib.idle_add(_app_destroy)
def log_range_clicked(): media_file = editorstate.MONITOR_MEDIA_FILE() if media_file == None: return if media_file.type == appconsts.PATTERN_PRODUCER: # INFOWINDOW ??? return if media_file.mark_in == -1 or media_file.mark_out == -1: return log_event = MediaLogEvent(appconsts.MEDIA_LOG_MARKS_SET, media_file.mark_in, media_file.mark_out, media_file.name, media_file.path) editorstate.PROJECT().media_log.append(log_event) editorstate.PROJECT().add_to_group(_get_current_group_index(), [log_event]) _update_list_view(log_event)
def _create_proxy_files(media_files_to_render): proxy_profile = _get_proxy_profile(editorstate.PROJECT()) global runner_thread #progress_window = ProxyRenderProgressDialog() runner_thread = ProxyRenderRunnerThread(proxy_profile, media_files_to_render) runner_thread.start()
def _set_saved_encoding(transition_widgets): saved_encoding = editorstate.PROJECT().get_project_property(appconsts.P_PROP_TRANSITION_ENCODING) if saved_encoding != None: encodings_cb, quality_cb = transition_widgets enc_index, quality_index = saved_encoding encodings_cb.set_active(enc_index) quality_cb.set_active(quality_index)
def init_project_gui(): """ Called after project load to initialize interface """ # Display media files gui.media_list_view.fill_data_model() try: # Fails if current bin is empty selection = gui.media_list_view.treeview.get_selection() selection.select_path("0") except Exception: pass # Display bins gui.bin_list_view.fill_data_model() selection = gui.bin_list_view.treeview.get_selection() selection.select_path("0") # Display sequences gui.sequence_list_view.fill_data_model() selection = gui.sequence_list_view.treeview.get_selection() selected_index = editorstate.project.sequences.index( editorstate.current_sequence()) selection.select_path(str(selected_index)) # Display media events medialog.update_media_log_view() render.set_default_values_for_widgets(True) gui.tline_left_corner.update_gui() projectinfogui.update_project_info() # Set render folder selector to last render if prefs require folder_path = editorstate.PROJECT().get_last_render_folder() if folder_path != None and editorpersistance.prefs.remember_last_render_dir == True: gui.render_out_folder.set_current_folder(folder_path)
def set_mode_display_value(self): if editorstate.PROJECT( ).proxy_data.proxy_mode == appconsts.USE_PROXY_MEDIA: mode_str = _("Using Proxy Media") else: mode_str = _("Using Original Media") self.proxy_mode_value.set_text(mode_str)
def response(self, dialog, response_id): if response_id == Gtk.ResponseType.CANCEL: dialog.destroy() else: if self.action_select.get_active( ) == 0: # Render Unrendered Possible & Use existing for f in self.other_project_proxies: f.add_existing_proxy_file(self.proxy_w, self.proxy_h, self.proxy_file_extension) if editorstate.PROJECT( ).proxy_data.proxy_mode == appconsts.USE_PROXY_MEDIA: f.set_as_proxy_media_file() else: # Rerender All Possible # We can't mess existing proxy files that are used by other projects _set_media_files_to_use_unique_proxies( self.other_project_proxies) _set_media_files_to_use_unique_proxies( self.already_have_proxies) # Add to files being rendered self.files_to_render.extend(self.other_project_proxies) self.files_to_render.extend(self.already_have_proxies) dialog.destroy() global proxy_render_issues_window proxy_render_issues_window = None _create_proxy_files(self.files_to_render)
def clips_drop(clips): for clip in clips: if clip.media_type == appconsts.VIDEO or clip.media_type == appconsts.AUDIO or clip.media_type == appconsts.IMAGE_SEQUENCE: if PROJECT().proxy_data.proxy_mode == appconsts.USE_ORIGINAL_MEDIA: clip_path = clip.path else: # We are in proxy mode, find out original media path media_item = PROJECT().get_media_file_for_path(clip.path) if media_item != None: # 'media_item.second_file_path' points now to original media # if proxy file exits. clip_path = media_item.second_file_path if clip_path == None: # no proxy for this clip, use media from dragged clip clip_path = clip.path else: # no media item for this clip, use media from dragged clip clip_path = clip.path log_event = MediaLogEvent(appconsts.MEDIA_LOG_MARKS_SET, clip.clip_in, clip.clip_out, clip.name, clip.path) log_event.ttl = clip.ttl editorstate.PROJECT().media_log.append(log_event) _update_list_view(log_event)
def set_menu_to_proxy_state(): if editorstate.PROJECT( ).proxy_data.proxy_mode == appconsts.USE_ORIGINAL_MEDIA: gui.editor_window.uimanager.get_widget( '/MenuBar/FileMenu/SaveSnapshot').set_sensitive(True) else: gui.editor_window.uimanager.get_widget( '/MenuBar/FileMenu/SaveSnapshot').set_sensitive(False)
def set_convert_buttons_state(self): proxy_mode = editorstate.PROJECT().proxy_data.proxy_mode if proxy_mode == appconsts.USE_PROXY_MEDIA: self.use_button.set_sensitive(False) self.dont_use_button.set_sensitive(True) else: self.use_button.set_sensitive(True) self.dont_use_button.set_sensitive(False)
def clips_drop(clips): for clip in clips: if clip.media_type == appconsts.VIDEO or clip.media_type == appconsts.AUDIO: log_event = MediaLogEvent(appconsts.MEDIA_LOG_MARKS_SET, clip.clip_in, clip.clip_out, clip.name, clip.path) editorstate.PROJECT().media_log.append(log_event) _update_list_view()
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 shutdown(): if projectaction.was_edited_since_last_save() == False: _shutdown_dialog_callback(None, None, True) return True else: dialogs.exit_confirm_dialog(_shutdown_dialog_callback, get_save_time_msg(), gui.editor_window.window, editorstate.PROJECT().name) return True # Signal that event is handled, otherwise it'll destroy window anyway
def _set_saved_encoding(transition_widgets): saved_encoding = editorstate.PROJECT().get_project_property(appconsts.P_PROP_TRANSITION_ENCODING) if saved_encoding != None: encodings_cb, encodings, quality_cb = transition_widgets enc_index, quality_index = saved_encoding # enc index is for all available renderencodings in renderconsumer, # combobox only displays subset (because of h264 audio bug) and we need find out # index for it from encdoings list that holds the same subset. encoding = renderconsumer.encoding_options[enc_index] selected_encoding_option_index = encodings.index(encoding) encodings_cb.set_active(selected_encoding_option_index) quality_cb.set_active(quality_index)
def _close_dialog_callback(dialog, response_id): dialog.destroy() if response_id == Gtk.ResponseType.CLOSE:# "Don't Save" pass elif response_id == Gtk.ResponseType.YES:# "Save" if editorstate.PROJECT().last_save_path != None: persistance.save_project(editorstate.PROJECT(), editorstate.PROJECT().last_save_path) else: dialogutils.warning_message(_("Project has not been saved previously"), _("Save project with File -> Save As before closing."), gui.editor_window.window) return else: # "Cancel" return # This is the same as opening default project sequence.AUDIO_TRACKS_COUNT = 4 sequence.VIDEO_TRACKS_COUNT = 5 new_project = projectdata.get_default_project() app.open_project(new_project)
def set_convert_buttons_state(self): proxy_mode = editorstate.PROJECT().proxy_data.proxy_mode if jobs.proxy_render_ongoing() == True: self.use_button.set_sensitive(False) self.dont_use_button.set_sensitive(False) self.info_label.set_text(_("There are on going Proxy renders, changing Proxy Mode not allowed.")) elif proxy_mode == appconsts.USE_PROXY_MEDIA: self.use_button.set_sensitive(False) self.dont_use_button.set_sensitive(True) else: self.use_button.set_sensitive(True) self.dont_use_button.set_sensitive(False)
def get_waveform_data(clip): # Return from memory if present global _waveforms try: waveform = _waveforms[clip.path] return waveform except: pass # Load from disk if found, otherwise queue for levels render levels_file_path = _get_levels_file_path(clip.path, editorstate.PROJECT().profile) if os.path.isfile(levels_file_path): f = open(levels_file_path) waveform = pickle.load(f) _waveforms[clip.path] = waveform return waveform else: global _queued_waveform_renders _queued_waveform_renders.append(clip.path) return None