Jump to: Board index » General » Fusion

Generation Scripting

Learn about 3D compositing, animation, broadcast design and VFX workflows.
  • Author
  • Message
Offline

Chris Wells

  • Posts: 59
  • Joined: Mon Nov 10, 2014 11:25 pm

Generation Scripting

PostMon Jun 22, 2015 7:40 pm

So I have been going through the generation scripting manual, But have a couple of questions.

first.

track.ClipGet(i).VersionGet().GetLoader().Length

works and gives me the length of the clip, but

track.ClipGet(i).VersionGet().GetLoader().OutPoint

only returns none? InPoint also returns none? So not sure if the documentation is wrong or it's a bug. but is problematic.

second.

I'm trying to create a system, that plays the current clip, looping, then you would hit next and it would start looping the next shot.

I can play and pause with.
gen.PlayControl("play")
gen.PlayControl("stop")

That works. And the documentation talks about setting the in and the out. but it's not clear how that would work. are you setting a timecode in and out or a frame in and out. and what is the syntax to make it work.

Last,
Is there a way to take a complete quicktime and an edl and use the timing from the EDL to cut up the quicktime in generation, making ClipM's out of every cut. This would be super useful to breakup shots from one quicktime.

Thanks
Chris
Offline
User avatar

Blazej Floch

  • Posts: 191
  • Joined: Tue Nov 11, 2014 12:48 am
  • Location: Toronto, ON

Re: Generation Scripting

PostTue Jun 23, 2015 12:34 pm

The documentation is correct. There is no In/OutPoints in the Loader, but in the ClipM.

Let me explain the logic behind this:
A loader represents a Video file in its full length.

In a timeline you can have many references to the same source footage but with different In/OutPoints.

For example:
videoA.mov is a 600 frames long take of someone talking overshoulder.
videoB.mov is the reverse shot.

The timeline could have the following editing sequence:
1. ClipM(InPoint 10, OutPoint 240)->Loader1(videoA)
2. ClipM(InPont 0, OutPoint 200)->Loader2(videoB)
3. ClipM(InPont 250, OutPoint 600)->Loader1(videoA)

Note that clip 1. and 2. share the same loader, however with a different In and Outpoint defined in the clips.

So you need to set the InPoints in the ClipM (=Column).
Refer to the documentation on page 29.

Hope that makes sense.
Offline

Chris Wells

  • Posts: 59
  • Joined: Mon Nov 10, 2014 11:25 pm

Re: Generation Scripting

PostTue Jun 23, 2015 3:45 pm

Thank you Blazej,

Yes that makes sense with regard to the in and out points. I was looking for the in and out to set the playback so was focused on trying to find the in and out of where the clip was in the timeline for playback and not thinking of the in and out of the loader inside the clipM. But that does makes sense, and also supports the idea of my 3rd question about cutting up the same loader with an edl to make clipM's for every edit.

so then maybe this little script I wrote wasn't' a waste :) it finds the in and out of every clip on the timeline in frames.

Code: Select all
import PeyeonScript as eyeon

# This bit connects to Generation
gen = eyeon.scriptapp("Generation")
proj = gen.ProjectGet()
track = proj.SubGet().TrackGet()
projectName = proj.Path
print("Project path: " + str(projectName))

last = float(-1)#This is so the first clip starts at 0
files = {}
for i in range(int(track.ClipCount())):
    length = track.ClipGet(i).VersionGet().GetLoader().Length
    if length == 1.0: #this is if it's a single frame and Default for Generation is hold for 50
        length = 50.0
    name = track.ClipGet(i).VersionGet().GetLoader().Filename
    garbage, sep, name = name.rpartition("\\")
    name, sep, garbage = name.partition(".")
    InPoint = last + 1
    last = length + last
    files[name] = (InPoint, last)

for key, value in sorted(files.items()):
    print(key, value)


So I know where they are on the timeline. But I still don't know how to do the playback?

Again the main purpose is so I can have a side tool, that I can just hit a next button, and it will go to the next shot, and loop it.

Thanks
Chris
Offline
User avatar

Blazej Floch

  • Posts: 191
  • Joined: Tue Nov 11, 2014 12:48 am
  • Location: Toronto, ON

Re: Generation Scripting

PostTue Jun 23, 2015 4:10 pm

As for the EDL: There is an EDL loading implemented in Generation.
Right Click anywhere: EDL Import ...

I am pretty sure that what you seek is already build in Generation.
Loop Menu: [L] toggles looping of the entire Clip on and off.
Play: [SPACE]
Clip Advance: [CTRL]+[Right] (if I am not mistaken)

