Created
May 14, 2020 07:06
-
-
Save tin2tin/ffe05cd36c23535156048075efc84218 to your computer and use it in GitHub Desktop.
Multilines, scrolling and fade in and out on a text effect https://developer.blender.org/T50218 (unfinished update)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ##### 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 sys | |
import os | |
#if sys.platform.startswith("win32"):# Non tested | |
# import winsound | |
#import exiftool # Put it in folder 2.78/scripts/modules | |
bl_info = { | |
"name": | |
"titles sequencer plus 10 ::", | |
"description": | |
"Ergonomic new titles functions for video editing in Blender VSE", | |
"author": | |
"Jean-Paul Favier - favijep@laposte.net, Turi Scandurra, Carlos Padial", | |
"version": (0, 0, 20161209), | |
"blender": (2, 80, 0), | |
"warning": | |
"ONLY TESTED ON LINUX Ubuntu 16.04.1 64 bits", | |
"category": | |
":", | |
"location": | |
"Sequencer", | |
"support": | |
"COMMUNITY" | |
} | |
## ************************************************************* | |
# Classes for the settings of a text effect | |
# | |
# # Add in space_sequencer.py - class SEQUENCER_PT_effect - strip.type == 'TEXT' after col.prop(strip, "align_y") | |
# # Sequencer plus | |
# col.operator('sequencerplus.move_text_start', text='Move title - cursor at strip start', icon='LAMP_POINT') | |
# col.operator('sequencerplus.move_text', text='Move title', icon='LAMP_POINT') | |
# col.label(text="Title position and size settings") | |
# col.operator("sequencerplus.title_set_start_param", text="Define start parameters") | |
# col.operator("sequencerplus.title_set_end_param", text="Define end parameters") | |
# col.label(text="Modify text") | |
# col.operator("sequencerplus.title_get_text", text="Modify title") | |
# row = layout.row(align=True) | |
# row.operator("sequencerplus.title_set_text", text="Paste title") | |
# row.operator("sequencerplus.title_set_text_center", text="Paste center") | |
# # End Sequencer plus | |
# See also down Classes for scrolling text effects | |
class Sequencer_Plus_Move_Text_Start(bpy.types.Operator): | |
""" Move the text of the text effect with the mouse | |
and move the time cursor at start of the strip """ | |
bl_label = 'Move_text' | |
bl_idname = 'sequencerplus.move_text_start' | |
bl_description = 'Click, move text with mouse and click' | |
def __init__(self): | |
print("Start") | |
def __del__(self): | |
print("End") | |
def execute(self, context): | |
scene_c = bpy.context.scene | |
bd_s_editor = bpy.data.scenes[scene_c.name].sequence_editor | |
diff_x = (self.x - self.init_x) | |
diff_x /= self.plage | |
diff_x = int(diff_x * 100) / 100 | |
bd_s_editor.sequences_all[self.Title].location[ | |
0] = self.x_init_position + diff_x | |
diff_y = (self.y - self.init_y) | |
diff_y /= self.plage | |
diff_y = int(diff_y * 100) / 100 | |
bd_s_editor.sequences_all[self.Title].location[ | |
1] = self.y_init_position + diff_y | |
def modal(self, context, event): | |
scene_c = bpy.context.scene | |
bd_s_editor = bpy.data.scenes[scene_c.name].sequence_editor | |
if event.type == 'MOUSEMOVE': # move mouse cursor | |
self.x = event.mouse_x | |
self.y = event.mouse_y | |
self.execute(context) | |
elif event.type == 'LEFTMOUSE': # Confirm | |
return {'FINISHED'} | |
elif event.type in ('RIGHTMOUSE', 'ESC'): # Undo | |
bd_s_editor.sequences_all[self.Title].location[ | |
0] = self.x_init_position | |
bd_s_editor.sequences_all[self.Title].location[ | |
1] = self.y_init_position | |
return {'CANCELLED'} | |
return {'RUNNING_MODAL'} | |
def invoke(self, context, event): | |
# plage = moving mouse range, initial position of the mouse cursor | |
scene_c = bpy.context.scene | |
bd_s_editor = bpy.data.scenes[scene_c.name].sequence_editor | |
self.plage = 300 | |
self.x = event.mouse_x | |
self.init_x = self.x | |
self.y = event.mouse_y | |
self.init_y = self.y | |
selectedStrips = bpy.context.selected_sequences | |
if selectedStrips: | |
for strip in selectedStrips: | |
self.Title = strip.name | |
# initial position of the text | |
strip_title = bd_s_editor.sequences_all[self.Title] | |
self.x_init_position = strip_title.location[0] | |
self.y_init_position = strip_title.location[1] | |
self.execute(context) | |
context.window_manager.modal_handler_add(self) | |
# The time cursor is moved to the start of the strip selected | |
# The background is visible and helps to position the text | |
bpy.context.scene.frame_current = strip.frame_offset_start + strip.frame_start | |
return {'RUNNING_MODAL'} | |
else: | |
return {'FINISHED'} | |
class Sequencer_Plus_Move_Text(bpy.types.Operator): | |
""" Move the text of the text effect with the mouse """ | |
bl_label = 'Move_text' | |
bl_idname = 'sequencerplus.move_text' | |
bl_description = 'Click on button, move text with mouse and click' | |
def __init__(self): | |
print("Start") | |
def __del__(self): | |
print("End") | |
def execute(self, context): | |
scene_c = bpy.context.scene | |
bd_s_editor = bpy.data.scenes[scene_c.name].sequence_editor | |
diff_x = (self.x - self.init_x) | |
diff_x /= self.plage | |
diff_x = int(diff_x * 100) / 100 | |
bd_s_editor.sequences_all[self.Title].location[ | |
0] = self.x_init_position + diff_x | |
diff_y = (self.y - self.init_y) | |
diff_y /= self.plage | |
diff_y = int(diff_y * 100) / 100 | |
bd_s_editor.sequences_all[self.Title].location[ | |
1] = self.y_init_position + diff_y | |
def modal(self, context, event): | |
scene_c = bpy.context.scene | |
bd_s_editor = bpy.data.scenes[scene_c.name].sequence_editor | |
if event.type == 'MOUSEMOVE': # move mouse cursor | |
self.x = event.mouse_x | |
self.y = event.mouse_y | |
self.execute(context) | |
elif event.type == 'LEFTMOUSE': # Confirm | |
return {'FINISHED'} | |
elif event.type in ('RIGHTMOUSE', 'ESC'): # Undo | |
bd_s_editor.sequences_all[self.Title].location[ | |
0] = self.x_init_position | |
bd_s_editor.sequences_all[self.Title].location[ | |
1] = self.y_init_position | |
return {'CANCELLED'} | |
return {'RUNNING_MODAL'} | |
def invoke(self, context, event): | |
scene_c = bpy.context.scene | |
bd_s_editor = bpy.data.scenes[scene_c.name].sequence_editor | |
# plage = moving mouse range, initial position of the mouse cursor | |
self.plage = 250 | |
self.x = event.mouse_x | |
self.init_x = self.x | |
self.y = event.mouse_y | |
self.init_y = self.y | |
selectedStrips = bpy.context.selected_sequences | |
if selectedStrips: | |
for strip in selectedStrips: | |
self.Title = strip.name | |
# initial position of the text | |
self.strip = strip | |
strip_start = strip.frame_start + strip.frame_offset_start | |
strip_end = strip.frame_final_end | |
if (scene_c.frame_current >= | |
strip_start) and (scene_c.frame_current <= strip_end): | |
strip_title = bd_s_editor.sequences_all[self.Title] | |
self.x_init_position = strip_title.location[0] | |
self.y_init_position = strip_title.location[1] | |
self.execute(context) | |
context.window_manager.modal_handler_add(self) | |
# The time bar is moved to the start of the strip selected | |
# The background is visible and helps to position the text | |
return {'RUNNING_MODAL'} | |
else: | |
if sys.platform.startswith("linux"): | |
sound_path = bpy.path.abspath("//../Sons/beep.wav") | |
os.system("aplay " + sound_path) | |
self.report( | |
{'ERROR'}, | |
"Time bar out of the limits of the selected strip") | |
# elif sys.platform.startswith("win32"): # Non tested | |
# sound_path = bpy.path.abspath("//..\\Sons\\beep.wav") | |
# winsound.PlaySound( sound_path, winsound.SND_FILENAME) | |
else: | |
pass | |
self.report({'ERROR'}, | |
"Time bar out of the limits of the selected strip") | |
return {'RUNNING_MODAL'} | |
else: | |
return {'FINISHED'} | |
class Sequencer_Plus_Title_Set_Start(bpy.types.Operator): | |
""" Set the position and the size of the text at the start of the strip (with keyframe) | |
""" | |
bl_label = 'Title set start parameters' | |
bl_idname = 'sequencerplus.title_set_start_param' | |
bl_description = 'Before click, set the position and the size of the text at the start of the effect' | |
@classmethod | |
def poll(cls, context): | |
return bpy.context.scene is not None | |
def execute(self, context): | |
scene_c = bpy.context.scene | |
bd_s_editor = bpy.data.scenes[scene_c.name].sequence_editor | |
selectedStrips = bpy.context.selected_sequences | |
# Test d'au moins une sélection | |
if selectedStrips: | |
for strip in selectedStrips: | |
self.Title = strip.name | |
strip_title = bd_s_editor.sequences_all[self.Title] | |
strip_start = strip_title.frame_start + strip_title.frame_offset_start | |
# delete existing keyframes | |
strip_title.keyframe_delete( | |
data_path="location", frame=strip_start, index=-1) | |
strip_title.keyframe_delete( | |
data_path="font_size", frame=strip_start, index=-1) | |
# initial position of the text | |
# insert keyframes using values of the sliders | |
strip_title.keyframe_insert( | |
data_path="location", frame=strip_start, index=-1) | |
strip_title.keyframe_insert( | |
data_path="font_size", frame=strip_start, index=-1) | |
return {'FINISHED'} | |
class Sequencer_Plus_Title_Set_End(bpy.types.Operator): | |
""" Set the position and the size of the text at the end of the strip with keyframe | |
""" | |
bl_label = 'Title set end parameters' | |
bl_idname = 'sequencerplus.title_set_end_param' | |
bl_description = 'Before click, set the position and the size of the text at the end of the effect' | |
@classmethod | |
def poll(cls, context): | |
return bpy.context.scene is not None | |
def execute(self, context): | |
scene_c = bpy.context.scene | |
bd_s_editor = bpy.data.scenes[scene_c.name].sequence_editor | |
fps = scene_c.render.fps | |
selectedStrips = bpy.context.selected_sequences | |
# Test d'au moins une sélection | |
if selectedStrips: | |
for strip in selectedStrips: | |
self.Title = strip.name | |
strip_title = bd_s_editor.sequences_all[self.Title] | |
# delete existing keyframes | |
strip_title.keyframe_delete( | |
data_path="location", | |
frame=strip_title.frame_final_end - fps, | |
index=-1) | |
strip_title.keyframe_delete( | |
data_path="font_size", | |
frame=strip_title.frame_final_end - fps, | |
index=-1) | |
# final position of the text | |
# insert keyframes using values of the sliders | |
strip_title.keyframe_insert( | |
data_path="location", | |
frame=strip_title.frame_final_end - fps, | |
index=-1) | |
strip_title.keyframe_insert( | |
data_path="font_size", | |
frame=strip_title.frame_final_end - fps, | |
index=-1) | |
return {'FINISHED'} | |
class Sequencer_Plus_Title_Get_text(bpy.types.Operator): | |
""" Get the text of the strip and put it in the text editor, block "Credits" | |
""" | |
bl_label = 'Title get text' | |
bl_idname = 'sequencerplus.title_get_text' | |
bl_description = 'Click to put the text inside the text editor, block "Credits"' | |
@classmethod | |
def poll(cls, context): | |
return bpy.context.scene is not None | |
def execute(self, context): | |
scene_c = bpy.context.scene | |
bd_s_editor = bpy.data.scenes[scene_c.name].sequence_editor | |
# fps = scene_c.render.fps | |
selectedStrips = bpy.context.selected_sequences | |
# Test d'au moins une sélection | |
if selectedStrips: | |
for strip in selectedStrips: | |
try: | |
bpy.data.texts["Credits"] | |
except: | |
text_object = bpy.data.texts.new(name="Credits") | |
text_credits_orig = bd_s_editor.sequences_all[ | |
strip.name].text | |
text_object.write(text_credits_orig) | |
return {'FINISHED'} | |
class Sequencer_Plus_Title_Set_text(bpy.types.Operator): | |
""" Set the text of the strip from block "Credits" | |
""" | |
bl_label = 'Title set text' | |
bl_idname = 'sequencerplus.title_set_text' | |
bl_description = 'Before click, set the text of block "Credits"' | |
@classmethod | |
def poll(cls, context): | |
return bpy.context.scene is not None | |
def execute(self, context): | |
scene_c = bpy.context.scene | |
bd_s_editor = bpy.data.scenes[scene_c.name].sequence_editor | |
# fps = scene_c.render.fps | |
selectedStrips = bpy.context.selected_sequences | |
# Test d'au moins une sélection | |
if selectedStrips: | |
for strip in selectedStrips: | |
if strip.type == "TEXT": | |
self.Title = strip.name | |
text_object = bpy.data.texts["Credits"] | |
texte = "" | |
for line in range(0, len(text_object.lines)): | |
texte += text_object.lines[line].body + "\n" | |
line += 1 | |
bd_s_editor.sequences_all[strip.name].text = texte | |
return {'FINISHED'} | |
class Sequencer_Plus_Title_Set_Text_Center(bpy.types.Operator): | |
""" Set the text of the strip after centering, block "Credits" | |
""" | |
bl_label = 'Title set text' | |
bl_idname = 'sequencerplus.title_set_text_center' | |
bl_description = 'Before click, set the text in block "Credits" which will be centered in the strip' | |
@classmethod | |
def poll(cls, context): | |
return bpy.context.scene is not None | |
def execute(self, context): | |
scene_c = bpy.context.scene | |
bd_s_editor = bpy.data.scenes[scene_c.name].sequence_editor | |
selectedStrips = bpy.context.selected_sequences | |
# Test at least one selection | |
if selectedStrips: | |
for strip in selectedStrips: | |
if strip.type == "TEXT": | |
self.Title = strip.name | |
text_object = bpy.data.texts["Credits"] | |
texte = "" | |
for line in range(0, len(text_object.lines)): | |
texte += text_object.lines[line].body + "\n" | |
line += 1 | |
texte = self.center_title(texte) | |
bd_s_editor.sequences_all[strip.name].text = texte | |
return {'FINISHED'} | |
def center_title(self, text): | |
lines = text.split("\n") | |
length_max = len(lines[0]) | |
for line in lines: | |
length = len(line) | |
if length > length_max: | |
length_max = length | |
center_text = "" | |
for line in lines: | |
line = line.center(length_max) | |
center_text = center_text + "\n" + line | |
return center_text | |
# End Classes for the settings of a text effect | |
# ************************************************************* | |
# ************************************************************* | |
# Classes for scrolling text and fade in or out effects | |
# New menu | |
# # Add a new menu in space_sequencer.py - SEQUENCER_MT_editor_menus | |
# # after layout.menu("SEQUENCER_MT_strip") | |
# # Sequencer plus | |
# layout.menu("SEQUENCER_MT_title") | |
# # End Sequencer plus | |
## Add in space_sequencer.py a new class SEQUENCER_MT_title(Menu) | |
# # Sequencer plus | |
#class SEQUENCER_MT_title(Menu): | |
# bl_label = "Tiitle scroll Horiz" | |
# | |
# def draw(self, context): | |
# layout = self.layout | |
# layout.operator_context = 'INVOKE_REGION_WIN' | |
# | |
# # Title | |
# layout.operator("sequencerplus.add_title", text="Still title") | |
# layout.operator("sequencerplus.add_title_fade_inout", | |
# text="Fade in-out still title") | |
# layout.operator("sequencerplus.add_title_h_scroll", | |
# text="Title H Right moving") | |
# layout.operator("sequencerplus.add_title_v_scroll_down", | |
# text="Title V down moving") | |
# layout.operator("sequencerplus.add_title_v_credits_text", text="Credits V up moving") | |
# layout.operator("sequencerplus.title_date", text="Date") | |
# # End Sequencer plus | |
class Sequencer_Plus_Add_Title(bpy.types.Operator): | |
""" Add strip text of the text effect (duration 5 seconds)""" | |
# Add in a new menu the add effect text | |
bl_label = 'Title' | |
bl_idname = 'sequencerplus.add_title' | |
bl_description = 'Add the text of text effect ' | |
@classmethod | |
def poll(cls, context): | |
return bpy.context.scene is not None | |
def execute(self, context): | |
scene_c = bpy.context.scene | |
bd_s_editor = bpy.data.scenes[scene_c.name].sequence_editor | |
bpy.ops.sequencer.effect_strip_add( | |
frame_start=scene_c.frame_current, | |
frame_end=scene_c.frame_current + 125, | |
channel=3, | |
replace_sel=True, | |
overlap=False, | |
type='TEXT') | |
selectedStrips = bpy.context.selected_sequences | |
# Test at least one selection | |
if selectedStrips: | |
for strip in selectedStrips: | |
self.Title = strip.name | |
bd_s_editor.sequences_all[self.Title].font_size = 80 | |
bd_s_editor.sequences_all[self.Title].text = "Title" | |
return {'FINISHED'} | |
# From "Extra Sequencer Actions", | |
# authors: "Turi Scandurra, Carlos Padial", | |
class Sequencer_Plus_Add_Title_Fade_Inout(bpy.types.Operator): | |
""" Add strip text of the text effect (duration 5 seconds) | |
with one second fades in and out""" | |
bl_label = 'Title' | |
bl_idname = 'sequencerplus.add_title_fade_inout' | |
bl_description = 'Add the text of text effect with fade in and out' | |
@classmethod | |
def poll(cls, context): | |
return bpy.context.scene is not None | |
def execute(self, context): | |
scene_c = bpy.context.scene | |
bd_s_editor = bpy.data.scenes[scene_c.name].sequence_editor | |
fps = scene_c.render.fps | |
bpy.ops.sequencer.effect_strip_add( | |
frame_start=scene_c.frame_current, | |
frame_end=scene_c.frame_current + 125, | |
channel=3, | |
replace_sel=True, | |
overlap=False, | |
type='TEXT') | |
selectedStrips = bpy.context.selected_sequences | |
# Test at least one selection | |
if selectedStrips: | |
for strip in selectedStrips: | |
self.Title = strip.name | |
bd_s_editor.sequences_all[self.Title].font_size = 80 | |
bd_s_editor.sequences_all[self.Title].text = "Title" | |
strip_start = strip.frame_final_start | |
strip_end = strip.frame_final_end | |
if (strip.type == "SOUND"): | |
strip.volume = 0 | |
strip.keyframe_insert('volume', -1, strip_end) | |
strip.keyframe_insert('volume', -1, strip_start) | |
strip.volume = 1 | |
strip.keyframe_insert('volume', -1, strip_end - fps) | |
strip.keyframe_insert('volume', -1, strip_start + fps) | |
else: | |
originalAlpha = strip.blend_alpha | |
strip.blend_alpha = 0 | |
strip.keyframe_insert('blend_alpha', -1, strip_end) | |
strip.keyframe_insert('blend_alpha', -1, strip_start) | |
strip.blend_alpha = originalAlpha | |
strip.keyframe_insert('blend_alpha', -1, strip_end - fps) | |
strip.keyframe_insert('blend_alpha', -1, strip_start + fps) | |
return {'FINISHED'} | |
class Sequencer_Plus_Add_Title_H_Scroll(bpy.types.Operator): | |
""" Add strip wich scrolls horizontally the text of the text effect | |
(duration 5 seconds)""" | |
bl_label = 'Add title scroll h' | |
bl_idname = 'sequencerplus.add_title_h_scroll' | |
bl_description = 'Add a text effect strip with horizontal scroll\nModify the keyframes with the graph editor' | |
@classmethod | |
def poll(cls, context): | |
return bpy.context.scene is not None | |
def execute(self, context): | |
scene_c = bpy.context.scene | |
bd_s_editor = bpy.data.scenes[scene_c.name].sequence_editor | |
fps = scene_c.render.fps | |
bpy.ops.sequencer.effect_strip_add( | |
frame_start=scene_c.frame_current, | |
frame_end=scene_c.frame_current + 5 * fps, | |
channel=3, | |
replace_sel=True, | |
overlap=False, | |
type='TEXT') | |
selectedStrips = bpy.context.selected_sequences | |
# Test at least one selection | |
if selectedStrips: | |
for strip in selectedStrips: | |
bd_s_editor.sequences_all[strip.name].font_size = 80 | |
bd_s_editor.sequences_all[strip.name].text = "Title" | |
strip_title = bd_s_editor.sequences_all[strip.name] | |
strip_start = strip_title.frame_start + strip_title.frame_offset_start | |
# initial position of the text | |
strip_title.location[0] = -0.2 | |
strip_title.location[1] = 0.1 | |
# final position of the text | |
strip_title.keyframe_insert( | |
data_path="location", frame=strip_start, index=-1) | |
strip_title.location[0] = 0.7 | |
strip_title.location[1] = 0.1 | |
strip_title.keyframe_insert( | |
data_path="location", | |
frame=strip_title.frame_final_end - fps, | |
index=-1) | |
return {'FINISHED'} | |
class Sequencer_Plus_Add_Title_V_Scroll_down(bpy.types.Operator): | |
""" Add strip wich scrolls down vertically the text of the text effect | |
(duration 5 seconds)""" | |
bl_label = 'Add scroll down title' | |
bl_idname = 'sequencerplus.add_title_v_scroll_down' | |
bl_description = 'Add a text effect strip with vertical down scroll\nModify the keyframes with the graph editor ' | |
@classmethod | |
def poll(cls, context): | |
return bpy.context.scene is not None | |
def execute(self, context): | |
scene_c = bpy.context.scene | |
bd_s_editor = bpy.data.scenes[scene_c.name].sequence_editor | |
fps = scene_c.render.fps | |
bpy.ops.sequencer.effect_strip_add( | |
frame_start=scene_c.frame_current, | |
frame_end=scene_c.frame_current + 5 * fps, | |
channel=3, | |
replace_sel=True, | |
overlap=False, | |
type='TEXT') | |
selected_strips = bpy.context.selected_sequences | |
# Test at least one selection | |
if selected_strips: | |
for strip in selected_strips: | |
bd_s_editor.sequences_all[strip.name].font_size = 80 | |
bd_s_editor.sequences_all[strip.name].text = "Title" | |
strip_title = bd_s_editor.sequences_all[strip.name] | |
strip_start = strip_title.frame_start + strip_title.frame_offset_start | |
# delete existing keyframes | |
strip_title.keyframe_delete( | |
data_path="location", frame=strip_start, index=-1) | |
strip_title.keyframe_delete( | |
data_path="location", | |
frame=strip_title.frame_final_end - fps, | |
index=-1) | |
# initial position of the text | |
strip_title.location[0] = 0.5 | |
strip_title.location[1] = 1 | |
# final position of the text | |
strip_title.keyframe_insert( | |
data_path="location", frame=strip_start, index=-1) | |
strip_title.location[0] = 0.5 | |
strip_title.location[1] = 0.1 | |
strip_title.keyframe_insert( | |
data_path="location", | |
frame=strip_title.frame_final_end - fps, | |
index=-1) | |
return {'FINISHED'} | |
class Sequencer_Plus_Add_Title_V_Credits_text(bpy.types.Operator): | |
""" Add strip wich scrolls up vertically the credits on several lines | |
(duration 20 seconds)""" | |
bl_label = 'Add title credits with a text edited in the text editor' | |
bl_idname = 'sequencerplus.add_title_v_credits_text' | |
bl_description = 'Add a text effect strip with vertical down scroll\nof credits edited in the text editor, block "Credits" ' | |
@classmethod | |
def poll(cls, context): | |
return bpy.context.scene is not None | |
def execute(self, context): | |
scene_c = bpy.context.scene | |
bd_s_editor = bpy.data.scenes[scene_c.name].sequence_editor | |
fps = scene_c.render.fps | |
bpy.ops.sequencer.effect_strip_add( | |
frame_start=scene_c.frame_current, | |
frame_end=scene_c.frame_current + 20 * fps, | |
channel=3, | |
replace_sel=True, | |
overlap=False, | |
type='COLOR') | |
bpy.ops.sequencer.effect_strip_add( | |
frame_start=scene_c.frame_current, | |
frame_end=scene_c.frame_current + 20 * fps, | |
channel=4, | |
replace_sel=True, | |
overlap=False, | |
type='TEXT') | |
selectedStrips = bpy.context.selected_sequences | |
# Test at least one selection and selects the last | |
if selectedStrips: | |
for strip in selectedStrips: | |
credits = "Line 1 \nLigne 2 \nLigne 3 \nLigne 4\nLigne 5 long\nLine 6 \nLigne 7 \nLigne 8 \nLigne 9\nLigne 10" | |
bd_s_editor.sequences_all[strip.name].font_size = 40 | |
bd_s_editor.sequences_all[strip.name].text = credits | |
strip_title = bd_s_editor.sequences_all[strip.name] | |
strip_start = strip_title.frame_start + strip_title.frame_offset_start | |
# initial position of the text | |
strip_value = bd_s_editor.sequences_all[strip.name].text | |
# The position of the first line depends of the font size and the number of lines | |
character_height = bd_s_editor.sequences_all[ | |
strip.name].font_size | |
start_y_position = self.nb_lines(strip_value) * int( | |
character_height) | |
strip_title.location[0] = 0.5 | |
# 0.035 experimental coefficient | |
strip_title.location[ | |
1] = -int(0.035 * 100 * start_y_position / 25) / 100 | |
# final position of the text | |
strip_title.keyframe_insert( | |
data_path="location", frame=strip_start, index=-1) | |
strip_title.location[0] = 0.5 | |
strip_title.location[1] = 1.0 | |
strip_title.keyframe_insert( | |
data_path="location", | |
frame=strip_title.frame_final_end - fps, | |
index=-1) | |
return {'FINISHED'} | |
def nb_lines(self, text): | |
n_lines = len(text.split("\n")) | |
return n_lines | |
#End Classes for scrolling text and fade in or out effects | |
# ************************************************************* | |
# ************************************************************* | |
# Classes for various text effects | |
class Sequencer_Plus_Add_Title_Date(bpy.types.Operator): | |
""" The text of the text effect is the date of | |
the video strip selected ; months in French | |
Use the velvet proxies and original files *.mts""" | |
bl_label = 'Title date' | |
bl_idname = 'sequencerplus.title_date' | |
bl_description = 'The text of text effect is the date of the video strip selected' | |
@classmethod | |
def poll(cls, context): | |
return bpy.context.scene is not None | |
def execute(self, context): | |
scene_c = bpy.context.scene | |
bd_s_editor = bpy.data.scenes[scene_c.name].sequence_editor | |
selected_strips = bpy.context.selected_sequences | |
# selectedStrips= None | |
# Test at least one selection and selects the last | |
# if selected_strips : | |
# for strip in selected_strips: | |
# if strip.type =='MOVIE' : | |
# path_strip =bd_s_editor.sequences_all[strip.name].filepath | |
# path_strip = self.file_proxy_origin(path_strip) | |
# if os.path.isfile(path_strip): | |
# try: | |
# with exiftool.ExifTool() as et: | |
# date = et.get_tag(tag = "File:FileModifyDate", filename = path_strip) | |
# except: | |
# self.report({'ERROR'},"erreur EXIF" + date) | |
# bpy.ops.sequencer.select_all(action='DESELECT') | |
# scene_c.frame_current = strip.frame_final_start | |
# bpy.ops.sequencer.effect_strip_add(frame_start=scene_c.frame_current, | |
# frame_end=scene_c.frame_current+125, channel=3, replace_sel=True, | |
# overlap=False, type='TEXT') | |
# selectedStrips = bpy.context.selected_sequences | |
# if selectedStrips : | |
# for strip in selectedStrips: | |
# title = strip.name | |
# date = self.date_conversion(date) | |
# bd_s_editor.sequences_all[title].text = date | |
# bd_s_editor.sequences_all[title].font_size = 90 | |
# strip.location[0] = 0.5 | |
# strip.location[1] = 0.5 | |
# else : | |
# message = "Select a strip" | |
# self.beep_sys(message) | |
# return {'FINISHED'} | |
def date_conversion(self, date_number): | |
month_list = [ | |
"janvier", "février", "mars", "avril", "mai", "juin", "juillet", | |
"août", "septembre", "octobre", "novembre", "décembre" | |
] | |
split_list_day_hour = date_number.replace(" ", ":") | |
split_list = split_list_day_hour.split(":") | |
date = split_list[2] + " " + month_list[int( | |
split_list[1] | |
) - 1] + " " + split_list[0] + " " + split_list[3] + " h " + split_list[4] | |
return date | |
pass | |
def file_proxy_origin(self, filename): | |
""" If velvet proxies used, we search the date of the original file | |
in the same folder """ | |
if "_proxy.mov" in filename: | |
filename_base = filename | |
# for .mts video files, ToDo : other file types | |
original_name = filename.replace("_proxy.mov", ".mts") | |
try: | |
os.path.isfile(original_name) | |
except: | |
self.report({'INFO'}, "No original file in this folder") | |
return filename_base | |
else: | |
return original_name | |
else: | |
return filename | |
# def beep_sys (self, message): | |
# if sys.platform.startswith("linux") : | |
## The file beep.wav is in a folder ~/project/Sons | |
## and the .blend file in a folder ~/project/Editing | |
# sound_path = bpy.path.abspath("//../Sons/beep.wav") | |
# os.system("aplay "+ sound_path) | |
## elif sys.platform.startswith("win32"): # Non tested | |
## sound_path = bpy.path.abspath("//..\\Sons\\beep.wav") | |
## winsound.PlaySound( sound_path, winsound.SND_FILENAME) | |
# else : | |
# pass | |
# self.report({'ERROR'},message) | |
# End of Classes for various text effects | |
# ************************************************************* | |
classes = ( | |
Sequencer_Plus_Move_Text_Start, | |
Sequencer_Plus_Move_Text, | |
Sequencer_Plus_Title_Set_Start, | |
Sequencer_Plus_Title_Set_End, | |
Sequencer_Plus_Title_Get_text, | |
Sequencer_Plus_Title_Set_text, | |
Sequencer_Plus_Title_Set_Text_Center, | |
Sequencer_Plus_Add_Title, | |
Sequencer_Plus_Add_Title_Fade_Inout, | |
Sequencer_Plus_Add_Title_H_Scroll, | |
Sequencer_Plus_Add_Title_V_Scroll_down, | |
Sequencer_Plus_Add_Title_V_Credits_text, | |
Sequencer_Plus_Add_Title_Date, | |
) | |
def register(): | |
for i in classes: | |
bpy.utils.register_class(i) | |
def unregister(): | |
for i in classes: | |
bpy.utils.unregister_class(i) | |
if __name__ == "__main__": | |
register() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment