Openshot Blender



  1. Openshot Blender Animated Title
  2. Blender Software
  3. Openshot Blender

Réaliser des titres animés pour OpenShot à l’aide de Blender

Retrouvez les explications complètes dans Linux Pratique 77

Blender 2.81 and OpenShot Hello, I just installed the fresh OpenShot editor and it complains of missing Blender, although I set its proper path, 'C:Program FilesBlender FoundationBlender 2.81blender.exe'. OpenShot is Award winning Opensource Video Editor Softwarehttps://www.openshot.org/https://www.blender.org/.

Zip file of the animated title

Softtext.zip

Animation Idea and automation

The first thing to do consists in creating an title animation with Blender. You can grab ideas all over the net. Just make a beautiful title in 3D wich is animated :-).

After that, you need to automate it using the API of blender. You can read lots of tutorial, watch amazing videos too. This is the big part of the work : create and automate.

It remains the integration in Openshot. That’s I’m going to explain here, based on an example.

Soft text animation and automation

Blender capture of the working blend file

The chosen animation on this example, is made of a falling text on a rough surface. The text is made of a soft material. So when reaching the ground, the text bounces and trembles before stopping. In the simulation, we can add a cylinder to show more physical effects.

Source code of the automation (using Blender API)

In this source code, we manage the possibility to hide the red cylinder and its physical effect on our soft text. The control variable is name “cylinder”

