Created
May 23, 2019 09:57
-
-
Save tin2tin/e8842c06681f25a5ee1145345803a29a to your computer and use it in GitHub Desktop.
2.80 Sequencer operators: SelectStripsUnderPlayhead, SelectStripsInChannel and CutHardAndHold
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ##### BEGIN GPL LICENSE BLOCK ##### | |
# | |
# This program is free software; you can redistribute it and/or | |
# modify it under the terms of the GNU General Public License | |
# as published by the Free Software Foundation; either version 2 | |
# of the License, or (at your option) any later version. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program; if not, write to the Free Software Foundation, | |
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |
# | |
# ##### END GPL LICENSE BLOCK ##### | |
# <pep8 compliant> | |
import bpy | |
import time | |
from bpy.types import Operator | |
from operator import attrgetter | |
from bpy.props import ( | |
IntProperty, | |
BoolProperty, | |
EnumProperty, | |
StringProperty, | |
) | |
def act_strip(context): | |
try: | |
return context.scene.sequence_editor.active_strip | |
except AttributeError: | |
return None | |
def is_2_input_effect(strip): | |
return strip.type in { | |
'ADD', 'SUBTRACT', 'ALPHA_OVER', 'ALPHA_UNDER', | |
'CROSS', 'GAMMA_CROSS', 'MULTIPLY', 'OVER_DROP', | |
'WIPE', 'COLORMIX', | |
} | |
def is_1_input_effect(strip): | |
return strip.type in { | |
'GLOW', 'TRANSFORM', 'SPEED', 'GAUSSIAN_BLUR', | |
} | |
def is_effect(strip): | |
return is_2_input_effect(strip) or is_1_input_effect(strip) | |
class SEQUENCER_OT_CrossfadeSounds(Operator): | |
"""Do cross-fading volume animation of two selected sound strips""" | |
bl_idname = "sequencer.crossfade_sounds" | |
bl_label = "Crossfade sounds" | |
bl_options = {'REGISTER', 'UNDO'} | |
@classmethod | |
def poll(cls, context): | |
if context.scene and context.scene.sequence_editor and context.scene.sequence_editor.active_strip: | |
return context.scene.sequence_editor.active_strip.type == 'SOUND' | |
else: | |
return False | |
def execute(self, context): | |
seq1 = None | |
seq2 = None | |
for s in context.scene.sequence_editor.sequences: | |
if s.select and s.type == 'SOUND': | |
if seq1 is None: | |
seq1 = s | |
elif seq2 is None: | |
seq2 = s | |
else: | |
seq2 = None | |
break | |
if seq2 is None: | |
self.report({'ERROR'}, "Select 2 sound strips") | |
return {'CANCELLED'} | |
if seq1.frame_final_start > seq2.frame_final_start: | |
s = seq1 | |
seq1 = seq2 | |
seq2 = s | |
if seq1.frame_final_end > seq2.frame_final_start: | |
tempcfra = context.scene.frame_current | |
context.scene.frame_current = seq2.frame_final_start | |
seq1.keyframe_insert("volume") | |
context.scene.frame_current = seq1.frame_final_end | |
seq1.volume = 0 | |
seq1.keyframe_insert("volume") | |
seq2.keyframe_insert("volume") | |
context.scene.frame_current = seq2.frame_final_start | |
seq2.volume = 0 | |
seq2.keyframe_insert("volume") | |
context.scene.frame_current = tempcfra | |
return {'FINISHED'} | |
else: | |
self.report({'ERROR'}, "The selected strips don't overlap") | |
return {'CANCELLED'} | |
class SEQUENCER_OT_CutMulticam(Operator): | |
"""Cut multi-cam strip and select camera""" | |
bl_idname = "sequencer.cut_multicam" | |
bl_label = "Cut multicam" | |
bl_options = {'REGISTER', 'UNDO'} | |
camera: IntProperty( | |
name="Camera", | |
min=1, max=32, | |
soft_min=1, soft_max=32, | |
default=1, | |
) | |
@classmethod | |
def poll(cls, context): | |
if context.scene and context.scene.sequence_editor and context.scene.sequence_editor.active_strip: | |
return context.scene.sequence_editor.active_strip.type == 'MULTICAM' | |
else: | |
return False | |
def execute(self, context): | |
camera = self.camera | |
s = context.scene.sequence_editor.active_strip | |
if s.multicam_source == camera or camera >= s.channel: | |
return {'FINISHED'} | |
if not s.select: | |
s.select = True | |
cfra = context.scene.frame_current | |
bpy.ops.sequencer.cut(frame=cfra, type='SOFT', side='RIGHT') | |
for s in context.scene.sequence_editor.sequences_all: | |
if s.select and s.type == 'MULTICAM' and s.frame_final_start <= cfra and cfra < s.frame_final_end: | |
context.scene.sequence_editor.active_strip = s | |
context.scene.sequence_editor.active_strip.multicam_source = camera | |
return {'FINISHED'} | |
class SEQUENCER_OT_DeinterlaceSelectedMovies(Operator): | |
"""Deinterlace all selected movie sources""" | |
bl_idname = "sequencer.deinterlace_selected_movies" | |
bl_label = "Deinterlace Movies" | |
bl_options = {'REGISTER', 'UNDO'} | |
@classmethod | |
def poll(cls, context): | |
return (context.scene and context.scene.sequence_editor) | |
def execute(self, context): | |
for s in context.scene.sequence_editor.sequences_all: | |
if s.select and s.type == 'MOVIE': | |
s.use_deinterlace = True | |
return {'FINISHED'} | |
class SEQUENCER_OT_SelectStripsUnderPlayhead(bpy.types.Operator): | |
"""Select strips under playhead""" | |
bl_idname = "sequencer.select_under_playhead" | |
bl_label = "Select strips under playhead" | |
bl_description = "Select strips under playhead" | |
bl_options = {"REGISTER", "UNDO"} | |
extend: BoolProperty( | |
name="Extend", | |
description="Extend selection", | |
default=False, | |
) | |
@classmethod | |
def poll(cls, context): | |
return act_strip(context) | |
def execute(self, context): | |
cfra = bpy.context.scene.frame_current | |
strips = [s for s in context.sequences | |
if s.frame_final_end >= cfra and | |
s.frame_final_start <= cfra] | |
if not self.extend: | |
bpy.ops.sequencer.select_all(action='DESELECT') | |
for strip in strips: | |
strip.select = True | |
context.scene.sequence_editor.active_strip = strip | |
return {"FINISHED"} | |
class SEQUENCER_OT_SelectStripsInChannel(Operator): | |
"""Select all strips in channels with selected strips""" | |
bl_idname = "sequencer.select_channel_strips" | |
bl_label = "Select Channel Strips" | |
bl_description = "Select all strips in channels with selected strips" | |
bl_options = {'REGISTER', 'UNDO'} | |
@classmethod | |
def poll(cls, context): | |
return act_strip(context) | |
def execute(self, context): | |
selection = bpy.context.selected_sequences | |
sequences = bpy.context.scene.sequence_editor.sequences_all | |
for s in selection: | |
for strip in sequences: | |
if strip.channel == s.channel: | |
strip.select = True | |
return {'FINISHED'} | |
class SEQUENCER_OT_CutHardAndHold(bpy.types.Operator): | |
"""Freeze frames from playhead position""" | |
bl_idname = "sequencer.cut_hard_and_hold" | |
bl_label = "Freeze Frames" | |
bl_description = "Freeze frames from playhead position" | |
bl_options = {"REGISTER", "UNDO"} | |
@classmethod | |
def poll(cls, context): | |
return act_strip(context) | |
def execute(self, context): | |
scene = bpy.context.scene | |
sequencer = bpy.ops.sequencer | |
selection = bpy.context.selected_sequences | |
bpy.ops.sequencer.select_all(action='DESELECT') | |
bpy.ops.sequencer.select_under_playhead(extend=False) | |
cf_selection = bpy.context.selected_sequences | |
for s in cf_selection: | |
for sel in selection: | |
if s == sel and not is_effect(s): | |
bpy.ops.sequencer.select_all(action='DESELECT') | |
s.select = True | |
s_end = s.frame_final_end | |
sequencer.cut(frame=scene.frame_current, type='HARD', side='RIGHT') | |
bpy.ops.sequencer.delete() | |
s.select = True | |
s.frame_final_end = s_end | |
bpy.ops.sequencer.select_all(action='DESELECT') | |
for s in selection: s.select = True | |
return {"FINISHED"} | |
classes = ( | |
SEQUENCER_OT_CrossfadeSounds, | |
SEQUENCER_OT_CutMulticam, | |
SEQUENCER_OT_DeinterlaceSelectedMovies, | |
SEQUENCER_OT_SelectStripsUnderPlayhead, | |
SEQUENCER_OT_SelectStripsInChannel, | |
SEQUENCER_OT_CutHardAndHold, | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment