markreidvfx / pyaaf

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

insert filler #26

Closed gone-fishing closed 8 years ago

gone-fishing commented 8 years ago

Hi, I am trying to search an AAF for composition_mobs that have a particular string in there name. Basically I want to search an AAF from an avid sequence for anything that has "SFX" in its name and then I want to remove it. I have been able to find the composition_mobs with "SFX" in their name and I have changed there length to 0 so they no longer exist in the sequence. (not sure if thats the best way to go about it but at this stage its working partially). but that then throws everything out of sync after this. So I thought I should then insert fill of the same duration. I have had success with .append but I thought .insert is more appropriate. I am assuming .append would place the filler a the end of the track. below is a bit of code I thought should work but its not. any advice or examples someone could show me would be greatly appreciated.(I am an assistant editor by trade, trying to learn to code so thanks for bearing with my ignorance)

if isinstance(i, aaf.component.Sequence): comp_fill = f.create.Filler("Sound", 10) i.insert(comp_fill)

Toadman30 commented 8 years ago

Give this a try. It will cycle through the all the audio tracks looking for the name "SFX". You may need tweak it based on your sequence.

import aaf

path = "path_to_aaf"

f = aaf.open(path, "rw")
header = f.header

def get_video_tracks(mob):
    tracks = []

    for slot in mob.slots():
        segment = slot.segment

        if segment.media_kind == "Sound":

            if isinstance(segment, aaf.component.Sequence):

                items = list(segment.components())
                items.insert(0, segment)
                tracks.append(items)
                # tracks.append(list(segment.components()))

    return tracks

def get_transition_offset(index, component_list):

    offset = 0

    nextItem = None
    prevousItem = None

    if len(component_list) > index + 1:
        nextItem = component_list[index + 1]

    if index != 0:
        prevousItem = component_list[index -1]

    if isinstance(nextItem,  aaf.component.Transition):
        offset -= nextItem.length - nextItem.cutpoint

    if isinstance(prevousItem,  aaf.component.Transition):
        offset -= prevousItem.cutpoint

    return offset

def find_sfx(seq, sourceClip, track_nb, in_frame, out_frame):

    if sourceClip.lower() == "sfx":
        duration = out_frame - in_frame

        comp_fill = f.create.Filler("Sound", duration)
        sequence = seq[track_nb - 1][0]

        index = sequence.index_at_time(out_frame)
        print "Track: V%i SFX Found at in: %i out: %i duration: %i index: %i" % (track_nb, in_frame, out_frame, duration, index)

        sequence.remove(index)
        sequence.insert(index, comp_fill)

def dump_sound(header):

    storage = header.storage()

    main_mob = list(storage.toplevel_mobs())[0]

    tracks = get_video_tracks(main_mob)

    for i, track in enumerate(tracks):

        length = 0
        for k, component in enumerate(track):

            transition_offset = get_transition_offset(k, track)
            component_length = component.length + transition_offset

            in_frame = length
            out_frame = length + component_length + transition_offset

            if isinstance(component,  aaf.component.SourceClip):
                find_sfx(tracks, component.resolve_ref().name, i+1, in_frame, out_frame)

            elif isinstance(component,  aaf.component.OperationGroup):
                for clip in component.input_segments():

                    if isinstance(clip, aaf.component.SourceClip):
                        find_sfx(tracks, clip.resolve_ref().name, i+1, in_frame, out_frame)

                    elif isinstance(clip, aaf.component.OperationGroup):
                        for clips_with_effects in clip.input_segments():
                            find_sfx(tracks, clips_with_effects.resolve_ref().name, i+1, in_frame, out_frame)

                    elif isinstance(clip, aaf.component.Sequence):
                        for segment in clip.components():
                            find_sfx(tracks, segment.resolve_ref().name, i+1, in_frame, out_frame)

            if not isinstance(component, aaf.component.Transition) and not isinstance(component, aaf.component.Sequence):
                length += component_length

dump_sound(header)
f.save()
f.close()
gone-fishing commented 8 years ago

thanks so much!! this is amazing. I have not had a chance to look at it. Ill let you know how it goes!

gone-fishing commented 8 years ago

I seem to be getting stuck with this, when I run it I get index = sequence.index_at_time(out_frame) AttributeError: 'aaf.component.Sequence' object has no attribute 'index_at_time' were you able to have any luck? thanks again

Toadman30 commented 8 years ago

Yes, it's working.

Are you using an old version of pyaaf without the function 'index_at_time'?

gone-fishing commented 8 years ago

Yes, thats totally it. and probably the problem all along. I thought it was a version from late last year but maybe it was older. again, thanks.