import bpy
from bpy.props import *
from math import pi
cylinder ='1'
#http://www.sebastianbauer.name/archive/117
def moveToLayer( object, layer ):
layers = [False]*20
layers[layer] = True
object.layers = layers
def createSoftText(title,extrude,bevel_depth,spacemode,textsize,width,font):
if cylinder'1':
bpy.data.objects['Cylinder'].hide_render = False
bpy.data.objects['Cylinder'].hide = False
bpy.ops.object.select_all(action='DESELECT')
#selecting Ground
bpy.context.scene.objects.active = bpy.data.objects['Cylinder']
bpy.context.scene.objects.active.select = True
#if bpy.data.objects['Ground'].modifiers.keys()[0] != 'Collision':
if bpy.data.objects['Cylinder'].modifiers.find('Collision') -1:
#print('collision = empty')
bpy.ops.object.modifier_add(type='COLLISION')
else:
print('OK')
else:
bpy.ops.object.select_all(action='DESELECT')
#selecting Cylinder
bpy.context.scene.objects.active = bpy.data.objects['Cylinder']
bpy.context.scene.objects.active.select = True
if bpy.data.objects['Cylinder'].modifiers.find('Collision') != -1:
bpy.ops.object.modifier_remove(modifier='Collision')
bpy.data.objects['Cylinder'].hide = True
bpy.data.objects['Cylinder'].hide_render = True
bpy.ops.object.select_all(action='DESELECT')
bpy.ops.object.text_add(view_align=False, enter_editmode=False,location=(0, 0, 0), rotation=(0, 0, 0))
ActiveObjectText = bpy.context.scene.objects.active
newtext = bpy.context.scene.objects.active
#erasing previous objects
if bpy.context.scene.objects.active.name != 'Text':
bpy.ops.object.select_all(action='DESELECT')
#selecting and erasing Text
bpy.context.scene.objects.active = bpy.data.objects['Text']
bpy.context.scene.objects.active.select = True
bpy.ops.object.delete(use_global=False)
bpy.ops.object.select_all(action='DESELECT')
#need to delete other objects
bpy.ops.object.select_all(action='DESELECT')
#selecting and erasing Turbulence field
bpy.context.scene.objects.active = bpy.data.objects['Enveloppe2']
bpy.context.scene.objects.active.select = True
bpy.ops.object.delete(use_global=False)
#selecting newText
bpy.context.scene.objects.active = newtext
bpy.context.scene.objects.active.select = True
#naming/renaming the text
bpy.context.scene.objects.active.name = 'Text';
bpy.context.scene.objects.active = bpy.data.objects['Text']
#rotating text
ActiveObjectText.rotation_euler[0]=0.0 #xaxis
ActiveObjectText.rotation_euler[1]=0.0 #yaxis
ActiveObjectText.rotation_euler[2]=0.0 #zaxis
ActiveObjectText.location[0]=0
ActiveObjectText.location[1]=-9.75
ActiveObjectText.location[2]=5 #dur to shadow on the ground
#changing text
ActiveObjectText.data.body = title
#centering text
ActiveObjectText.data.align= spacemode
#extrude text
ActiveObjectText.data.extrude=extrude
#bevel text
ActiveObjectText.data.bevel_depth = bevel_depth
ActiveObjectText.data.bevel_resolution = 5
#text size
ActiveObjectText.data.size = textsize
bpy.context.scene.objects.active.data.space_character = width
bpy.context.scene.objects.active.data.font = font
#convert to mesh to apply effect
bpy.ops.object.convert(target='MESH', keep_original=False)
#put origin to center of text
#bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY', center='MEDIAN')
# Don't use Median, because it does not always put the origin to the center!
bpy.ops.object.origin_set(type='GEOMETRY_ORIGIN', center='BOUNDS')
#affect material
ActiveObjectText.data.materials.append(bpy.data.materials['MAT_PRE_Obsidian'])
#copy the pre loopecut cube
bpy.ops.object.select_all(action='DESELECT')
#obsolete
#bpy.ops.object.select_name(name='Enveloppe')
bpy.context.scene.objects.active = bpy.context.scene.objects['Enveloppe']
#activate in 3D
bpy.context.scene.objects.active.select = True
bpy.ops.object.duplicate(linked=False, mode='TRANSLATION')
#bpy.ops.object.duplicate_move(OBJECT_OT_duplicate={'linked':False, 'mode':'TRANSLATION'}, TRANSFORM_OT_translate={'value':(0, 0, 0), 'constraint_axis':(False, False, False), 'constraint_orientation':'GLOBAL', 'mirror':False, 'proportional':'DISABLED', 'proportional_edit_falloff':'SMOOTH', 'proportional_size':1, 'snap':False, 'snap_target':'CLOSEST', 'snap_point':(0, 0, 0), 'snap_align':False, 'snap_normal':(0, 0, 0), 'texture_space':False, 'release_confirm':False})
ActiveObjectEnveloppe = bpy.context.scene.objects.active
ActiveObjectEnveloppe.name = 'Enveloppe2'
ActiveObjectEnveloppe.draw_type = 'WIRE'
ActiveObjectEnveloppe.hide_render = True
#need to be on the visible layer to do duplication?
#moving object
ActiveObjectEnveloppe.location[0]=0
ActiveObjectEnveloppe.location[1]=-9.75
ActiveObjectEnveloppe.location[2]=5
# mo ve to layer 0 (first one)
#moveToLayer(ActiveObjectEnveloppe,0)
#adjust size of existed envelope to text
IncrementX = 0.3
IncrementY = 0.3
IncrementZ = 0.15
ActiveObjectEnveloppe.dimensions = (ActiveObjectText.dimensions[0]+IncrementX),(ActiveObjectText.dimensions[1]+IncrementY), (ActiveObjectText.dimensions[2]+IncrementZ)
#bpy.ops.object.origin_set(type='GEOMETRY_ORIGIN', center='MEDIAN')
bpy.ops.object.origin_set(type='GEOMETRY_ORIGIN', center='BOUNDS')
bpy.ops.object.modifier_add(type='SOFT_BODY')
#link text to enveloppe
bpy.ops.object.select_all(action='DESELECT')
#obsolete
#bpy.ops.object.select_name(name='Enveloppe')
bpy.context.scene.objects.active = ActiveObjectText
#activate in 3D
bpy.context.scene.objects.active.select = True
bpy.ops.object.modifier_add(type='MESH_DEFORM')
#configuring mesh deform
ActiveObjectText.modifiers['MeshDeform'].object = ActiveObjectEnveloppe
ActiveObjectText.modifiers['MeshDeform'].precision = 6 #<6 does not work!!! grid precision?
#binding text to cube
bpy.ops.object.meshdeform_bind(modifier='MeshDeform')
#softbody configuration
ActiveObjectEnveloppe.soft_body.use_goal=False
ActiveObjectEnveloppe.soft_body.use_stiff_quads = True
ActiveObjectEnveloppe.soft_body.plastic=10
ActiveObjectEnveloppe.data.update()
bpy.ops.ptcache.free_bake_all() # erase baked dynamics
bpy.ops.ptcache.bake_all() # bake dynamics : take time but needed before rendering animation
font = bpy.data.fonts['Bfont'] #don't forget to save datablock with Bfont :-)
extrude = 0.1
bevel_depth = 0.01
spacemode = 'CENTER'
text_size = 1.0
width = 1.0
createSoftText(title,extrude,bevel_depth,spacemode,text_size,width,font)

Result image (number 85 in animation)

Making of

Integration

How it works

Now the animation is full fonctionning in Blender (You can try it with the blend file embedded in the ZIP archive). We have to use it with Openshot. Before we need to understand how an animation made with Blender can be used in Openshot.

For that, Openshot use the following synoptic :