As for Scripting:
Scripting Manual Page 40:
Generation.PlayControl(command[, value ])
Allows to control the playback controls via Script. Returns loop in and loop out point if no value is given. If an
“out” command returns 0 (zero) it means the end of the media, clip or sub.
Valid commands: “play”, “stop”, “set”, “in”, “out”


I am actually not sure if these in/outs are meant to be global. I guess so. If not.
Page 29:
ClipM.GlobalFrame2ClipFrame
This should convert your global frame to clip frames.
Offline

Chris Wells

  • Posts: 59
  • Joined: Mon Nov 10, 2014 11:25 pm

Re: Generation Scripting

PostTue Jun 23, 2015 4:43 pm

Yes!! the set media in to "record Relative" does what I want. I have only ever used EDL's with the individual files. Didn't know it could change. but that is exactly what I want :)

And yeah I'm trying to [CTRL]+[Right] for clip advance with a script.
I found the playback stuff in the manual. and it's me not really getting aspects of generations scripting. but gen.PlayControl("play") works to play, but then I try to set in's and out's and I don't know the formatting to do it. and all my guess just error out.

The long answer is I'm trying to making the bidding process easier, most small shops/freelancers. we artists are the guys that do the bidding. And most the time a client just sends some big quicktime and says bid this. So I'm trying to come up with a system inside Generation to make it less painful.

first would be ask for and EDL so I can cut up the quicktime inside Generation. We can do that!!

next, I'm working on a companion app, that talks to/controls generation's playback system. The idea being. it's playing. you hit next. put in the hours. type your notes. hit next. do the same. it will give you a total based on an hourly and you can add scene build costs and show build costs.

Then at the end it could generate a report so you can see how everything breaks down. I've attached a picture of the current gui.

Anyway That's the big picture of what I'm trying to do.
Attachments
bidFire.jpg
bidFire.jpg (62.28 KiB) Viewed 3208 times
Offline

Chris Wells

  • Posts: 59
  • Joined: Mon Nov 10, 2014 11:25 pm

Re: Generation Scripting

PostTue Jun 23, 2015 5:08 pm

so this is my struggle
Generation.PlayControl(command[, value ])

I know this maybe simple but I'm struggling to get the formatting correct.

my guess was

gen.PlayControl("play"[0, 78])

but that says TypeError: string indices must be integers, not tuple
gen.PlayControl("play"[0][78])
IndexError: string index out of range

it's just how to format this to get it to work.
Thanks
Chris
Offline

Chris Wells

  • Posts: 59
  • Joined: Mon Nov 10, 2014 11:25 pm

Re: Generation Scripting

PostTue Jun 23, 2015 5:22 pm

figured it out

they have to all be separate

gen.PlayControl("in", 0)
gen.PlayControl("out",30 )
gen.PlayControl("play")
Offline
User avatar

Blazej Floch

  • Posts: 191
  • Joined: Tue Nov 11, 2014 12:48 am
  • Location: Toronto, ON

Re: Generation Scripting

PostWed Jun 24, 2015 11:26 am

Yes, the scripting API of Generation is a bit weird because of historical reasons.
But glad you figured it out!
Offline

Chris Wells

  • Posts: 59
  • Joined: Mon Nov 10, 2014 11:25 pm

Re: Generation Scripting

PostWed Jun 24, 2015 3:48 pm

So I keep running into things,

I know how to get the selected clip info,
or all the clips info.

but how do I get the info for the clip that is currently playing? once it's playing nothing is considered selected. And in the manual under playback. it has playerview. activate overlay, but I need the script to know what it is?

is there a way?
Thanks
chris
Offline
User avatar

Blazej Floch

  • Posts: 191
  • Joined: Tue Nov 11, 2014 12:48 am
  • Location: Toronto, ON

Re: Generation Scripting

PostThu Jun 25, 2015 11:19 am

I am not sure if the API offers something that shows the current playing clip.

You could trigger and control the playback yourself, and then you know your clip.
Offline

Chris Wells

  • Posts: 59
  • Joined: Mon Nov 10, 2014 11:25 pm

Re: Generation Scripting

PostMon Jun 29, 2015 5:34 pm

ya that's what I"m doing, is just controlling the playback myself.
Just would be nice to be able to see what was being played.

Okay another question I am trying to get the ClipV name. because they are all unique. even if it's the same file name generation will add some number to the end. However, When I try to do it. for example I select the second clip in my timeline. and run this. the ClipV returns the first clips name not the second.
not sure what I"m doing wrong.

