markreidvfx / pyaaf

Python Bindings for the Advanced Authoring Format (AAF)
http://markreidvfx.github.io/pyaaf
MIT License
49 stars 9 forks source link

Simple Timeline Example #54

Closed maptz closed 1 year ago

maptz commented 1 year ago

Hi Mark,

I'm not sure how active you are on this project any more.

I'm hoping to bring in some edits into my Avid system using pyaaf.

I just wondered if you can guide me in creating a very quick sample. I'm bashing my head against a wall.

I've got as far as your test_create_sequence.py file and worked out how to link the existing MXF files into that file, but I can't work out how on earth I add audio tracks and how to add the imported mobs into the sequence.

Can you help?

from __future__ import (
    unicode_literals,
    absolute_import,
    print_function,
    division,
    )

import aaf2

def create_file():
    mob_count = 0
    components = 0

    source_file = ["Z:\\Avid MediaFiles\\MXF\\SFX_BBC_MXFs\\4Minute_BBA01.5E5D05003B53A.mxf",
               "Z:\\Avid MediaFiles\\MXF\\SFX_BBC_MXFs\\4Minute_BBA02.5E5D05003CA7A.mxf"]

    with aaf2.open("output.aaf", "w")  as f:

        #video_rate = " 30000/1001"
        video_rate = " 24000/1001"
        comp_mob = f.create.CompositionMob()
        sequence = f.create.Sequence(media_kind="picture")

        timeline_slot = comp_mob.create_timeline_slot(video_rate)
        timeline_slot.segment= sequence

        for path in source_file:
            for mob in f.content.link_external_mxf(path):
                print(mob.name)
                source_clip = mob.slots[0].segment
                # audio_sequence.components.append(source_clip)

                #track1 = file_mob.create_sound_slot(video_rate)
                #track2 = file_mob.create_sound_slot(video_rate)

                # for mob in f.content.mastermobs():
                #     length = 100
                #     start = 0
                #     slot_id = 3
                #     filler = f.create.Filler('sound', length)
                #     audio_clip =  mob.create_source_clip(slot_id, start, length)
                #     track1.segment.components.append(filler)
                #     track1.segment.components.append(audio_clip)

                # timeline_audio_slot = comp_mob.create_timeline_slot(video_rate)
                # timeline_audio_slot.segment= audio_sequence

        f.content.mobs.append(comp_mob)

        fp = 30
        fp = 24
        length = 60 * fp
        filler_len = 100
        timecode_fps = fp
        mob_count += 1

        test_path = "some_path.mov"

        for path in source_file:
            for mob in f.content.link_external_mxf(path):
                print(mob.name)
                # Add this to an audio track here....

        for i in range(10):

            # Make the Tape MOB
            tape_mob = f.create.SourceMob()
            tape_name = "tape_name"
            tape_slot, tape_timecode_slot = tape_mob.create_tape_slots(tape_name, video_rate, timecode_fps)
            tape_slot.segment.length = length

            f.content.mobs.append(tape_mob)
            mob_count += 1
            # Make a FileMob
            file_mob = f.create.SourceMob()

            # Make a locator
            loc = f.create.NetworkLocator()
            loc['URLString'].value = test_path

            file_description = f.create.CDCIDescriptor()
            file_description.locator.append(loc)

            file_description['ComponentWidth'].value = 8
            file_description['HorizontalSubsampling'].value = 4
            file_description['ImageAspectRatio'].value = '16/9'
            file_description['StoredWidth'].value = 1920
            file_description['StoredHeight'].value = 1080
            file_description['FrameLayout'].value = 'FullFrame'
            file_description['VideoLineMap'].value = [42, 0]
            file_description['SampleRate'].value = video_rate
            file_description['Length'].value = 10

            file_mob.descriptor = file_description

            clip = tape_mob.create_source_clip(slot_id=1, length=length)
            slot = file_mob.create_picture_slot(video_rate)

            slot.segment.components.append(clip)

            f.content.mobs.append(file_mob)
            mob_count += 1

            # Make the Master MOB
            master_mob = f.create.MasterMob()
            master_mob.name = "Master Mob %i" % i

            master_mob.comments['Test'] = 'Value'
            master_mob.comments.append(f.create.TaggedValue("Test2", 42))

            assert master_mob.comments['Test'] == "Value"
            assert master_mob.comments['Test2'] == 42

            clip = file_mob.create_source_clip(slot_id=1)
            assert clip.length == length
            slot = master_mob.create_picture_slot(video_rate)
            slot.segment.components.append(clip)

            f.content.mobs.append(master_mob)
            mob_count += 1

            # Create a SourceClip
            clip = master_mob.create_source_clip(slot_id=1)
            assert clip.length == length
            sequence.components.append(clip)
            components += 1

            # Create a filler
            comp_fill = f.create.Filler("picture", filler_len)
            sequence.components.append(comp_fill)
            components += 1
create_file()
maptz commented 1 year ago

By the way, I've made some progress, but could still use some guidance, and a simple example.

I can add a couple of audio tracks to my sequence. I can even pull in some clips onto one of these tracks.

What's funky here is that my OP-ATOM files aren't all recognised correctly.

My OP-ATOM files are stereo files which are linked together. I think they should be showing up as a single mob with two slots, but in fact they're coming in as 4 mobs (maybe???).

Some hints would be great.

  sound_slot = comp_mob.create_sound_slot(video_rate) # add a track
        sound_slot2 = comp_mob.create_sound_slot(video_rate) # add a track
        # audio_sequence = f.create.Sequence(media_kind="sound")
        # sound_slot.segment = audio_sequence

        audio_mobs = []
        for path in source_file:
            for mob in f.content.link_external_mxf(path):
                if (mob not in audio_mobs):
                    audio_mobs.append(mob)
                    print(mob.name)

        for mob in audio_mobs:
            slot = mob.slots[0]
            sound_slot.segment.components.append(mob.create_source_clip(slot.slot_id, length = 100)) # 100 frames
            sound_slot.segment.components.append(f.create.Filler('sound', 100)) # 100 frames

        for mob in audio_mobs:
            slot = mob.slots[0]
            sound_slot2.segment.components.append(mob.create_source_clip(1, length = 100))
            sound_slot2.segment.components.append(f.create.Filler('sound', 100))
maptz commented 1 year ago

Apologies. I wrote this on the wrong repo. Should be on the pyaaf2 one.