Timeline Manipulation with Python
Create move edit Block and Keyframe inside Timeline
When you parse the Timeline Parsing with Python you can use the function .isChildOf() to test if a track or parameter is linked to the object you want.
createBlock
The function createBlock(targetElement) on the timeline object take as argument a Element and return a tuple of the Track and the Track Block .
The block will be created at the cursor position.
Here is an example of creating a block of a uniform layer in the main timeline:
t = script.parentElement.mainAnimation
layer = script.parentElement.layers["Uniform"]
t.transport.position.set(5.5) #set the timeline position to 5.5 second
track,block = t.createBlock(layer) #create the block at the timeline position
block.length.set(10) #modify the block length
createKeyframe
The function createKeyframe(targetParameter,position,automaticInterpolation) on the timeline object take as argument a Exposed Parameter ,a position in second and a boolean and return a tuple of the Track and the Keyframe .
Here is an example of creating a keyFrame for the rotation of a uniform layer in the main timeline:
t = script.parentElement.mainAnimation
layer = script.parentElement.layers["Uniform"]
track,key = t.createKeyframe(layer.renderer.placement.rotation,26.0,True) #Create the keyframe at the second 26.0 with a automatic interpolation ( linear )
key.key.set(3.14159) #set key value, here in radian for the rotation
Example: Block Replication
In the script below we first have a layer selector, then we have a function (that is used later) that help find the last block in a track and then we have the parsing of the timeline where we use elt.isChildOf() to know the track that correspond to the selection.
Once we have the correct track we do some manipulation of the block ( cloning, finding the last one, moving the clone and then adding it to the track):
BlockMargin: Oil.Seconds(1)
layer: Oil.createObject("WeakPointer(Layer)")
t = script.parentElement.mainAnimation
layer = script.layer.get() #script.parentElement.layers["test"]
def getLastBlock(blocks): # helper function to find the last block
position = 0
for block in blocks:
if block.position.get() >= position:
lastBlock = block
position = block.position.get()
return lastBlock
for element, track in t.elementTracks.items(): #parsing of the timeline
elt = element.get()
if elt.isChildOf(layer): #finding the right element and
blocks = track.blocks
newBlock = blocks[0].clone()
lastOne = getLastBlock(blocks)
newBlock.position.set(lastOne.position.get()+lastOne.length.get() + script.BlockMargin.get())
blocks.append(newBlock)
Example: Keyframes Replication
Here we have a similar script that above for the block but now we add new keyframe after the last one and change it’s value with a random one:
BlockMargin: Oil.Seconds(1)
layer: Oil.createObject("WeakPointer(Layer)")
from random import random
t = script.parentElement.mainAnimation
layer = script.layer.get() #script.parentElement.layers["test"]
def getLastKey(keys): # helper function to find the last block
position = 0
for key in keys:
if key.position.get() >= position:
lastKey = key
position = key.position.get()
return lastKey
for object, track in t.parameterTracks.items():
parameter = object.get()
if parameter.isChildOf(layer): #finding the right element
print(f"Parameter {parameter.getFriendlyName()}")
f = track.function
newKey = f.keyframes[0].clone()
lastKey = getLastKey(f.keyframes)
newKey.position.set(lastKey.position.get() + script.BlockMargin.get())
newKey.key.set(random()) # setting the key value
f.keyframes.append(newKey)
Example: Using Markers
Here is a example to create blocks at every markers in a timeline for the selected layer:
layer: Oil.createObject("WeakPointer(Layer)")
t = script.parentElement.mainAnimation
layer = script.layer.get() #script.parentElement.layers["test"]
print(layer.label)
for element, track in t.elementTracks.items(): #parsing of the timeline
elt = element.get()
if elt.isChildOf(layer): #finding the right element to clear the track
track.blocks.clear()
for marker in t.timeMarkers:
track,newBlock = t.createBlock(layer)
newBlock.position.set(marker.position)
print("New Block Added")