Openshot uses 4 files to be able to propose to the user a new 3D title :

  • An icon file which represents the final render of the title in th e Openshot GUI
  • An XML file which contains the GUI interface for configuring the 3D title
  • A blender file, the main file, which will be use by Blender to generate the animation
  • An python file which contains the core code for modifying the blender file according to configuration made by the user in the GUI. All the modification will be given to the blend file when rendering.
    These files are located in different directories under /usr/share/pyshared/openshot/blender :
Blender
$ tree -d /usr/share/pyshared/openshot/blender
/usr/share/pyshared/openshot/blender
├── blend
├── earth
├── icons
└── scripts
4 directories

The « blender » directory contains the « XML » files of the titles GUI configurators. The « blend » directory contains originals Blender files which embed animation on a generic text. The « earth » directory contains NASA images for the realistic earth title. The “icons” directory contains icons for the title GUI. The “scripts” directory contains python files which link Openshot to Blender for rendering. Theses files are the most difficult to write. They contains all the automation of the animation, and the Blender API commands which modify the original blender file to suit the user’s configuration.

So we need to create these files for our soft text animation.

When the 3D Title is configured, you can launched rendering. At this time, Openshot is calling Blender in commandline mode like that :

Blender command: /home/yann/Téléchargements/blender-2.62-linux-glibc27-x86_64/blender -b '/usr/lib/pymodules/python2.7/openshot/blender/blend/explode.blend' -P '/home/yann/.openshot/blender/cdd6b89e-1439-11e2-a257-0024d6b0a314/explode.py'
update_image: /home/yann/.openshot/blender/cdd6b89e-1439-11e2-a257-0024d6b0a314/TitleFileName0075.png
Blender render thread finished

Blender is run with two parameters :

  • « -b » indicates the blend file to use and render in background. This option allows to use Openshot during the render ;
  • « -P » indicates the python script to be executed with the blend file.

The sample image is written in a subdirectory of your home « /.openshot/blender ».

Creation from previous animation

Except for the icon file, we will use existing files from the Openshot distribution software to create the new ones.

Here is our new icon :

Other file are created by copying existing files :

$ cp /home/yann/Documents/articles_lpmag/article_titre_openshot/images/title_icon.png ./icons/softtext.png
$ cp fly_by_1.xml softtext.xml
$ cp /home/yann/blender/softtext/mysofttext_openshot.blend blend/softtext.blend
$ cp scripts/fly_by_1.py scripts/softtext.py

Modification of the XML file for interface

We modify the head of the file to suit the new animation :

<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<!DOCTYPE openshot-effect>
<effect>
<title translatable='True'>Falling Soft Text</title>
<description translatable='True'>The soft boby title is on the ground</description>
<icon>softtext.png</icon>
<category>Video</category>
<service>softtext.blend</service>

And in order to manage the cylinder in the animation, we add a dropdown menu in th e GUI :

<param name='cylinder_on_off' type='dropdown' description='>
<values>
<value name='Yes' num='1'/>
<value name='No' num='0'/>
</values>
<default>1</default>

Finally modify the animation duration to fit you blend file animation length :

<param name='end_frame' type='spinner' description='>
<min>144</min>
<max>144</max>
<default>144</default>
</param>

Even if the new title is not yet operational, you can see the new GUI for our sofftext by launching Openshot :

Modification of the python script

We need to modify the python script to match the new 3D title.

This file is globally divided in 3 parts :

  • Inclusions and funtions ;
  • Initialisation of all the parameters ;
  • Modification of the Blender file parameters from the Openshot GUI.

Just after the “loadfont” function we put our “createSoftText” function

