Getting Started with hiero.core

All Python objects related to data manipulation in Hiero are placed in the hiero.core namespace within the following structure:

_images/structure.png

Before using hiero.core, import the necessary symbols using:

import hiero.core

Generic Operations

We can get elements contained by an object using the items method:

for item in myProject.clipsBin().items():
  print( item )

Every Python object in Hiero has a name:

myProject.name()
item.name()

Accessing Bins

Here is an example of some items loaded into Hiero:

_images/core_bin_example.png

Note

To create the example shown above, copy and paste this example script into the Script Editor and execute it.

There are a number of items shown there that you might want access to in Python.

To access the project, you could get a reference to the Python object for it by name using the project() method or, if it’s the last project loaded, by taking the last item in the projects() list. For example:

import hiero.core

# get the last loaded project
myProject = hiero.core.projects()[-1]

# get the project by name
myProject = hiero.core.project("Untitled 2")

Either of the above methods work, and return a Project object.

Once you have a project, you might want to get at the clips it contains. Project objects have two top level bin containers: the clips bin, and the tags bin. To access either of these bins, you can use the Project.clipsBin() and the Project.tagsBin() methods.

clipsBin = myProject.clipsBin()

The Project.clipsBin() and the Project.tagsBin() methods both return Bin objects. Bin objects contain lists of other Bin objects as well as BinItem.

Bin Items

BinItem objects are the containers used to hold Clips and Sequences. Most access to Clips and Sequences, once they are held onto by a Bin object, is through BinItem objects.

To get a list of all of the items contained by a Bin object, use any of the Bin.clips(), Bin.sequences(), Bin.bins() or Bin.items() methods.

clips = clipsBin.clips()
sequences = clipsBin.sequences()
bins = clipsBin.bins()
allItems = clipsBin.items()
certainItemTypes = clipsBin.items(hiero.core.Bin.ItemType.kClip | hiero.core.Bin.ItemType.kSequence)

print( "clips: " + str(clips) )
print( "sequences: " + str(sequences) )
print( "bins: " + str(bins) )
print( "allItems: " + str(allItems) )
print( "certainItemTypes: " + str(certainItemTypes) )

Given the example project loaded in Hiero, shown at the top of this document, the code above shows the following:

clips: (BinItem('blue_green_checkerboard'),)
sequences: (BinItem('NewSequence'),)
bins: (Bin('Bin 1'), Bin('Bin 3'))
allItems: (Bin('Bin 1'), Bin('Bin 3'), BinItem('blue_green_checkerboard'), BinItem('NewSequence'))
certainItemTypes: (BinItem('blue_green_checkerboard'), BinItem('NewSequence'))

To access the Clip or Sequence item contained by a BinItem object, use its BinItem.activeItem() method:

clip = clips[0].activeItem()
sequence = sequences[0].activeItem()

Accessing the Media

To access a clip’s media, you can get its MediaSource using the Clip.mediaSource() method

mediaSource = clip.mediaSource()

Once you have a MediaSource object, you can find the path to its media using the MediaSource.fileinfos() method. The MediaSource.fileinfos() method returns a tuple of MediaFileInfo objects, from which you can retrieve the file path for the media on disk from:

files = mediaSource.fileinfos()
for file in files:
  print( file.filename() )

Note

MediaSource objects can contain references to multiple files, which is why the MediaSource.fileinfos() method returns a tuple. It is best not to assume that there will only be one item in the tuple returned.

Alternatively, Clips also have an associated Read node, which gives you access to most of the knobs you would have available in Nuke. For example:

readNode = clip.readNode()
print( readNode["file"].value() )
print( readNode["colorspace"].value() )

Creating a Project from Scratch

To start off with, let’s clear the currently loaded projects out. Assuming that you’ve already imported hiero.core, you can call the closeAllProjects() method:

hiero.core.closeAllProjects()

Now you want to create a new project. Use the newProject() method:

myProject = hiero.core.newProject()

Creating Bins

To create Bin objects, you can just initialise a new Bin object, supplying the name to the initialiser method:

bin1 = hiero.core.Bin("Bin 1")
bin2 = hiero.core.Bin("Bin 2")
bin3 = hiero.core.Bin("Bin 3")

