sequencer.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. # ##### BEGIN GPL LICENSE BLOCK #####
  2. #
  3. # This program is free software; you can redistribute it and/or
  4. # modify it under the terms of the GNU General Public License
  5. # as published by the Free Software Foundation; either version 2
  6. # of the License, or (at your option) any later version.
  7. #
  8. # This program is distributed in the hope that it will be useful,
  9. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. # GNU General Public License for more details.
  12. #
  13. # You should have received a copy of the GNU General Public License
  14. # along with this program; if not, write to the Free Software Foundation,
  15. # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  16. #
  17. # ##### END GPL LICENSE BLOCK #####
  18. # <pep8 compliant>
  19. import bpy
  20. from bpy.types import Operator
  21. from bpy.props import IntProperty
  22. class SequencerCrossfadeSounds(Operator):
  23. """Do cross-fading volume animation of two selected sound strips"""
  24. bl_idname = "sequencer.crossfade_sounds"
  25. bl_label = "Crossfade sounds"
  26. bl_options = {'REGISTER', 'UNDO'}
  27. @classmethod
  28. def poll(cls, context):
  29. if context.scene and context.scene.sequence_editor and context.scene.sequence_editor.active_strip:
  30. return context.scene.sequence_editor.active_strip.type == 'SOUND'
  31. else:
  32. return False
  33. def execute(self, context):
  34. seq1 = None
  35. seq2 = None
  36. for s in context.scene.sequence_editor.sequences:
  37. if s.select and s.type == 'SOUND':
  38. if seq1 is None:
  39. seq1 = s
  40. elif seq2 is None:
  41. seq2 = s
  42. else:
  43. seq2 = None
  44. break
  45. if seq2 is None:
  46. self.report({'ERROR'}, "Select 2 sound strips")
  47. return {'CANCELLED'}
  48. if seq1.frame_final_start > seq2.frame_final_start:
  49. s = seq1
  50. seq1 = seq2
  51. seq2 = s
  52. if seq1.frame_final_end > seq2.frame_final_start:
  53. tempcfra = context.scene.frame_current
  54. context.scene.frame_current = seq2.frame_final_start
  55. seq1.keyframe_insert("volume")
  56. context.scene.frame_current = seq1.frame_final_end
  57. seq1.volume = 0
  58. seq1.keyframe_insert("volume")
  59. seq2.keyframe_insert("volume")
  60. context.scene.frame_current = seq2.frame_final_start
  61. seq2.volume = 0
  62. seq2.keyframe_insert("volume")
  63. context.scene.frame_current = tempcfra
  64. return {'FINISHED'}
  65. else:
  66. self.report({'ERROR'}, "The selected strips don't overlap")
  67. return {'CANCELLED'}
  68. class SequencerCutMulticam(Operator):
  69. """Cut multi-cam strip and select camera"""
  70. bl_idname = "sequencer.cut_multicam"
  71. bl_label = "Cut multicam"
  72. bl_options = {'REGISTER', 'UNDO'}
  73. camera: IntProperty(
  74. name="Camera",
  75. min=1, max=32,
  76. soft_min=1, soft_max=32,
  77. default=1,
  78. )
  79. @classmethod
  80. def poll(cls, context):
  81. if context.scene and context.scene.sequence_editor and context.scene.sequence_editor.active_strip:
  82. return context.scene.sequence_editor.active_strip.type == 'MULTICAM'
  83. else:
  84. return False
  85. def execute(self, context):
  86. camera = self.camera
  87. s = context.scene.sequence_editor.active_strip
  88. if s.multicam_source == camera or camera >= s.channel:
  89. return {'FINISHED'}
  90. if not s.select:
  91. s.select = True
  92. cfra = context.scene.frame_current
  93. bpy.ops.sequencer.cut(frame=cfra, type='SOFT', side='RIGHT')
  94. for s in context.scene.sequence_editor.sequences_all:
  95. if s.select and s.type == 'MULTICAM' and s.frame_final_start <= cfra and cfra < s.frame_final_end:
  96. context.scene.sequence_editor.active_strip = s
  97. context.scene.sequence_editor.active_strip.multicam_source = camera
  98. return {'FINISHED'}
  99. class SequencerDeinterlaceSelectedMovies(Operator):
  100. """Deinterlace all selected movie sources"""
  101. bl_idname = "sequencer.deinterlace_selected_movies"
  102. bl_label = "Deinterlace Movies"
  103. bl_options = {'REGISTER', 'UNDO'}
  104. @classmethod
  105. def poll(cls, context):
  106. return (context.scene and context.scene.sequence_editor)
  107. def execute(self, context):
  108. for s in context.scene.sequence_editor.sequences_all:
  109. if s.select and s.type == 'MOVIE':
  110. s.use_deinterlace = True
  111. return {'FINISHED'}
  112. classes = (
  113. SequencerCrossfadeSounds,
  114. SequencerCutMulticam,
  115. SequencerDeinterlaceSelectedMovies,
  116. )