def createSoftText(title,extrude,bevel_depth,spacemode,textsize,width,font):
if cylinder'1':
bpy.data.objects['Cylinder'].hide_render = False
bpy.data.objects['Cylinder'].hide = False
bpy.ops.object.select_all(action='DESELECT')
#selecting Ground
bpy.context.scene.objects.active = bpy.data.objects['Cylinder']
bpy.context.scene.objects.active.select = True
#if bpy.data.objects['Ground'].modifiers.keys()[0] != 'Collision':
if bpy.data.objects['Cylinder'].modifiers.find('Collision') -1:
#print('collision = empty')
bpy.ops.object.modifier_add(type='COLLISION')
#else:
#print('OK')
else:
bpy.ops.object.select_all(action='DESELECT')
#selecting Cylinder
bpy.context.scene.objects.active = bpy.data.objects['Cylinder']
bpy.context.scene.objects.active.select = True
if bpy.data.objects['Cylinder'].modifiers.find('Collision') != -1:
bpy.ops.object.modifier_remove(modifier='Collision')
bpy.data.objects['Cylinder'].hide = True
bpy.data.objects['Cylinder'].hide_render = True
bpy.ops.object.select_all(action='DESELECT')
bpy.ops.object.text_add(view_align=False, enter_editmode=False,location=(0, 0, 0), rotation=(0, 0, 0))
ActiveObjectText = bpy.context.scene.objects.active
newtext = bpy.context.scene.objects.active
#erasing previous objects
if bpy.context.scene.objects.active.name != 'Text':
bpy.ops.object.select_all(action='DESELECT')
#selecting and erasing Text
bpy.context.scene.objects.active = bpy.data.objects['Text']
bpy.context.scene.objects.active.select = True
bpy.ops.object.delete(use_global=False)
bpy.ops.object.select_all(action='DESELECT')
#need to delete other objects
bpy.ops.object.select_all(action='DESELECT')
#selecting and erasing Turbulence field
bpy.context.scene.objects.active = bpy.data.objects['Enveloppe2']
bpy.context.scene.objects.active.select = True
bpy.ops.object.delete(use_global=False)
#selecting newText
bpy.context.scene.objects.active = newtext
bpy.context.scene.objects.active.select = True
#naming/renaming the text
bpy.context.scene.objects.active.name = 'Text';
bpy.context.scene.objects.active = bpy.data.objects['Text']
#rotating text
ActiveObjectText.rotation_euler[0]=0.0 #xaxis
ActiveObjectText.rotation_euler[1]=0.0 #yaxis
ActiveObjectText.rotation_euler[2]=0.0 #zaxis
ActiveObjectText.location[0]=0
ActiveObjectText.location[1]=-9.75
ActiveObjectText.location[2]=5 #dur to shadow on the ground
#changing text
ActiveObjectText.data.body = title
#centering text
ActiveObjectText.data.align= spacemode
#extrude text
ActiveObjectText.data.extrude=extrude
#bevel text
ActiveObjectText.data.bevel_depth = bevel_depth
ActiveObjectText.data.bevel_resolution = 5
#text size
ActiveObjectText.data.size = textsize
bpy.context.scene.objects.active.data.space_character = width
bpy.context.scene.objects.active.data.font = font
#convert to mesh to apply effect
bpy.ops.object.convert(target='MESH', keep_original=False)
#put origin to center of text
#bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY', center='MEDIAN')
# Don't use Median, because it does not always put the origin to the center!
bpy.ops.object.origin_set(type='GEOMETRY_ORIGIN', center='BOUNDS')
#affect material
ActiveObjectText.data.materials.append(bpy.data.materials['MAT_PRE_Obsidian'])
#copy the pre loopecut cube
bpy.ops.object.select_all(action='DESELECT')
#obsolete
#bpy.ops.object.select_name(name='Enveloppe')
bpy.context.scene.objects.active = bpy.context.scene.objects['Enveloppe']
#activate in 3D
bpy.context.scene.objects.active.select = True
bpy.ops.object.duplicate(linked=False, mode='TRANSLATION')
#bpy.ops.object.duplicate_move(OBJECT_OT_duplicate={'linked':False, 'mode':'TRANSLATION'}, TRANSFORM_OT_translate={'value':(0, 0, 0), 'constraint_axis':(False, False, False), 'constraint_orientation':'GLOBAL', 'mirror':False, 'proportional':'DISABLED', 'proportional_edit_falloff':'SMOOTH', 'proportional_size':1, 'snap':False, 'snap_target':'CLOSEST', 'snap_point':(0, 0, 0), 'snap_align':False, 'snap_normal':(0, 0, 0), 'texture_space':False, 'release_confirm':False})
ActiveObjectEnveloppe = bpy.context.scene.objects.active
ActiveObjectEnveloppe.name = 'Enveloppe2'
ActiveObjectEnveloppe.draw_type = 'WIRE'
ActiveObjectEnveloppe.hide_render = True
#need to be on the visible layer to do duplication?
#moving object
ActiveObjectEnveloppe.location[0]=0
ActiveObjectEnveloppe.location[1]=-9.75
ActiveObjectEnveloppe.location[2]=5
# mo ve to layer 0 (first one)
#moveToLayer(ActiveObjectEnveloppe,0)
#adjust size of existed envelope to text
IncrementX = 0.3
IncrementY = 0.3
IncrementZ = 0.15
ActiveObjectEnveloppe.dimensions = (ActiveObjectText.dimensions[0]+IncrementX),(ActiveObjectText.dimensions[1]+IncrementY), (ActiveObjectText.dimensions[2]+IncrementZ)
#bpy.ops.object.origin_set(type='GEOMETRY_ORIGIN', center='MEDIAN')
bpy.ops.object.origin_set(type='GEOMETRY_ORIGIN', center='BOUNDS')
bpy.ops.object.modifier_add(type='SOFT_BODY')
#link text to enveloppe
bpy.ops.object.select_all(action='DESELECT')
#obsolete
#bpy.ops.object.select_name(name='Enveloppe')
bpy.context.scene.objects.active = ActiveObjectText
#activate in 3D
bpy.context.scene.objects.active.select = True
bpy.ops.object.modifier_add(type='MESH_DEFORM')
#configuring mesh deform
ActiveObjectText.modifiers['MeshDeform'].object = ActiveObjectEnveloppe
ActiveObjectText.modifiers['MeshDeform'].precision = 6 #<6 does not work!!! grid precision?
#binding text to cube
bpy.ops.object.meshdeform_bind(modifier='MeshDeform')
#softbody configuration
ActiveObjectEnveloppe.soft_body.use_goal=False
ActiveObjectEnveloppe.soft_body.use_stiff_quads = True
ActiveObjectEnveloppe.soft_body.plastic=10
ActiveObjectEnveloppe.data.update()
bpy.ops.ptcache.free_bake_all() # erase baked dynamics
bpy.ops.ptcache.bake_all() # bake dynamics : take time but needed before rendering animation

