pyaaf2 icon indicating copy to clipboard operation
pyaaf2 copied to clipboard

Add OperationGroup

Open bcvery1 opened this issue 3 years ago • 2 comments

I've created an AAF in Media Composer where a clip has a 3D Warp effect with two keyframes on it, and I'd like to be able to recreate it with PyAAF2.

I have this script to get some data from the Media Composer made AAF:

import pyaaf2
import sys


def main_comp(f: pyaaf2.file.AAFFile):
    try:
        m_c = next(f.content.toplevel())
    except StopIteration:
        m_c = next(f.content.compositionmobs())

    return m_c


def main(path: str):
    with pyaaf2.open(path, 'rb') as f:
        mc = main_comp(f)
        for sequence in mc.slots:
            process_timeslot(sequence)


def process_timeslot(slot: pyaaf2.mobslots.TimelineMobSlot):
    if 'Components' in slot.segment:
        for comp in slot.segment['Components'].value:
            process_operation_group(comp)


def process_operation_group(comp: pyaaf2.components.OperationGroup):
    if isinstance(comp, pyaaf2.components.OperationGroup):
        print(comp.operation)
        print_strong_ref_set(comp.parameters)


def print_strong_ref_set(params: pyaaf2.properties.StrongRefSetProperty):
    for _, v in params.items():
        if isinstance(v, pyaaf2.misc.VaryingValue):
            print_varying_value(v)


def print_varying_value(vv: pyaaf2.misc.VaryingValue):
    print(vv.interpolation)
    for point in vv.pointlist:
        print(point.time, point.value)


if __name__ == '__main__':
    main(sys.argv[1])

This produces:

$ python3 aaf.py two_keyframes.aaf 
<pyaaf2.dictionary.OperationDef SBlend_v2 47052d96-effc-431a-b2fe-3b4291c5d8fd at 0x7fc9d56a0810>
<pyaaf2.dictionary.InterpolationDef LinearInterp 5b6c85a4-0ede-11d3-80a9-006008143e6f at 0x7fc9d56abdb0>
0.09090909090909091 0.0
0.8181818181818182 972.0
<pyaaf2.dictionary.InterpolationDef LinearInterp 5b6c85a4-0ede-11d3-80a9-006008143e6f at 0x7fc9d56abdb0>
0.09090909090909091 0.0
0.8181818181818182 0.0
<pyaaf2.dictionary.InterpolationDef LinearInterp 5b6c85a4-0ede-11d3-80a9-006008143e6f at 0x7fc9d56abdb0>
0.09090909090909091 0.0
0.8181818181818182 0.0

When I try create the OperationGroup I ran into a few issues and thought I might have to register the SBlend_v2 OperationDef as I couldn't find it anywhere in the library. I'm trying to do this with (where self is of type pyaaf2.file.AAFFile):

self.dictionary.register_def(self.create.OperationDef(auid='47052d96-effc-431a-b2fe-3b4291c5d8fd',
                                                              name='SBlend_v2'))

This is how I was trying to create the OperationGroup (where aaf_file is of type pyaaf2.file.AAFFile:

aaf_file.create.OperationGroup('SBlend_v2')

However I get the error from the register_def line:

Traceback (most recent call last):
  File "wrap.py", line 293, in <module>
    create_aaf('output.aaf', 'seq_name', 24.0, 480, 120, 0, True, 5, fixed_gen(), 2)
  File "wrap.py", line 254, in create_aaf
    with WrappedAAF(outputfile, 'wb+') as aaf_file:
  File "wrap.py", line 217, in __init__
    print(self.create.OperationDef(auid='47052d96-effc-431a-b2fe-3b4291c5d8fd',
  File "/home/bcvery1/pyaaf2/file.py", line 63, in create_instance
    return self.from_name(self.class_name, *args, **kwargs)
TypeError: from_name() got multiple values for argument 'name'

Is there any example code which could help? Am I approaching this from completely the wrong angle?

bcvery1 avatar Jul 03 '21 16:07 bcvery1

Update to this, I've been working on the register part and now have:

        sblend_op_def: pyaaf2.dictionary.OperationDef = self.create.OperationDef(
            auid='47052d96-effc-431a-b2fe-3b4291c5d8fd')
        weak_ref_set: pyaaf2.properties.WeakRefArrayProperty = pyaaf2.properties.WeakRefArrayProperty(sblend_op_def,
                                                                                                    7689,
                                                                                                    26)

        avid_param_byte_order_param_def = self.create.ParameterDef(auid='c0038672-a8cf-11d3-a05b-006094eb75cb')
        avid_param_byte_order_param_def.name = 'AvidParameterByteOrder'
        avid_param_byte_order_param_def.description = ''

        avid_effect_id = self.create.ParameterDef(auid='93994bd6-a81d-11d3-a05b-006094eb75cb')
        avid_effect_id.name = 'AvidEffectID'
        avid_effect_id.description = ''

        weak_ref_set.extend([avid_param_byte_order_param_def, avid_effect_id])

        sblend_op_def['ParametersDefined'] = weak_ref_set

        self.dictionary.register_def(sblend_op_def)

Which results in this error:

Traceback (most recent call last):
  File "wrap.py", line 320, in <module>
    create_aaf('output.aaf', 'seq_name', 24.0, 480, 120, 0, True, 5, fixed_gen(), 2)
  File "wrap.py", line 281, in create_aaf
    with WrappedAAF(outputfile, 'wb+') as aaf_file:
  File "wrap.py", line 243, in __init__
    sblend_op_def['ParametersDefined'] = weak_ref_set
AttributeError: __setitem__

Would greatly appreciate any help if anyone has any insight

bcvery1 avatar Jul 05 '21 12:07 bcvery1

here is an example that might help from another project https://github.com/markreidvfx/pyavb/blob/master/examples/avb2aaf.py#L21

markreidvfx avatar Jul 06 '21 07:07 markreidvfx