ADOBE AFTER EFFECTS: Forum Expressions Tutorials Creative Cloud

Using a CSV with time information to determine layer and comp timings

COW Forums : Adobe After Effects Expressions

<< PREVIOUS   •   FAQ   •   VIEW ALL   •   PRINT   •   NEXT >>
Perry Sheppard
Using a CSV with time information to determine layer and comp timings
on Jul 10, 2020 at 3:40:27 am

I'm new to expressions (and coding), but have worked through controlling alignment, parented font styles, linking csv data dynamically using the comp name as the variable, expression controls and a number of other simple things with master controls, but I'm beginning to think I have a fundamental misunderstanding of a couple of key elements, so my apologies if this is super basic.

I've set up an excel spreadsheet where my team can enter textual content for 'text-style' animations for social media (the simple square videos that are primarily text with some images or video in the background). There are three text boxes in each excel row that are used as three separate text layers in an AE comp. Each row of text is a separate 'slide' (a comp in AE). The excel sheet is set up to automatically calculate the timings for the slide in and out points, as well as for each text layer based on standard reading rates as well as generate a caption file for accessibility.

My goal is to create a mogrt for Premiere to simplify my team's creation process. My team would use the excel file to enter their text, which would generate a csv for the mogrt in Premiere, as well as export a timed caption file. The audio and background video/images would be handled in Premiere (I'll look into scripting that as my next step).

So, my project is set up so that I can make changes to a single comp (comp 0) and then duplicate it as many times as I need to and place those 'slide comps' into a master comp as layers. The csv data is linked using the comp name as a guide so the csv data updates to match. My plan was to have all the slide comps (0,1,2,3...) run the entire length of the mogrt and adjust the "start, in, out, off" timings for each layer in the 'slide comps' as well as the start time/opacity for each comp layer in the master comp using the data from the csv. The project is working in all respects with the exception of the timing expressions.

My setup right now doesn't really use keyframes, but I've successfully used a linear expression as a test in controlling keyframes to shift the time, but that seems to be limited to two keyframes and I need to control 4. Start, In, Out, Off. So, I looked at startTime, InPoint, Offset, etc. There seems to be a lot of information about using a controller to adjust keyframes, but I haven't been able to find anything to just use a new time provided dynamically.

Which is why I think I'm probably experiencing a fundamental misunderstanding of how AE handles time. If anyone has any insight into how I might be able to just override timing using dynamic values, please let me know.


Return to posts index

Perry Sheppard
Re: Using a CSV with time information to determine layer and comp timings
on Jul 10, 2020 at 4:24:41 am

For code reference, see below. I was planning to add 4 keyframes to the relevant layers/sub-properties where necessary and use the code below. I know this doesn't work (valueAtTime is the wrong parameter to use for this), but thought I'd include it in case it clarifies what I'm trying to accomplish.

keyAnimationStart = 1;
keyAnimationIn = 2;
keyAnimationOut = 3;
keyAnimationEnd = 4;

startTimeText = comp("Master").layer("SlideContent2.csv")("Data")("Outline")("Text1Start")("Text1Start 0"); //only need to change these values
endTimeText = comp("Master").layer("SlideContent2.csv")("Data")("Outline")("Text1End")("Text1End 0"); //only need to change these values
slideStart = comp("Master").layer("SlideContent2.csv")("Data")("Outline")("SlideStart")("SlideStart 0"); //only need to change these values
slideEnd = comp("Master").layer("SlideContent2.csv")("Data")("Outline")("SlideEnd")("SlideEnd 0"); //only need to change these values

myAnimationStart = startTimeText;
myAnimationIn = startTimeText + valueAtTime(key(keyAnimationIn).time);
myAnimationOut = slideEnd - valueAtTime(key(keyAnimationEnd).time) - valueAtTime(key(keyAnimationOut).time);
myAnimationEnd = slideEnd;


valueAtTime(key(keyAnimationStart).time + myAnimationStart);
valueAtTime(key(keyAnimationIn).time + myAnimationIn);
valueAtTime(key(keyAnimationOut).time == myAnimationOut);
valueAtTime(key(keyAnimationEnd).time == myAnimationEnd);


Return to posts index

Filip Vandueren
Re: Using a CSV with time information to determine layer and comp timings
on Jul 10, 2020 at 10:33:58 am

If I understand correctly, you are trying to accomplish that the expression would move your four keyframes to a different time ?