Important : The two last lines bakes all the physics stuff which can be long. But if you don’t do that, your sample image will be false, because the history of the animation is not taken into account while Openshot makes render only for one frame for sample images.

After that, we need to add the new cylinder variable in the params area :

# Init all of the variables needed by this script. Because Blender executes
# this script, OpenShot will inject a dictionary of the required parameters
# before this script is executed.
params = {
'title' : 'Oh Yeah! OpenShot!',
'extrude' : 0.05,
'bevel_depth' : 0.01,
'spacemode' : 'CENTER',
'text_size' : 1,
'width' : 1.0,
'fontname' : 'Bfont',
'color' : [0.8,0.8,0.8],
'alpha' : 1.0,
'output_path' : '/tmp/',
'fps' : 24,
'quality' : 90,
'file_format' : 'PNG',
'color_mode' : 'RGBA',
'horizon_color' : [0, 0, 0],
'resolution_x' : 1920,
'resolution_y' : 1080,
'resolution_percentage' : 100,
'start_frame' : 20,
'end_frame' : 25,
'animation' : True,
}

The next step, is made of comments. We need to comment some old python stuff on unused text object :

#text_object = bpy.data.curves['txtName1']
#text_object.extrude = params['extrude']
#text_object.bevel_depth = params['bevel_depth']
#text_object.body = params['title']
#text_object.align = params['spacemode']
#text_object.size = params['text_size']
#text_object.space_character = params['width']

Same thing for the font which is managed by the function now :

Next we call the main function with the GUI parameters :

# function call createSoftText(title,extrude,bevel_depth,spacemode,textsize,width,font,cylinder)
createSoftText(params['title'],params['extrude'],params['bevel_depth'],params['spacemode'],params['text_size'],params['width'], font, params['cylinder_on_off'])

Finally, we ajust the material pointer to the our text material in the blend file :

# Change the material settings (color, alpha, etc...)
#material_object = bpy.data.materials['Material.001']
material_object = bpy.data.materials['MAT_PRE_Obsidian'] #match the text material in Blend file

Here the full code of the softtext.py file

