1 # SPDX-License-Identifier: GPL-2.0-or-later
4 from typing
import List
, Sequence
, Tuple
5 from bpy
.types
import (
10 def send_sound_strip(s
, dest_scn
):
11 '''recreate sound strip in another scene
12 :dest_scn: scene destination
13 :return: newly create sound strip
18 vse
= dest_scn
.sequence_editor
19 ns
= vse
.sequences
.new_sound(name
=s
.name
, filepath
=s
.sound
.filepath
, channel
=s
.channel
, frame_start
=int(s
.frame_start
))
20 ns
.sound
= s
.sound
# reget the same sound source
29 setattr(ns
, attr
, getattr(s
, attr
))
34 def get_all_overlapping_sound_strip(scn_strip
, skip_mute
=True):
35 """return array of all sound strips for this strip"""
36 if scn_strip
.type != 'SCENE':
39 src_scn
= scn_strip
.id_data
40 vse
= src_scn
.sequence_editor
41 overlapping_sounds
= []
42 for s
in vse
.sequences
:
45 if skip_mute
and s
.mute
:
48 if (s
.frame_final_end
- 1 < scn_strip
.frame_final_start
)\
49 or (s
.frame_final_start
- 1 > scn_strip
.frame_final_end
):
52 overlapping_sounds
.append(s
)
54 return overlapping_sounds
56 def delete_sounds(scene
):
57 for st
in reversed(scene
.sequence_editor
.sequences
):
58 if st
.type == 'SOUND':
59 scene
.sequence_editor
.sequences
.remove(st
)
61 def get_scene_frame_from_sequencer_frame(scn_strip
, sound
) -> float:
62 """return frame in scene referential"""
63 return sound
.frame_start
- scn_strip
.frame_start
+ scn_strip
.scene
.frame_start
65 def send_sound_to_strip_scene(scn_strip
, clear_sequencer
=True, skip_mute
=True):
66 """Add sounds to strip scene"""
67 if scn_strip
.type != 'SCENE':
69 tgt_scene
= scn_strip
.scene
71 sounds
= get_all_overlapping_sound_strip(scn_strip
, skip_mute
=skip_mute
)
75 # Clear sounds if exists in scene vse already
77 delete_sounds(tgt_scene
)
79 print(f
'Duplicating sounds in {tgt_scene.name}:')
81 new_start
= get_scene_frame_from_sequencer_frame(scn_strip
, s
)
82 ns
= send_sound_strip(s
, tgt_scene
)
84 ns
.frame_start
= new_start
85 ns
.frame_offset_start
= s
.frame_offset_start
86 ns
.frame_final_duration
= s
.frame_final_duration
91 def dispatch_sounds_in_scenes(selected_scn_only
=True, skip_mute
=True):
92 """Main function to duplicate sounds in strip scenes"""
93 edit_scene
= bpy
.context
.scene
94 edit
= edit_scene
.sequence_editor
97 for strip
in edit
.sequences
:
98 if strip
.type != 'SCENE':
101 if selected_scn_only
and not strip
.select
:
104 sounds
= send_sound_to_strip_scene(strip
, skip_mute
=skip_mute
)
109 print('INFO', f
'Sound duplicated in {ct} scenes')
111 print('ERROR', f
'No duplication occured')
114 class STORYPENCIL_OT_duplicate_sound_in_edit_scene(Operator
):
115 bl_idname
= "storypencil.duplicate_sound_in_edit_scene"
116 bl_label
= "Sounds To Scenes"
117 bl_description
= "Copy sound strips from VSE to the source scenes"
118 bl_options
= {'REGISTER', 'UNDO'}
121 def poll(cls
, context
):
122 if context
.space_data
.type != 'SEQUENCE_EDITOR':
127 def execute(self
, context
):
128 scene
= context
.scene
129 dispatch_sounds_in_scenes(
130 selected_scn_only
=scene
.storypencil_selected_scn_only
,
131 skip_mute
=scene
.storypencil_skip_sound_mute
)
133 bpy
.ops
.sequencer
.reload()