Expressions cannot "physically" do that (a script could though). An expression is just a calculation that gives you a '(numeric) value of what the property it is on should be "now".

So you need to look at the current Time, and calculate a correct value from that.
In your case, if you provide 4 keyframes, then we can look up their values.

Let's say we're talking about the position of your slides, and you already set up 4 keyframes: between keyframe 1 and 2 the layer slides in, and between 3 and 4 it slides out.


slideStart = comp("Master").layer("SlideContent2.csv")("Data")("Outline")("SlideStart")("SlideStart 0");
slideEnd = comp("Master").layer("SlideContent2.csv")("Data")("Outline")("SlideEnd")("SlideEnd 0");

move_in_duration = key(2).time - key(1).time;
move_out_duration = key(4).time - key(3).time;

if (time < slideStart + move_in_duration) { //
valueAtTime(time-key(1).time);

} else if (time < slideEnd - move_out_duration) {
key(2).value; // hold at key 2

} else {
valueAtTime(time-key(3).time);
}





Return to posts index


Filip Vandueren
Re: Using a CSV with time information to determine layer and comp timings
on Jul 10, 2020 at 10:43:22 am

Sorry, I forgot a few things in my previous code:


slideStart = comp("Master").layer("SlideContent2.csv")("Data")("Outline")("SlideStart")("SlideStart 0");
slideEnd = comp("Master").layer("SlideContent2.csv")("Data")("Outline")("SlideEnd")("SlideEnd 0");

move_in_duration = key(2).time - key(1).time;
move_out_duration = key(4).time - key(3).time;

if (time < slideStart + move_in_duration) { //
valueAtTime(time + key(1).time - slideStart);

} else if (time < slideEnd - move_out_duration) {
key(2).value; // hold at key 2

} else {
valueAtTime(time + key(3).time - (slideEnd - move_out_duration))
}




Return to posts index

Perry Sheppard
Re: Using a CSV with time information to determine layer and comp timings
on Jul 10, 2020 at 6:33:09 pm

Thanks Filip. Given what you've said, and that I only have one layer animator with keyframes, I suspect I'd be better off writing an expression to set the values using expressions without the need for keyframes.

Is there an example where I could set values at specific times like I would using a linear expression, but that would work with four points on the layer instead of just two?

This would be:
1. Start time of the layer and its value
2. In time of the layer and its value
3. Out time of the layer and its value
4. Off time of the layer and its value

Thanks again. I cannot tell you how much I've benefited from the shared knowledge available here. It's much appreciated.

Best,
Perry


Return to posts index

Filip Vandueren
Re: Using a CSV with time information to determine layer and comp timings
on Jul 10, 2020 at 7:52:15 pm

There is no method built in for a sort of “timeline” with multiple times and values.
If you know in advance how many different interpolations you need,
You would use if/then::

pseudocode:
If time is less than t2
Linear (time, t1, t2, value1, value2)
Else if time is less than t3
Linear(time, t2,t3, value2, value3)
Else
Linear(time, t3, t4, value3, vue4)

Downside is that you are limited to linear/ease/easeIn/easeOut.
If you supply the keyframes as in my previous example, then you also get any fancy non-linear interpolation curves between the keyframes.



Return to posts index


Perry Sheppard
Re: Using a CSV with time information to determine layer and comp timings
on Jul 10, 2020 at 7:53:52 pm

I took another look at the code you provided and I think I understand how it's working. I added the start and end times for the specific text item because I need to stagger the three animations for the three text layers, but they all have the same out time. I'll sort that out once I have an understanding of the base code you provided.

I took a stab at modifying the code you provided, so it doesn't rely on keyframes, but I know I haven't gotten this right. I think I'm misunderstanding the valueAtTime, how to declare a time value, and how to declare a value and reference it at a specific time.

slideStart = comp("Master").layer("SlideContent2.csv")("Data")("Outline")("SlideStart")("SlideStart 0");
startTimeText = comp("Master").layer("SlideContent2.csv")("Data")("Outline")("Text1Start")("Text1Start 0");
endTimeText = comp("Master").layer("SlideContent2.csv")("Data")("Outline")("Text1End")("Text1End 0");
slideEnd = comp("Master").layer("SlideContent2.csv")("Data")("Outline")("SlideEnd")("SlideEnd 0");

slideOn = slideStart
slideIn = startTimeText + 2
slideOut = slideOff - 2
slideOff = slideEnd

move_in_duration = slideIn - slideOn; //could also set this as a number for the transition length
move_out_duration = slideOff - slideOut; //could also set this as a number for the transition length