# OpenShot Video Editor is a program that creates, modifies, and edits video files.
# Copyright (C) 2009 Jonathan Thomas
#
# This file is part of OpenShot Video Editor (http://launchpad.net/openshot/).
#
# OpenShot Video Editor 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 3 of the License, or
# (at your option) any later version.
#
# OpenShot Video Editor 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 OpenShot Video Editor. If not, see <http://www.gnu.org/licenses/>.
# Import Blender's python API. This only works when the script is being
# run from the context of Blender. Blender contains it's own version of Python
# with this library pre-installed.
import bpy
# Load a font
def load_font(font_path):
'' Load a new TTF font into Blender, and return the font object ''
# get the original list of fonts (before we add a new one)
original_fonts = bpy.data.fonts.keys()
# load new font
bpy.ops.font.open(filepath=font_path)
# get the new list of fonts (after we added a new one)
for font_name in bpy.data.fonts.keys():
if font_name not in original_fonts:
return bpy.data.fonts[font_name]
# no new font was added
return None
def createSoftText(title,extrude,bevel_depth,spacemode,textsize,width,font,cylinder):
'' Create an animated falling softbody text ''
if cylinder'1':
bpy.data.objects['Cylinder'].hide_render = False
bpy.data.objects['Cylinder'].hide = False
bpy.ops.object.select_all(action='DESELECT')
#selecting Ground
bpy.context.scene.objects.active = bpy.data.objects['Cylinder']
bpy.context.scene.objects.active.select = True
#if bpy.data.objects['Ground'].modifiers.keys()[0] != 'Collision':
if bpy.data.objects['Cylinder'].modifiers.find('Collision') -1:
#print('collision = empty')
bpy.ops.object.modifier_add(type='COLLISION')
#else:
#print('OK')
else:
bpy.ops.object.select_all(action='DESELECT')
#selecting Cylinder
bpy.context.scene.objects.active = bpy.data.objects['Cylinder']
bpy.context.scene.objects.active.select = True
if bpy.data.objects['Cylinder'].modifiers.find('Collision') != -1:
bpy.ops.object.modifier_remove(modifier='Collision')
bpy.data.objects['Cylinder'].hide = True
bpy.data.objects['Cylinder'].hide_render = True
bpy.ops.object.select_all(action='DESELECT')
bpy.ops.object.text_add(view_align=False, enter_editmode=False,location=(0, 0, 0), rotation=(0, 0, 0))
ActiveObjectText = bpy.context.scene.objects.active
newtext = bpy.context.scene.objects.active
#erasing previous objects
if bpy.context.scene.objects.active.name != 'Text':
bpy.ops.object.select_all(action='DESELECT')
#selecting and erasing Text
bpy.context.scene.objects.active = bpy.data.objects['Text']
bpy.context.scene.objects.active.select = True
bpy.ops.object.delete(use_global=False)
bpy.ops.object.select_all(action='DESELECT')
#need to delete other objects
bpy.ops.object.select_all(action='DESELECT')
#selecting and erasing Turbulence field
bpy.context.scene.objects.active = bpy.data.objects['Enveloppe2']
bpy.context.scene.objects.active.select = True
bpy.ops.object.delete(use_global=False)
#selecting newText
bpy.context.scene.objects.active = newtext
bpy.context.scene.objects.active.select = True
#naming/renaming the text
bpy.context.scene.objects.active.name = 'Text';
bpy.context.scene.objects.active = bpy.data.objects['Text']
#rotating text
ActiveObjectText.rotation_euler[0]=0.0 #xaxis
ActiveObjectText.rotation_euler[1]=0.0 #yaxis
ActiveObjectText.rotation_euler[2]=0.0 #zaxis
ActiveObjectText.location[0]=0
ActiveObjectText.location[1]=-9.75
ActiveObjectText.location[2]=5 #dur to shadow on the ground
#changing text
ActiveObjectText.data.body = title
#centering text
ActiveObjectText.data.align= spacemode
#extrude text
ActiveObjectText.data.extrude=extrude
#bevel text
ActiveObjectText.data.bevel_depth = bevel_depth
ActiveObjectText.data.bevel_resolution = 5
#text size
ActiveObjectText.data.size = textsize
bpy.context.scene.objects.active.data.space_character = width
bpy.context.scene.objects.active.data.font = font
#convert to mesh to apply effect
bpy.ops.object.convert(target='MESH', keep_original=False)
#put origin to center of text
#bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY', center='MEDIAN')
# Don't use Median, because it does not always put the origin to the center!
bpy.ops.object.origin_set(type='GEOMETRY_ORIGIN', center='BOUNDS')
#affect material
ActiveObjectText.data.materials.append(bpy.data.materials['MAT_PRE_Obsidian'])
#copy the pre loopecut cube
bpy.ops.object.select_all(action='DESELECT')
#obsolete
#bpy.ops.object.select_name(name='Enveloppe')
bpy.context.scene.objects.active = bpy.context.scene.objects['Enveloppe']
#activate in 3D
bpy.context.scene.objects.active.select = True
bpy.ops.object.duplicate(linked=False, mode='TRANSLATION')
#bpy.ops.object.duplicate_move(OBJECT_OT_duplicate={'linked':False, 'mode':'TRANSLATION'}, TRANSFORM_OT_translate={'value':(0, 0, 0), 'constraint_axis':(False, False, False), 'constraint_orientation':'GLOBAL', 'mirror':False, 'proportional':'DISABLED', 'proportional_edit_falloff':'SMOOTH', 'proportional_size':1, 'snap':False, 'snap_target':'CLOSEST', 'snap_point':(0, 0, 0), 'snap_align':False, 'snap_normal':(0, 0, 0), 'texture_space':False, 'release_confirm':False})
ActiveObjectEnveloppe = bpy.context.scene.objects.active
ActiveObjectEnveloppe.name = 'Enveloppe2'
ActiveObjectEnveloppe.draw_type = 'WIRE'
ActiveObjectEnveloppe.hide_render = True
#need to be on the visible layer to do duplication?
#moving object
ActiveObjectEnveloppe.location[0]=0
ActiveObjectEnveloppe.location[1]=-9.75
ActiveObjectEnveloppe.location[2]=5
# mo ve to layer 0 (first one)
#moveToLayer(ActiveObjectEnveloppe,0)
#adjust size of existed envelope to text
IncrementX = 0.3
IncrementY = 0.3
IncrementZ = 0.15
ActiveObjectEnveloppe.dimensions = (ActiveObjectText.dimensions[0]+IncrementX),(ActiveObjectText.dimensions[1]+IncrementY), (ActiveObjectText.dimensions[2]+IncrementZ)
#bpy.ops.object.origin_set(type='GEOMETRY_ORIGIN', center='MEDIAN')
bpy.ops.object.origin_set(type='GEOMETRY_ORIGIN', center='BOUNDS')
bpy.ops.object.modifier_add(type='SOFT_BODY')
#link text to enveloppe
bpy.ops.object.select_all(action='DESELECT')
#obsolete
#bpy.ops.object.select_name(name='Enveloppe')
bpy.context.scene.objects.active = ActiveObjectText
#activate in 3D
bpy.context.scene.objects.active.select = True
bpy.ops.object.modifier_add(type='MESH_DEFORM')
#configuring mesh deform
ActiveObjectText.modifiers['MeshDeform'].object = ActiveObjectEnveloppe
ActiveObjectText.modifiers['MeshDeform'].precision = 6 #<6 does not work!!! grid precision?
#binding text to cube
bpy.ops.object.meshdeform_bind(modifier='MeshDeform')
#softbody configuration
ActiveObjectEnveloppe.soft_body.use_goal=False
ActiveObjectEnveloppe.soft_body.use_stiff_quads = True
ActiveObjectEnveloppe.soft_body.plastic=10
ActiveObjectEnveloppe.data.update()
bpy.ops.ptcache.free_bake_all() # erase baked dynamics
bpy.ops.ptcache.bake_all() # bake dynamics : take time but needed before rendering animation
# Debug Info:
# ./blender -b test.blend -P demo.py
# -b = background mode
# -P = run a Python script within the context of the project file
# Init all of the variables needed by this script. Because Blender executes
# this script, OpenShot will inject a dictionary of the required parameters
# before this script is executed.
params = {
'title' : 'Oh Yeah! OpenShot!',
'extrude' : 0.1,
'bevel_depth' : 0.02,
'spacemode' : 'CENTER',
'text_size' : 1.5,
'width' : 1.0,
'fontname' : 'Bfont',
'cylinder_on_off' : '1',
'color' : [0.8,0.8,0.8],
'alpha' : 1.0,
'output_path' : '/tmp/',
'fps' : 24,
'quality' : 90,
'file_format' : 'PNG',
'color_mode' : 'RGBA',
'horizon_color' : [0.57, 0.57, 0.57],
'resolution_x' : 1920,
'resolution_y' : 1080,
'resolution_percentage' : 100,
'start_frame' : 20,
'end_frame' : 25,
'animation' : True,
}
#INJECT_PARAMS_HERE
# The remainder of this script will modify the current Blender .blend project
# file, and adjust the settings. The .blend file is specified in the XML file
# that defines this template in OpenShot.
#----------------------------------------------------------------------------
# Modify Text / Curve settings
#print (bpy.data.curves.keys())
#text_object = bpy.data.curves['txtName1']
#text_object.extrude = params['extrude']
#text_object.bevel_depth = params['bevel_depth']
#text_object.body = params['title']
#text_object.align = params['spacemode']
#text_object.size = params['text_size']
#text_object.space_character = params['width']
# Get font object
font = None
if params['fontname'] != 'Bfont':
# Add font so it's available to Blender
font = load_font(params['fontname'])
else:
# Get default font
font = bpy.data.fonts['Bfont']
# set the font
#text_object.font = font
# function call createSoftText(title,extrude,bevel_depth,spacemode,textsize,width,font,cylinder)
createSoftText(params['title'],params['extrude'],params['bevel_depth'],params['spacemode'],params['text_size'],params['width'], font, params['cylinder_on_off'])
# Change the material settings (color, alpha, etc...)
#material_object = bpy.data.materials['Material.001']
material_object = bpy.data.materials['MAT_PRE_Obsidian'] #match the text material in Blend file
material_object.diffuse_color = params['diffuse_color']
material_object.specular_color = params['specular_color']
material_object.specular_intensity = params['specular_intensity']
material_object.alpha = params['alpha']
# Set the render options. It is important that these are set
# to the same values as the current OpenShot project. These
# params are automatically set by OpenShot
bpy.context.scene.render.filepath = params['output_path']
bpy.context.scene.render.fps = params['fps']
try:
bpy.context.scene.render.file_format = params['file_format']
bpy.context.scene.render.color_mode = params['color_mode']
except:
bpy.context.scene.render.image_settings.file_format = params['file_format']
bpy.context.scene.render.image_settings.color_mode = params['color_mode']
bpy.data.worlds[0].horizon_color = params['horizon_color']
bpy.context.scene.render.resolution_x = params['resolution_x']
bpy.context.scene.render.resolution_y = params['resolution_y']
bpy.context.scene.render.resolution_percentage = params['resolution_percentage']
bpy.context.scene.frame_start = params['start_frame']
bpy.context.scene.frame_end = params['end_frame']
# Animation Speed (use Blender's time remapping to slow or speed up animation)
animation_speed = int(params['animation_speed']) # time remapping multiplier
new_length = int(params['end_frame']) * animation_speed # new length (in frames)
bpy.context.scene.frame_end = new_length
bpy.context.scene.render.frame_map_old = 1
bpy.context.scene.render.frame_map_new = animation_speed
if params['start_frame'] params['end_frame']:
bpy.context.scene.frame_start = params['end_frame']
bpy.context.scene.frame_end = params['end_frame']
# Render the current animation to the params['output_path'] folder
bpy.ops.render.render(animation=params['animation'])