To make a bin a child of another bin, use the Bin.addItem() method:

bin1.addItem(bin2)

To add the bins to the project, and display them in the bin view, add the bins to the clipsBin for the project:

clipsBin = myProject.clipsBin()
clipsBin.addItem(bin1)
clipsBin.addItem(bin3)

Note

Attached vs Unattached

There are two different ways/conventions when creating and manipulating objects in Hiero: attached and unattached. Attached objects are those that have been inserted as a child of a Project object in some way. In the above code, calling addItem on the clipsBin attaches bin1 and bin3 to the project. It also attaches bin2 to the project, as bin2 is a child of bin1.

The two important things to note about attached objects are:

  • methods called on them throw an exception if not called on the main thread.

  • undo/redo items are added to the undo/redo stack for almost all methods called that modify the underlying state of attached objects.

Unattached objects are those that have not been made a child, directly or indirectly, or a Project object. The two important things to note about unattached objects are:

  • methods called on them work on any thread.

  • undo/redo items are not added to the undo/redo stack for any methods called that modify the underlying state of the objects.

It is recommended to add objects to a project whenever possible.

Creating Clips

To create a Clip, you can use the Bin.createClip() method, which creates a clip and adds it to a project in one call.

We can do this using the sample resources provided with this guide, which are located in the ‘Resources’ directory.

import os.path

resourcesPath = os.path.join(pathToHieroPythonDevGuide, "Resources")

print( resourcesPath )

We can now create Clip objects:

clip1 = clipsBin.createClip(os.path.join(resourcesPath, "blue_green_checkerboard.mov"))
clip2 = bin1.createClip(os.path.join(resourcesPath, "red_black_checkerboard.mov"))
clip3 = bin2.createClip(os.path.join(resourcesPath, "colour_bars.mov"))
clip4 = bin3.createClip(os.path.join(resourcesPath, "colour_wheel.mov"))
clip5 = bin3.createClip(os.path.join(resourcesPath, "purple.######.dpx"))

Your project should now look like this:

_images/untitled_core_bin_example.png

Creating Sequences

To create a new Sequence and add it to the project, do the following:

sequence = hiero.core.Sequence("NewSequence")
clipsBin.addItem(hiero.core.BinItem(sequence))

Note

As mentioned in previous sections, Sequence objects are wrapped in BinItems before they can be stored in Bins.

Sequences consist of VideoTracks and AudioTracks, which are composed of TrackItems. To create a track, create either a VideoTrack or an AudioTrack, like so:

track = hiero.core.VideoTrack("VideoTrack")

Next, given a source clip, you can create and initialise TrackItems like so:

# create the item
trackItem = track.createTrackItem("Shot23")

# set its source clip
trackItem.setSource(clip1)

# set its timeline values
trackItem.setTimelineIn(0)
trackItem.setTimelineOut(trackItem.sourceDuration() - 1)

# add it to the track
track.addItem(trackItem)

To add the track to the sequence, just call the Sequence.addTrack() method:

sequence.addTrack(track)

Creating Effects

To create a new effect, you can initialize it directly like so:

gradeEffect = hiero.core.EffectTrackItem("Grade", timelineIn=0, timelineOut=trackItem.sourceDuration()-1)

You can then add it to a video track with:

track.addSubTrackItem(gradeEffect, 0)

It is recommended that you use the Track.createEffect() method, which simplifies the creation of soft effects. To add an effect which covers the whole sequence:

track.createEffect("Transform")

To create an effect which applies to the first item on a track:

track.createEffect("TimeWarp", trackItem=track.items()[0])

To create an effect which is cloned and applied to all items on a track:

# Add an effect to the first item
firstTrackItem = track.items()[0]
gradeEffect = track.createEffect(effectType="Grade", trackItem=firstTrackItem)

# Next clone this effect to the other items on the track
otherTrackItems = track.items()[1:]
for item in otherTrackItems:
  track.createEffect(cloneFrom=gradeEffect, trackItem=item)

Create Objects Example

See the create_example.py for an example of creating a Project, adding some clips to it and creating a sequence. After running that, you should have a bin view that looks like this (as shown at the top of this page):

_images/core_bin_example.png