Code: Select all
        for clip in proj.SelectedVersions().values():
            ClipM = track.ClipGet(clip)
            ClipV = ClipM.VersionGet(0.0)
            vName = ClipV.Name
            fName = clip.GetLoader().Filename
            print"this is ClipV.Name" + str(vName)
            print"this is filename " + str(fName)


so the ClipV name should match the filename. but it doesn't, V shows the first shot, and filename shows the one that's actually selected. which in my case was the second.

Sorry for all the questions. just so much of this is confusing to me.

thanks for the help
Chris
Offline

Chris Wells

  • Posts: 59
  • Joined: Mon Nov 10, 2014 11:25 pm

Re: Generation Scripting

PostMon Jul 06, 2015 8:11 pm

I haven't found away around this yet, and it's looking more like a bug. They should both return the same shot information.

Can one of the developers confirm?

thanks
Chris
Offline
User avatar

Blazej Floch

  • Posts: 191
  • Joined: Tue Nov 11, 2014 12:48 am
  • Location: Toronto, ON

Re: Generation Scripting

PostTue Jul 14, 2015 8:13 pm

I am not sure I get you question correctly.

But the way it works is that a bunch of ClipVs can reference the very same Loader with the very same Filename. Or even, a bunch of unique Loaders with the very same Filename.

I am not sure if ClipVs names are unique, but if they are you should be able to get them.
I am especially not sure if ClipVs are globally unique or only in their respective ClipM collections.

Not sure if that is the cause for trouble but do not use floats for VersionGet(0.0).

VersionGet(0) is safe, especially as floating point values are not what you expect in most cases.
Offline

Chris Wells

  • Posts: 59
  • Joined: Mon Nov 10, 2014 11:25 pm

Re: Generation Scripting

PostTue Jul 14, 2015 9:16 pm

So a simpler way to ask it is. When I click on metadata in generation and go to clip Name, Generation adds a number to the name of every clip sometimes just an underscore, sometimes both an underscore and a number, I haven't found a pattern to it yet but I'm sure there is one, but that number makes it unique on a global level.

I'm trying to get that name. Both by clicking on it and having it selected. As well as just listing every clipM's bottom most unique name in the generation project. Up until now I've just gotten the loader name, but as you mentioned the same clip can have the same loader. so that doesn't work all the time.

With the code I pasted. it will return that unique name, but it does it for the wrong shot. It always returns it for the first clipM in generation, and I need it to return the unique name for the clipM I have selected.

does that makes sense?
Thanks
Chris
Offline
User avatar

Blazej Floch

  • Posts: 191
  • Joined: Tue Nov 11, 2014 12:48 am
  • Location: Toronto, ON

Re: Generation Scripting

PostWed Jul 15, 2015 8:38 pm

I get it.
ClipVs names are indeed unique. The problem with your script is that you already have the unique ClipV from the selection. So this works:
Code: Select all
proj = gen.ProjectGet()
track = proj.SubGet().TrackGet()
for ClipV in proj.SelectedVersions().values():
   vName = ClipV.Name
   fName = ClipV.GetLoader().Filename
   print "this is ClipV.Name " + str(vName)
   print "this is filename " + str(fName)


The problem with your snippet is that track:ClipGet expects an index:http://documents.blackmagicdesign.com/Fusion/Fusion_7_Generation_Scripting_Manual_2013-12-04.pdf#section.6.4

If you give it a clip it defaults to 0 - so you get the first clip back in all cases of the loop.
Offline
User avatar

Blazej Floch

  • Posts: 191
  • Joined: Tue Nov 11, 2014 12:48 am
  • Location: Toronto, ON

Re: Generation Scripting

PostWed Jul 15, 2015 8:48 pm

If you want to go through all clips on the track you can use:
Code: Select all
for indexm in range(int(track.ClipCount())):
    clipm = track.ClipGet(indexm)
    print ("ClipM: {0}".format(indexm))
    for indexv in range(int(clipm.VersionCount())):
        print ("\tClipV: {0}".format(clipm.VersionGet(indexv).Name))


Btw: Just realized, Gen does give back floats. I guess this has to do with the "Number"-Type in scripting. Still use ints for indices. Will keep you sane.
Offline

Chris Wells

  • Posts: 59
  • Joined: Mon Nov 10, 2014 11:25 pm

Re: Generation Scripting

PostWed Jul 15, 2015 9:17 pm

Thanks so much Blazej!

That was exactly my question,

Return to Fusion

Who is online

Users browsing this forum: No registered users and 56 guests