# SPDX-License-Identifier: GPL-2.0-or-later import bpy import re from bpy.app.handlers import persistent from pathlib import Path from vse_toolbox.bl_utils import get_scene_settings, get_strip_settings def get_strips(channel=0, selected_only=False): scn = bpy.context.scene if isinstance(channel, str): channel = get_channel(channel) strips = [s for s in scn.sequence_editor.sequences_all if s.channel==channel] if selected_only: strips = [s for s in strips if s.select] return sorted(strips, key=lambda x : x.frame_final_start) def get_channel(name): scn = bpy.context.scene channel_id = 0 channel = scn.sequence_editor.channels.get(name) if channel: channel_id = scn.sequence_editor.channels.keys().index(name) return channel_id def get_shot_sequence(shot): sequences = get_strips(channel='Sequences') return next((s.name for s in sequences if s.frame_final_start<=shot.frame_final_start {name}') strip.name = name previous_sequence = sequence strip_number += 1 def set_channels(): scn = bpy.context.scene settings = get_scene_settings() items = settings.rna_type.bl_rna.properties['channel'].enum_items for i, c in enumerate(items.keys(), start=1): scn.sequence_editor.channels[i].name = c.title() def render_strips(strips): for strip in strips: print(strip.name) def import_edit(filepath, adapter="cmx_3600", clean_sequencer=False): import opentimelineio as otio from opentimelineio.schema import ( Clip, ExternalReference, Gap, ImageSequenceReference, Stack, Timeline, Track, ) scn = bpy.context.scene sequences = scn.sequence_editor.sequences if clean_sequencer: movie = get_strips(channel='Movie') audio = get_strips(channel='Audio') for strip in sequences: if strip not in (movie+audio): sequences.remove(strip) edl = Path(filepath) try: timeline = otio.adapters.read_from_file( str(edl), adapter, rate=scn.render.fps, ignore_timecode_mismatch=True) except: print("[>.] read_from_file Failed. Using read_from_string method.") data = edl.read_text(encoding='latin-1') timeline = otio.adapters.read_from_string( data, adapter, rate=scn.render.fps, ignore_timecode_mismatch=True) scn.frame_start = ( 0 if timeline.global_start_time is None else timeline.global_start_time ) for track in timeline.tracks: for child in track.each_child(shallow_search=True): # FIXME Exclude Gaps for now. Gaps are Transitions, Blank Spaces... if not isinstance(child, Clip): continue # FIXME Exclude Audio for now if any(child.name.endswith(ext) for ext in ('.wav', '.mp3')): channel = get_channel('Audio') continue channel = get_channel('Shots') frame_start = otio.opentime.to_frames( child.range_in_parent().start_time) frame_end = frame_start + otio.opentime.to_frames( child.range_in_parent().duration) try: strip = sequences.new_effect( name=child.name, type='COLOR', channel=channel, frame_start=frame_start, frame_end=frame_end, ) strip.blend_alpha = 0.0 strip.select = False strip.vsetb_strip_settings.source_name = child.name except Exception as e: print('e: ', e) continue scn.frame_end = frame_end-1 return timeline def import_movie(filepath): scn = bpy.context.scene res_x = scn.render.resolution_x res_y = scn.render.resolution_y strip = scn.sequence_editor.sequences.new_movie( name=filepath.stem, filepath=str(filepath), channel=get_channel('Movie'), frame_start=scn.frame_start ) elem = strip.strip_elem_from_frame(scn.frame_current) src_width, src_height = elem.orig_width, elem.orig_height if src_width != res_x: strip.transform.scale_x = (res_x / src_width) if src_height != res_y: strip.transform.scale_y = (res_y / src_height) if bpy.data.is_saved: strip.filepath = bpy.path.relpath(str(filepath)) return strip def import_sound(filepath): scn = bpy.context.scene strip = scn.sequence_editor.sequences.new_sound( name=filepath.stem, filepath=str(filepath), channel=get_channel('Audio'), frame_start=scn.frame_start ) if bpy.data.is_saved: strip.sound.filepath = bpy.path.relpath(str(filepath)) strip.show_waveform = True return strip def clean_sequencer(edit=False, movie=False, sound=False): scn = bpy.context.scene sequences = [] if edit: sequences.extend(get_strips('Shots')) if movie: sequences.extend(get_strips('Movie')) if sound: sequences.extend(get_strips('Audio')) for sequence in sequences: scn.sequence_editor.sequences.remove(sequence) @persistent def get_active_strip(scene): scn = bpy.context.scene settings = get_scene_settings() if settings.auto_select_strip == False: return screen = bpy.context.screen bpy.ops.sequencer.select_all(action="DESELECT") strip = None frame_current = scn.frame_current strips = bpy.context.sequences strips = sorted(strips,key=lambda x: (x.channel, x.frame_final_start)) for strip in strips: #FIXME Pas propre de mettre le channel name en dur if strip.channel != get_channel('Shots') or 0: continue if (not strip.lock and strip.frame_final_end >= frame_current and strip.frame_final_start <= frame_current): strip.select = True scn.sequence_editor.active_strip = strip