Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multitrack Video AAF in Resolve #43

Closed
kevinparkbss opened this issue Mar 16, 2019 · 8 comments
Closed

Multitrack Video AAF in Resolve #43

kevinparkbss opened this issue Mar 16, 2019 · 8 comments

Comments

@kevinparkbss
Copy link

First of all, thank you Mark for this amazing resource.

I wrote a simple script with pyaaf2 that creates an embedded sequence AAF with multiple video tracks that imports into the Avid as expected, and am trying to import that same AAF in Resolve.

When I try to import the pyaaf2 created AAF into Resolve, Resolve says that the AAF doesn't have a primary timecode track. I was able to get past that by creating an empty sequence slot and setting the start timecode to 86400 (1hr at 24fps, although it sets the seq duration to 1036800 in the Avid).

The bigger issue is that it then asks me to choose a Source Timeline and gives me a dropdown option to choose one of the tracks I've created when I select on, Resolve only shows me that single track on the timeline.

Can you give me some guidance on how I can get Resolve to import all video tracks I've created into a single timeline? I'm thinking that I need to contain the tracks in a NestedScope but I'm clueless as to how I can get that to work.

I'm attaching my janky script. I realized that Resolve doesn't support embedded AAF's so I'll have to link to the files instead of embedding but that's another issue for another day.

Thanks!
aaf_avid.txt

@markreidvfx
Copy link
Owner

I haven't tested your code yet, but at a glance, the first issue could be the compositionMobs usage code might need to be set to Usage_TopLevel

@kevinparkbss
Copy link
Author

Thanks Mark. I had tried that with no change in Resolve so I had taken it back out.

comp_mob.usage = 'Usage_TopLevel'

one other interesting note is that in the avid i can see the clip name and tape name but in resolve, it only brings in the tape name as 'Reel Name' and doesn't see a file/clip name.

@markreidvfx
Copy link
Owner

I'm able to replicate your issue, I have not had much time to diagnose.

@markreidvfx
Copy link
Owner

using a nested scope for the video tracks like this appears to work.

Screen Shot 2019-03-29 at 7 34 40 PM

@markreidvfx
Copy link
Owner

markreidvfx commented Mar 30, 2019

here is your script modified too

import aaf2

# mocked up dictionary from Layout
maya_seq = {
        'aaf_name': 'Layout_Seq_AAF',
        'seq_name': 'Layout Send to Edit',
        'tracks': [
            {
                'v_track': 1,
                'v_track_name': 'Track 1',
                'clips': [
                    {'name': 'filler', 'frames': 50},
                    {'name': '960_010', 'frames': 100, 'start': 20, 'tape': '960_010_tape'}
                ]
            },
            {
                'v_track': 2,
                'v_track_name': 'Track 2',
                'clips': [
                    {'name': 'filler', 'frames': 130},
                    {'name': '960_020a', 'frames': 96, 'start': 1, 'tape': '960_020a_tape'}
                ]
            },
            {
                'v_track': 3,
                'v_track_name': 'Track 3',
                'clips': [
                    {'name': 'filler', 'frames': 130},
                    {'name': '960_020b', 'frames': 96, 'start': 1, 'tape': '960_020b_tape'}
                ]
            }

        ]
    }

with aaf2.open(maya_seq['aaf_name']+'.aaf', 'w') as f:

    edit_rate = 23.976
    timecode_fps = 24

    comp_mob = f.create.CompositionMob()
    comp_mob.usage = "Usage_TopLevel"
    comp_mob.name = maya_seq['seq_name']
    f.content.mobs.append(comp_mob)

    tc_slot = comp_mob.create_empty_sequence_slot(edit_rate, media_kind='timecode')
    tc = f.create.Timecode(24, True)
    tc.start = 86400
    tc_slot.segment.components.append(tc)

    nested_slot = comp_mob.create_timeline_slot(edit_rate)
    nested_slot['PhysicalTrackNumber'].value = 1
    nested_scope = f.create.NestedScope()
    nested_slot.segment= nested_scope

    for i in maya_seq['tracks']:
        sequence = f.create.Sequence(media_kind="picture")
        nested_scope.slots.append(sequence)

        for j in i['clips']:
            if j['name'] == 'filler':
                if i['v_track'] <= 1:
                    comp_fill = f.create.Filler("picture", j['frames'])
                else:
                    comp_fill = f.create.ScopeReference("picture", j['frames'])
                    comp_fill['RelativeSlot'].value = 1
                    comp_fill['RelativeScope'].value = 0

                sequence.components.append(comp_fill)

            else:

                tape_mob = f.create.SourceMob()
                tape_name = j['tape']
                tape_slot, tape_timecode_slot = tape_mob.create_tape_slots(tape_name, edit_rate, timecode_fps, media_kind='picture')
                tape_slot.segment.length = (j['frames'] + 86400)
                f.content.mobs.append(tape_mob)

                file_mob = f.create.SourceMob()
                tm_clip = tape_mob.create_source_clip(slot_id=1, start=86400, length=j['frames'])
                # NOTE: if you use the import_dnxhd_essence on master_mob you can skip the file_mobs
                file_mob.import_dnxhd_essence(j['name']+".dnxhd", edit_rate, tm_clip)

                file_mob.name = j['name']
                f.content.mobs.append(file_mob)

                master_mob = f.create.MasterMob()
                master_mob.name = j['name']
                f.content.mobs.append(master_mob)

                fm_clip = file_mob.create_source_clip(slot_id=1, length=j['frames'])
                print fm_clip.start, fm_clip.length

                slot = master_mob.create_picture_slot(edit_rate)
                slot.segment.components.append(fm_clip)

                mm_clip = master_mob.create_source_clip(slot_id=1, start=(j['start']-1), length=j['frames'])
                sequence.components.append(mm_clip)

    # comp_mob.dump()

@kevinparkbss
Copy link
Author

this is amazing, thank you! I just had to change the fps to 24 but it works as expected in Resolve!

A couple things tho if you can point me in the right direction. While I was trying to sort out AAF's in Resolve, I've been using an xml creation script that points to quicktimes on the network. This works well. Resolve doesn't support embedded aaf's so I'd like to be able to point the clips to motion jpeg quicktimes on the network. Is this something I can do with aaf's created with pyaaf2?

Second thing is that when I create an aaf with a timecode track, the sequence length in the avid is 13 hours long. Is there a way to restrict the overall length of the avid timeline?

Thank you!

@markreidvfx
Copy link
Owner

The way I do it is with the reel_name. Resolve will use tapemob.name as the reel_name and its timecode. If they match the embedded reel_name in your quicktimes or you set the reel name some other way (resolve has a bunch of options) it should be able to link them up.

I think you just set tc.length (untested)

@kevinparkbss
Copy link
Author

you are a wizard!! I haven't worked on the linked clips in resolve but the tc.length works perfectly in the avid. Another benefit of using the nested slots is that I'm now able to add markers to the sequence to multiple tracks. You wouldn't by chance know what marker value I need to give to change the marker color do you? I tried using marker['Color'].value but that doesn't seem to work and I'm having difficulty calling up all the available options for DescriptiveMarker.

Thanks Mark! I owe you a beer (or twelve)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants