Timeline Manipulation with Python

Create move edit Block and Keyframe inside Timeline

PythonTimelineManipulation PythonTimelineManipulation PythonTimelineManipulation PythonTimelineManipulation

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 Parameter Icon 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")