Очень часто при создании видео в Blender VSE бывает нужно отдельно формировать видео-ряд без звука, и только потом на отредактированный видео-поток накладывать отдельно подготовленные звуковые дорожки. В тоже время при добавлении видео стрипа в VSE он добавляется вместе со своей звуковой дорожкой, причем аудио еще и дополнительно склеено с видео. Разъединить аудио- и видео-дорожки не сложно, но это занимает время. Напишем небольшой скрипт, который будет автоматически отсоединять аудио от видео в добавляемом в VSE стрипе, и дополнительно совсем удалять исходную аудио-дорожку.
Для начала нам нужно сохранить список уже имеющихся в VSE стрипов, чтобы не обрабатывать их каждый раз повторно при добавлении нового стрипа.
Сохраним список имен имеющихся стрипов и добавим его в объект WindowManager, чтобы у нас в дальнейшем был к нему доступ.
|
1 2 |
bpy.context.window_manager['existed_strips'] = [_strip.name for _strip \ in bpy.context.scene.sequence_editor.strips[:]] |
Определим функцию, в которой мы будем совершать все операции по разъединению дорожек и удалению аудио.
|
1 |
def auto_remove_audio_from_strip(scene, depsgraph): |
Эта функция будет у нас вызываться каждый раз, когда мы добавляем в VSE новый стрип.
Здесь нам в первую очередь нужно определить добавленные стрипы. Это очень просто — они всегда будут выделены. Получим список имен выделенных стрипов.
|
1 |
selected_strips = [_strip.name for _strip in bpy.context.scene.sequence_editor.strips if _strip.select] |
Нам нужно будет выполнить несколько действий. Поэтому сделаем переменную-флаг, определяющую, нужно ли нам обработать выделенные стрипы или нет.
|
1 2 3 4 5 |
process = False for _strip in selected_strips: if _strip not in bpy.context.window_manager['existed_strips']: # need to process process = True |
Изначально флаг стоит в значение False, т.е. мы ничего не обрабатываем. Затем мы ищем имена выделенных стрипов в ранее сохраненном списке всех уже имеющихся стрипов. И если имени выделенного стрипа в списке нет — переставляем флаг в True, что значит, что выделенные стрипы — новые и нам нужно будет их обработать.
Итак, если нам нужно обработать выделенные стрпиы:
|
1 |
if process: |
Сначала удалим все аудио-дорожки.
|
1 2 3 4 |
for _strip in selected_strips: strip_ptr = bpy.context.scene.sequence_editor.strips.get(_strip) if strip_ptr.type == 'SOUND': bpy.context.scene.sequence_editor.strips.remove(strip_ptr) |
Здесь мы обращаемся к стрипу через указатель по его имени и если тип текущего стрипа «SOUND» — удаляем его.
Теперь, когда у нас остались одни видео-дорожки, обновим список имен уже существующих и обработанных стрипов, чтобы при последующих действиях не обрабатывать текущие по новой.
|
1 2 |
bpy.context.window_manager['existed_strips'] = [_strip.name for _strip \ in bpy.context.scene.sequence_editor.strips[:]] |
На этом мы завершаем формирование нашей функции. Осталось сделать так, чтобы она вызывалась в нужный нам момент — при добавлении новых стрипов.
Конкретного обработчика, вызывающегося при добавлении стрипов в VSE, в Blender Python API нет. Но мы можем отлавливать любые события изменения сцены, в том числе и добавление стрипов, через общий обработчик depsgraph_update_post.
Зарегистрируем вызов нашей функции через него.
|
1 2 |
if auto_remove_audio_from_strip not in bpy.app.handlers.depsgraph_update_post: bpy.app.handlers.depsgraph_update_post.append(auto_remove_audio_from_strip) |
Теперь мы можем запустить наш код.
При его выполнении функция, которую мы написали, будет вызываться при каждом изменении сцены. А уже внутри функции мы определяем, было ли это изменение сцены вызвано добавлением новых стрипов, и если да — мы обрабатываем добавленные в VSE стрипы удаляя из них аудио-дорожку.

.blend file on Patreon