# ##### 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 ##### # my current blender version: r34626 bl_info = { "name": "Jump to Cut 4", "author": "Carlos Padial", "version": (4,0,5), "blender": (2, 5, 7, 1), "api": 37548, "category": "Sequencer", "location": "Sequencer > UI > Jump to Cut", "description": "Tool collection to help speed up editting and grade videos with blender.", "warning": "", "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/Sequencer/Jump_to_cut", "tracker_url": "https://projects.blender.org/tracker/index.php?func=detail&aid=24279",} """ """ #----------------------------------------------------------------------------------------------------- import bpy class Jumptocut4(bpy.types.Panel): bl_space_type = "SEQUENCE_EDITOR" bl_region_type = "UI" bl_label = "Jump to Cut 4" def draw_header(self, context): layout = self.layout layout.label(text="", icon="NLA") def draw(self, context): layout = self.layout row=layout.row() split=row.split(percentage=0.5) colL = split.column() colR = split.column() colL.operator("sequencer.jumpprev", icon="PLAY_REVERSE") colR.operator("sequencer.jumpnext", icon='PLAY') row=layout.row() split=row.split() colL1 = split.column() colL2 = split.column() colL1.operator("sequencer.sourcein", icon="REW") colL2.operator("sequencer.sourceout", icon='FF') row=layout.row() split=row.split() colR1 = split.column() colR1.operator("sequencer.setinout", icon="ARROW_LEFTRIGHT") row=layout.row() split=row.split(percentage=0.5) colR1 = split.column() colR1.operator("sequencer.triminout", icon="FULLSCREEN_EXIT") colR2 = split.column() colR2.operator("sequencer.setstartend", icon="SETTINGS") row=layout.row() split=row.split() colL = split.column() colR = split.column() colL.operator("sequencer.markprev", icon="MARKER_HLT") colR.operator("sequencer.marknext", icon='MARKER_HLT') row=layout.row() split=row.split() colL = split.column() colR = split.column() colL.operator("sequencer.keyprev", icon="SPACE2") colR.operator("sequencer.keynext", icon='SPACE2') row=layout.row() split=row.split() colR1 = split.column() colR1.operator("sequencer.extractaudio", icon="SOUND") row=layout.row() split=row.split() colR1 = split.column() colR2 = split.column() colR1.operator("sequencer.metacopy", icon="COPYDOWN") colR2.operator("sequencer.metapaste", icon='PASTEDOWN') #----------------------------------------------------------------------------------------------------- class OBJECT_OT_Setinout(bpy.types.Operator): bl_label = "Mark in & out to active strip" bl_idname = "sequencer.setinout" bl_description = "set IN and OUT markers to the active strip limits" def invoke(self, context, event): scene=bpy.context.scene markers=scene.timeline_markers seq=scene.sequence_editor strip= seq.active_strip if strip != None: sin = strip.frame_start + strip.frame_offset_start sout = sin + strip.frame_final_duration if "IN" not in markers: mark=markers.new(name="IN") mark.frame=sin else: mark=markers["IN"] mark.frame=sin if "OUT" not in markers: mark= markers.new(name="OUT") mark.frame=sout else: mark=markers["OUT"] mark.frame=sout bpy.ops.sequencer.reload() return {'FINISHED'} def triminout(strip,sin,sout): start = strip.frame_start+strip.frame_offset_start end = start+strip.frame_final_duration 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 bpy.ops.sequencer.reload() return {'FINISHED'} class OBJECT_OT_Triminout(bpy.types.Operator): bl_label = "Trim to in & out" bl_idname = "sequencer.triminout" bl_description = "trim the selected strip to IN and OUT markers (if exists)" def invoke(self, context, event): scene=bpy.context.scene markers=scene.timeline_markers seq=scene.sequence_editor strip= seq.active_strip if strip != None: if "IN" and "OUT" in markers: sin=markers["IN"].frame sout=markers["OUT"].frame triminout(strip,sin,sout) else: self.report("WARNING", "there is no IN and OUT") bpy.ops.sequencer.reload() return {'FINISHED'} def extractaudio(self,seq, conaudio, meta1): audiolist1 = [] videolist1 = [] audiolist2 = [] videolist2 = [] metalist = [] start = meta1.frame_start + meta1.frame_offset_start end = start + meta1.frame_final_duration #print(start," ",end) for i in meta1.sequences: if i.type == 'SOUND': audiolist1.append(i) if i.mute == False and conaudio == False: conaudio = True if conaudio == True: bpy.ops.sequencer.duplicate() meta2 = seq.active_strip meta2.channel = meta1.channel+1 for i in meta2.sequences: if i.type == 'SOUND': audiolist2.append(i) for i in meta2.sequences: if i.type in ('MOVIE','META','COLOR','TRANSITION','CROSS','ADD','SUBTRACT','ALPHA_OVER',\ 'ALPHA_UNDER','GAMMA_CROSS','MULTIPLY','OVER_DROP','PLUGIN','WIPE',\ 'GLOW','TRANSFORM','COLOR','SPEED','MULTICAM','ADJUSTMENT'): videolist2.append(i) bpy.ops.sequencer.meta_separate() for i in audiolist1: # mute a los que no estaban en mute i.mute=True for i in seq.sequences: if i.select == True: bpy.ops.sequencer.select_all_toggle() bpy.ops.sequencer.reload() break #lo deselecciona todo meta1.select = False for i in videolist2: i.mute = False i.select = True seq.active_strip = i #print("borrable ",i.name," ",i.select," ", i.mute) for i in audiolist2: if i.mute == True: i.select = True else: i.select = False bpy.ops.sequencer.delete() self.report("INFO", "audio extracted") else: self.report("ERROR", "no visible audio strips") bpy.ops.sequencer.reload() return {'FINISHED'} class OBJECT_OT_Extractaudio(bpy.types.Operator): bl_label = "Extract audio from meta" bl_idname = "sequencer.extractaudio" bl_description = "Extract audio from meta and mute audio inside meta" def invoke(self, context, event): conaudio = False scene=bpy.context.scene seq=scene.sequence_editor if seq.active_strip != None: meta1 = seq.active_strip if meta1.type == 'META': extractaudio(self,seq, conaudio, meta1) if conaudio == False: seq.active_strip = meta1 else: self.report("INFO", "Select a metastrip, please!") return {'FINISHED'} def searchprev(j, list): list.sort() list.reverse() for i in list: if i < j: result = i break else: result = j return result def searchnext(j, list): list.sort() for i in list: if i > j: result = i break else: result = j return result def geteditpoints(seq): #this create a list of editpoints including strips from # inside metastrips. It reads only 1 level into the metastrip editpoints = [] cliplist = [] metalist = [] for i in seq.sequences: if i.type == 'META': metalist.append(i) start = i.frame_start + i.frame_offset_start end = start + i.frame_final_duration editpoints.append(start) editpoints.append(end) else: cliplist.append(i) for i in metalist: for j in i.sequences: cliplist.append(j) for i in cliplist: start = i.frame_start + i.frame_offset_start end = start + i.frame_final_duration editpoints.append(start) editpoints.append(end) #print(start," ",end) return editpoints # MARKER class OBJECT_OT_Markerprev(bpy.types.Operator): bl_label = "Marker previous" bl_idname = "sequencer.markprev" bl_description = "jump to previous marker" def invoke(self, context, event): markerlist = [] scene= bpy.context.scene markers = scene.timeline_markers for i in markers: markerlist.append(i.frame) bpy.context.scene.frame_current = searchprev(scene.frame_current, markerlist) return {'FINISHED'} class OBJECT_OT_Markernext(bpy.types.Operator): bl_label = "Marker next" bl_idname = "sequencer.marknext" bl_description = "jump to next marker" def invoke(self, context, event): markerlist = [] scene= bpy.context.scene markers = scene.timeline_markers for i in markers: markerlist.append(i.frame) bpy.context.scene.frame_current = searchnext(scene.frame_current, markerlist) return {'FINISHED'} # KEY class OBJECT_OT_Keyprev(bpy.types.Operator): bl_label = "Key previous" bl_idname = "sequencer.keyprev" bl_description = "jump to previous keyframe" def invoke(self, context, event): bpy.ops.screen.keyframe_jump(next=False) return {'FINISHED'} class OBJECT_OT_Keynext(bpy.types.Operator): bl_label = "Key next" bl_idname = "sequencer.keynext" bl_description = "jump to next keyframe" def invoke(self, context, event): bpy.ops.screen.keyframe_jump() return {'FINISHED'} #JUMP class OBJECT_OT_Jumpprev(bpy.types.Operator): #Operator jump previous edit point bl_label = "Cut previous" bl_idname = "sequencer.jumpprev" bl_description = "jump to previous edit point" editpoints = [] def invoke(self, context, event): scene=bpy.context.scene seq=scene.sequence_editor editpoints = geteditpoints(seq) bpy.context.scene.frame_current = searchprev(scene.frame_current, editpoints) return {'FINISHED'} class OBJECT_OT_Jumpnext(bpy.types.Operator): #Operator jump next edit point bl_label = "Cut next" bl_idname = "sequencer.jumpnext" bl_description = "jump to next edit point" def invoke(self, context, event): scene=bpy.context.scene seq=scene.sequence_editor editpoints = geteditpoints(seq) bpy.context.scene.frame_current = searchnext(scene.frame_current, editpoints) return {'FINISHED'} # SOURCE IN OUT class OBJECT_OT_Sourcein(bpy.types.Operator): #Operator source in bl_label = "Source IN" bl_idname = "sequencer.sourcein" bl_description = "add a marker named IN" def invoke(self, context, event): scene=bpy.context.scene markers=scene.timeline_markers if "OUT" in markers: sout=markers["OUT"] if scene.frame_current <= sout.frame: if "IN" not in markers: sin=markers.new(name="IN") sin.frame=scene.frame_current else: sin=markers["IN"] sin.frame=scene.frame_current else: self.report("ERROR", "In after Out") #print("error: in after out") else: sin=markers.new(name="IN") sin.frame=scene.frame_current bpy.ops.sequencer.reload() return {'FINISHED'} class OBJECT_OT_Sourceout(bpy.types.Operator): #Operator source out bl_label = "Source OUT" bl_idname = "sequencer.sourceout" bl_description = "add a marker named OUT" def invoke(self, context, event): scene=bpy.context.scene markers=scene.timeline_markers if "IN" in markers: sin=markers["IN"] if scene.frame_current >= sin.frame: if "OUT" not in markers: sout= markers.new(name="OUT") sout.frame=scene.frame_current else: sout=markers["OUT"] sout.frame=scene.frame_current else: self.report("ERROR", "Out before In") #print("error: out before in") else: sout= markers.new(name="OUT") sout.frame=scene.frame_current bpy.ops.sequencer.reload() return {'FINISHED'} class OBJECT_OT_Setstartend(bpy.types.Operator): #Operator set start & end bl_label = "set Start & End" bl_idname = "sequencer.setstartend" bl_description = "set Start = In and End = Out" def invoke(self, context, event): scene=bpy.context.scene markers=scene.timeline_markers if "IN" and "OUT" in markers: sin=markers["IN"] sout=markers["OUT"] scene.frame_preview_start = sin.frame scene.frame_preview_end = sout.frame else: self.report("WARNING", "There is no IN and OUT") bpy.ops.sequencer.reload() return {'FINISHED'} # COPY PASTE class OBJECT_OT_Metacopy(bpy.types.Operator): #Operator copy source in/out bl_label = "Trim & Meta-Copy" bl_idname = "sequencer.metacopy" bl_description = "make meta from selected strips, trim it to in/out (if available) and copy it to clipboard" def invoke(self, context, event): # rehacer scene=bpy.context.scene seq = scene.sequence_editor markers=scene.timeline_markers strip1= seq.active_strip if strip1 != None: if "IN" and "OUT" in markers: sin=markers["IN"].frame sout=markers["OUT"].frame bpy.ops.sequencer.meta_make() strip2= seq.active_strip triminout(strip2,sin,sout) bpy.ops.sequencer.copy() bpy.ops.sequencer.meta_separate() self.report("INFO", "META has been trimed and copied") else: bpy.ops.sequencer.meta_make() bpy.ops.sequencer.copy() bpy.ops.sequencer.meta_separate() self.report("WARNING", "No In & Out. META has been copied") return {'FINISHED'} class OBJECT_OT_Metapaste(bpy.types.Operator): #Operator paste source in/out bl_label = "Paste in current Frame" bl_idname = "sequencer.metapaste" bl_description = "paste source from clipboard to current frame" def invoke(self, context, event): # rehacer scene=bpy.context.scene bpy.ops.sequencer.paste() bpy.ops.sequencer.snap(frame=scene.frame_current) return {'FINISHED'} # Registering / Unregister def register(): bpy.utils.register_class(Jumptocut4) bpy.utils.register_class(OBJECT_OT_Jumpprev) bpy.utils.register_class(OBJECT_OT_Jumpnext) bpy.utils.register_class(OBJECT_OT_Markerprev) bpy.utils.register_class(OBJECT_OT_Markernext) bpy.utils.register_class(OBJECT_OT_Keyprev) bpy.utils.register_class(OBJECT_OT_Keynext) bpy.utils.register_class(OBJECT_OT_Sourcein) bpy.utils.register_class(OBJECT_OT_Sourceout) bpy.utils.register_class(OBJECT_OT_Metacopy) bpy.utils.register_class(OBJECT_OT_Metapaste) bpy.utils.register_class(OBJECT_OT_Extractaudio) bpy.utils.register_class(OBJECT_OT_Triminout) bpy.utils.register_class(OBJECT_OT_Setinout) bpy.utils.register_class(OBJECT_OT_Setstartend) def unregister(): bpy.utils.unregister_class(Jumptocut4) bpy.utils.unregister_class(OBJECT_OT_Jumpprev) bpy.utils.unregister_class(OBJECT_OT_Jumpnext) bpy.utils.register_class(OBJECT_OT_Markerprev) bpy.utils.register_class(OBJECT_OT_Markernext) bpy.utils.register_class(OBJECT_OT_Keyprev) bpy.utils.register_class(OBJECT_OT_Keynext) bpy.utils.unregister_class(OBJECT_OT_Sourcein) bpy.utils.unregister_class(OBJECT_OT_Sourceout) bpy.utils.unregister_class(OBJECT_OT_Metacopy) bpy.utils.unregister_class(OBJECT_OT_Metapaste) bpy.utils.unregister_class(OBJECT_OT_Extractaudio) bpy.utils.unregister_class(OBJECT_OT_Triminout) bpy.utils.unregister_class(OBJECT_OT_Setinout) bpy.utils.unregister_class(OBJECT_OT_Setstartend) if __name__ == "__main__": register()