Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sequencer_kinoraw_tools/__init__.py399
-rw-r--r--sequencer_kinoraw_tools/audio_tools.py358
-rw-r--r--sequencer_kinoraw_tools/datamosh.py189
-rw-r--r--sequencer_kinoraw_tools/eco.py127
-rw-r--r--sequencer_kinoraw_tools/exiftool.py330
-rw-r--r--sequencer_kinoraw_tools/functions.py455
-rw-r--r--sequencer_kinoraw_tools/jumptocut.py656
-rw-r--r--sequencer_kinoraw_tools/operators_extra_actions.py1302
-rw-r--r--sequencer_kinoraw_tools/proxy_tools.py344
-rw-r--r--sequencer_kinoraw_tools/random_editor.py138
-rw-r--r--sequencer_kinoraw_tools/recursive_loader.py266
-rw-r--r--sequencer_kinoraw_tools/ui.py765
12 files changed, 0 insertions, 5329 deletions
diff --git a/sequencer_kinoraw_tools/__init__.py b/sequencer_kinoraw_tools/__init__.py
deleted file mode 100644
index c4af8988..00000000
--- a/sequencer_kinoraw_tools/__init__.py
+++ /dev/null
@@ -1,399 +0,0 @@
-# ##### 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 #####
-
-bl_info = {
- "name": "Kinoraw Tools",
- "author": "Carlos Padial, Turi Scandurra",
- "version": (0, 5, 2),
- "blender": (2, 74, 0),
- "location": "Sequencer",
- "description": "Compilation of tools to improve video editing with Blender's VSE",
- "wiki_url": "https://github.com/kinoraw/kinoraw_tools/blob/master/README.md",
- "tracker_url": "https://github.com/kinoraw/kinoraw_tools",
- "support": "COMMUNITY",
- "category": "Sequencer"
- }
-
-
-if "bpy" in locals():
- import importlib
- importlib.reload(jumptocut)
- importlib.reload(operators_extra_actions)
- importlib.reload(audio_tools)
- importlib.reload(proxy_tools)
- importlib.reload(recursive_loader)
- importlib.reload(eco)
- importlib.reload(random_editor)
- importlib.reload(ui)
- importlib.reload(datamosh)
-else:
- from . import jumptocut
- from . import operators_extra_actions
- from . import audio_tools
- from . import proxy_tools
- from . import recursive_loader
- from . import eco
- from . import random_editor
- from . import ui
- from . import datamosh
-
-import bpy
-from bpy.types import (
- AddonPreferences,
- )
-from bpy.props import (
- IntProperty,
- StringProperty,
- BoolProperty,
- EnumProperty,
- )
-
-
-class KinorawToolsAddon(AddonPreferences):
- # this must match the addon name, use '__package__'
- # when defining this in a submodule of a python package.
- bl_idname = __package__
- bl_option = {'REGISTER'}
-
- # extra_actions
- kr_show_tools: BoolProperty(
- name="Show tools",
- description="Show extra tools in the panel",
- default=False
- )
- kr_mini_ui: BoolProperty(
- name="Mini UI",
- description="Enable mini UI",
- default=True
- )
- kr_show_info: BoolProperty(
- name="Show info",
- description="Show basic info from selected strip",
- default=False
- )
- kr_show_trim: BoolProperty(
- name="Show trim",
- default=False
- )
- kr_show_modifiers: BoolProperty(
- name="Show modifiers",
- description="Show modifiers from selected strip",
- default=False
- )
- kr_extra_info: BoolProperty(
- name="Show extra info",
- description="Show extra info and settings from selected strip",
- default=False
- )
- # exif
- use_exif_panel: BoolProperty(
- name="Exif info Panel | depends on external programs, see Documentation",
- default=False
- )
- # glitch
- use_glitch_panel: BoolProperty(
- name="Glitch panel | depends on external programs, see Documentation",
- default=False
- )
- all_keyframes: BoolProperty(
- name="Remove all keyframes",
- default=True
- )
- load_glitch: BoolProperty(
- name="Load glitch after conversion > UNSTABLE!!!",
- default=True
- )
- # jump to cut
- use_jumptocut: BoolProperty(
- name="Jump to Cut Panel",
- default=True
- )
- use_io_tools: BoolProperty(
- name="Enable in and out tools in Jump to Cut Panel",
- default=False
- )
- # Proxy Tools
- use_proxy_tools: BoolProperty(
- name="Proxy tools Panel | depends on external programs, see Documentation",
- default=False
- )
- proxy_dir: StringProperty(
- name="Proxy Custom Directory",
- default="//proxies/"
- )
- proxy_scripts_path: StringProperty(
- name="Directory to store proxy scripts",
- default="//proxy_scripts/"
- )
- proxy_scripts: BoolProperty(
- name="Generate ffmpeg scripts",
- default=False
- )
- ffmpeg_command: StringProperty(
- name="Command to generate proxy",
- default='''ffmpeg -i {} -vcodec mjpeg -q:v 10 -s {}x{} -an -y {}'''
- )
- use_internal_proxy = BoolProperty(
- name="Use internal Blender's proxy system",
- default=True
- )
- use_bi_custom_directory = BoolProperty(
- name="Proxy Custom Directory",
- default=True
- )
- quality = IntProperty(
- name="Quality",
- default=90,
- min=0, max=32767
- )
- tc_list = [
- ("NONE", "No TC in use", ""), ("RECORD_RUN", "Record Run", ""),
- ("FREE_RUN", "Free Run", ""), ("FREE_RUN_REC_DATE", "Free Run (rec date)", ""),
- ("RECORD_RUN_NO_GAPS", "Record Run No Gaps", "")
- ]
- timecode = EnumProperty(
- name="Settings Type",
- items=tc_list,
- default="NONE",
- description="Timecode"
- )
- # Audio Tools
- use_audio_tools = BoolProperty(
- name="Audio tools Panel | depends on external programs, see Documentation",
- default=False
- )
- audio_dir = StringProperty(
- name="Path to store extracted audio",
- default="//audio/"
- )
- audio_scripts_path = StringProperty(
- name="Path to store audio scripts",
- default="//audio_scripts/"
- )
- audio_scripts = BoolProperty(
- name="Generate ffmpeg scripts",
- default=False
- )
- # Audio Tools - external links
- audio_use_external_links = BoolProperty(
- name="Use external audio linked to movie strips",
- default=False
- )
- audio_external_filename = StringProperty(
- name="File to store info about linked audio",
- default="//external_audio_sync_info.txt"
- )
- # audio tools vu-meter
- meterbridge = [
- ("VU", "Classic moving needle VU meter", ""), ("PPM", "PPM meter", ""),
- ("DPM", "Digital peak meter", ""), ("JF", "'Jellyfish' phase meter", ""),
- ("SCO", "Oscilloscope meter", "")
- ]
- metertype = EnumProperty(
- name="Meter type",
- items=meterbridge,
- default="DPM",
- description="Meterbridge meter type"
- )
- # eco
- use_eco_tools = BoolProperty(
- name="Eco tools Panel",
- default=True
- )
- eco_value = IntProperty(
- name="Number of echoes",
- default=5,
- min=1, max=25
- )
- eco_offset = IntProperty(
- name="Echo Offset",
- default=1,
- min=-25000, max=25000
- )
- eco_use_add_blend_mode = BoolProperty(
- name='use_add_blend_mode',
- default=False
- )
- # random editor
- use_random_editor = BoolProperty(
- name="Random editor Panel | Experimental",
- default=False
- )
- random_frames = IntProperty(
- name="Frames",
- default=1,
- min=1, max=1000
- )
- random_selected_scene = StringProperty(
- name="Selected Scene",
- default=""
- )
- random_use_marker_subsets = BoolProperty(
- name="Use_Marker subsets",
- default=True
- )
- random_number_of_subsets = IntProperty(
- name="Number of subsets",
- default=3,
- min=1, max=5
- )
- show_shortcuts = BoolProperty(
- name="Hot Keys",
- default=False,
- description="List of the shortcuts used for the included various tools",
- )
- show_experimental = BoolProperty(
- name="Tools with External Dependencies / Experimental",
- default=False,
- description="List of various tools that need an External Library "
- "or are Experimental\nPlease read the Documentation "
- "before enabling them",
- )
-
- def draw(self, context):
- layout = self.layout
- icon_1 = "TRIA_RIGHT" if not self.show_shortcuts else "TRIA_DOWN"
- icon_2 = "TRIA_RIGHT" if not self.show_experimental else "TRIA_DOWN"
-
- box = layout.box()
- box.prop(self, "use_jumptocut")
- box = layout.box()
- box.prop(self, "use_eco_tools")
-
- box_exp = layout.box()
- box_exp.prop(self, "show_experimental", emboss=False, icon=icon_2)
-
- if self.show_experimental:
- box = box_exp.box()
- box.prop(self, "use_audio_tools")
- box = box_exp.box()
- box.prop(self, "use_proxy_tools")
- box = box_exp.box()
- box.prop(self, "use_exif_panel")
- box = box_exp.box()
- box.prop(self, "use_glitch_panel")
- box = box_exp.box()
- box.prop(self, "use_random_editor")
-
- box = layout.box()
- box.prop(self, "show_shortcuts", emboss=False, icon=icon_1)
-
- if self.show_shortcuts:
- box.label(text="Skip One Second Forward: Ctrl + Shift + Right Arrow", icon="LAYER_USED")
- box.label(text="Skip One Second Backwards: Ctrl + Shift + Left Arrow", icon="LAYER_USED")
- box.label(text="Jump to Previous Strip: Q", icon="LAYER_USED")
- box.label(text="Jump to Next Strip: W", icon="LAYER_USED")
- box.label(text="Source IN: Ctrl + Shift + I", icon="LAYER_USED")
- box.label(text="Source OUT: Ctrl + Shift + O", icon="LAYER_USED")
- box.label(text="Jump to Previous Marker: Shift + Q", icon="LAYER_USED")
- box.label(text="Jump to Next Marker: Shift + W", icon="LAYER_USED")
-
-
-# Registration
-def register():
- bpy.utils.register_class(KinorawToolsAddon)
-
- bpy.utils.register_module(__name__)
-
- # Append menu entries
- bpy.types.SEQUENCER_MT_add.prepend(ui.sequencer_add_menu_func)
- bpy.types.SEQUENCER_MT_select.prepend(ui.sequencer_select_menu_func)
- bpy.types.SEQUENCER_MT_strip.prepend(ui.sequencer_strip_menu_func)
- bpy.types.SEQUENCER_HT_header.append(ui.sequencer_header_func)
- bpy.types.CLIP_HT_header.append(ui.clip_header_func)
- bpy.types.CLIP_MT_clip.prepend(ui.clip_clip_menu_func)
- bpy.types.TIME_MT_frame.prepend(ui.time_frame_menu_func)
- bpy.types.TIME_HT_header.append(ui.time_header_func)
-
- # Add keyboard shortcut configuration
- kc = bpy.context.window_manager.keyconfigs.addon
- km = kc.keymaps.new(name='Frames')
-
- # jump 1 second
- kmi = km.keymap_items.new('screenextra.frame_skip',
- 'RIGHT_ARROW', 'PRESS', ctrl=True, shift=True)
- kmi.properties.back = False
- kmi = km.keymap_items.new('screenextra.frame_skip',
- 'LEFT_ARROW', 'PRESS', ctrl=True, shift=True)
- kmi.properties.back = True
-
- # jump to cut
- kmi = km.keymap_items.new("sequencer.strip_jump",
- 'Q', 'PRESS', ctrl=False, shift=False)
- kmi.properties.next = False
- kmi.properties.center = False
- kmi = km.keymap_items.new("sequencer.strip_jump",
- 'W', 'PRESS', ctrl=False, shift=False)
- kmi.properties.next = True
- kmi.properties.center = False
-
- # in and out
- kmi = km.keymap_items.new("sequencerextra.sourcein",
- 'I', 'PRESS', ctrl=True, shift=True)
- kmi = km.keymap_items.new("sequencerextra.sourceout",
- 'O', 'PRESS', ctrl=True, shift=True)
-
- # markers
- kc = bpy.context.window_manager.keyconfigs.active
- km = kc.keymaps.new(name='Screen')
- kmi = km.keymap_items.new("screen.marker_jump",
- 'Q', 'PRESS', ctrl=False, shift=True)
- kmi.properties.next = False
- kmi = km.keymap_items.new("screen.marker_jump",
- 'W', 'PRESS', ctrl=False, shift=True)
- kmi.properties.next = True
-
-
-def unregister():
- bpy.utils.unregister_module(__name__)
-
- try:
- bpy.utils.unregister_class(KinorawToolsAddon)
- except RuntimeError:
- pass
-
- # Remove menu entries
- bpy.types.SEQUENCER_MT_add.remove(ui.sequencer_add_menu_func)
- bpy.types.SEQUENCER_MT_select.remove(ui.sequencer_select_menu_func)
- bpy.types.SEQUENCER_MT_strip.remove(ui.sequencer_strip_menu_func)
- bpy.types.SEQUENCER_HT_header.remove(ui.sequencer_header_func)
- bpy.types.CLIP_HT_header.remove(ui.clip_header_func)
- bpy.types.CLIP_MT_clip.remove(ui.clip_clip_menu_func)
- bpy.types.TIME_MT_frame.remove(ui.time_frame_menu_func)
- bpy.types.TIME_HT_header.remove(ui.time_header_func)
-
- # Remove keyboard shortcut configuration
- kc = bpy.context.window_manager.keyconfigs.addon
- km = kc.keymaps['Frames']
- km.keymap_items.remove(km.keymap_items['screenextra.frame_skip'])
- km.keymap_items.remove(km.keymap_items['screenextra.frame_skip'])
-
- km.keymap_items.remove(km.keymap_items['sequencer.strip_jump'])
- km.keymap_items.remove(km.keymap_items['sequencer.strip_jump'])
-
- km.keymap_items.remove(km.keymap_items['sequencerextra.sourcein'])
- km.keymap_items.remove(km.keymap_items['sequencerextra.sourceout'])
-
- kc = bpy.context.window_manager.keyconfigs.active
- km = kc.keymaps['Screen']
- km.keymap_items.remove(km.keymap_items['screen.marker_jump'])
- km.keymap_items.remove(km.keymap_items['screen.marker_jump'])
-
-
-if __name__ == '__main__':
- register()
diff --git a/sequencer_kinoraw_tools/audio_tools.py b/sequencer_kinoraw_tools/audio_tools.py
deleted file mode 100644
index 82a9a834..00000000
--- a/sequencer_kinoraw_tools/audio_tools.py
+++ /dev/null
@@ -1,358 +0,0 @@
-# gpl: authors Carlos Padial, Turi Scandurra
-
-import bpy
-import os
-from bpy.types import (
- Operator,
- Panel,
- )
-import subprocess
-from . import functions
-
-
-proxy_qualities = [
- ("1", "25%", ""), ("2", "50%", ""),
- ("3", "75%", ""), ("4", "100%", "")]
-
-#
-# ls *.sh | parallel -j 8 sh {}
-#
-
-
-# functions
-def createsyncfile(filename):
- if not os.path.isfile(bpy.path.abspath(filename)):
- f = open(bpy.path.abspath(filename), "w")
- data = []
-
- try:
- f.writelines(data) # Write a sequence of strings to a file
- finally:
- f.close()
-
-
-def readsyncfile(filename):
- try:
- file = open(bpy.path.abspath(filename))
- data = file.readlines()
- file.close()
-
- return data
-
- except IOError:
- pass
-
-
-def writesyncfile(filename, data):
- try:
- f = open(bpy.path.abspath(filename), "w")
- try:
- for line in data:
- f.writelines(line) # Write a sequence of strings to a file
- finally:
- f.close()
-
- except IOError:
- pass
-
-
-# classes
-
-class ExtractWavOperator(Operator):
- bl_idname = "sequencer.extract_wav_operator"
- bl_label = "Extract Wav from movie strip Operator"
- bl_description = "Use ffmpeg to extract audio from video and import it synced"
-
- @staticmethod
- def has_sequencer(context):
- return (context.space_data.view_type in
- {'SEQUENCER', 'SEQUENCER_PREVIEW'})
-
- @classmethod
- def poll(self, context):
- strip = functions.act_strip(context)
- scn = context.scene
- if scn and scn.sequence_editor and scn.sequence_editor.active_strip:
- return strip.type in ('MOVIE')
- else:
- return False
-
- def execute(self, context):
-
- preferences = context.preferences
- audio_dir = preferences.addons[__package__].preferences.audio_dir
-
- functions.create_folder(bpy.path.abspath(audio_dir))
-
- for strip in context.selected_editable_sequences:
-
- # get filename
- if strip.type == "MOVIE":
- filename = bpy.path.abspath(strip.filepath)
- newfilename = bpy.path.abspath(strip.filepath).rpartition(
- "/")[2]
- fileoutput = os.path.join(
- bpy.path.abspath(audio_dir),
- newfilename) + ".wav"
-
- # check for wav existing file
- if not os.path.isfile(fileoutput):
- # if not, extract the file
- extract_audio = "ffmpeg -i '{}' -acodec pcm_s16le -ac 2 {}".\
- format(filename, fileoutput)
- print(extract_audio)
- os.system(extract_audio)
- else:
- print("The audio File exists")
-
- if strip.type == "MOVIE":
- # import the file and trim in the same way the original
- bpy.ops.sequencer.sound_strip_add(
- filepath=fileoutput,
- frame_start=strip.frame_start,
- channel=strip.channel + 1,
- replace_sel=True, overlap=False,
- cache=False
- )
-
- # Update view_layer
- context.view_layer.update()
-
- newstrip = context.scene.sequence_editor.active_strip
-
- # deselect all other strips
- for i in context.selected_editable_sequences:
- if i.name != newstrip.name:
- i.select = False
-
- # Update view_layer
- context.view_layer.update()
-
- # Match the original clip's length
- newstrip.frame_start = strip.frame_start - strip.animation_offset_start
-
- functions.triminout(newstrip,
- strip.frame_start + strip.frame_offset_start,
- strip.frame_start + strip.frame_offset_start +
- strip.frame_final_duration)
-
- return {'FINISHED'}
-
-
-class ExternalAudioSetSyncOperator(Operator):
- bl_idname = "sequencer.external_audio_set_sync"
- bl_label = "set sync info"
- bl_description = ("Get sync info from selected audio and video strip "
- "and store it into a text file")
-
- @staticmethod
- def has_sequencer(context):
- return (context.space_data.view_type in
- {'SEQUENCER', 'SEQUENCER_PREVIEW'})
-
- @classmethod
- def poll(cls, context):
- if cls.has_sequencer(context):
- if len(context.selected_editable_sequences) == 2:
- types = []
- for i in context.selected_editable_sequences:
- types.append(i.type)
- if 'MOVIE' and 'SOUND' in types:
- return True
- else:
- return False
-
- def execute(self, context):
-
- preferences = context.preferences
- filename = preferences.addons[__package__].preferences.audio_external_filename
-
- for strip in context.selected_editable_sequences:
- if strip.type == "MOVIE":
- moviestrip = strip
- elif strip.type == "SOUND":
- soundstrip = strip
-
- offset = str(moviestrip.frame_start - soundstrip.frame_start)
-
- data1 = readsyncfile(filename)
- data2 = []
- newline = moviestrip.filepath + " " + soundstrip.filepath + " " + offset + "\n"
-
- if data1 is not None:
- repeated = False
- for line in data1:
- if line.split()[0] == moviestrip.filepath and line.split()[1] == soundstrip.filepath:
- data2.append(newline)
- repeated = True
- else:
- data2.append(line)
- if not repeated:
- data2.append(newline)
- else:
- data2.append(newline)
-
- createsyncfile(filename)
- writesyncfile(filename, data2)
-
- return {'FINISHED'}
-
-
-class ExternalAudioReloadOperator(Operator):
- bl_idname = "sequencer.external_audio_reload"
- bl_label = "Reload External audio"
- bl_description = ("Reload external audio synced to selected movie strip "
- "according to info from a text file")
-
- @staticmethod
- def has_sequencer(context):
- return (context.space_data.view_type in
- {'SEQUENCER', 'SEQUENCER_PREVIEW'})
-
- @classmethod
- def poll(cls, context):
- if cls.has_sequencer(context):
- if len(context.selected_editable_sequences) == 1:
- if context.selected_editable_sequences[0].type == 'MOVIE':
- return True
- else:
- return False
-
- def execute(self, context):
- preferences = context.preferences
- filename = preferences.addons[__package__].preferences.audio_external_filename
-
- data = readsyncfile(filename)
-
- for strip in context.selected_editable_sequences:
- sounds = []
-
- for line in data:
- if line.split()[0] == strip.filepath:
- moviefile = bpy.path.abspath(line.split()[0])
- soundfile = bpy.path.abspath(line.split()[1])
- offset = int(line.split()[2])
- sounds.append((soundfile, offset))
-
- for soundfile, offset in sounds:
- print(soundfile, offset)
- print(strip.filepath)
- # find start frame for sound strip (using offset from file)
- sound_frame_start = strip.frame_start - strip.animation_offset_start - offset
-
- # import the file and trim in the same way the original
- bpy.ops.sequencer.sound_strip_add(
- filepath=soundfile,
- frame_start=sound_frame_start,
- channel=strip.channel + 1,
- replace_sel=True, overlap=False,
- cache=False
- )
-
- # Update view_layer
- context.view_layer.update()
-
- newstrip = context.scene.sequence_editor.active_strip
-
- # deselect all other strips
- for i in context.selected_editable_sequences:
- if i.name != newstrip.name:
- i.select = False
-
- # Update view_layer
- context.view_layer.update()
-
- # trim sound strip like original one
- functions.triminout(newstrip,
- strip.frame_start + strip.frame_offset_start,
- strip.frame_start + strip.frame_offset_start +
- strip.frame_final_duration
- )
-
- return {'FINISHED'}
-
-
-class AudioToolPanel(Panel):
- bl_label = "Audio Tools"
- bl_idname = "OBJECT_PT_AudioTool"
- bl_space_type = 'SEQUENCE_EDITOR'
- bl_region_type = 'UI'
-
- @classmethod
- def poll(self, context):
- if context.space_data.view_type in {'SEQUENCER', 'SEQUENCER_PREVIEW'}:
- scn = context.scene
- preferences = context.preferences
- prefs = preferences.addons[__package__].preferences
- if scn and scn.sequence_editor and scn.sequence_editor.active_strip:
- if prefs.use_audio_tools:
- return True
- else:
- return False
-
- def draw_header(self, context):
- layout = self.layout
- layout.label(text="", icon="PLAY_AUDIO")
-
- def draw(self, context):
- preferences = context.preferences
- prefs = preferences.addons[__package__].preferences
-
- strip = functions.act_strip(context)
-
- if strip.type == "MOVIE":
- layout = self.layout
- layout.prop(prefs, "audio_dir", text="Path for Audio files")
-
- layout.operator("sequencer.extract_wav_operator", text="Extract Wav")
-
- layout = self.layout
- layout.prop(prefs, "audio_scripts")
-
- if prefs.audio_scripts:
- layout = self.layout
- layout.prop(prefs, "audio_scripts_path", text="Path for scripts")
-
- layout = self.layout
- layout.prop(prefs, "audio_use_external_links", text="External Audio sync")
-
- if prefs.audio_use_external_links:
- layout = self.layout
- layout.prop(prefs, "audio_external_filename", text="Sync data")
-
- row = layout.row(align=True)
- row.operator("sequencer.external_audio_set_sync", text="Set sync")
- row.operator("sequencer.external_audio_reload", text="Reload Audio")
-
- layout = self.layout
-
- row = layout.row()
- row.prop(prefs, "metertype", text="")
- row.operator("sequencer.openmeterbridge",
- text="Launch Audio Meter", icon="SOUND")
-
-
-class OpenMeterbridgeOperator(Operator):
- bl_idname = "sequencer.openmeterbridge"
- bl_label = "External VU meter"
- bl_description = "Open external VU meter to work with Jack"
-
- @staticmethod
- def has_sequencer(context):
- return (context.space_data.view_type in {'SEQUENCER', 'SEQUENCER_PREVIEW'})
-
- @classmethod
- def poll(cls, context):
- if cls.has_sequencer(context):
- if len(context.selected_editable_sequences) == 1:
- return True
-
- def execute(self, context):
- preferences = context.preferences
- prefs = preferences.addons[__package__].preferences
-
- command = "meterbridge -t {} 'PulseAudio JACK Sink:front-left' " \
- "'PulseAudio JACK Sink:front-right' &".format(prefs.metertype.lower())
- p = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True)
-
- return {'FINISHED'}
diff --git a/sequencer_kinoraw_tools/datamosh.py b/sequencer_kinoraw_tools/datamosh.py
deleted file mode 100644
index f64adbed..00000000
--- a/sequencer_kinoraw_tools/datamosh.py
+++ /dev/null
@@ -1,189 +0,0 @@
-# gpl: authors Carlos Padial, Turi Scandurra
-
-import bpy
-import os
-from bpy.props import IntProperty
-from bpy.types import (
- Operator,
- Panel,
- )
-from . import functions
-
-
-proxy_qualities = [
- ("1", "25%", ""), ("2", "50%", ""),
- ("3", "75%", ""), ("4", "100%", ""),
- ("5", "none", "")
- ]
-
-
-# functions
-def createdatamosh(context, strip):
- preferences = context.preferences
- prefs = preferences.addons[__package__].preferences
-
- fileinput = bpy.path.abspath(strip.filepath)
- fileoutput = fileinput.rpartition(".")[0] + "_datamosh.avi"
-
- if prefs.all_keyframes:
- command = "datamosh '{}' -a -o '{}'".format(fileinput, fileoutput)
- else:
- command = "datamosh '{}' -o '{}'".format(fileinput, fileoutput)
- print(command)
- os.system(command)
- return fileoutput
-
-
-def createavi(context, strip):
- fileinput = bpy.path.abspath(strip.filepath)
- fileoutput = fileinput.rpartition(".")[0] + "_.avi"
-
- command = "ffmpeg -i '{}' -vcodec copy '{}'".format(fileinput, fileoutput)
-
- print(command)
- os.system(command)
-
- return fileoutput
-
-
-def createavimjpeg(context, strip):
- fileinput = bpy.path.abspath(strip.filepath)
- fileoutput = fileinput.rpartition(".")[0] + "_mjpeg.avi"
-
- command = "ffmpeg -i '{}' -vcodec mjpeg -q:v 1 '{}'".format(fileinput, fileoutput)
-
- print(command)
- os.system(command)
-
- return fileoutput
-
-
-# classes
-class CreateAvi(Operator):
- bl_idname = "sequencer.createavi"
- bl_label = "Create avi file"
- bl_description = "Create an avi output file"
- bl_options = {'REGISTER', 'UNDO'}
-
- size: IntProperty(
- name="proxysize",
- default=1
- )
-
- @classmethod
- def poll(self, context):
- strip = functions.act_strip(context)
- scn = context.scene
- if scn and scn.sequence_editor and scn.sequence_editor.active_strip:
- return strip.type in ('MOVIE')
- else:
- return False
-
- def execute(self, context):
- strips = functions.get_selected_strips(context)
-
- for strip in strips:
- # deselect all other strips
- for i in strips:
- i.select = False
- # select current strip
- strip.select = True
- if strip.type == "MOVIE":
- if self.size == 1:
- fileoutput = createavi(context, strip)
- elif self.size == 2:
- fileoutput = createavimjpeg(context, strip)
- strip.filepath = fileoutput
-
- # select all strips again
- for strip in strips:
- try:
- strip.select = True
- except ReferenceError:
- pass
-
- bpy.ops.sequencer.reload()
-
- return {'FINISHED'}
-
-
-class CreateDatamosh(Operator):
- bl_idname = "sequencer.createdatamosh"
- bl_label = "Create Datamosh"
- bl_description = "Create Datamosh"
-
- @classmethod
- def poll(self, context):
- strip = functions.act_strip(context)
- scn = context.scene
- if scn and scn.sequence_editor and scn.sequence_editor.active_strip:
- return strip.type in ('MOVIE')
- else:
- return False
-
- def execute(self, context):
- preferences = context.preferences
- prefs = preferences.addons[__package__].preferences
- strips = functions.get_selected_strips(context)
-
- for strip in strips:
- # deselect all other strips
- for i in strips:
- i.select = False
- # select current strip
- strip.select = True
- if strip.type == "MOVIE":
- fileoutput = createdatamosh(context, strip)
- if prefs.load_glitch:
- strip.filepath = fileoutput
-
- # select all strips again
- for strip in strips:
- try:
- strip.select = True
- except ReferenceError:
- pass
-
- bpy.ops.sequencer.reload()
-
- return {'FINISHED'}
-
-
-class CreateGlitchToolPanel(Panel):
- bl_label = "Glitch Tools"
- bl_idname = "OBJECT_PT_GlitchTool"
- bl_space_type = 'SEQUENCE_EDITOR'
- bl_region_type = 'UI'
-
- @classmethod
- def poll(self, context):
- if context.space_data.view_type in {'SEQUENCER',
- 'SEQUENCER_PREVIEW'}:
- strip = functions.act_strip(context)
- scn = context.scene
- preferences = context.preferences
- prefs = preferences.addons[__package__].preferences
- if scn and scn.sequence_editor and scn.sequence_editor.active_strip:
- if prefs.use_glitch_panel:
- return strip.type in ('MOVIE')
- else:
- return False
-
- def draw_header(self, context):
- layout = self.layout
- layout.label(text="", icon="GAME")
-
- def draw(self, context):
-
- preferences = context.preferences
- prefs = preferences.addons[__package__].preferences
-
- layout = self.layout
-
- layout.operator("sequencer.createavi", text="Create avi (same codec)")
- layout.operator("sequencer.createavi", text="Create avi (mjpeg)").size = 2
-
- layout.prop(prefs, "all_keyframes")
- layout.prop(prefs, "load_glitch")
-
- layout.operator("sequencer.createdatamosh")
diff --git a/sequencer_kinoraw_tools/eco.py b/sequencer_kinoraw_tools/eco.py
deleted file mode 100644
index 55810b55..00000000
--- a/sequencer_kinoraw_tools/eco.py
+++ /dev/null
@@ -1,127 +0,0 @@
-# File sequencer_slide_strip.py
-
-# ##### 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 #####
-
-
-import bpy
-from bpy.types import (
- Operator,
- Panel,
- )
-from . import functions
-
-
-class EcoPanel(Panel):
- bl_label = "Eco Tool"
- bl_idname = "OBJECT_PT_EcoTool"
- bl_space_type = "SEQUENCE_EDITOR"
- bl_region_type = "UI"
-
- @staticmethod
- def has_sequencer(context):
- return (context.space_data.view_type in
- {'SEQUENCER', 'SEQUENCER_PREVIEW'})
-
- @classmethod
- def poll(self, context):
- if context.space_data.view_type in {'SEQUENCER', 'SEQUENCER_PREVIEW'}:
- strip = functions.act_strip(context)
- scn = context.scene
- preferences = context.preferences
- prefs = preferences.addons[__package__].preferences
- if scn and scn.sequence_editor and scn.sequence_editor.active_strip:
- if prefs.use_eco_tools:
- return strip.type in ('META')
- else:
- return False
-
- def draw_header(self, context):
- layout = self.layout
- layout.label(text="", icon="FORCE_HARMONIC")
-
- def draw(self, context):
- strip = functions.act_strip(context)
- seq_type = strip.type
-
- preferences = context.preferences
- prefs = preferences.addons[__package__].preferences
-
- if seq_type in ('MOVIE', 'IMAGE', 'META', 'MOVIECLIP', 'SCENE'):
- layout = self.layout
- col = layout.column()
-
- col.prop(prefs, "eco_value", text="Ecos")
- col.prop(prefs, "eco_offset", text="Offset")
- col.prop(prefs, "eco_use_add_blend_mode", text="Use add blend mode")
- col.operator("sequencer.eco")
-
-
-class OBJECT_OT_EcoOperator(Operator):
- bl_idname = "sequencer.eco"
- bl_label = "Eco operator"
- bl_description = "Generate an echo effect by duplicating the selected strip"
- bl_options = {'REGISTER', 'UNDO'}
-
- @staticmethod
- def has_sequencer(context):
- return (context.space_data.view_type in
- {'SEQUENCER', 'SEQUENCER_PREVIEW'})
-
- @classmethod
- def poll(self, context):
- strip = functions.act_strip(context)
- scn = context.scene
- if scn and scn.sequence_editor and scn.sequence_editor.active_strip:
- return strip.type in ('META')
- else:
- return False
-
- def execute(self, context):
- active_strip = functions.act_strip(context)
-
- preferences = context.preferences
- prefs = preferences.addons[__package__].preferences
-
- eco = prefs.eco_value
- offset = prefs.eco_offset
-
- active_strip.blend_type = 'REPLACE'
- active_strip.blend_alpha = 1
- for i in range(eco):
- bpy.ops.sequencer.duplicate(mode='TRANSLATION')
- bpy.ops.transform.seq_slide(
- value=(offset, 1), snap=False, snap_target='CLOSEST',
- snap_point=(0, 0, 0), snap_align=False,
- snap_normal=(0, 0, 0), release_confirm=False
- )
-
- active_strip = functions.act_strip(context)
-
- if prefs.eco_use_add_blend_mode:
- active_strip.blend_type = 'ADD'
- active_strip.blend_alpha = 1 - 1 / eco
- else:
- active_strip.blend_type = 'ALPHA_OVER'
- active_strip.blend_alpha = 1 / eco
-
- bpy.ops.sequencer.select_all(action='TOGGLE')
- bpy.ops.sequencer.select_all(action='TOGGLE')
- bpy.ops.sequencer.meta_make()
-
- return {'FINISHED'}
diff --git a/sequencer_kinoraw_tools/exiftool.py b/sequencer_kinoraw_tools/exiftool.py
deleted file mode 100644
index e51b825c..00000000
--- a/sequencer_kinoraw_tools/exiftool.py
+++ /dev/null
@@ -1,330 +0,0 @@
-# -*- coding: utf-8 -*-
-# PyExifTool <http://github.com/smarnach/pyexiftool>
-# Copyright 2012 Sven Marnach
-
-# This file is part of PyExifTool.
-#
-# PyExifTool 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 3 of the License, or
-# (at your option) any later version.
-#
-# PyExifTool 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 PyExifTool. If not, see <http://www.gnu.org/licenses/>.
-
-"""
-PyExifTool is a Python library to communicate with an instance of Phil
-Harvey's excellent ExifTool_ command-line application. The library
-provides the class :py:class:`ExifTool` that runs the command-line
-tool in batch mode and features methods to send commands to that
-program, including methods to extract meta-information from one or
-more image files. Since ``exiftool`` is run in batch mode, only a
-single instance needs to be launched and can be reused for many
-queries. This is much more efficient than launching a separate
-process for every single query.
-
-.. _ExifTool: http://www.sno.phy.queensu.ca/~phil/exiftool/
-
-The source code can be checked out from the github repository with
-
-::
-
- git clone git://github.com/smarnach/pyexiftool.git
-
-Alternatively, you can download a tarball_. There haven't been any
-releases yet.
-
-.. _tarball: https://github.com/smarnach/pyexiftool/tarball/master
-
-PyExifTool is licenced under GNU GPL version 3 or later.
-
-Example usage::
-
- import exiftool
-
- files = ["a.jpg", "b.png", "c.tif"]
- with exiftool.ExifTool() as et:
- metadata = et.get_metadata_batch(files)
- for d in metadata:
- print("{:20.20} {:20.20}".format(d["SourceFile"],
- d["EXIF:DateTimeOriginal"]))
-"""
-
-from __future__ import unicode_literals
-
-import sys
-import subprocess
-import os
-import json
-import warnings
-import codecs
-
-try: # Py3k compatibility
- basestring
-except NameError:
- basestring = (bytes, str)
-
-executable = "exiftool"
-"""The name of the executable to run.
-
-If the executable is not located in one of the paths listed in the
-``PATH`` environment variable, the full path should be given here.
-"""
-
-# Sentinel indicating the end of the output of a sequence of commands.
-# The standard value should be fine.
-sentinel = b"{ready}"
-
-# The block size when reading from exiftool. The standard value
-# should be fine, though other values might give better performance in
-# some cases.
-block_size = 4096
-
-# This code has been adapted from Lib/os.py in the Python source tree
-# (sha1 265e36e277f3)
-
-
-def _fscodec():
- encoding = sys.getfilesystemencoding()
- errors = "strict"
- if encoding != "mbcs":
- try:
- codecs.lookup_error("surrogateescape")
- except LookupError:
- pass
- else:
- errors = "surrogateescape"
-
- def fsencode(filename):
- """
- Encode filename to the filesystem encoding with 'surrogateescape' error
- handler, return bytes unchanged. On Windows, use 'strict' error handler
- if the file system encoding is 'mbcs' (which is the default encoding).
- """
- if isinstance(filename, bytes):
- return filename
- else:
- return filename.encode(encoding, errors)
-
- return fsencode
-
-fsencode = _fscodec()
-del _fscodec
-
-
-class ExifTool(object):
- """Run the `exiftool` command-line tool and communicate to it.
-
- You can pass the file name of the ``exiftool`` executable as an
- argument to the constructor. The default value ``exiftool`` will
- only work if the executable is in your ``PATH``.
-
- Most methods of this class are only available after calling
- :py:meth:`start()`, which will actually launch the subprocess. To
- avoid leaving the subprocess running, make sure to call
- :py:meth:`terminate()` method when finished using the instance.
- This method will also be implicitly called when the instance is
- garbage collected, but there are circumstance when this won't ever
- happen, so you should not rely on the implicit process
- termination. Subprocesses won't be automatically terminated if
- the parent process exits, so a leaked subprocess will stay around
- until manually killed.
-
- A convenient way to make sure that the subprocess is terminated is
- to use the :py:class:`ExifTool` instance as a context manager::
-
- with ExifTool() as et:
- ...
-
- .. warning:: Note that there is no error handling. Nonsensical
- options will be silently ignored by exiftool, so there's not
- much that can be done in that regard. You should avoid passing
- non-existent files to any of the methods, since this will lead
- to undefined behaviour.
-
- .. py:attribute:: running
-
- A Boolean value indicating whether this instance is currently
- associated with a running subprocess.
- """
-
- def __init__(self, executable_=None):
- if executable_ is None:
- self.executable = executable
- else:
- self.executable = executable_
- self.running = False
-
- def start(self):
- """Start an ``exiftool`` process in batch mode for this instance.
-
- This method will issue a ``UserWarning`` if the subprocess is
- already running. The process is started with the ``-G`` and
- ``-n`` as common arguments, which are automatically included
- in every command you run with :py:meth:`execute()`.
- """
- if self.running:
- warnings.warn("ExifTool already running; doing nothing.")
- return
- with open(os.devnull, "w") as devnull:
- self._process = subprocess.Popen(
- [self.executable, "-stay_open", "True", "-@", "-",
- "-common_args", "-G", "-u", "-a", "-n"],
- stdin=subprocess.PIPE, stdout=subprocess.PIPE,
- stderr=devnull)
- self.running = True
-
- def terminate(self):
- """Terminate the ``exiftool`` process of this instance.
-
- If the subprocess isn't running, this method will do nothing.
- """
- if not self.running:
- return
- self._process.stdin.write(b"-stay_open\nFalse\n")
- self._process.stdin.flush()
- self._process.communicate()
- del self._process
- self.running = False
-
- def __enter__(self):
- self.start()
- return self
-
- def __exit__(self, exc_type, exc_val, exc_tb):
- self.terminate()
-
- def __del__(self):
- self.terminate()
-
- def execute(self, *params):
- """Execute the given batch of parameters with ``exiftool``.
-
- This method accepts any number of parameters and sends them to
- the attached ``exiftool`` process. The process must be
- running, otherwise ``ValueError`` is raised. The final
- ``-execute`` necessary to actually run the batch is appended
- automatically; see the documentation of :py:meth:`start()` for
- the common options. The ``exiftool`` output is read up to the
- end-of-output sentinel and returned as a raw ``bytes`` object,
- excluding the sentinel.
-
- The parameters must also be raw ``bytes``, in whatever
- encoding exiftool accepts. For filenames, this should be the
- system's filesystem encoding.
-
- .. note:: This is considered a low-level method, and should
- rarely be needed by application developers.
- """
- if not self.running:
- raise ValueError("ExifTool instance not running.")
- self._process.stdin.write(b"\n".join(params + (b"-execute\n",)))
- self._process.stdin.flush()
- output = b""
- fd = self._process.stdout.fileno()
- while not output[-32:].strip().endswith(sentinel):
- output += os.read(fd, block_size)
- return output.strip()[:-len(sentinel)]
-
- def execute_json(self, *params):
- """Execute the given batch of parameters and parse the JSON output.
-
- This method is similar to :py:meth:`execute()`. It
- automatically adds the parameter ``-j`` to request JSON output
- from ``exiftool`` and parses the output. The return value is
- a list of dictionaries, mapping tag names to the corresponding
- values. All keys are Unicode strings with the tag names
- including the ExifTool group name in the format <group>:<tag>.
- The values can have multiple types. All strings occurring as
- values will be Unicode strings. Each dictionary contains the
- name of the file it corresponds to in the key ``"SourceFile"``.
-
- The parameters to this function must be either raw strings
- (type ``str`` in Python 2.x, type ``bytes`` in Python 3.x) or
- Unicode strings (type ``unicode`` in Python 2.x, type ``str``
- in Python 3.x). Unicode strings will be encoded using
- system's filesystem encoding. This behaviour means you can
- pass in filenames according to the convention of the
- respective Python version – as raw strings in Python 2.x and
- as Unicode strings in Python 3.x.
- """
- params = map(fsencode, params)
- return json.loads(self.execute(b"-j", *params).decode("utf-8"))
-
- def get_metadata_batch(self, filenames):
- """Return all meta-data for the given files.
-
- The return value will have the format described in the
- documentation of :py:meth:`execute_json()`.
- """
- return self.execute_json(*filenames)
-
- def get_metadata(self, filename):
- """Return meta-data for a single file.
-
- The returned dictionary has the format described in the
- documentation of :py:meth:`execute_json()`.
- """
- return self.execute_json(filename)[0]
-
- def get_tags_batch(self, tags, filenames):
- """Return only specified tags for the given files.
-
- The first argument is an iterable of tags. The tag names may
- include group names, as usual in the format <group>:<tag>.
-
- The second argument is an iterable of file names.
-
- The format of the return value is the same as for
- :py:meth:`execute_json()`.
- """
- # Explicitly ruling out strings here because passing in a
- # string would lead to strange and hard-to-find errors
- if isinstance(tags, basestring):
- raise TypeError("The argument 'tags' must be "
- "an iterable of strings")
- if isinstance(filenames, basestring):
- raise TypeError("The argument 'filenames' must be "
- "an iterable of strings")
- params = ["-" + t for t in tags]
- params.extend(filenames)
- return self.execute_json(*params)
-
- def get_tags(self, tags, filename):
- """Return only specified tags for a single file.
-
- The returned dictionary has the format described in the
- documentation of :py:meth:`execute_json()`.
- """
- return self.get_tags_batch(tags, [filename])[0]
-
- def get_tag_batch(self, tag, filenames):
- """Extract a single tag from the given files.
-
- The first argument is a single tag name, as usual in the
- format <group>:<tag>.
-
- The second argument is an iterable of file names.
-
- The return value is a list of tag values or ``None`` for
- non-existent tags, in the same order as ``filenames``.
- """
- data = self.get_tags_batch([tag], filenames)
- result = []
- for d in data:
- d.pop("SourceFile")
- result.append(next(iter(d.values()), None))
- return result
-
- def get_tag(self, tag, filename):
- """Extract a single tag from a single file.
-
- The return value is the value of the specified tag, or
- ``None`` if this tag was not found in the file.
- """
- return self.get_tag_batch(tag, [filename])[0]
diff --git a/sequencer_kinoraw_tools/functions.py b/sequencer_kinoraw_tools/functions.py
deleted file mode 100644
index b51f495c..00000000
--- a/sequencer_kinoraw_tools/functions.py
+++ /dev/null
@@ -1,455 +0,0 @@
-# ##### 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 #####
-
-import bpy
-import os.path
-import operator
-import subprocess
-import random
-from bpy.props import (
- IntProperty,
- FloatProperty,
- EnumProperty,
- BoolProperty,
- )
-
-imb_ext_image = [
- # IMG
- ".png", ".tga", ".bmp", ".jpg", ".jpeg", ".sgi", ".rgb",
- ".rgba", ".tif", ".tiff", ".tx", ".jp2", ".hdr", ".dds",
- ".dpx", ".cin", ".exr", ".rw2",
- # IMG QT
- ".gif", ".psd", ".pct", ".pict", ".pntg", ".qtif"
- ]
-imb_ext_audio = [
- ".wav", ".ogg", ".oga", ".mp3", ".mp2", ".ac3", ".aac",
- ".flac", ".wma", ".eac3", ".aif", ".aiff", ".m4a"
- ]
-imb_ext_movie = [
- ".avi", ".flc", ".mov", ".movie", ".mp4", ".m4v", ".m2v",
- ".m2t", ".m2ts", ".mts", ".mv", ".avs", ".wmv", ".ogv", ".ogg",
- ".dv", ".mpeg", ".mpg", ".mpg2", ".vob", ".mkv", ".flv",
- ".divx", ".xvid", ".mxf"
- ]
-movieextdict = [
- ("1", ".avi", ""),
- ("2", ".flc", ""), ("3", ".mov", ""),
- ("4", ".movie", ""), ("5", ".mp4", ""),
- ("6", ".m4v", ""), ("7", ".m2v", ""),
- ("8", ".m2t", ""), ("9", ".m2ts", ""),
- ("10", ".mts", ""), ("11", ".mv", ""),
- ("12", ".avs", ""), ("13", ".wmv", ""),
- ("14", ".ogv", ""), ("15", ".dv", ""),
- ("16", ".mpeg", ""), ("17", ".mpg", ""),
- ("18", ".mpg2", ""), ("19", ".vob", ""),
- ("20", ".mkv", ""), ("21", ".flv", ""),
- ("22", ".divx", ""), ("23", ".xvid", ""),
- ("24", ".mxf", "")
- ]
-
-
-# Functions
-def error_handlers(self, op_name, errors, reports="ERROR"):
- if self and reports:
- self.report({'INFO'},
- reports + ": some operations could not be performed "
- "(See Console for more info)")
-
- print("\n[Kinoraw Tools]\nOperator: {}\nWarning: {}\n".format(op_name, errors))
-
-
-def initSceneProperties(context):
- # initSceneProperties is ONLY for variables that should
- # be keeped with the blend file. Any other addon preferences
- # should go to the addon preferences operator in __init__
- try:
- if context.scene.kr_scn_init is True:
- return False
- except AttributeError:
- pass
-
- scn = context.scene
-
- # jump to cut
- bpy.types.Scene.kr_auto_markers = BoolProperty(
- name="kr_auto_markers",
- description="Activate Auto markers",
- default=False
- )
- scn.kr_auto_markers = False
-
- bpy.types.Scene.kr_in_marker = IntProperty(
- name="In",
- description="In frame position",
- min=-30000, max=30000,
- default=1
- )
- scn.kr_in_marker = 1
-
- bpy.types.Scene.kr_out_marker = IntProperty(
- name="Out",
- description="Out frame position",
- min=scn.kr_in_marker, max=30000,
- default=75
- )
- scn.kr_out_marker = 75
-
- # sequencer extra actions
- bpy.types.Scene.kr_default_fade_duration = IntProperty(
- name="Duration",
- description="Number of frames to fade",
- min=1, max=250,
- default=scn.render.fps
- )
- scn.kr_default_fade_duration = scn.render.fps
-
- bpy.types.Scene.kr_default_fade_amount = FloatProperty(
- name="Amount",
- description="Maximum value of fade",
- min=0.0,
- max=100.0,
- default=1.0
- )
- scn.kr_default_fade_amount = 1.0
-
- # recursive loader
- bpy.types.Scene.kr_recursive = BoolProperty(
- name="Recursive",
- description="Load in recursive folders",
- default=False
- )
- scn.kr_recursive = False
-
- bpy.types.Scene.kr_recursive_select_by_extension = BoolProperty(
- name="Recursive ext",
- description="Load only clips with selected extension",
- default=False
- )
- scn.kr_recursive_select_by_extension = False
-
- bpy.types.Scene.kr_default_ext = EnumProperty(
- items=movieextdict,
- name="ext enum",
- default="3"
- )
- scn.kr_default_ext = "3"
-
- bpy.types.Scene.kr_scn_init = BoolProperty(
- name="Init",
- default=False
- )
- scn.kr_scn_init = True
-
- return True
-
-
-def get_selected_strips(context):
- "return a list of selected strips"
- strips = []
- for i in context.scene.sequence_editor.sequences_all:
- if i.select is True:
- strips.append(i)
- return strips
-
-
-def create_folder(path):
- if not os.path.isdir(bpy.path.abspath(path)):
- folder = bpy.path.abspath(path)
- command = "mkdir " + folder
- subprocess.call(command, shell=True)
-
-
-def add_marker(context, text, frame):
- scn = context.scene
- markers = scn.timeline_markers
- mark = markers.new(name=text)
- mark.frame = frame
-
-
-def act_strip(context):
- try:
- return context.scene.sequence_editor.active_strip
- except AttributeError:
- return None
-
-
-def detect_strip_type(filepath):
- extension = os.path.splitext(filepath)[1]
- extension = extension.lower()
- if extension in imb_ext_image:
- type = 'IMAGE'
- elif extension in imb_ext_movie:
- type = 'MOVIE'
- elif extension in imb_ext_audio:
- type = 'SOUND'
- else:
- type = None
-
- return type
-
-
-# recursive load functions
-def getpathfrombrowser(context):
- '''
- returns path from filebrowser
- '''
- for a in context.window.screen.areas:
- if a.type == 'FILE_BROWSER':
- params = a.spaces[0].params
- break
- try:
- params
- except UnboundLocalError:
- return {'CANCELLED'}
-
- path = params.directory
- return path
-
-
-def getfilepathfrombrowser(context):
- """
- returns path and file from filebrowser
- """
- for a in context.window.screen.areas:
- if a.type == 'FILE_BROWSER':
- params = a.spaces[0].params
- break
- try:
- params
- except UnboundLocalError:
- return {'CANCELLED'}
-
- if params.filename == '':
- return {'CANCELLED'}
-
- path = params.directory
- filename = params.filename
- return path, filename
-
-
-def setpathinbrowser(context, path, file):
- '''
- set path and file in the filebrowser
- '''
- for a in context.window.screen.areas:
- if a.type == 'FILE_BROWSER':
- params = a.spaces[0].params
- break
- try:
- params
- except UnboundLocalError:
-
- return {'CANCELLED'}
-
- params.directory = path
- params.filename = file
- return path, params
-
-
-def sortlist(filelist):
- '''
- given a list of tuplas (path, filename) returns a list sorted by filename
- '''
- filelist_sorted = sorted(filelist, key=operator.itemgetter(1))
- return filelist_sorted
-
-
-def onefolder(context, recursive_select_by_extension, ext):
- '''
- returns a list of MOVIE type files from folder selected in file browser
- '''
- filelist = []
- path, filename = getfilepathfrombrowser(context)
-
- for i in movieextdict:
- if i[0] == ext:
- extension = i[1].rpartition(".")[2]
- break
-
- if detect_strip_type(path + filename) == 'MOVIE':
- if recursive_select_by_extension is True:
- # filtering by extension...
- for file in os.listdir(path):
- if file.rpartition(".")[2].lower() == extension:
- filelist.append((path, file))
- else:
- # looking for all known extensions
- for file in os.listdir(path):
- for i in movieextdict:
- if file.rpartition(".")[2].lower() == i[1].rpartition(".")[2]:
- filelist.append((path, file))
- return (filelist)
-
-
-def recursive(context, recursive_select_by_extension, ext):
- '''
- returns a list of MOVIE type files recursively from file browser
- '''
- filelist = []
- path = getpathfrombrowser(context)
-
- for i in movieextdict:
- if i[0] == ext:
- extension = i[1].rpartition(".")[2]
- break
-
- for root, dirs, files in os.walk(path):
- for file in files:
- if recursive_select_by_extension is True:
- # filtering by extension...
- if file.rpartition(".")[2].lower() == extension:
- filelist.append((root, file))
- else:
- # looking for all known extensions
- for i in movieextdict:
- if file.rpartition(".")[2].lower() == i[1].rpartition(".")[2]:
- filelist.append((root, file))
- return filelist
-
-
-# jump to cut functions
-def triminout(strip, sin, sout):
-
- """trim the strip to in and out, and returns
- true if the strip is outside given in and out"""
-
- start = strip.frame_start + strip.frame_offset_start - strip.frame_still_start
- end = start + strip.frame_final_duration
-
- remove = False
- if end < sin:
- remove = True
- if start > sout:
- remove = True
-
- if end > sin:
- if start < sin:
- strip.select_right_handle = False
- strip.select_left_handle = True
- bpy.ops.sequencer.snap(frame=sin)
- strip.select_left_handle = False
- if start < sout:
- if end > sout:
- strip.select_left_handle = False
- strip.select_right_handle = True
- bpy.ops.sequencer.snap(frame=sout)
- strip.select_right_handle = False
-
- return remove
-
-
-# random editor functions
-
-def randompartition(lst, n, rand):
- division = len(lst) / float(n)
- lista = []
- for i in range(n):
- lista.append(division)
-
- var = 0
- for i in range(n - 1):
- lista[i] += random.randint(-int(rand * division), int(rand * division))
- var += lista[i]
-
- if lista[n - 1] != len(lst) - var:
- lista[n - 1] = len(lst) - var
-
- random.shuffle(lista)
- division = len(lst) / float(n)
- count = 0
- newlist = []
- for i in range(n):
- # print(lst[count : int(lista[i]-1)+count])
- newlist.append([lst[count: int(lista[i] - 1) + count]])
- count += int(lista[i])
-
- return newlist
-
-
-def randomframe(strip):
- # random frame between a and b
- a = strip.frame_start
- b = strip.frame_final_duration
- rand = a + int(random.random() * b)
-
- return rand
-
-
-# ???
-def get_matching_markers(scene, name=None):
- '''
- return a list of markers with same name
- from the scene, or all markers if name is None
- '''
- selected_markers = []
- markers = scene.timeline_markers
- for mark in markers:
- # print(mark.name, name)
- if mark.name == name or name is None:
- selected_markers.append(mark.frame)
-
- return selected_markers
-
-
-def generate_subsets_list(number_of_subsets):
- # generate marker subsets list
- subset_list = []
- subset_names = ['A', 'B', 'C', 'D', 'E', 'F']
-
- for subset in range(number_of_subsets):
- subset_list.append(subset_names[subset])
- return subset_list
-
-
-def get_marker_dict(scene, number_of_subsets):
- """
- return a dict where:
- keys = subset names
- values = list of markers
- """
-
- subset_list = generate_subsets_list(number_of_subsets)
- # generate dict with a list for each subset
- marker_dict = {}
-
- for subset in subset_list:
- lists = get_matching_markers(scene, subset)
- marker_dict[subset] = lists
- return marker_dict
-
-
-def get_cut_dict(scene, number_of_subsets):
- """
- return a dict where:
- keys = markers in the scene + start and end
- values = duration in frames from key marker to next marker
- """
- # generate cut_list
-
- lists = get_matching_markers(scene)
- lists.append(scene.frame_start)
- lists.append(scene.frame_end)
- lists.sort()
- cut_dict = {}
-
- for i, j in enumerate(lists):
- try:
- cut_dict[j] = lists[i + 1] - j
- except IndexError:
- continue
- return cut_dict
diff --git a/sequencer_kinoraw_tools/jumptocut.py b/sequencer_kinoraw_tools/jumptocut.py
deleted file mode 100644
index 45a02cf4..00000000
--- a/sequencer_kinoraw_tools/jumptocut.py
+++ /dev/null
@@ -1,656 +0,0 @@
-# ##### 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 #####
-
-
-import bpy
-from . import functions
-from bpy.types import (
- Operator,
- )
-from bpy.props import (
- IntProperty,
- )
-from bpy.app.handlers import persistent
-
-
-class OBJECT_OT_Setinout(Operator):
- bl_label = "Set IN and OUT to selected"
- bl_idname = "sequencerextra.setinout"
- bl_description = "Set IN and OUT markers to the selected strips limits"
- bl_options = {'REGISTER', 'UNDO'}
-
- @classmethod
- def poll(self, context):
- scn = context.scene
- if scn and scn.sequence_editor:
- return scn.sequence_editor.active_strip
- else:
- return False
-
- def execute(self, context):
- functions.initSceneProperties(context)
-
- scn = context.scene
- markers = scn.timeline_markers
- seq = scn.sequence_editor
-
- meta_level = len(seq.meta_stack)
- if meta_level > 0:
- seq = seq.meta_stack[meta_level - 1]
-
- # search for timeline limits
- tl_start = 300000
- tl_end = -300000
- for i in context.selected_editable_sequences:
- if i.select is True:
- start = i.frame_start + i.frame_offset_start - i.frame_still_start
- end = start + i.frame_final_duration
- if start < tl_start:
- tl_start = start
- if end > tl_end:
- tl_end = end
- # print(tl_start,tl_end)
-
- if scn.kr_auto_markers:
- scn.kr_in_marker = tl_start
- scn.kr_out_marker = tl_end
- else:
- scn.kr_in_marker = tl_start
- scn.kr_out_marker = tl_end
-
- if "IN" in markers:
- mark = markers["IN"]
- mark.frame = scn.kr_in_marker
- else:
- mark = markers.new(name="IN")
- mark.frame = scn.kr_in_marker
-
- if "OUT" in markers:
- mark = markers["OUT"]
- mark.frame = scn.kr_out_marker
- else:
- mark = markers.new(name="OUT")
- mark.frame = scn.kr_in_marker
-
- return {'FINISHED'}
-
-
-class OBJECT_OT_Triminout(Operator):
- bl_label = "Trim to in & out"
- bl_idname = "sequencerextra.triminout"
- bl_description = "Trim the selected strip to IN and OUT markers (if exists)"
-
- bl_options = {'REGISTER', 'UNDO'}
-
- @classmethod
- def poll(self, context):
- scn = context.scene
- if scn and scn.sequence_editor:
- if scn.sequence_editor.active_strip:
- markers = scn.timeline_markers
- if "IN" and "OUT" in markers:
- return True
- else:
- return False
-
- def execute(self, context):
-
- scene = context.scene
- seq = scene.sequence_editor
-
- meta_level = len(seq.meta_stack)
- if meta_level > 0:
- seq = seq.meta_stack[meta_level - 1]
-
- markers = scene.timeline_markers
- sin = markers["IN"].frame
- sout = markers["OUT"].frame
- strips = context.selected_editable_sequences
-
- # (triminout function only works fine
- # with one strip selected at a time)
- for strip in strips:
- # deselect all other strips
- for i in strips:
- i.select = False
- # select current strip
- strip.select = True
- remove = functions.triminout(strip, sin, sout)
- if remove is True:
- bpy.ops.sequencer.delete()
-
- # select all strips again
- for strip in strips:
- try:
- strip.select = True
- except ReferenceError:
- pass
-
- bpy.ops.sequencer.reload()
-
- return {'FINISHED'}
-
-
-# SOURCE IN OUT
-class OBJECT_OT_Sourcein(Operator): # Operator source in
- bl_label = "Source IN"
- bl_idname = "sequencerextra.sourcein"
- bl_description = "Add or move a marker named IN"
- bl_options = {'REGISTER', 'UNDO'}
-
- @classmethod
- def poll(self, context):
- scn = context.scene
- if scn:
- return scn.sequence_editor
- else:
- return False
-
- def execute(self, context):
- functions.initSceneProperties(context)
- scn = context.scene
- markers = scn.timeline_markers
-
- if scn.kr_auto_markers:
- scn.kr_in_marker = scn.frame_current
-
- else:
- scn.kr_in_marker = scn.frame_current
- if "IN" in markers:
- mark = markers["IN"]
- mark.frame = scn.kr_in_marker
- else:
- mark = markers.new(name="IN")
- mark.frame = scn.kr_in_marker
-
- # limit OUT marker position with IN marker
- if scn.kr_in_marker > scn.kr_out_marker:
- scn.kr_out_marker = scn.kr_in_marker
-
- if "OUT" in markers:
- mark = markers["OUT"]
- mark.frame = scn.kr_out_marker
-
- for m in markers:
- m.select = False
- if m.name in {"IN", "OUT"}:
- m.select = True
- bpy.ops.sequencer.reload()
-
- return {'FINISHED'}
-
-
-class OBJECT_OT_Sourceout(Operator): # Operator source out
- bl_label = "Source OUT"
- bl_idname = "sequencerextra.sourceout"
- bl_description = "Add or move a marker named OUT"
- bl_options = {'REGISTER', 'UNDO'}
-
- @classmethod
- def poll(self, context):
- scn = context.scene
- if scn:
- return scn.sequence_editor
- else:
- return False
-
- def execute(self, context):
- scn = context.scene
- functions.initSceneProperties(context)
- markers = scn.timeline_markers
-
- if scn.kr_auto_markers:
- scn.kr_out_marker = scn.frame_current
-
- else:
- scn.kr_out_marker = scn.frame_current
-
- # limit OUT marker position with IN marker
- if scn.kr_out_marker < scn.kr_in_marker:
- scn.kr_out_marker = scn.kr_in_marker
-
- if "OUT" in markers:
- mark = markers["OUT"]
- mark.frame = scn.kr_out_marker
- else:
- mark = markers.new(name="OUT")
- mark.frame = scn.kr_out_marker
-
- for m in markers:
- m.select = False
- if m.name in {"IN", "OUT"}:
- m.select = True
- bpy.ops.sequencer.reload()
- return {'FINISHED'}
-
-
-class OBJECT_OT_Setstartend(Operator): # Operator set start & end
- bl_label = "Set Start and End"
- bl_idname = "sequencerextra.setstartend"
- bl_description = "Set Start and End to IN and OUT marker values"
- bl_options = {'REGISTER', 'UNDO'}
-
- @classmethod
- def poll(self, context):
- scn = context.scene
- markers = scn.timeline_markers
- if "IN" and "OUT" in markers:
- return True
- else:
- return False
-
- def execute(self, context):
- functions.initSceneProperties(context)
- scn = context.scene
- markers = scn.timeline_markers
- sin = markers["IN"]
- sout = markers["OUT"]
- scn.frame_start = sin.frame
- scn.frame_end = sout.frame - 1
- bpy.ops.sequencer.reload()
-
- return {'FINISHED'}
-
-
-# Copy paste
-
-class OBJECT_OT_Metacopy(Operator): # Operator copy source in/out
- bl_label = "Trim and Meta-Copy"
- bl_idname = "sequencerextra.metacopy"
- bl_description = ("Make meta from selected strips, trim it to in / out\n"
- "(if available) and copy it to clipboard")
-
- bl_options = {'REGISTER', 'UNDO'}
-
- def execute(self, context):
- try:
- # redo
- scene = bpy.context.scene
- seq = scene.sequence_editor
- markers = scene.timeline_markers
- strip1 = seq.active_strip
-
- if strip1 is None:
- self.report({'ERROR'}, "No strip selected")
- return {"CANCELLED"}
-
- if "IN" and "OUT" in markers:
- sin = markers["IN"].frame
- sout = markers["OUT"].frame
- bpy.ops.sequencer.meta_make()
- strip2 = seq.active_strip
- functions.triminout(strip2, sin, sout)
- bpy.ops.sequencer.copy()
- bpy.ops.sequencer.meta_separate()
- self.report({'INFO'}, "META2 has been trimmed and copied")
- else:
- bpy.ops.sequencer.meta_make()
- bpy.ops.sequencer.copy()
- bpy.ops.sequencer.meta_separate()
- self.report({'WARNING'}, "No In and Out!! META has been copied")
-
- except Exception as e:
- functions.error_handlers(self,
- "sequencerextra.metacopy", e, "Trim and Meta-Copy")
-
- return {"CANCELLED"}
-
- return {'FINISHED'}
-
-
-class OBJECT_OT_Metapaste(Operator): # Operator paste source in/out
- bl_label = "Paste in current Frame"
- bl_idname = "sequencerextra.metapaste"
- bl_description = "Paste source from clipboard to current frame"
- bl_options = {'REGISTER', 'UNDO'}
-
- def execute(self, context):
- # redo
- scene = bpy.context.scene
- bpy.ops.sequencer.paste()
- bpy.ops.sequencer.snap(frame=scene.frame_current)
- strips = context.selected_editable_sequences
- context.scene.sequence_editor.active_strip = strips[0]
- context.view_layer.update()
-
- return {'FINISHED'}
-
-
-# Operator paste source in/out
-class OBJECT_OT_Unmetatrim(Operator):
- bl_label = "Paste in current Frame"
- bl_idname = "sequencerextra.meta_separate_trim"
- bl_description = "Unmeta and trim the content to meta duration"
- bl_options = {'REGISTER', 'UNDO'}
-
- @classmethod
- def poll(self, context):
- scn = context.scene
- if scn and scn.sequence_editor:
- if scn.sequence_editor.active_strip:
- return scn.sequence_editor.active_strip.type == "META"
- else:
- return False
-
- def execute(self, context):
- scn = context.scene
- seq = scn.sequence_editor
- markers = scn.timeline_markers
-
- # setting in and out around meta
- # while keeping data to restore in and out positions
- strip = seq.active_strip
- sin = strip.frame_start + strip.frame_offset_start
- sout = sin + strip.frame_final_duration
-
- borrarin = False
- borrarout = False
- original_in = 0
- original_out = 0
-
- if "IN" in markers:
- original_in = markers["IN"].frame
- markers["IN"].frame = sin
- else:
- mark = markers.new(name="IN")
- mark.frame = sin
- borrarin = True
-
- if "OUT" in markers:
- original_out = markers["OUT"].frame
- markers["OUT"].frame = sout
- else:
- mark = markers.new(name="OUT")
- mark.frame = sout
- borrarout = True
-
- # here starts the operator...
-
- # get all META from selected strips
- metastrips = []
- for i in context.selected_editable_sequences:
- if i.type == "META":
- metastrips.append(i)
-
- for meta in metastrips:
- bpy.ops.sequencer.reload()
-
- # deselect all strips
- for i in context.selected_editable_sequences:
- i.select = False
-
- # make active current meta
- meta.select = True
- seq.active_strip = meta
- bpy.ops.sequencer.reload()
-
- # set in and out to meta
- sin = meta.frame_start + meta.frame_offset_start
- sout = sin + meta.frame_final_duration
- # print("meta: ", sin, sout)
-
- # grab meta content
- newstrips = []
- for i in meta.sequences:
- newstrips.append(i)
-
- # store meta channel
- basechan = meta.channel
- # look for upper and lower channels used by strips inside the meta
- lowerchan = 32
- upperchan = 0
- for i in newstrips:
- if i.channel < lowerchan:
- lowerchan = i.channel
- if i.channel > upperchan:
- upperchan = i.channel
-
- # calculate channel increment needed
- deltachan = basechan - lowerchan
- # reorder strips inside the meta
- # before separate we need to store channel data
- delta = upperchan - lowerchan + 1
- for i in newstrips:
- i.channel = i.channel + delta
- chandict = {}
- for i in newstrips:
- i.channel = i.channel + deltachan - delta
- chandict[i.name] = i.channel
-
- """
- for i in chandict:
- print(i, chandict[i])
- """
- # go inside meta to trim strips
- bpy.ops.sequencer.meta_toggle()
-
- # update seq definition according to meta
- meta_level = len(seq.meta_stack)
- if meta_level > 0:
- seq = seq.meta_stack[meta_level - 1]
-
- # create a list to store clips outside selection
- # that will be removed
- rmlist = []
-
- # deselect all separated strips
- for j in newstrips:
- j.select = False
- # print("newstrips: ",j.name, j.type)
-
- # trim each strip separately
- # first check special strips:
- # (those who can move when any other does)
- for i in newstrips:
- if i.type in {"CROSS", "SPEED", "WIPE"}:
- i.select = True
- remove = functions.triminout(i, sin, sout)
- if remove is True:
- # print("checked: ",i.name, i.type)
- rmlist.append(i)
- i.select = False
-
- # now for the rest of strips
- for i in newstrips:
- i.select = True
- remove = functions.triminout(i, sin, sout)
- if remove is True:
- # print("checked: ",i.name, i.type)
- rmlist.append(i)
- i.select = False
-
- # back outside the meta and separate it
- bpy.ops.sequencer.meta_toggle()
- bpy.ops.sequencer.meta_separate()
-
- # reset seq definition
- seq = scn.sequence_editor
-
- # remove strips from outside the meta duration
- for i in rmlist:
- # print("removing: ",i.name, i.type)
- for j in scn.sequence_editor.sequences_all:
- j.select = False
-
- i.select = True
- scn.sequence_editor.active_strip = i
- bpy.ops.sequencer.delete()
-
- # select all strips and set one of the strips as active
- for i in newstrips:
- if i not in rmlist:
- i.select = True
- scn.sequence_editor.active_strip = i
-
- bpy.ops.sequencer.reload()
-
- # restore original IN and OUT values
- if borrarin:
- markers.remove(markers['IN'])
- else:
- markers["IN"].frame = original_in
- if borrarout:
- markers.remove(markers['OUT'])
- else:
- markers["OUT"].frame = original_out
- scn.update()
-
- return {'FINISHED'}
-
-
-class OBJECT_OT_Extrasnap(Operator): # Operator paste source in/out
- bl_label = "Extra Snap"
- bl_idname = "sequencerextra.extrasnap"
- bl_description = "Snap the right, center or left of the strip to current frame"
- bl_options = {'REGISTER', 'UNDO'}
-
- # align: 0 = left snap, 1 = center snap, 2= right snap
- align: IntProperty(
- name="Align",
- min=0, max=2,
- default=1
- )
-
- @classmethod
- def poll(self, context):
- scn = context.scene
- if scn and scn.sequence_editor:
- return scn.sequence_editor.active_strip
- else:
- return False
-
- def execute(self, context):
- scene = bpy.context.scene
- bpy.ops.sequencer.snap(frame=scene.frame_current)
-
- if self.align != 0:
- strips = context.selected_editable_sequences
- for strip in strips:
- if self.align == 1: # center snap
- strip.frame_start -= strip.frame_final_duration / 2
- else: # right snap
- strip.frame_start -= strip.frame_final_duration
-
- return {'FINISHED'}
-
-
-class OBJECT_OT_Extrahandles(Operator): # Operator paste source in/out
- bl_label = "Extra Handles"
- bl_idname = "sequencerextra.extrahandles"
- bl_description = "Snap the right, center or left of the strip to current frame"
- bl_options = {'REGISTER', 'UNDO'}
-
- # side: 0 = left , 1 = both, 2= right
- side: IntProperty(
- name="Side",
- min=0, max=2,
- default=1
- )
-
- @classmethod
- def poll(self, context):
- scn = context.scene
- if scn and scn.sequence_editor:
- return scn.sequence_editor.active_strip
- else:
- return False
-
- def execute(self, context):
- strips = context.selected_editable_sequences
-
- resetLeft = False
- resetRight = False
- changelistLeft = []
- changelistRight = []
-
- for strip in strips:
- if self.side == 0 or self.side == 1:
- if strip.select_left_handle:
- resetLeft = True
- changelistLeft.append(strip)
- if self.side == 1 or self.side == 2:
- if strip.select_right_handle:
- resetRight = True
- changelistRight.append(strip)
-
- if len(changelistLeft) == len(strips):
- resetLeft = False
-
- if len(changelistRight) == len(strips):
- resetRight = False
-
- if ((len(changelistRight) != len(strips)) or
- (len(changelistRight) != len(strips))) and \
- self.side == 1:
- resetLeft = True
- resetRight = True
-
- for strip in strips:
- if resetLeft:
- strip.select_left_handle = False
-
- if self.side == 0 or self.side == 1:
- if strip.select_left_handle:
- strip.select_left_handle = False
- else:
- strip.select_left_handle = True
-
- if resetRight:
- strip.select_right_handle = False
-
- if self.side == 1 or self.side == 2:
- if strip.select_right_handle:
- strip.select_right_handle = False
- else:
- strip.select_right_handle = True
-
- return {'FINISHED'}
-
-
-@persistent
-def marker_handler(scn):
- context = bpy.context
- functions.initSceneProperties(context)
-
- if scn.kr_auto_markers:
- markers = scn.timeline_markers
-
- if "IN" in markers:
- mark = markers["IN"]
- mark.frame = scn.kr_in_marker
- else:
- mark = markers.new(name="IN")
- mark.frame = scn.kr_in_marker
-
- if "OUT" in markers:
- mark = markers["OUT"]
- mark.frame = scn.kr_out_marker
- else:
- mark = markers.new(name="OUT")
- mark.frame = scn.kr_out_marker
-
- # limit OUT marker position with IN marker
- if scn.kr_in_marker > scn.kr_out_marker:
- scn.kr_out_marker = scn.kr_in_marker
-
- return {'FINISHED'}
- else:
- return {'CANCELLED'}
-
-
-bpy.app.handlers.scene_update_post.append(marker_handler)
diff --git a/sequencer_kinoraw_tools/operators_extra_actions.py b/sequencer_kinoraw_tools/operators_extra_actions.py
deleted file mode 100644
index 8a060acb..00000000
--- a/sequencer_kinoraw_tools/operators_extra_actions.py
+++ /dev/null
@@ -1,1302 +0,0 @@
-# ##### 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 #####
-
-import bpy
-import os
-from bpy.types import Operator
-from bpy.props import (
- IntProperty,
- FloatProperty,
- EnumProperty,
- BoolProperty,
- )
-from . import functions
-
-
-# Skip one second
-class Sequencer_Extra_FrameSkip(Operator):
- bl_label = "Skip One Second"
- bl_idname = "screenextra.frame_skip"
- bl_description = "Skip through the Timeline by one-second increments"
- bl_options = {'REGISTER', 'UNDO'}
-
- back: BoolProperty(
- name="Back",
- default=False
- )
-
- def execute(self, context):
- one_second = bpy.context.scene.render.fps
- if self.back is True:
- one_second *= -1
- bpy.ops.screen.frame_offset(delta=one_second)
-
- return {'FINISHED'}
-
-
-# Trim timeline
-class Sequencer_Extra_TrimTimeline(Operator):
- bl_label = "Trim to Timeline Content"
- bl_idname = "timeextra.trimtimeline"
- bl_description = "Automatically set start and end frames"
- bl_options = {'REGISTER', 'UNDO'}
-
- @classmethod
- def poll(self, context):
- scn = context.scene
- if scn and scn.sequence_editor:
- return scn.sequence_editor.sequences
- else:
- return False
-
- def execute(self, context):
- scn = context.scene
- seq = scn.sequence_editor
- meta_level = len(seq.meta_stack)
- if meta_level > 0:
- seq = seq.meta_stack[meta_level - 1]
-
- frame_start = 300000
- frame_end = -300000
- for i in seq.sequences:
- try:
- if i.frame_final_start < frame_start:
- frame_start = i.frame_final_start
- if i.frame_final_end > frame_end:
- frame_end = i.frame_final_end - 1
- except AttributeError:
- pass
-
- if frame_start != 300000:
- scn.frame_start = frame_start
- if frame_end != -300000:
- scn.frame_end = frame_end
-
- bpy.ops.sequencer.view_all()
-
- return {'FINISHED'}
-
-
-# Trim timeline to selection
-class Sequencer_Extra_TrimTimelineToSelection(Operator):
- bl_label = "Trim to Selection"
- bl_idname = "timeextra.trimtimelinetoselection"
- bl_description = "Set start and end frames to selection"
- bl_options = {'REGISTER', 'UNDO'}
-
- @classmethod
- def poll(self, context):
- scn = context.scene
- if scn and scn.sequence_editor:
- return scn.sequence_editor.sequences
- else:
- return False
-
- def execute(self, context):
- scn = context.scene
- seq = scn.sequence_editor
- meta_level = len(seq.meta_stack)
- if meta_level > 0:
- seq = seq.meta_stack[meta_level - 1]
-
- frame_start = 300000
- frame_end = -300000
- for i in seq.sequences:
- try:
- if i.frame_final_start < frame_start and i.select is True:
- frame_start = i.frame_final_start
- if i.frame_final_end > frame_end and i.select is True:
- frame_end = i.frame_final_end - 1
- except AttributeError:
- pass
-
- if frame_start != 300000:
- scn.frame_start = frame_start
- if frame_end != -300000:
- scn.frame_end = frame_end
-
- bpy.ops.sequencer.view_selected()
- return {'FINISHED'}
-
-
-# Open image with editor and create movie clip strip
-"""
- When a movie or image strip is selected, this operator creates a movieclip
- or find the correspondent movieclip that already exists for this footage,
- and add a VSE clip strip with same cuts the original strip has.
- It can convert movie strips and image sequences, both with hard cuts or
- soft cuts.
-"""
-
-
-class Sequencer_Extra_CreateMovieclip(Operator):
- bl_label = "Create a Movieclip from selected strip"
- bl_idname = "sequencerextra.createmovieclip"
- bl_description = "Create a Movieclip strip from a MOVIE or IMAGE strip"
-
- @classmethod
- def poll(self, context):
- strip = functions.act_strip(context)
- scn = context.scene
- if scn and scn.sequence_editor and scn.sequence_editor.active_strip:
- return strip.type in ('MOVIE', 'IMAGE')
- else:
- return False
-
- def execute(self, context):
- strip = functions.act_strip(context)
- scn = context.scene
-
- if strip.type == 'MOVIE':
- path = strip.filepath
- data_exists = False
-
- for i in bpy.data.movieclips:
- if i.filepath == path:
- data_exists = True
- data = i
- newstrip = None
- if data_exists is False:
- try:
- data = bpy.data.movieclips.load(filepath=path)
- newstrip = bpy.ops.sequencer.movieclip_strip_add(
- replace_sel=True, overlap=False,
- clip=data.name
- )
- newstrip = functions.act_strip(context)
- newstrip.frame_start = strip.frame_start\
- - strip.animation_offset_start
- tin = strip.frame_offset_start + strip.frame_start
- tout = tin + strip.frame_final_duration
- # print(newstrip.frame_start, strip.frame_start, tin, tout)
- functions.triminout(newstrip, tin, tout)
- except:
- self.report({'ERROR_INVALID_INPUT'}, 'Error loading file')
- return {'CANCELLED'}
-
- else:
- try:
- newstrip = bpy.ops.sequencer.movieclip_strip_add(
- replace_sel=True, overlap=False,
- clip=data.name
- )
- newstrip = functions.act_strip(context)
- newstrip.frame_start = strip.frame_start\
- - strip.animation_offset_start
- # i need to declare the strip this way in order
- # to get triminout() working
- clip = bpy.context.scene.sequence_editor.sequences[
- newstrip.name
- ]
- # i cannot change these movie clip attributes via scripts
- # but it works in the python console...
- # clip.animation_offset_start = strip.animation.offset_start
- # clip.animation_offset_end = strip.animation.offset_end
- # clip.frame_final_duration = strip.frame_final_duration
- tin = strip.frame_offset_start + strip.frame_start
- tout = tin + strip.frame_final_duration
- # print(newstrip.frame_start, strip.frame_start, tin, tout)
- functions.triminout(clip, tin, tout)
- except:
- self.report({'ERROR_INVALID_INPUT'}, 'Error loading file')
- return {'CANCELLED'}
-
- elif strip.type == 'IMAGE':
- # print("image")
- base_dir = bpy.path.abspath(strip.directory)
- scn.frame_current = strip.frame_start - strip.animation_offset_start
-
- # searching for the first frame of the sequencer. This is mandatory
- # for hard cutted sequence strips to be correctly converted,
- # avoiding to create a new movie clip if not needed
- filename = sorted(os.listdir(base_dir))[0]
- path = os.path.join(base_dir, filename)
- # print(path)
- data_exists = False
- for i in bpy.data.movieclips:
- # print(i.filepath, path)
- if i.filepath == path:
- data_exists = True
- data = i
- # print(data_exists)
- if data_exists is False:
- try:
- data = bpy.data.movieclips.load(filepath=path)
- newstrip = bpy.ops.sequencer.movieclip_strip_add(
- replace_sel=True, overlap=False,
- clip=data.name
- )
- newstrip = functions.act_strip(context)
- newstrip.frame_start = strip.frame_start\
- - strip.animation_offset_start
- clip = bpy.context.scene.sequence_editor.sequences[
- newstrip.name
- ]
- tin = strip.frame_offset_start + strip.frame_start
- tout = tin + strip.frame_final_duration
- # print(newstrip.frame_start, strip.frame_start, tin, tout)
- functions.triminout(clip, tin, tout)
- except:
- self.report({'ERROR_INVALID_INPUT'}, 'Error loading file')
- return {'CANCELLED'}
- else:
- try:
- newstrip = bpy.ops.sequencer.movieclip_strip_add(
- replace_sel=True, overlap=False,
- clip=data.name
- )
- newstrip = functions.act_strip(context)
- newstrip.frame_start = strip.frame_start\
- - strip.animation_offset_start
- # need to declare the strip this way in order
- # to get triminout() working
- clip = bpy.context.scene.sequence_editor.sequences[
- newstrip.name
- ]
- # cannot change this attributes via scripts...
- # but it works in the python console...
- # clip.animation_offset_start = strip.animation.offset_start
- # clip.animation_offset_end = strip.animation.offset_end
- # clip.frame_final_duration = strip.frame_final_duration
- tin = strip.frame_offset_start + strip.frame_start
- tout = tin + strip.frame_final_duration
- # print(newstrip.frame_start, strip.frame_start, tin, tout)
- functions.triminout(clip, tin, tout)
- except:
- self.report({'ERROR_INVALID_INPUT'}, 'Error loading file')
- return {'CANCELLED'}
-
- # show the new clip in a movie clip editor, if available.
- if strip.type == 'MOVIE' or 'IMAGE':
- for a in context.window.screen.areas:
- if a.type == 'CLIP_EDITOR':
- a.spaces[0].clip = data
-
- return {'FINISHED'}
-
-
-# Open image with editor
-class Sequencer_Extra_Edit(Operator):
- bl_label = "Open with Editor"
- bl_idname = "sequencerextra.edit"
- bl_description = "Open with Movie Clip or Image Editor"
-
- @classmethod
- def poll(self, context):
- strip = functions.act_strip(context)
- scn = context.scene
- if scn and scn.sequence_editor and scn.sequence_editor.active_strip:
- return strip.type in ('MOVIE', 'IMAGE')
- else:
- return False
-
- def execute(self, context):
- strip = functions.act_strip(context)
- scn = context.scene
- data_exists = False
-
- if strip.type == 'MOVIE':
- path = strip.filepath
-
- for i in bpy.data.movieclips:
- if i.filepath == path:
- data_exists = True
- data = i
-
- if data_exists is False:
- try:
- data = bpy.data.movieclips.load(filepath=path)
- except:
- self.report({'ERROR_INVALID_INPUT'}, "Error loading file")
- return {'CANCELLED'}
-
- elif strip.type == 'IMAGE':
- base_dir = bpy.path.abspath(strip.directory)
- strip_elem = strip.strip_elem_from_frame(scn.frame_current)
- elem_name = strip_elem.filename
- path = base_dir + elem_name
-
- for i in bpy.data.images:
- if i.filepath == path:
- data_exists = True
- data = i
-
- if data_exists is False:
- try:
- data = bpy.data.images.load(filepath=path)
- except:
- self.report({'ERROR_INVALID_INPUT'}, 'Error loading file')
- return {'CANCELLED'}
-
- if strip.type == 'MOVIE':
- for a in context.window.screen.areas:
- if a.type == 'CLIP_EDITOR':
- a.spaces[0].clip = data
- elif strip.type == 'IMAGE':
- for a in context.window.screen.areas:
- if a.type == 'IMAGE_EDITOR':
- a.spaces[0].image = data
-
- return {'FINISHED'}
-
-
-# Open image with external editor
-class Sequencer_Extra_EditExternally(Operator):
- bl_label = "Open with External Editor"
- bl_idname = "sequencerextra.editexternally"
- bl_description = "Open with the default external image editor"
-
- @classmethod
- def poll(self, context):
- strip = functions.act_strip(context)
- scn = context.scene
- if scn and scn.sequence_editor and scn.sequence_editor.active_strip:
- return strip.type == 'IMAGE'
- else:
- return False
-
- def execute(self, context):
- strip = functions.act_strip(context)
- scn = context.scene
- base_dir = bpy.path.abspath(strip.directory)
- strip_elem = strip.strip_elem_from_frame(scn.frame_current)
- path = base_dir + strip_elem.filename
-
- try:
- bpy.ops.image.external_edit(filepath=path)
- except:
- self.report({'ERROR_INVALID_INPUT'},
- "Please specify an Image Editor in Preferences > File")
- return {'CANCELLED'}
-
- return {'FINISHED'}
-
-
-# File name to strip name
-class Sequencer_Extra_FileNameToStripName(Operator):
- bl_label = "File Name to Selected Strips Name"
- bl_idname = "sequencerextra.striprename"
- bl_description = "Set strip name to input file name"
- bl_options = {'REGISTER', 'UNDO'}
-
- @classmethod
- def poll(self, context):
- scn = context.scene
- if scn and scn.sequence_editor:
- return scn.sequence_editor.sequences
- else:
- return False
-
- def execute(self, context):
- scn = context.scene
- seq = scn.sequence_editor
- meta_level = len(seq.meta_stack)
- if meta_level > 0:
- seq = seq.meta_stack[meta_level - 1]
- selection = False
- for i in seq.sequences:
- if i.select is True:
- if i.type == 'IMAGE' and not i.mute:
- selection = True
- i.name = i.elements[0].filename
- if (i.type == 'SOUND' or i.type == 'MOVIE') and not i.mute:
- selection = True
- i.name = bpy.path.display_name_from_filepath(i.filepath)
- if selection is False:
- self.report({'ERROR_INVALID_INPUT'},
- "No image or movie strip selected")
- return {'CANCELLED'}
- return {'FINISHED'}
-
-
-# Navigate up
-class Sequencer_Extra_NavigateUp(Operator):
- bl_label = "Navigate Up"
- bl_idname = "sequencerextra.navigateup"
- bl_description = "Move to Parent Timeline"
-
- @classmethod
- def poll(self, context):
- try:
- if context.scene.sequence_editor.meta_stack:
- return True
- return False
- except:
- return False
-
- def execute(self, context):
- if (functions.act_strip(context)):
- strip = functions.act_strip(context)
- seq_type = strip.type
- if seq_type == 'META':
- context.scene.sequence_editor.active_strip = None
-
- bpy.ops.sequencer.meta_toggle()
- return {'FINISHED'}
-
-
-# Ripple delete
-class Sequencer_Extra_RippleDelete(Operator):
- bl_label = "Ripple Delete"
- bl_idname = "sequencerextra.rippledelete"
- bl_description = "Delete a strip and shift back following ones"
- bl_options = {'REGISTER', 'UNDO'}
-
- @classmethod
- def poll(self, context):
- scn = context.scene
- if scn and scn.sequence_editor and scn.sequence_editor.active_strip:
- return True
- else:
- return False
-
- def execute(self, context):
- scn = context.scene
- seq = scn.sequence_editor
- meta_level = len(seq.meta_stack)
- if meta_level > 0:
- seq = seq.meta_stack[meta_level - 1]
- # strip = functions.act_strip(context)
- for strip in context.selected_editable_sequences:
- cut_frame = strip.frame_final_start
- next_edit = 300000
- bpy.ops.sequencer.select_all(action='DESELECT')
- strip.select = True
- bpy.ops.sequencer.delete()
- striplist = []
- for i in seq.sequences:
- try:
- if (i.frame_final_start > cut_frame and
- not i.mute):
- if i.frame_final_start < next_edit:
- next_edit = i.frame_final_start
- if not i.mute:
- striplist.append(i)
- except AttributeError:
- pass
-
- if next_edit == 300000:
- return {'FINISHED'}
- ripple_length = next_edit - cut_frame
- for i in range(len(striplist)):
- str = striplist[i]
- try:
- if str.frame_final_start > cut_frame:
- str.frame_start = str.frame_start - ripple_length
- except AttributeError:
- pass
- bpy.ops.sequencer.reload()
- return {'FINISHED'}
-
-
-# Ripple cut
-class Sequencer_Extra_RippleCut(Operator):
- bl_label = "Ripple Cut"
- bl_idname = "sequencerextra.ripplecut"
- bl_description = "Move a strip to buffer and shift back following ones"
- bl_options = {'REGISTER', 'UNDO'}
-
- @classmethod
- def poll(self, context):
- scn = context.scene
- if scn and scn.sequence_editor and scn.sequence_editor.active_strip:
- return True
- else:
- return False
-
- def execute(self, context):
- scn = context.scene
- seq = scn.sequence_editor
- meta_level = len(seq.meta_stack)
- if meta_level > 0:
- seq = seq.meta_stack[meta_level - 1]
- strip = functions.act_strip(context)
- bpy.ops.sequencer.select_all(action='DESELECT')
- strip.select = True
- temp_cf = scn.frame_current
- scn.frame_current = strip.frame_final_start
- bpy.ops.sequencer.copy()
- scn.frame_current = temp_cf
-
- bpy.ops.sequencerextra.rippledelete()
- return {'FINISHED'}
-
-
-# Insert
-class Sequencer_Extra_Insert(Operator):
- bl_label = "Insert"
- bl_idname = "sequencerextra.insert"
- bl_description = ("Move active strip to current frame and shift "
- "forward following ones")
- bl_options = {'REGISTER', 'UNDO'}
-
- singlechannel: BoolProperty(
- name="Single Channel",
- default=False
- )
-
- @classmethod
- def poll(self, context):
- scn = context.scene
- if scn and scn.sequence_editor and scn.sequence_editor.active_strip:
- return True
- else:
- return False
-
- def execute(self, context):
- scn = context.scene
- seq = scn.sequence_editor
- meta_level = len(seq.meta_stack)
- if meta_level > 0:
- seq = seq.meta_stack[meta_level - 1]
- strip = functions.act_strip(context)
- gap = strip.frame_final_duration
- bpy.ops.sequencer.select_all(action='DESELECT')
- current_frame = scn.frame_current
-
- striplist = []
- for i in seq.sequences:
- try:
- if (i.frame_final_start >= current_frame and
- not i.mute):
- if self.singlechannel is True:
- if i.channel == strip.channel:
- striplist.append(i)
- else:
- striplist.append(i)
- except AttributeError:
- pass
- try:
- bpy.ops.sequencerextra.selectcurrentframe('EXEC_DEFAULT',
- mode='AFTER')
- except:
- self.report({'ERROR_INVALID_INPUT'}, "Execution Error, "
- "check your Blender version")
- return {'CANCELLED'}
-
- for i in range(len(striplist)):
- str = striplist[i]
- try:
- if str.select is True:
- str.frame_start += gap
- except AttributeError:
- pass
- try:
- diff = current_frame - strip.frame_final_start
- strip.frame_start += diff
- except AttributeError:
- pass
-
- strip = functions.act_strip(context)
- scn.frame_current += strip.frame_final_duration
- bpy.ops.sequencer.reload()
-
- return {'FINISHED'}
-
-
-# Copy strip properties
-class Sequencer_Extra_CopyProperties(Operator):
- bl_label = "Copy Properties"
- bl_idname = "sequencerextra.copyproperties"
- bl_description = "Copy properties of active strip to selected strips"
- bl_options = {'REGISTER', 'UNDO'}
-
- prop: EnumProperty(
- name="Property",
- items=[
- # common
- ('name', 'Name', ''),
- ('blend_alpha', 'Opacity', ''),
- ('blend_type', 'Blend Mode', ''),
- ('animation_offset', 'Input - Trim Duration', ''),
- # non-sound
- ('use_translation', 'Input - Image Offset', ''),
- ('crop', 'Input - Image Crop', ''),
- ('proxy', 'Proxy / Timecode', ''),
- ('strobe', 'Filter - Strobe', ''),
- ('color_multiply', 'Filter - Multiply', ''),
- ('color_saturation', 'Filter - Saturation', ''),
- ('deinterlace', 'Filter - De-Interlace', ''),
- ('flip', 'Filter - Flip', ''),
- ('float', 'Filter - Convert Float', ''),
- ('alpha_mode', 'Filter - Alpha Mode', ''),
- ('reverse', 'Filter - Backwards', ''),
- # sound
- ('pan', 'Sound - Pan', ''),
- ('pitch', 'Sound - Pitch', ''),
- ('volume', 'Sound - Volume', ''),
- ('cache', 'Sound - Caching', ''),
- # image
- ('directory', 'Image - Directory', ''),
- # movie
- ('mpeg_preseek', 'Movie - MPEG Preseek', ''),
- ('stream_index', 'Movie - Stream Index', ''),
- # wipe
- ('wipe', 'Effect - Wipe', ''),
- # transform
- ('transform', 'Effect - Transform', ''),
- # color
- ('color', 'Effect - Color', ''),
- # speed
- ('speed', 'Effect - Speed', ''),
- # multicam
- ('multicam_source', 'Effect - Multicam Source', ''),
- # effect
- ('effect_fader', 'Effect - Effect Fader', ''),
- ],
- default='blend_alpha'
- )
-
- @classmethod
- def poll(self, context):
- scn = context.scene
- if scn and scn.sequence_editor and scn.sequence_editor.active_strip:
- return True
- else:
- return False
-
- def execute(self, context):
- strip = functions.act_strip(context)
-
- scn = context.scene
- seq = scn.sequence_editor
- meta_level = len(seq.meta_stack)
- if meta_level > 0:
- seq = seq.meta_stack[meta_level - 1]
-
- for i in seq.sequences:
- if (i.select is True and not i.mute):
- try:
- if self.prop == 'name':
- i.name = strip.name
- elif self.prop == 'blend_alpha':
- i.blend_alpha = strip.blend_alpha
- elif self.prop == 'blend_type':
- i.blend_type = strip.blend_type
- elif self.prop == 'animation_offset':
- i.animation_offset_start = strip.animation_offset_start
- i.animation_offset_end = strip.animation_offset_end
- elif self.prop == 'use_translation':
- i.use_translation = strip.use_translation
- i.transform.offset_x = strip.transform.offset_x
- i.transform.offset_y = strip.transform.offset_y
- elif self.prop == 'crop':
- i.use_crop = strip.use_crop
- i.crop.min_x = strip.crop.min_x
- i.crop.min_y = strip.crop.min_y
- i.crop.max_x = strip.crop.max_x
- i.crop.max_y = strip.crop.max_y
- elif self.prop == 'proxy':
- i.use_proxy = strip.use_proxy
- p = strip.proxy.use_proxy_custom_directory # pep80
- i.proxy.use_proxy_custom_directory = p
- i.proxy.use_proxy_custom_file = strip.proxy.use_proxy_custom_file
- i.proxy.build_100 = strip.proxy.build_100
- i.proxy.build_25 = strip.proxy.build_25
- i.proxy.build_50 = strip.proxy.build_50
- i.proxy.build_75 = strip.proxy.build_75
- i.proxy.directory = strip.proxy.directory
- i.proxy.filepath = strip.proxy.filepath
- i.proxy.quality = strip.proxy.quality
- i.proxy.timecode = strip.proxy.timecode
- i.proxy.use_overwrite = strip.proxy.use_overwrite
- elif self.prop == 'strobe':
- i.strobe = strip.strobe
- elif self.prop == 'color_multiply':
- i.color_multiply = strip.color_multiply
- elif self.prop == 'color_saturation':
- i.color_saturation = strip.color_saturation
- elif self.prop == 'deinterlace':
- i.use_deinterlace = strip.use_deinterlace
- elif self.prop == 'flip':
- i.use_flip_x = strip.use_flip_x
- i.use_flip_y = strip.use_flip_y
- elif self.prop == 'float':
- i.use_float = strip.use_float
- elif self.prop == 'alpha_mode':
- i.alpha_mode = strip.alpha_mode
- elif self.prop == 'reverse':
- i.use_reverse_frames = strip.use_reverse_frames
- elif self.prop == 'pan':
- i.pan = strip.pan
- elif self.prop == 'pitch':
- i.pitch = strip.pitch
- elif self.prop == 'volume':
- i.volume = strip.volume
- elif self.prop == 'cache':
- i.use_memory_cache = strip.use_memory_cache
- elif self.prop == 'directory':
- i.directory = strip.directory
- elif self.prop == 'mpeg_preseek':
- i.mpeg_preseek = strip.mpeg_preseek
- elif self.prop == 'stream_index':
- i.stream_index = strip.stream_index
- elif self.prop == 'wipe':
- i.angle = strip.angle
- i.blur_width = strip.blur_width
- i.direction = strip.direction
- i.transition_type = strip.transition_type
- elif self.prop == 'transform':
- i.interpolation = strip.interpolation
- i.rotation_start = strip.rotation_start
- i.use_uniform_scale = strip.use_uniform_scale
- i.scale_start_x = strip.scale_start_x
- i.scale_start_y = strip.scale_start_y
- i.translation_unit = strip.translation_unit
- i.translate_start_x = strip.translate_start_x
- i.translate_start_y = strip.translate_start_y
- elif self.prop == 'color':
- i.color = strip.color
- elif self.prop == 'speed':
- i.use_default_fade = strip.use_default_fade
- i.speed_factor = strip.speed_factor
- i.use_as_speed = strip.use_as_speed
- i.scale_to_length = strip.scale_to_length
- i.multiply_speed = strip.multiply_speed
- i.use_frame_blend = strip.use_frame_blend
- elif self.prop == 'multicam_source':
- i.multicam_source = strip.multicam_source
- elif self.prop == 'effect_fader':
- i.use_default_fade = strip.use_default_fade
- i.effect_fader = strip.effect_fader
- except:
- pass
-
- bpy.ops.sequencer.reload()
- return {'FINISHED'}
-
-
-# Fade in and out
-class Sequencer_Extra_FadeInOut(Operator):
- bl_idname = "sequencerextra.fadeinout"
- bl_label = "Fade..."
- bl_description = "Fade volume or opacity of active strip"
- bl_options = {'REGISTER', 'UNDO'}
-
- mode: EnumProperty(
- name='Direction',
- items=(
- ('IN', "Fade In...", ""),
- ('OUT', "Fade Out...", ""),
- ('INOUT', "Fade In and Out...", "")),
- default='IN',
- )
-
- fade_duration: IntProperty(
- name='Duration',
- description='Number of frames to fade',
- min=1, max=250,
- default=25)
- fade_amount: FloatProperty(
- name='Amount',
- description='Maximum value of fade',
- min=0.0,
- max=100.0,
- default=1.0)
-
- @classmethod
- def poll(cls, context):
- scn = context.scene
- if scn and scn.sequence_editor and scn.sequence_editor.active_strip:
- return True
- else:
- return False
-
- def execute(self, context):
- seq = context.scene.sequence_editor
- scn = context.scene
- strip = seq.active_strip
- tmp_current_frame = context.scene.frame_current
-
- if strip.type == 'SOUND':
- if(self.mode) == 'OUT':
- scn.frame_current = strip.frame_final_end - self.fade_duration
- strip.volume = self.fade_amount
- strip.keyframe_insert('volume')
- scn.frame_current = strip.frame_final_end
- strip.volume = 0
- strip.keyframe_insert('volume')
- elif(self.mode) == 'INOUT':
- scn.frame_current = strip.frame_final_start
- strip.volume = 0
- strip.keyframe_insert('volume')
- scn.frame_current += self.fade_duration
- strip.volume = self.fade_amount
- strip.keyframe_insert('volume')
- scn.frame_current = strip.frame_final_end - self.fade_duration
- strip.volume = self.fade_amount
- strip.keyframe_insert('volume')
- scn.frame_current = strip.frame_final_end
- strip.volume = 0
- strip.keyframe_insert('volume')
- else:
- scn.frame_current = strip.frame_final_start
- strip.volume = 0
- strip.keyframe_insert('volume')
- scn.frame_current += self.fade_duration
- strip.volume = self.fade_amount
- strip.keyframe_insert('volume')
-
- else:
- if(self.mode) == 'OUT':
- scn.frame_current = strip.frame_final_end - self.fade_duration
- strip.blend_alpha = self.fade_amount
- strip.keyframe_insert('blend_alpha')
- scn.frame_current = strip.frame_final_end
- strip.blend_alpha = 0
- strip.keyframe_insert('blend_alpha')
- elif(self.mode) == 'INOUT':
- scn.frame_current = strip.frame_final_start
- strip.blend_alpha = 0
- strip.keyframe_insert('blend_alpha')
- scn.frame_current += self.fade_duration
- strip.blend_alpha = self.fade_amount
- strip.keyframe_insert('blend_alpha')
- scn.frame_current = strip.frame_final_end - self.fade_duration
- strip.blend_alpha = self.fade_amount
- strip.keyframe_insert('blend_alpha')
- scn.frame_current = strip.frame_final_end
- strip.blend_alpha = 0
- strip.keyframe_insert('blend_alpha')
- else:
- scn.frame_current = strip.frame_final_start
- strip.blend_alpha = 0
- strip.keyframe_insert('blend_alpha')
- scn.frame_current += self.fade_duration
- strip.blend_alpha = self.fade_amount
- strip.keyframe_insert('blend_alpha')
-
- scn.frame_current = tmp_current_frame
-
- scn.kr_default_fade_duration = self.fade_duration
- scn.kr_default_fade_amount = self.fade_amount
- return{'FINISHED'}
-
- def invoke(self, context, event):
- scn = context.scene
- functions.initSceneProperties(context)
- self.fade_duration = scn.kr_default_fade_duration
- self.fade_amount = scn.kr_default_fade_amount
- return context.window_manager.invoke_props_dialog(self)
-
-
-# Extend to fill
-class Sequencer_Extra_ExtendToFill(Operator):
- bl_idname = "sequencerextra.extendtofill"
- bl_label = "Extend to Fill"
- bl_description = "Extend active strip forward to fill adjacent space"
- bl_options = {'REGISTER', 'UNDO'}
-
- @classmethod
- def poll(cls, context):
- scn = context.scene
- if scn and scn.sequence_editor and scn.sequence_editor.active_strip:
- return True
- else:
- return False
-
- def execute(self, context):
- scn = context.scene
- seq = scn.sequence_editor
- meta_level = len(seq.meta_stack)
- if meta_level > 0:
- seq = seq.meta_stack[meta_level - 1]
- strip = functions.act_strip(context)
- chn = strip.channel
- stf = strip.frame_final_end
- enf = 300000
-
- for i in seq.sequences:
- ffs = i.frame_final_start
- if (i.channel == chn and ffs > stf):
- if ffs < enf:
- enf = ffs
- if enf == 300000 and stf < scn.frame_end:
- enf = scn.frame_end
-
- if enf == 300000 or enf == stf:
- self.report({'ERROR_INVALID_INPUT'}, 'Unable to extend')
- return {'CANCELLED'}
- else:
- strip.frame_final_end = enf
-
- bpy.ops.sequencer.reload()
- return {'FINISHED'}
-
-
-# Place from file browser
-class Sequencer_Extra_PlaceFromFileBrowser(Operator):
- bl_label = "Place"
- bl_idname = "sequencerextra.placefromfilebrowser"
- bl_description = "Place or insert active file from File Browser"
- bl_options = {'REGISTER', 'UNDO'}
-
- insert: BoolProperty(
- name="Insert",
- default=False
- )
-
- def execute(self, context):
- scn = context.scene
- for a in context.window.screen.areas:
- if a.type == 'FILE_BROWSER':
- params = a.spaces[0].params
- break
- try:
- params
- except UnboundLocalError:
- self.report({'ERROR_INVALID_INPUT'}, 'No visible File Browser')
- return {'CANCELLED'}
-
- if params.filename == '':
- self.report({'ERROR_INVALID_INPUT'}, 'No file selected')
- return {'CANCELLED'}
-
- path = os.path.join(params.directory, params.filename)
- frame = context.scene.frame_current
- strip_type = functions.detect_strip_type(params.filename)
-
- try:
- if strip_type == 'IMAGE':
- image_file = []
- filename = {"name": params.filename}
- image_file.append(filename)
- f_in = scn.frame_current
- f_out = f_in + scn.render.fps - 1
- bpy.ops.sequencer.image_strip_add(files=image_file,
- directory=params.directory, frame_start=f_in,
- frame_end=f_out, relative_path=False)
- elif strip_type == 'MOVIE':
- bpy.ops.sequencer.movie_strip_add(filepath=path,
- frame_start=frame, relative_path=False)
- elif strip_type == 'SOUND':
- bpy.ops.sequencer.sound_strip_add(filepath=path,
- frame_start=frame, relative_path=False)
- else:
- self.report({'ERROR_INVALID_INPUT'}, 'Invalid file format')
- return {'CANCELLED'}
- except:
- self.report({'ERROR_INVALID_INPUT'}, 'Error loading file')
- return {'CANCELLED'}
-
- if self.insert is True:
- try:
- striplist = []
- for i in bpy.context.selected_editable_sequences:
- if (i.select is True and i.type == "SOUND"):
- striplist.append(i)
- bpy.ops.sequencerextra.insert()
- if striplist[0]:
- striplist[0].frame_start = frame
- except:
- self.report({'ERROR_INVALID_INPUT'}, "Execution Error, "
- "check your Blender version")
- return {'CANCELLED'}
- else:
- strip = functions.act_strip(context)
- scn.frame_current += strip.frame_final_duration
- bpy.ops.sequencer.reload()
-
- return {'FINISHED'}
-
-
-# Select strips on same channel
-class Sequencer_Extra_SelectSameChannel(Operator):
- bl_label = "Select Strips on the Same Channel"
- bl_idname = "sequencerextra.selectsamechannel"
- bl_description = "Select strips on the same channel as active one"
- bl_options = {'REGISTER', 'UNDO'}
-
- @classmethod
- def poll(self, context):
- scn = context.scene
- if scn and scn.sequence_editor and scn.sequence_editor.active_strip:
- return True
- else:
- return False
-
- def execute(self, context):
- scn = context.scene
- seq = scn.sequence_editor
- meta_level = len(seq.meta_stack)
- if meta_level > 0:
- seq = seq.meta_stack[meta_level - 1]
- bpy.ops.sequencer.select_active_side(side="LEFT")
- bpy.ops.sequencer.select_active_side(side="RIGHT")
-
- return {'FINISHED'}
-
-
-# Current-frame-aware select
-class Sequencer_Extra_SelectCurrentFrame(Operator):
- bl_label = "Current-Frame-Aware Select"
- bl_idname = "sequencerextra.selectcurrentframe"
- bl_description = "Select strips according to current frame"
- bl_options = {'REGISTER', 'UNDO'}
-
- mode: EnumProperty(
- name='Mode',
- items=(
- ('BEFORE', 'Before Current Frame', ''),
- ('AFTER', 'After Current Frame', ''),
- ('ON', 'On Current Frame', '')),
- default='BEFORE',
- )
-
- @classmethod
- def poll(self, context):
- scn = context.scene
- if scn and scn.sequence_editor:
- return scn.sequence_editor.sequences
- else:
- return False
-
- def execute(self, context):
- mode = self.mode
- scn = context.scene
- seq = scn.sequence_editor
- cf = scn.frame_current
- meta_level = len(seq.meta_stack)
- if meta_level > 0:
- seq = seq.meta_stack[meta_level - 1]
-
- if mode == 'AFTER':
- for i in seq.sequences:
- try:
- if (i.frame_final_start >= cf and not i.mute):
- i.select = True
- except AttributeError:
- pass
- elif mode == 'ON':
- for i in seq.sequences:
- try:
- if (i.frame_final_start <= cf and
- i.frame_final_end > cf and
- not i.mute):
- i.select = True
- except AttributeError:
- pass
- else:
- for i in seq.sequences:
- try:
- if (i.frame_final_end < cf and not i.mute):
- i.select = True
- except AttributeError:
- pass
-
- return {'FINISHED'}
-
-
-# Select by type
-class Sequencer_Extra_SelectAllByType(Operator):
- bl_label = "All by Type"
- bl_idname = "sequencerextra.select_all_by_type"
- bl_description = "Select all the strips of the same type"
- bl_options = {'REGISTER', 'UNDO'}
-
- type: EnumProperty(
- name="Strip Type",
- items=(
- ('ACTIVE', 'Same as Active Strip', ''),
- ('IMAGE', 'Image', ''),
- ('META', 'Meta', ''),
- ('SCENE', 'Scene', ''),
- ('MOVIE', 'Movie', ''),
- ('SOUND', 'Sound', ''),
- ('TRANSFORM', 'Transform', ''),
- ('COLOR', 'Color', '')),
- default='ACTIVE',
- )
-
- @classmethod
- def poll(self, context):
- scn = context.scene
- if scn and scn.sequence_editor:
- return scn.sequence_editor.sequences
- else:
- return False
-
- def execute(self, context):
- strip_type = self.type
- scn = context.scene
- seq = scn.sequence_editor
- meta_level = len(seq.meta_stack)
- if meta_level > 0:
- seq = seq.meta_stack[meta_level - 1]
- active_strip = functions.act_strip(context)
- if strip_type == 'ACTIVE':
- if active_strip is None:
- self.report({'ERROR_INVALID_INPUT'},
- 'No active strip')
- return {'CANCELLED'}
- strip_type = active_strip.type
-
- striplist = []
- for i in seq.sequences:
- try:
- if (i.type == strip_type and not i.mute):
- striplist.append(i)
- except AttributeError:
- pass
- for i in range(len(striplist)):
- str = striplist[i]
- try:
- str.select = True
- except AttributeError:
- pass
-
- return {'FINISHED'}
-
-
-# Open in movie clip editor from file browser
-class Clip_Extra_OpenFromFileBrowser(Operator):
- bl_label = "Open from File Browser"
- bl_idname = "clipextra.openfromfilebrowser"
- bl_description = "Load a Movie or Image Sequence from File Browser"
- bl_options = {'REGISTER', 'UNDO'}
-
- def execute(self, context):
- for a in context.window.screen.areas:
- if a.type == 'FILE_BROWSER':
- params = a.spaces[0].params
- break
- try:
- params
- except:
- self.report({'ERROR_INVALID_INPUT'}, 'No visible File Browser')
- return {'CANCELLED'}
-
- if params.filename == '':
- self.report({'ERROR_INVALID_INPUT'}, 'No file selected')
- return {'CANCELLED'}
-
- path = params.directory + params.filename
- strip_type = functions.detect_strip_type(params.filename)
- data_exists = False
-
- if strip_type in ('MOVIE', 'IMAGE'):
- for i in bpy.data.movieclips:
- if i.filepath == path:
- data_exists = True
- data = i
-
- if data_exists is False:
- try:
- data = bpy.data.movieclips.load(filepath=path)
- except:
- self.report({'ERROR_INVALID_INPUT'}, 'Error loading file')
- return {'CANCELLED'}
- else:
- self.report({'ERROR_INVALID_INPUT'}, 'Invalid file format')
- return {'CANCELLED'}
-
- for a in context.window.screen.areas:
- if a.type == 'CLIP_EDITOR':
- a.spaces[0].clip = data
-
- return {'FINISHED'}
-
-
-# Open in movie clip editor from sequencer
-class Clip_Extra_OpenActiveStrip(Operator):
- bl_label = "Open Active Strip"
- bl_idname = "clipextra.openactivestrip"
- bl_description = "Load a Movie or Image Sequence from Sequence Editor"
- bl_options = {'REGISTER', 'UNDO'}
-
- @classmethod
- def poll(cls, context):
- scn = context.scene
- strip = functions.act_strip(context)
- if scn and scn.sequence_editor and scn.sequence_editor.active_strip:
- return strip.type in ('MOVIE', 'IMAGE')
- else:
- return False
-
- def execute(self, context):
- strip = functions.act_strip(context)
- data_exists = False
-
- if strip.type == 'MOVIE':
- path = strip.filepath
- elif strip.type == 'IMAGE':
- base_dir = bpy.path.relpath(strip.directory)
- filename = strip.elements[0].filename
- path = base_dir + '/' + filename
- else:
- self.report({'ERROR_INVALID_INPUT'}, 'Invalid file format')
- return {'CANCELLED'}
-
- for i in bpy.data.movieclips:
- if i.filepath == path:
- data_exists = True
- data = i
- if data_exists is False:
- try:
- data = bpy.data.movieclips.load(filepath=path)
- except:
- self.report({'ERROR_INVALID_INPUT'}, 'Error loading file')
- return {'CANCELLED'}
-
- for a in context.window.screen.areas:
- if a.type == 'CLIP_EDITOR':
- a.spaces[0].clip = data
-
- return {'FINISHED'}
-
-
-# Jog / Shuttle
-class Sequencer_Extra_JogShuttle(Operator):
- bl_label = "Jog/Shuttle"
- bl_idname = "sequencerextra.jogshuttle"
- bl_description = ("Jog through the current sequence\n"
- "Left Mouse button to confirm, Right mouse\Esc to cancel")
-
- def execute(self, context):
- scn = context.scene
- start_frame = scn.frame_start
- end_frame = scn.frame_end
- duration = end_frame - start_frame
- diff = self.x - self.init_x
- diff /= 5
- diff = int(diff)
- extended_frame = diff + (self.init_current_frame - start_frame)
- looped_frame = extended_frame % (duration + 1)
- target_frame = start_frame + looped_frame
- context.scene.frame_current = target_frame
-
- def modal(self, context, event):
- if event.type == 'MOUSEMOVE':
- self.x = event.mouse_x
- self.execute(context)
- elif event.type == 'LEFTMOUSE':
- return {'FINISHED'}
- elif event.type in ('RIGHTMOUSE', 'ESC'):
- return {'CANCELLED'}
-
- return {'RUNNING_MODAL'}
-
- def invoke(self, context, event):
- scn = context.scene
- self.x = event.mouse_x
- self.init_x = self.x
- self.init_current_frame = scn.frame_current
- self.execute(context)
- context.window_manager.modal_handler_add(self)
-
- return {'RUNNING_MODAL'}
diff --git a/sequencer_kinoraw_tools/proxy_tools.py b/sequencer_kinoraw_tools/proxy_tools.py
deleted file mode 100644
index ba8c1454..00000000
--- a/sequencer_kinoraw_tools/proxy_tools.py
+++ /dev/null
@@ -1,344 +0,0 @@
-# gpl: authors Carlos Padial, Turi Scandurra
-
-import bpy
-import os
-from bpy.types import (
- Operator,
- Panel,
- )
-from bpy.props import IntProperty
-import subprocess
-from . import functions
-
-
-proxy_qualities = [
- ("1", "25%", ""), ("2", "50%", ""),
- ("3", "75%", ""), ("4", "100%", ""),
- ("5", "none", "")
- ]
-
-
-# Functions
-def setup_proxy(context, strip, size):
- preferences = context.preferences
- prefs = preferences.addons[__package__].preferences
-
- # set up proxy settings
- strip.use_proxy = True
-
- if prefs.use_bi_custom_directory:
- strip.use_proxy_custom_directory = True
- filename = strip.filepath.rpartition("/")[2].rpartition(".")[0]
- strip.proxy.directory = bpy.path.relpath(prefs.proxy_dir + filename)
- else:
- strip.use_proxy_custom_directory = False
-
- if strip.use_proxy_custom_file is True:
- strip.use_proxy_custom_file = False
-
- strip.proxy.quality = prefs.quality
- strip.proxy.timecode = prefs.timecode
-
- if size == 5:
- strip.use_proxy = False
- strip.proxy.build_25 = False
- strip.proxy.build_50 = False
- strip.proxy.build_75 = False
- strip.proxy.build_100 = False
-
- else:
- proxysuffix = proxy_qualities[size - 1][1].split("%")[0]
-
- if (proxysuffix == "25"):
- strip.proxy.build_25 = True
- if (proxysuffix == "50"):
- strip.proxy.build_50 = True
- if (proxysuffix == "75"):
- strip.proxy.build_75 = True
- if (proxysuffix == "100"):
- strip.proxy.build_100 = True
-
- return {"FINISHED"}
-
-
-def create_proxy(context, strip, size, res):
- # calculate proxy resolution
- div = 4 / size
- newres = (int(int(res[0]) / div), int(int(res[1]) / div))
-
- preferences = context.preferences
- proxy_dir = preferences.addons[__package__].preferences.proxy_dir
- scripts = preferences.addons[__package__].preferences.proxy_scripts
- ffmpeg_command = preferences.addons[__package__].preferences.ffmpeg_command
-
- functions.create_folder(proxy_dir)
-
- if scripts:
- commands = []
-
- # get filename
- if strip.type == "MOVIE":
- filename = bpy.path.abspath(strip.filepath)
- proxysuffix = proxy_qualities[size - 1][1].split("%")[0]
- proxy_dir = bpy.path.abspath(proxy_dir)
- newfilename = os.path.join(proxy_dir, filename.rpartition("/")[2])
- fileoutput = newfilename.rpartition(".")[0] + "-" + proxysuffix + ".avi"
-
- # default value for ffmpeg_command = "fmpeg -i {} -vcodec mjpeg -qv 1 -s {}x{} -y {}"
-
- command = ffmpeg_command.format(filename, newres[0], newres[1], fileoutput)
- print(command)
-
- if scripts:
- commands.append(command)
- else:
- # check for existing file
- if not os.path.isfile(fileoutput):
- subprocess.call(command, shell=True)
- else:
- print("File already exists")
-
- # set up proxy settings
- strip.use_proxy = True
- try:
- strip.use_proxy_custom_file = True
- strip.proxy.filepath = bpy.path.relpath(fileoutput)
- except:
- pass
-
- if (proxysuffix == "25"):
- strip.proxy.build_25 = True
- if (proxysuffix == "50"):
- strip.proxy.build_50 = True
- if (proxysuffix == "75"):
- strip.proxy.build_75 = True
- if (proxysuffix == "100"):
- strip.proxy.build_100 = True
-
- if scripts:
- return commands
- else:
- return None
-
-
-def create_proxy_scripts(scripts_dir, commands, strip_name=None):
-
- functions.create_folder(bpy.path.abspath(scripts_dir))
- for i in commands:
- # print(i)
- filename = "{}/proxy_script_{}.sh".format(scripts_dir, strip_name)
- text_file = open(bpy.path.abspath(filename), "w")
- # print(filename)
- text_file.write(i)
- text_file.close()
-
-
-# classes
-class CreateProxyOperator(Operator):
- bl_idname = "sequencer.create_proxy_operator"
- bl_label = "Create Proxy"
- bl_description = ("Use ffmpeg to create a proxy from video\n"
- "and setup proxies for selected strip")
- bl_options = {'REGISTER', 'UNDO'}
-
- size: IntProperty(
- name="Proxy Size",
- default=1
- )
-
- @classmethod
- def poll(self, context):
- strip = functions.act_strip(context)
- scn = context.scene
- if scn and scn.sequence_editor and scn.sequence_editor.active_strip:
- return strip.type in ('MOVIE')
- else:
- return False
-
- def execute(self, context):
- preferences = context.preferences
- proxy_scripts_path = preferences.addons[__package__].preferences.proxy_scripts_path
-
- for strip in context.selected_editable_sequences:
- # get resolution from active strip
- try:
- bpy.ops.sequencerextra.read_exif()
- except:
- pass
-
- sce = context.scene
- try:
- res = sce['metadata'][0]['Composite:ImageSize'].split("x")
- except:
- res = (sce.render.resolution_x, sce.render.resolution_y)
-
- commands = create_proxy(context, strip, self.size, res)
-
- if commands is None:
- # Update view_layer
- context.view_layer.update()
- newstrip = context.scene.sequence_editor.active_strip
-
- # deselect all other strips
- for i in context.selected_editable_sequences:
- if i.name != newstrip.name:
- i.select = False
-
- # Update view_layer
- context.view_layer.update()
- else:
- create_proxy_scripts(proxy_scripts_path, commands, strip.name)
-
- return {'FINISHED'}
-
-
-class CreateBIProxyOperator(Operator):
- bl_idname = "sequencer.create_bi_proxy_operator"
- bl_label = "Create proxy with Blender Internal"
- bl_description = "Use BI system to create a proxy"
- bl_options = {'REGISTER', 'UNDO'}
-
- size: IntProperty(
- name="Proxy Size",
- default=1
- )
-
- @classmethod
- def poll(self, context):
- strip = functions.act_strip(context)
- scn = context.scene
- if scn and scn.sequence_editor and scn.sequence_editor.active_strip:
- return strip.type in ('MOVIE')
- else:
- return False
-
- def execute(self, context):
- try:
- strips = functions.get_selected_strips(context)
-
- for strip in strips:
- # deselect all other strips
- for i in strips:
- i.select = False
- # select current strip
- strip.select = True
- if strip.type == "MOVIE":
- setup_proxy(context, strip, self.size)
- except Exception as e:
- functions.error_handlers(
- self,
- "sequencer.create_bi_proxy_operator", e,
- "Create proxy with blender internal"
- )
- return {"CANCELLED"}
-
- # select all strips again
- for strip in strips:
- try:
- strip.select = True
- except ReferenceError:
- pass
- bpy.ops.sequencer.reload()
-
- return {'FINISHED'}
-
-
-class CreateProxyToolPanel(Panel):
- bl_label = "Proxy Tools"
- bl_idname = "OBJECT_PT_ProxyTool"
- bl_space_type = 'SEQUENCE_EDITOR'
- bl_region_type = 'UI'
-
- @classmethod
- def poll(self, context):
- if context.space_data.view_type in {'SEQUENCER',
- 'SEQUENCER_PREVIEW'}:
- strip = functions.act_strip(context)
- scn = context.scene
- preferences = context.preferences
- prefs = preferences.addons[__package__].preferences
- if scn and scn.sequence_editor and scn.sequence_editor.active_strip:
- if prefs.use_proxy_tools:
- return strip.type in ('MOVIE')
- else:
- return False
-
- def draw_header(self, context):
- layout = self.layout
- layout.label(text="", icon="AUTO")
-
- def draw(self, context):
-
- preferences = context.preferences
- prefs = preferences.addons[__package__].preferences
-
- layout = self.layout
- layout.prop(prefs, "use_internal_proxy", text="Use BI proxy builder")
-
- strip = functions.act_strip(context)
-
- if prefs.use_internal_proxy:
- layout = self.layout
- row = layout.row(align=True)
- row.prop(prefs, "use_bi_custom_directory")
-
- if prefs.use_bi_custom_directory:
- row.prop(prefs, "proxy_dir", text="")
- filename = strip.filepath.rpartition("/")[2].rpartition(".")[0]
- layout.label(text="sample dir: //" + bpy.path.abspath(prefs.proxy_dir + filename))
-
- layout = self.layout
- col = layout.column()
- col.label(text="Build JPEG quality")
- col.prop(prefs, "quality")
-
- if strip.type == 'MOVIE':
- col = layout.column()
- col.label(text="Use timecode index:")
-
- col.prop(prefs, "timecode")
-
- layout = self.layout
- layout.label(text="Setup and create BI proxy:")
- row = layout.row(align=True)
-
- for i in range(4):
- proxysuffix = proxy_qualities[i][1]
- row.operator("sequencer.create_bi_proxy_operator",
- text=proxysuffix).size = i + 1
-
- layout = self.layout
- layout.operator("sequencer.create_bi_proxy_operator",
- text="Clear proxy sizes").size = 5
-
- else:
- layout = self.layout
- layout.prop(prefs, "proxy_dir", text="Path for proxies")
-
- layout = self.layout
- layout.label(text="Create and import proxy from clip:")
- row = layout.row(align=True)
-
- layout = self.layout
- layout.prop(prefs, "ffmpeg_command", text="command")
-
- layout.label(text="{} = filename, with, height, fileoutput")
- label = prefs.ffmpeg_command.format("filename", "with", "height", "fileoutput")
- layout.label(label)
-
- for i in range(4):
- proxysuffix = proxy_qualities[i][1]
- row.operator("sequencer.create_proxy_operator",
- text=proxysuffix).size = i + 1
-
- layout = self.layout
- layout.prop(prefs, "proxy_scripts")
-
- if prefs.proxy_scripts:
- layout = self.layout
- layout.prop(prefs, "proxy_scripts_path", text="Path for scripts")
-
- layout = self.layout
- box = layout.box()
- box.prop(context.space_data, "proxy_render_size")
- box.operator("sequencer.rebuild_proxy", text="Rebuild Proxies and TC")
diff --git a/sequencer_kinoraw_tools/random_editor.py b/sequencer_kinoraw_tools/random_editor.py
deleted file mode 100644
index 654136fd..00000000
--- a/sequencer_kinoraw_tools/random_editor.py
+++ /dev/null
@@ -1,138 +0,0 @@
-# ##### 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 #####
-
-# Note: the Operator LoadRandomEditOperator was removed since is not
-# working. If it is fixed, reimplemented it can be reintroduced later
-
-import bpy
-from bpy.types import (
- Operator,
- Panel,
- )
-from . import functions
-
-
-# classes
-class RandomScratchOperator(Operator):
- bl_idname = "sequencer.randomscratchoperator"
- bl_label = "Random Scratch Operator"
- bl_description = "Random Scratch Operator"
-
- @classmethod
- def poll(self, context):
- strip = functions.act_strip(context)
- scn = context.scene
- if scn and scn.sequence_editor and scn.sequence_editor.active_strip:
- return strip.type in ('META')
- else:
- return False
-
- def invoke(self, context, event):
- preferences = context.preferences
- random_frames = preferences.addons[__package__].preferences.random_frames
-
- sce = context.scene
- seq = sce.sequence_editor
- markers = sce.timeline_markers
-
- if seq:
- strip = seq.active_strip
- if strip is not None:
- if "IN" and "OUT" in markers:
- sin = markers["IN"].frame
- sout = markers["OUT"].frame
-
- # select active strip
- strip = context.scene.sequence_editor.active_strip
- stripname = strip.name
- # collect strip names inside the meta
- stripnames = []
- stripnames.append(strip.name)
- for i in seq.active_strip.sequences:
- stripnames.append(i.name)
- # get strip channel
- channel = strip.channel
- repeat = range(int((sout - sin) / random_frames))
- print(sin, sout, sout - sin, (sout - sin) / random_frames, repeat)
-
- for i in repeat:
- # select all related strips
- for j in stripnames:
- strip = seq.sequences_all[j]
- strip.select = True
- strip = seq.sequences_all[stripname]
- seq.active_strip = strip
- # deselect all other strips
- for j in context.selected_editable_sequences:
- if j.name not in stripnames:
- j.select = False
- a = bpy.ops.sequencer.duplicate_move()
- # select new strip
- newstrip = seq.active_strip
- # deselect all other strips
-
- for j in context.selected_editable_sequences:
- if j.name != newstrip.name:
- j.select = False
- # random cut
- newstrip.frame_start = sin + i * random_frames
- rand = functions.randomframe(newstrip)
- functions.triminout(newstrip, rand, rand + random_frames)
- newstrip.frame_start = i * random_frames + sin - newstrip.frame_offset_start
- newstrip.channel = channel + 1
- else:
- self.report({'WARNING'}, "There is no IN and OUT Markers")
- bpy.ops.sequencer.reload()
-
- return {'FINISHED'}
-
-
-class RandomEditorPanel(Panel):
- bl_label = "Random Editor"
- bl_idname = "OBJECT_PT_RandomEditor"
- bl_space_type = 'SEQUENCE_EDITOR'
- bl_region_type = 'UI'
-
- @classmethod
- def poll(self, context):
- if context.space_data.view_type in {'SEQUENCER',
- 'SEQUENCER_PREVIEW'}:
- strip = functions.act_strip(context)
- scn = context.scene
- preferences = context.preferences
- prefs = preferences.addons[__package__].preferences
- if scn and scn.sequence_editor and scn.sequence_editor.active_strip:
- if prefs.use_random_editor:
- return strip.type in ('META')
- else:
- return False
-
- def draw_header(self, context):
- layout = self.layout
- layout.label(text="", icon="MOD_BUILD")
-
- def draw(self, context):
-
- preferences = context.preferences
- prefs = preferences.addons[__package__].preferences
-
- layout = self.layout
- col = layout.column(align=True)
- col.label(text="Cut duration:")
- col.prop(prefs, "random_frames")
- col.operator("sequencer.randomscratchoperator")
diff --git a/sequencer_kinoraw_tools/recursive_loader.py b/sequencer_kinoraw_tools/recursive_loader.py
deleted file mode 100644
index 07cc1e8e..00000000
--- a/sequencer_kinoraw_tools/recursive_loader.py
+++ /dev/null
@@ -1,266 +0,0 @@
-# ##### 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 #####
-
-import bpy
-import os
-from bpy.types import (
- Operator,
- Panel,
- )
-from bpy.props import (
- EnumProperty,
- BoolProperty,
- )
-from . import functions
-from . import exiftool
-
-
-class Sequencer_Extra_RecursiveLoader(Operator):
- bl_idname = "sequencerextra.recursiveload"
- bl_label = "Recursive Load"
- bl_options = {'REGISTER', 'UNDO'}
-
- recursive: BoolProperty(
- name="Recursive",
- description="Load in recursive folders",
- default=False
- )
- recursive_select_by_extension: BoolProperty(
- name="Select by extension",
- description="Load only clips with selected extension",
- default=False
- )
- ext: EnumProperty(
- items=functions.movieextdict,
- name="Extension",
- default='3'
- )
-
- @classmethod
- def poll(self, context):
- scn = context.scene
- if scn and scn.sequence_editor:
- return (scn.sequence_editor)
- else:
- return False
-
- def invoke(self, context, event):
- scn = context.scene
- try:
- self.recursive = scn.kr_recursive
- self.recursive_select_by_extension = scn.kr_recursive_select_by_extension
- self.ext = scn.kr_default_ext
- except AttributeError:
- functions.initSceneProperties(context)
- self.recursive = scn.kr_recursive
- self.recursive_select_by_extension = scn.kr_recursive_select_by_extension
- self.ext = scn.kr_default_ext
-
- return context.window_manager.invoke_props_dialog(self)
-
- def loader(self, context, filelist):
- scn = context.scene
- if filelist:
- for i in filelist:
- functions.setpathinbrowser(context, i[0], i[1])
- try:
- bpy.ops.sequencerextra.placefromfilebrowser()
- except:
- print("Error loading file (recursive loader error): ", i[1])
- functions.add_marker(context, i[1], scn.frame_current)
- self.report({'ERROR_INVALID_INPUT'}, 'Error loading file ')
- pass
-
- def execute(self, context):
- scn = context.scene
- if self.recursive is True:
- # recursive
- self.loader(
- context, functions.sortlist(
- functions.recursive(context, self.recursive_select_by_extension,
- self.ext)
- )
- )
- else:
- # non recursive
- self.loader(
- context, functions.sortlist(functions.onefolder(
- context, self.recursive_select_by_extension,
- self.ext)
- )
- )
- try:
- scn.kr_recursive = self.recursive
- scn.kr_recursive_select_by_extension = self.recursive_select_by_extension
- scn.kr_default_ext = self.ext
- except AttributeError:
- functions.initSceneProperties(context)
- self.recursive = scn.kr_recursive
- self.recursive_select_by_extension = scn.kr_recursive_select_by_extension
- self.ext = scn.kr_default_ext
-
- return {'FINISHED'}
-
-
-# Read exif data
-# load exifdata from strip to scene['metadata'] property
-
-class Sequencer_Extra_ReadExifData(Operator):
- bl_label = "Read EXIF Data"
- bl_idname = "sequencerextra.read_exif"
- bl_description = "Load exifdata from strip to metadata property in scene"
- bl_options = {'REGISTER', 'UNDO'}
-
- @classmethod
- def poll(self, context):
- scn = context.scene
- if scn and scn.sequence_editor and scn.sequence_editor.active_strip:
- return scn.sequence_editor.active_strip.type in ('IMAGE', 'MOVIE')
- else:
- return False
-
- def execute(self, context):
- try:
- exiftool.ExifTool().start()
- except:
- self.report({'ERROR_INVALID_INPUT'}, "exiftool not found in PATH")
-
- return {'CANCELLED'}
-
- def getexifdata(strip):
-
- def getexifvalues_image(lista):
- metadata = []
- with exiftool.ExifTool() as et:
- try:
- metadata = et.get_metadata_batch(lista)
- except UnicodeDecodeError as Err:
- print(Err)
- # print(metadata[0])
- print(len(metadata))
- return metadata
-
- def getexifvalues_movie(path):
- metadata = []
- with exiftool.ExifTool() as et:
- try:
- metadata = et.get_metadata_batch([path])
- except UnicodeDecodeError as Err:
- print(Err)
- print(metadata[0])
- print(len(metadata))
- return metadata
-
- def getlist(lista):
- for root, dirs, files in os.walk(path):
- for f in files:
- if "." + f.rpartition(".")[2].lower() in \
- functions.imb_ext_image:
- lista.append(f)
- """
- if "." + f.rpartition(".")[2] in imb_ext_movie:
- lista.append(f)
- """
- strip.elements
- lista.sort()
- return lista
-
- if strip.type == "IMAGE":
- path = bpy.path.abspath(strip.directory)
- os.chdir(path)
- # get a list of files
- lista = []
- for i in strip.elements:
- lista.append(i.filename)
- print(lista)
- return getexifvalues_image(lista)
-
- if strip.type == "MOVIE":
- path = bpy.path.abspath(strip.filepath)
- print([path])
- return getexifvalues_movie(path)
-
- sce = bpy.context.scene
- strip = context.scene.sequence_editor.active_strip
- sce['metadata'] = getexifdata(strip)
-
- return {'FINISHED'}
-
-
-# TODO: fix poll to hide when useless
-
-class ExifInfoPanel(Panel):
- """Creates a Panel in the Object properties window"""
- bl_label = "EXIF Info Panel"
- bl_space_type = 'SEQUENCE_EDITOR'
- bl_region_type = 'UI'
-
- @classmethod
- def poll(self, context):
- if context.space_data.view_type in {'SEQUENCER', 'SEQUENCER_PREVIEW'}:
- strip = functions.act_strip(context)
- scn = context.scene
- preferences = context.preferences
- prefs = preferences.addons[__package__].preferences
-
- if scn and scn.sequence_editor and scn.sequence_editor.active_strip:
- if prefs.use_exif_panel:
- return strip.type in ('MOVIE', 'IMAGE')
- else:
- return False
-
- def draw_header(self, context):
- layout = self.layout
- layout.label(text="", icon="RADIO")
-
- def draw(self, context):
- layout = self.layout
- sce = context.scene
- row = layout.row()
- row.operator("sequencerextra.read_exif")
- row = layout.row()
- row.label(text="Exif Data", icon='RENDER_REGION')
- row = layout.row()
-
- try:
- strip = context.scene.sequence_editor.active_strip
-
- f = strip.frame_start
- frame = sce.frame_current
- try:
- if len(sce['metadata']) == 1:
- for d in sce['metadata'][0]:
- split = layout.split(factor=0.5)
- col = split.column()
- row = col.row()
- col.label(text=d)
- col = split.column()
- col.label(text=str(sce['metadata'][0][d]))
- else:
- for d in sce['metadata'][frame - f]:
- split = layout.split(factor=0.5)
- col = split.column()
- row = col.row()
- col.label(text=d)
- col = split.column()
- col.label(text=str(sce['metadata'][frame - f][d]))
-
- except (IndexError, KeyError):
- pass
- except AttributeError:
- pass
diff --git a/sequencer_kinoraw_tools/ui.py b/sequencer_kinoraw_tools/ui.py
deleted file mode 100644
index a2721cac..00000000
--- a/sequencer_kinoraw_tools/ui.py
+++ /dev/null
@@ -1,765 +0,0 @@
-# ##### 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 #####
-
-import bpy
-from bpy.types import (
- Menu,
- Panel,
- )
-from . import functions
-
-
-# UI
-class SEQUENCER_EXTRA_MT_input(Menu):
- bl_label = "Input"
-
- def draw(self, context):
- self.layout.label(text="Kinoraw Input")
- self.layout.separator()
-
- self.layout.operator_context = "INVOKE_REGION_WIN"
- self.layout.operator("sequencerextra.striprename",
- text="File Name to Strip Name")
- self.layout.operator("sequencerextra.editexternally",
- text="Open with External Editor")
- self.layout.operator("sequencerextra.edit",
- text="Open with Editor")
- self.layout.operator("sequencerextra.createmovieclip",
- text="Create Movieclip strip")
-
-
-def sequencer_header_func(self, context):
- self.layout.menu("SEQUENCER_EXTRA_MT_input")
-
-
-def sequencer_add_menu_func(self, context):
- self.layout.operator("sequencerextra.placefromfilebrowser",
- text="Place from File Browser").insert = False
- self.layout.operator("sequencerextra.placefromfilebrowser",
- text="Insert from File Browser").insert = True
- self.layout.operator("sequencerextra.recursiveload",
- text="Recursive Load from Browser")
- self.layout.separator()
-
-
-def sequencer_select_menu_func(self, context):
- self.layout.operator_menu_enum('sequencerextra.select_all_by_type',
- 'type', text='All by Type')
- self.layout.separator()
- self.layout.operator('sequencerextra.selectcurrentframe',
- text='Before Current Frame').mode = 'BEFORE'
- self.layout.operator('sequencerextra.selectcurrentframe',
- text='After Current Frame').mode = 'AFTER'
- self.layout.operator('sequencerextra.selectcurrentframe',
- text='On Current Frame').mode = 'ON'
- self.layout.separator()
- self.layout.operator('sequencerextra.selectsamechannel',
- text='Same Channel')
-
-
-def sequencer_strip_menu_func(self, context):
- self.layout.operator('sequencerextra.extendtofill',
- text='Extend to Fill')
- self.layout.operator_menu_enum('sequencerextra.fadeinout',
- 'mode', text='Fade')
- self.layout.operator_menu_enum('sequencerextra.copyproperties',
- 'prop')
-
- self.layout.operator("sequencerextra.insert",
- text="Insert (Single Channel)").singlechannel = True
- self.layout.operator("sequencerextra.insert",
- text="Insert").singlechannel = False
- self.layout.operator("sequencerextra.ripplecut",
- text="Ripple Cut")
- self.layout.operator("sequencerextra.rippledelete",
- text="Ripple Delete")
- self.layout.separator()
-
-
-def time_frame_menu_func(self, context):
- self.layout.operator('timeextra.trimtimelinetoselection',
- text='Trim to Selection')
- self.layout.operator('timeextra.trimtimeline',
- text='Trim to Timeline Content')
- self.layout.separator()
- self.layout.operator('screenextra.frame_skip',
- text='Skip Forward One Second').back = False
- self.layout.operator('screenextra.frame_skip',
- text='Skip Back One Second').back = True
- self.layout.separator()
-
-
-def time_header_func(self, context):
- self.layout.operator('sequencerextra.jogshuttle',
- text='Jog/Shuttle', icon='NDOF_TURN')
-
-
-def clip_header_func(self, context):
- self.layout.operator('sequencerextra.jogshuttle',
- text='Jog/Shuttle', icon='NDOF_TURN')
-
-
-def clip_clip_menu_func(self, context):
- self.layout.operator('clipextra.openactivestrip',
- text='Open Active Strip')
- self.layout.operator('clipextra.openfromfilebrowser',
- text='Open from File Browser')
- self.layout.separator()
-
-
-def draw_color_balance(layout, color_balance):
- layout = layout.split(factor=0.33)
- col = layout.column()
- col.label(text="Lift:")
- col.template_color_picker(color_balance, "lift", value_slider=True, cubic=True)
- row = col.row()
- row.prop(color_balance, "lift", text="")
- row.prop(color_balance, "invert_lift", text="Invert")
-
- col = layout.column()
- col.label(text="Gamma:")
- col.template_color_picker(color_balance, "gamma", value_slider=True,
- lock_luminosity=True, cubic=True)
- row = col.row()
- row.prop(color_balance, "gamma", text="")
- row.prop(color_balance, "invert_gamma", text="Invert")
-
- col = layout.column()
- col.label(text="Gain:")
- col.template_color_picker(color_balance, "gain", value_slider=True,
- lock_luminosity=True, cubic=True)
- row = col.row()
- row.prop(color_balance, "gain", text="")
- row.prop(color_balance, "invert_gain", text="Invert")
-
-
-class JumptoCut(Panel):
- bl_space_type = "SEQUENCE_EDITOR"
- bl_region_type = "UI"
- bl_label = "Jump to Cut"
-
- COMPAT_ENGINES = {'BLENDER_RENDER'}
-
- _frame_rate_args_prev = None
- _preset_class = None
-
- @staticmethod
- def _draw_framerate_label(*args):
- # avoids re-creating text string each draw
- if JumptoCut._frame_rate_args_prev == args:
- return JumptoCut._frame_rate_ret
-
- fps, fps_base, preset_label = args
-
- if fps_base == 1.0:
- fps_rate = round(fps)
- else:
- fps_rate = round(fps / fps_base, 2)
-
- # TODO: Change the following to iterate over existing presets
- custom_framerate = (fps_rate not in {23.98, 24, 25, 29.97, 30, 50, 59.94, 60})
-
- if custom_framerate is True:
- fps_label_text = "Custom (%r fps)" % fps_rate
- show_framerate = True
- else:
- fps_label_text = "%r fps" % fps_rate
- show_framerate = (preset_label == "Custom")
-
- JumptoCut._frame_rate_args_prev = args
- JumptoCut._frame_rate_ret = args = (fps_label_text, show_framerate)
- return args
-
- @staticmethod
- def draw_framerate(sub, rd):
- if JumptoCut._preset_class is None:
- JumptoCut._preset_class = bpy.types.RENDER_MT_framerate_presets
-
- args = rd.fps, rd.fps_base, JumptoCut._preset_class.bl_label
- fps_label_text, show_framerate = JumptoCut._draw_framerate_label(*args)
-
- sub.menu("RENDER_MT_framerate_presets", text=fps_label_text)
-
- if show_framerate:
- sub.prop(rd, "fps")
- sub.prop(rd, "fps_base", text="/")
-
- @classmethod
- def poll(self, context):
- if context.space_data.view_type in {'SEQUENCER', 'SEQUENCER_PREVIEW'}:
- scn = context.scene
- preferences = context.preferences
- prefs = preferences.addons[__package__].preferences
- if scn and scn.sequence_editor:
- if prefs.use_jumptocut:
- return True
- else:
- return False
-
- def draw_header(self, context):
- layout = self.layout
- layout.label(text="", icon="RENDER_ANIMATION")
-
- def draw(self, context):
- scn = context.scene
- strip = functions.act_strip(context)
-
- preferences = context.preferences
- prefs = preferences.addons[__package__].preferences
-
- layout = self.layout
- layout = layout.box()
- # jump to cut main controls
- col = layout.column(align=True)
- row = col.row(align=True)
- split = row.split(factor=0.33, align=True)
- box = split.box()
-
- row = box.row(align=True)
- row.label(icon='TIME', text="Jump(sec)")
- row.operator('screenextra.frame_skip',
- text="", icon='TRIA_LEFT').back = True
- row.operator('screenextra.frame_skip',
- text="", icon='TRIA_RIGHT').back = False
-
- box = split.box()
- row = box.row(align=True)
- row.label(icon='IPO_BOUNCE', text="Cuts")
- row.operator("sequencer.strip_jump", icon="PLAY_REVERSE", text="").next = False
- row.operator("sequencer.strip_jump", icon='PLAY', text="").next = True
-
- box = split.box()
- row = box.row(align=True)
- row.label(icon='MARKER_HLT', text="Marker")
- row.operator("screen.marker_jump", icon="TRIA_LEFT", text="").next = False
- row.operator("screen.marker_jump", icon='TRIA_RIGHT', text="").next = True
-
- rd = scn.render
- screen = context.screen
- row = col.row(align=True)
- split = row.split(factor=0.33, align=True)
- sub_box = split.box()
- sub_row = sub_box.row(align=True)
- sub_row.alignment = "CENTER"
-
- sub_row.operator("screen.frame_jump", text="", icon='REW').end = False
- sub_row.operator("screen.keyframe_jump", text="", icon='PREV_KEYFRAME').next = False
-
- if not screen.is_animation_playing:
- # if using JACK and A/V sync:
- # hide the play-reversed button
- # since JACK transport doesn't support reversed playback
- if scn.sync_mode == 'AUDIO_SYNC' and \
- context.preferences.system.audio_device == 'JACK':
- sub = sub_row.row(align=True)
- sub.scale_x = 2.0
- sub.operator("screen.animation_play", text="", icon='PLAY')
- else:
- sub_row.operator("screen.animation_play", text="",
- icon='PLAY_REVERSE').reverse = True
- sub_row.operator("screen.animation_play", text="", icon='PLAY')
- else:
- sub = sub_row.row(align=True)
- sub.scale_x = 2.0
- sub.operator("screen.animation_play", text="", icon="PAUSE")
- sub_row.operator("screen.keyframe_jump", text="", icon="NEXT_KEYFRAME").next = True
- sub_row.operator("screen.frame_jump", text="", icon="FF").end = True
-
- sub_box = split.box()
- sub_box.prop(scn, "sync_mode", text="")
- sub_box = split.box()
- self.draw_framerate(sub_box, rd)
-
- row = layout.row(align=True)
- row.operator("sequencer.refresh_all")
- row.operator("sequencer.rendersize", text="Set Render size")
-
- row = layout.row(align=True)
- row.operator("sequencerextra.setstartend", icon="PREVIEW_RANGE", text="IN/OUT")
- row.operator("timeextra.trimtimelinetoselection",
- text="Selection", icon="PREVIEW_RANGE")
- row.operator("timeextra.trimtimeline", text="All", icon="PREVIEW_RANGE")
-
- layout = self.layout
-
- # panel setup
- row = layout.row(align=True)
- split = row.split(factor=0.5)
- sub_row = split.row(align=True)
- sub_row.prop(prefs, "kr_show_tools", text="Tools", icon='SEQ_SEQUENCER')
- if prefs.kr_show_tools:
- sub_row.prop(prefs, "kr_mini_ui", text="Compact UI", toggle=True)
-
- row = split.row()
- row = row.split(factor=0.33)
- row.prop(prefs, "kr_show_info", text="", icon='VIEWZOOM')
- row = row.split(factor=0.5)
- row.prop(prefs, "kr_extra_info", text="", icon='BORDERMOVE')
- row = row.split(factor=1)
- row.prop(prefs, "kr_show_modifiers", text="", icon='RESTRICT_VIEW_OFF')
-
- if prefs.kr_show_tools:
- layout = self.layout
- layout = layout.box()
- # snap, handler selector and meta tools
-
- if prefs.kr_mini_ui:
- row = layout.row(align=True)
- row.operator("sequencerextra.extrasnap", text="", icon="SNAP_ON").align = 0
- row.operator("sequencerextra.extrasnap", text="", icon="NONE").align = 1
- row.operator("sequencerextra.extrasnap", text="", icon="SNAP_ON").align = 2
-
- row.separator()
- row.operator("sequencerextra.extrahandles", text="", icon="TRIA_LEFT").side = 0
- row.operator("sequencerextra.extrahandles", text="", icon="PMARKER").side = 1
- row.operator("sequencerextra.extrahandles", text="", icon="TRIA_RIGHT").side = 2
-
- row.separator()
- row.operator("sequencerextra.metacopy", icon="COPYDOWN", text="")
- row.operator("sequencerextra.metapaste", icon="PASTEDOWN", text="")
- row.separator()
- row.operator("sequencerextra.meta_separate_trim", text="", icon="ALIGN")
- row.separator()
- row.prop(prefs, "use_io_tools", text="I/O Tools")
-
- # In / Out tools
- if prefs.use_io_tools:
- row = layout.row(align=True)
- if scn.kr_auto_markers is True:
- row.prop(scn, "kr_auto_markers", text="", toggle=True, icon="SPACE2")
-
- row.separator()
- row.operator("sequencerextra.sourcein", icon="MARKER_HLT", text="")
- row.prop(scn, "kr_in_marker")
- row.operator("sequencerextra.sourceout", icon='MARKER_HLT', text="")
- row.prop(scn, "kr_out_marker")
- else:
- row.prop(scn, "kr_auto_markers", text="Auto I/O", toggle=True, icon="SPACE2")
- row.operator("sequencerextra.sourcein", icon="MARKER_HLT", text="IN")
- row.operator("sequencerextra.sourceout", icon='MARKER_HLT', text="OUT")
-
- row.separator()
- row.operator("sequencerextra.setinout", icon='ARROW_LEFTRIGHT', text="")
- row.operator("sequencerextra.triminout", icon="FULLSCREEN_EXIT", text="")
-
- # miniUI extra actions
- row = layout.row(align=True)
- row.operator("sequencerextra.jogshuttle",
- text="", icon="NDOF_TURN")
- row.operator("sequencerextra.navigateup",
- text="", icon="FILE_PARENT")
- row.operator("sequencerextra.extendtofill",
- text="", icon="STYLUS_PRESSURE")
- row.operator("sequencerextra.placefromfilebrowser",
- text="", icon="TRIA_DOWN").insert = False
- row.operator("sequencerextra.placefromfilebrowser",
- text="", icon="TRIA_RIGHT").insert = True
- row.operator("sequencer.slip",
- text="", icon="MOD_SHRINKWRAP")
- row.operator_menu_enum("sequencerextra.fadeinout",
- "mode", text="Fade", icon="MOD_ARRAY")
- row.operator_menu_enum("sequencerextra.copyproperties",
- "prop", text="Copy", icon="SCRIPT")
-
- else:
- row = layout.row(align=True)
- row.label(text="Snap:")
-
- row.operator("sequencerextra.extrasnap", text="Left", icon="SNAP_ON").align = 0
- row.operator("sequencerextra.extrasnap", text="Center", icon="SNAP_SURFACE").align = 1
- row.operator("sequencerextra.extrasnap", text="Right", icon="SNAP_ON").align = 2
-
- row = layout.row(align=True)
- row.label(text="Handlers:")
- row.operator("sequencerextra.extrahandles",
- text="Left", icon="TRIA_LEFT").side = 0
- row.operator("sequencerextra.extrahandles",
- text="Both", icon="PMARKER").side = 1
- row.operator("sequencerextra.extrahandles",
- text="Right", icon="TRIA_RIGHT").side = 2
-
- box = layout.box()
- col = box.column_flow(columns=3, align=True)
- row1 = col.row(align=True)
- row1.operator("sequencerextra.metacopy", icon="COPYDOWN", text="Meta Copy")
- row2 = col.row(align=True)
- row2.operator("sequencerextra.metapaste", icon='PASTEDOWN', text="Paste Snap")
- row3 = col.row()
- row3.operator("sequencerextra.meta_separate_trim",
- text="unMeta & Trim", icon="ALIGN")
-
- # in /out tools
- box = layout.box()
- col = box.column_flow(columns=3, align=True)
- row1 = col.row(align=True)
- row1.operator("sequencerextra.sourcein", icon="MARKER_HLT", text="Set IN")
- row2 = col.row(align=True)
- row2.operator("sequencerextra.sourceout", icon='MARKER_HLT', text="Set OUT")
- row3 = col.row()
- row3.operator("sequencerextra.setinout", icon='ARROW_LEFTRIGHT', text="Selected")
-
- sub_col = box.split(factor=0.67, align=True)
- row4 = sub_col.row(align=True)
-
- if scn.kr_auto_markers is False:
- row4.prop(scn, "kr_auto_markers",
- text="Auto Markers", toggle=True, icon="SPACE2")
- else:
- row4.prop(scn, "kr_auto_markers", text="", icon="SPACE2")
- row4.prop(scn, "kr_in_marker")
- row4.prop(scn, "kr_out_marker")
- box4 = row4.box()
- box4.scale_x = 0.25
- box4.scale_y = 0.5
- box4.label(text="", icon="BLANK1")
-
- row5 = sub_col.row()
- row5.operator("sequencerextra.triminout", icon="FULLSCREEN_EXIT",
- text="Trim", emboss=True)
-
- # UI extra actions
- box = layout.box()
- row = box.row(align=True)
- row.operator("sequencerextra.jogshuttle",
- text="Jog/Shuttle", icon="NDOF_TURN")
- row.operator("sequencerextra.navigateup",
- text="Navigate Up", icon="FILE_PARENT")
- row.operator("sequencerextra.extendtofill",
- text="Extend to Fill", icon="STYLUS_PRESSURE")
-
- row = box.row(align=True)
- row.operator("sequencerextra.placefromfilebrowser",
- text="File Place", icon="TRIA_DOWN").insert = False
- row.operator("sequencerextra.placefromfilebrowser",
- text="File Insert", icon="TRIA_RIGHT").insert = True
- row.operator("sequencer.slip",
- text="Slip", icon="MOD_SHRINKWRAP")
- row = layout.row(align=True)
- row.operator_menu_enum("sequencerextra.fadeinout",
- "mode", text="Fade", icon="MOD_ARRAY")
- row.operator_menu_enum("sequencerextra.copyproperties",
- "prop", icon="SCRIPT")
-
- # INFO boxes
- if strip is not None:
- if prefs.kr_show_info:
- layout = layout.box()
- row = layout.split(factor=0.075)
- row.prop(prefs, "kr_show_info", text="", icon='VIEWZOOM', emboss=True)
- row = row.split(factor=0.3)
- row.prop(strip, "type", text="")
- row = row.split(factor=1)
- row.prop(strip, "name", text="")
-
- # mute information
- layout.active = (not strip.mute)
-
- # basic info
- row = layout.row()
- row.prop(strip, "channel")
- row.prop(strip, "frame_start")
- row.prop(strip, "frame_final_duration")
-
- # source info
- row = layout.split(factor=0.8)
-
- if strip.type == 'MOVIE':
- row.prop(strip, "filepath", text="")
-
- if strip.type == 'SOUND':
- # Note: sound strip has a different structure
- sound = strip.sound
- if sound is not None:
- row.prop(sound, "filepath", text="")
-
- if strip.type == 'IMAGE':
- row.prop(strip, "directory", text="")
- # Current element for the filename
- elem = strip.strip_elem_from_frame(context.scene.frame_current)
- if elem:
- row = layout.row()
- # strip.elements[0] could be a fallback
- row.prop(elem, "filename", text="File")
- row.operator("sequencer.change_path", text="change files")
-
- if strip.type == 'COLOR':
- row.prop(strip, "color", text="")
-
- # trim info
- if strip.type not in {"SPEED", "WIPE", "CROSS", "ADJUSTMENT"}:
- row = row.split(factor=1)
- row.prop(prefs, "kr_show_trim", text="Trim", toggle=True)
- if prefs.kr_show_trim:
- box = layout.box()
- if not isinstance(strip, bpy.types.EffectSequence):
- row = box.row(align=True)
- row.label(text="Hard:")
- row.prop(strip, "animation_offset_start", text="Start")
- row.prop(strip, "animation_offset_end", text="End")
- row = box.row(align=True)
- row.label(text="Soft:")
- row.prop(strip, "frame_offset_start", text="Start")
- row.prop(strip, "frame_offset_end", text="End")
-
- row = layout.row()
-
- # special strips info
- if strip.type == 'SPEED':
- row.prop(strip, "multiply_speed")
-
- if strip.type in {'CROSS', 'GAMMA_CROSS', 'WIPE',
- 'ALPHA_OVER', 'ALPHA_UNDER', 'OVER_DROP'}:
- row.prop(strip, "use_default_fade", "Default Fade")
- if not strip.use_default_fade:
- row.prop(strip, "effect_fader", text="Effect fader")
-
- if strip.type == 'GAUSSIAN_BLUR':
- row.prop(strip, "size_x")
- row.prop(strip, "size_y")
-
- if strip.type == 'WIPE':
- row = layout.row()
- row.prop(strip, "transition_type", expand=True)
- row = layout.row()
- row.prop(strip, "direction", expand=True)
- row.prop(strip, "blur_width", slider=True)
- if strip.transition_type in {'SINGLE', 'DOUBLE'}:
- row.prop(strip, "angle")
-
- if strip.type == 'GLOW':
- flow = layout.column_flow()
- flow.prop(strip, "threshold", slider=True)
- flow.prop(strip, "clamp", slider=True)
- flow.prop(strip, "boost_factor")
- flow.prop(strip, "blur_radius")
-
- row = layout.row()
- row.prop(strip, "quality", slider=True)
- row.prop(strip, "use_only_boost")
-
- if strip.type == 'SPEED':
- row = layout.row()
- row.prop(strip, "use_default_fade", "Stretch to input strip length")
- if not strip.use_default_fade:
- row.prop(strip, "use_as_speed")
- if strip.use_as_speed:
- layout.prop(strip, "speed_factor")
- else:
- layout.prop(strip, "speed_factor", text="Frame number")
- layout.prop(strip, "scale_to_length")
-
- if strip.type == 'TRANSFORM':
- row = layout.row(align=True)
- row.prop(strip, "interpolation")
- row.prop(strip, "translation_unit")
- row = layout.row(align=True)
- row.prop(strip, "translate_start_x", text="Pos X")
- row.prop(strip, "translate_start_y", text="Pos Y")
-
- row = layout.row(align=True)
- if strip.use_uniform_scale:
- row.prop(strip, "scale_start_x", text="Scale")
- else:
- row.prop(strip, "scale_start_x", text="Scale X")
- row.prop(strip, "scale_start_y", text="Scale Y")
- row = layout.row(align=True)
- row.prop(strip, "use_uniform_scale")
- row.prop(strip, "rotation_start", text="Rotation")
-
- if strip.type == 'MULTICAM':
- layout.prop(strip, "multicam_source")
-
- row = layout.row(align=True)
- sub = row.row(align=True)
- sub.scale_x = 2.0
-
- sub.operator("screen.animation_play", text="", icon='PAUSE' if
- context.screen.is_animation_playing else 'PLAY')
-
- row.label(text="Cut To")
- for i in range(1, strip.channel):
- row.operator("sequencer.cut_multicam", text="%d" % i).camera = i
-
- try:
- if strip.input_count > 0:
- col = layout.column()
- col.prop(strip, "input_1")
- if strip.input_count > 1:
- col.prop(strip, "input_2")
- except AttributeError:
- pass
-
- # extra info box:
- if prefs.kr_extra_info:
- layout = self.layout
- box = layout.box()
- if strip.type not in {'SOUND'}:
- row = box.row(align=True)
- sub = row.row(align=True)
- # mute this box
- box.active = (not strip.mute)
- sub.prop(prefs, "kr_extra_info", text="", icon='BORDERMOVE', emboss=True)
- sub.separator()
- sub.prop(strip, "blend_alpha", text="Opacity", slider=True)
- row.prop(strip, "mute", toggle=True, icon_only=True)
- row.prop(strip, "lock", toggle=True, icon_only=True)
-
- split = box.split(factor=0.5)
- left_box = split.box()
- row = left_box.row()
- row.prop(strip, "strobe")
-
- col = left_box.column(align=True)
- col.separator()
- col.prop(strip, "use_flip_x", text="Flip X", toggle=True)
- col.prop(strip, "use_flip_y", text="Flip Y", toggle=True)
- col.prop(strip, "use_reverse_frames", text="Backwards", toggle=True)
- col.prop(strip, "use_deinterlace", toggle=True)
-
- right_box = split.box()
- col = right_box.column()
- col.prop(strip, "blend_type", icon='COLOR')
- col.prop(strip, "alpha_mode")
-
- col = right_box.column()
- col.prop(strip, "color_saturation", text="Saturation")
- col.prop(strip, "color_multiply", text="Multiply")
- col.prop(strip, "use_float", text="Convert Float")
-
- row = box.row(align=True)
- row.prop(strip, "use_translation", text="Image Offset", icon="AXIS_TOP")
- row.prop(strip, "use_crop", text="Image Crop", icon="BORDER_RECT")
- if strip.use_translation:
- row = box.row(align=True)
- row.prop(strip.transform, "offset_x", text="X")
- row.prop(strip.transform, "offset_y", text="Y")
- if strip.use_crop:
- row = box.row(align=True)
- row.prop(strip.crop, "max_y")
- row.prop(strip.crop, "min_x")
- row.prop(strip.crop, "min_y")
- row.prop(strip.crop, "max_x")
-
- else:
- # sound type
- row = box.row()
- row.prop(prefs, "kr_extra_info", text="", icon='BORDERMOVE', emboss=True)
- sub = row.row(align=True)
- sub.prop(strip, "volume")
- sub.prop(strip, "mute", toggle=True, icon_only=True)
- sub.prop(strip, "lock", toggle=True, icon_only=True)
-
- sound = strip.sound
- if sound is not None:
- row = box.row()
- if sound.packed_file:
- row.operator("sound.unpack", icon='PACKAGE', text="Unpack")
- else:
- row.operator("sound.pack", icon='UGLYPACKAGE', text="Pack")
-
- row.prop(sound, "use_memory_cache", toggle=True, icon="DISK_DRIVE")
-
- row.prop(strip, "show_waveform", toggle=True, icon="RNDCURVE")
-
- row = box.row(align=True)
- row.prop(strip, "pitch")
- row.prop(strip, "pan")
-
- # modifiers
- if strip.type != 'SOUND' and prefs.kr_show_modifiers:
- sequencer = context.scene.sequence_editor
- layout = self.layout
- layout = layout.box()
- # mute this box
- layout.active = (not strip.mute)
- row = layout.split(factor=0.075)
- row.prop(prefs, "kr_show_modifiers", text="",
- icon='RESTRICT_VIEW_OFF', emboss=True)
- row = row.split(factor=0.40)
- row.prop(strip, "use_linear_modifiers", text="Linear")
- row = row.split(factor=1)
- row.operator_menu_enum("sequencer.strip_modifier_add", "type")
-
- for mod in strip.modifiers:
- box = layout.box()
-
- row = box.row()
- row.prop(mod, "show_expanded", text="", emboss=False)
- row.prop(mod, "name", text="")
-
- row.prop(mod, "mute", text="")
-
- sub = row.row(align=True)
- props = sub.operator("sequencer.strip_modifier_move", text="", icon='TRIA_UP')
- props.name = mod.name
- props.direction = 'UP'
- props = sub.operator("sequencer.strip_modifier_move", text="", icon='TRIA_DOWN')
- props.name = mod.name
- props.direction = 'DOWN'
-
- row.operator("sequencer.strip_modifier_remove", text="", icon='X',
- emboss=False).name = mod.name
-
- if mod.show_expanded:
- row = box.row()
- row.prop(mod, "input_mask_type", expand=True)
-
- if mod.input_mask_type == 'STRIP':
- sequences_object = sequencer
- if sequencer.meta_stack:
- sequences_object = sequencer.meta_stack[-1]
- box.prop_search(mod, "input_mask_strip",
- sequences_object, "sequences", text="Mask")
- else:
- box.prop(mod, "input_mask_id")
- row = box.row()
- row.prop(mod, "mask_time", expand=True)
-
- if mod.type == 'COLOR_BALANCE':
- box.prop(mod, "color_multiply")
- draw_color_balance(box, mod.color_balance)
- elif mod.type == 'CURVES':
- box.template_curve_mapping(mod, "curve_mapping", type='COLOR')
- elif mod.type == 'HUE_CORRECT':
- box.template_curve_mapping(mod, "curve_mapping", type='HUE')
- elif mod.type == 'BRIGHT_CONTRAST':
- col = box.column()
- col.prop(mod, "bright")
- col.prop(mod, "contrast")
- elif mod.type == 'WHITE_BALANCE':
- col = box.column()
- col.prop(mod, "white_value")
- elif mod.type == 'TONEMAP':
- col = box.column()
- col.prop(mod, "tonemap_type")
- if mod.tonemap_type == 'RD_PHOTORECEPTOR':
- col.prop(mod, "intensity")
- col.prop(mod, "contrast")
- col.prop(mod, "adaptation")
- col.prop(mod, "correction")
- elif mod.tonemap_type == 'RH_SIMPLE':
- col.prop(mod, "key")
- col.prop(mod, "offset")
- col.prop(mod, "gamma")
-
- if "copy_modifiers" in dir(bpy.ops.sequencer):
- row = layout.row(align=True)
- row.operator("sequencer.copy_modifiers",
- text="Copy Modifiers", icon='COPYDOWN')
- row.operator("sequencer.paste_modifiers",
- text="Paste Modifiers", icon='PASTEDOWN')