And now the result in Openshot :


OpenShot Video Editor is a free and versatile video editing program that can create and edit a number of different types of high definition video formats and apply different effects and transitions easily.

The application has a beautiful user interface that was obviously designed with productivity and ease-of-use in mind taking some obvious queues from some commercial video editing suites. Though not as complicated as applications like Adobe Premiere Pro, OpenShot can edit and mix videos based on layers called tracks.

For each clip loaded into this video editing application, you can drag-and-drop sections of videos or entire video clips into the interface's Project Files. From here, adding these clips to a new track is as simple as dragging it.

The video preview area displays the current frame of the video project, depending on which track is selected. While editing videos in tracks, you can easily add an effect to the clip by opening the effects panel. Things like blur, brightness and contrast, crop, color shift, negative, pixelate and wave are some of the built-in effects. Dragging them to the track will add an icon to the layer which can be edited by right-clicking and hitting Properties.

Beautiful transitions, effects, frame adjustments and animated titles

Perfecting video projects with fine-tuning the image is one area where OpenShot shines. You can change the saturation, brightness, contrast, blur, alpha (transparency), width, height and more under filter properties.

The transitions that OpenShot Video Editor include are pretty cool. Easily apply circle in and out, fade, wipe left to right (or right to left), blinds, distortions, fish eyes and a whole slew of different effects to video tracks transitioning between frames and separate videos.