if (time &lt; slideStart + move_in_duration) { //
valueAtTime(time + slideOn - slideStart);

} else if (time &lt; slideEnd - move_out_duration) {
slideIn; // hold at key 2

} else {
valueAtTime(time + slideOut - (slideEnd - move_out_duration))
}


Return to posts index

Perry Sheppard
Re: Using a CSV with time information to determine layer and comp timings
on Jul 10, 2020 at 7:58:16 pm

Oh. I think I get it now. Because the property 'time' is constantly being evaluated, and if/else statement can be used to change the value of a layer multiple times.


Return to posts index

Perry Sheppard
Re: Using a CSV with time information to determine layer and comp timings
on Jul 14, 2020 at 8:10:20 pm

So, I finally broke down and went with the keyframe control option for a position property on an expression selector. I've modified the timing code a little bit to hold on key3 because I want to use this expression from Dan Ebberts for the position bounce (code below).

The timing code (inserted below) and the bounce code work on their own, but I cannot for the life of me get them to work together (six hours of research, tutorials and code attempts and no glory). If there's a tutorial on something like this, I'd be happy to go that route, but I haven't been able to find anything.

If there's a way to integrate the two I'd appreciate the help. Thanks!

transitionLength1 = key(3).time - key(1).time;
transitionLength2 = key(4).time - key(3).time;

t1 = startTimeText;
t6 = mySlideEnd - transitionLength2;

//if statement for timing

if (time &lt; t1 + transitionLength1)
{
valueAtTime(time + key(1).time - t1);
}
else if (time &lt; t6) {
key(3).value; // hold at key 3 because the bounce continues to key 3 and t6 is slideEnd - transitionLength2
}
else {
valueAtTime(time + key(4).time - t6) //t6 is slide end - transitionLength2
}

//bounce statement
freq = 3;
decay = 4.5;

n = 0;
if (numKeys &gt; 0){
n = nearestKey(time).index;
if (key(n).time &gt; time) n--;
}
if (n &gt; 0){
t = time - key(n).time;
amp = velocityAtTime(key(n).time - .001);
w = freq*Math.PI*2;
value + amp*(Math.sin(t*w)/Math.exp(decay*t)/w);
}else
value


Return to posts index


Filip Vandueren
Re: Using a CSV with time information to determine layer and comp timings
on Jul 14, 2020 at 10:10:45 pm

Something like this:


transitionLength1 = key(3).time - key(1).time;
transitionLength2 = key(4).time - key(3).time;

t1 = 3;
t6 = 10 - transitionLength2;

//if statement for timing

if (time < t1 + transitionLength1)
{
time_offset = time + key(1).time - t1;
//bounce statement
freq = 3;
decay = 4.5;

n = 0;
if (numKeys > 0){
n = nearestKey(time_offset).index;
if (key(n).time > time_offset) n--;
}
if (n > 0){
t = time_offset - key(n).time;
amp = velocityAtTime(key(n).time - .001);
w = freq*Math.PI*2;
valueAtTime(time_offset) + amp*(Math.sin(t*w)/Math.exp(decay*t)/w);
}else
valueAtTime(time_offset);
// valueAtTime(time + key(1).time - t1);
}
else if (time < t6) {
key(3).value; // hold at key 3 because the bounce continues to key 3 and t6 is slideEnd - transitionLength2
}
else {
valueAtTime(time + key(3).time - t6) //t6 is slide end - transitionLength2
}




Return to posts index

Perry Sheppard
Re: Using a CSV with time information to determine layer and comp timings
on Jul 14, 2020 at 11:15:43 pm

Thanks Filip. That did the trick. I was about to resort to TypeArray, but I'm really trying to learn as much as I can before I start relying on pre-built solutions.

Based on the code changes you made, defining 'time_offset' cleaned things up quite a bit. I was trying something similar, but wrote it out in longform in each instance and then started adding 't1' to key(n).time everywhere. It also looks like I need to do some additional reading on 'nearestKey' because I was trying n = nearestKey(time + t1).index.

Really appreciate the assistance on this. This was the last thing I wanted to add to this project, so I should have a working solution in the next couple of days to help my colleagues out (this isn't actually part of my job, but they're so busy right now I wanted to see if I could help them out). Thanks!


Return to posts index

<< PREVIOUS   •   VIEW ALL   •   PRINT   •   NEXT >>
© 2020 CreativeCOW.net All Rights Reserved
[TOP]