A really awesome feature that comes with this program is the ability to add animated titles. This feature is powered by Blender and has a few really nice looking presets to choose from. You can configure and customize a few options in title effects such as the text, bevel depth, font and text size. Installation of Blender is required however.

Edit and create 4K, HD 1080p / 720p videos

In terms of what types of video and audio files OpenShot Video Editor supports: It's a long list. You can open virtually any type of file not limited to MP4, MKV, FLV, AVI, MOV, WebM (VP9), AVCHD (libx264), HEVC (libx265) and many others. We saw no issues including MP3 files, OGG, Vorbis and AAC files and the ability to edit audio tracks is pretty good.

Exporting videos includes many different options, not least of which one which allows you to export between start and end frames which can be useful for testing which encoder works best for your project. It can export AVI, MKV, WebM, MP4 and others using various codecs which take advantage of CPU optimization. A few video profile presets may also be used which target for a certain FPS and resolution anywhere from 4K UHD, HD 1080p, HD 720p and mobile formats.

Openshot Blender

Conclusion

Openshot Blender Animated Title

When it comes to stability, this program was excellent and didn't use as much in terms of system resources as one would expect. It got all tasks done in record time, making it a favorite.

Blender Software

All in all, OpenShot Video Editor is a lovely freeware video editing utility that just breezes through projects while offering a user interface that has a very low learning curve. It's fast, free and fully capable of creating some really good looking video files in many open formats.

Openshot

Openshot Blender

OpenShot Video Editor 2.5.1 on 32-bit and 64-bit PCs

This download is licensed as freeware for the Windows (32-bit and 64-bit) operating system on a laptop or desktop PC from audio and video editors without restrictions. OpenShot Video Editor 2.5.1 is available to all software users as a free download for Windows. As an open source project, you are free to view the source code and distribute this software application freely.

The program was created by the developer as a freeware product, but donations for the continued development are highly appreciated. You may generally make a donation via the developer's main web site.

Filed under:
  1. OpenShot Video Editor Download
  2. Freeware Audio and Video Editors
  3. Open source and GPL software
  4. Major release: OpenShot Video Editor 2.5
  5. Video Production Software