• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Data-Driven Animation Using JSON

Community Beginner ,
Aug 27, 2022 Aug 27, 2022

Copy link to clipboard

Copied

For my project, I am breaking down the lines of a song and showing who sings what part. This is shown in seconds, which I display using a slider attached to a Source Text (Example : One line sang would be 0.0 - 3.43 seconds, the next line sang would be 3.43 - 6.57 seconds, etc.). The slider is attached to a null, and that's how I change the seconds. The slider is also attached to a moving progress bar. (Example : The progress bar moves the more lines are sung.) This progress bar is also attached to the null. So, all in all, I have the progress bar, number, icon, etc. all hooked up to a null so I can move all properties at once. I have multiple of these nulls depending on how many people are singing. 

 

What I want is to change the null's y-position depending on the value of the slider. For example, if singer A's slider source text is higher than singer B, and singer B is above A, I want them to switch positions. However, keyframing each individual moment where one person surpasses another in seconds is very time consuming, and I would like to cut my time down. I read about data-driven animation, and how I could make an automated ranking system using JSON, but it has been difficult for me to grasp just how I would go about doing this. Any help would be needed, thank you!

TOPICS
Expressions , How to

Views

572

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Expert , Aug 28, 2022 Aug 28, 2022

I am not sure I completely understand your workflow because there are no screenshots. I don't think creating a database with time and singer names and then using a JSON file to turn those times and names into animation would be faster than just setting keyframes. From what you describe, I think the whole animation can be simplified with a few markers and a few expressions. You would not need to set any keyframes; just add and name some markers. I have done a lot of dynamic text (Lyric Videos) wh

...

Votes

Translate

Translate
LEGEND ,
Aug 27, 2022 Aug 27, 2022

Copy link to clipboard

Copied

I think you have a wrong idea what data driven animation can do and how difficult it would be to implement such a system. It's not that this is impossible, but creating a complex expression and making it look elegant would consume just as much time as hand animating it. The first question would have to be whether your texts are already split up and tagged by singer so there's actually something a loop could count in order to determine who's "in the lead". Unless that's already the case, you have to refactor your CSV. Outside that there could be a million issues with positioning in relation to the progress bar, different text blocks having different dimensions, requiring adjustments with sourceRectAtTime(), and the actual transition potentially requiring complex valueAtTime() calculations. Point in case: There's a ton of variables at play and whipping up a set of expressions is not trivial at all.

 

Mylenium

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 28, 2022 Aug 28, 2022

Copy link to clipboard

Copied

I am not sure I completely understand your workflow because there are no screenshots. I don't think creating a database with time and singer names and then using a JSON file to turn those times and names into animation would be faster than just setting keyframes. From what you describe, I think the whole animation can be simplified with a few markers and a few expressions. You would not need to set any keyframes; just add and name some markers. I have done a lot of dynamic text (Lyric Videos) where most of the animation is controlled by markers added to an audio track and layer in and out points. 

 

If you added a marker to the audio track every time the singer changes, then you simply named each marker, you could use an expression to read the time of the marker, then use that time to drive an animation by cutting from one layer to another using opacity, moving a layer into position, or any other animation you would like. You can even use the marker time with a linear or ease interpolation method to ease one effect or movement into another. 

 

You could also use Premiere Pro or Audition to generate an audio track with the words to the song added to markers in sync with the audio track, which can be used to animate a text layer to generate the lyrics.

 

Here's the basic idea. You start with an if statement that says when you get to the first marker, if the marker's name is "Bob," move the layer up 100 pixels over ten frames until you get to the next marker. Then all you have to do to adjust the timing and all the animations tied to the markers is move the markers left or right on the layer, and everything follows. 

 

It sounds like your Expression Control Slider controls a shape layer or scale to control the progress bar's length and convert the value to time. A more efficient workflow for that kind of animation would be to use a time expression for the counter and to control Trim Paths or Scale for the progress bar. For example, add this expression to a text layer:

 

 

 

 

timeToNTSCTimecode(time - inPoint)

 

 

 

 

That will give you a timecode display starting from the in-point of the text layer. Use a monospaced font like Courier to keep the spacing consistent. If you only want minutes and seconds, you can use a mask. 

 

If you want fractions of a second (less readable or understandable by the audience) use this expression for the text layer:

 

 

 

 

(time - inPoint).toFixed(2)

 

 

 

 

Now you have a text layer that reads the time of the layer without any keyframing or fiddling.

 

To create a progress bar, draw a horizontal line on a shape layer with stroke only, then add Trim Paths, then add this expression to the End property:

 

 

 

 

t = time - inPoint;
tMin = 0;
tMax =  outPoint - inPoint;
linear(t, tMin, tMax, 0, 100)

 

 

 

 

If you want to scale a layer instead, set the anchor point to 0, 500 (half the layer height) and modify the expression to look like this:

 

 

 

 

t = time - inPoint;
tMin = 0;
tMax =  outPoint - inPoint;
x = linear(t, tMin, tMax, 0, 100);
[x, value[1]]

 

 

 

 

As long as the text layer and the progress bar layer have the same length, the timer will run, and the progress bar will sync no matter how long the song is without any keyframes.

 

Now let's talk about the Audio Track and the layer markers. Assuming you have two singers, Bob and Alice. Every time Bob sings, add a marker to the audio layer and name it Bob. Do the same for Alice. You can do this using the Ctrl key and the 8 key while the audio is playing, then go back and name the markers.

 

If you set up a null as the starting point, you can add this expression to each singer's text layer position. The singer with the same name as the marker will be on top.

 

 

 

 

m = thisComp.layer("Audio").marker;
i = m.nearestKey(time).index;
if (m.nearestKey(time).time > time){ i--;}
if (i < 1) { i = 1};
mrkrName = m.key(i).comment;

ofst = 250;  // layer offset
movTime = .3; //transition time in seconds
// ref layer
ref = thisComp.layer("Baseline").transform.position
t = time - m.key(i).time;;


if (name == mrkrName){
	value2 = ref[1] - ofst;
	y = linear(t, 0, movTime, ref[1], value2);
}
else if (name !== mrkrName){
	value2 = ref[1];
	y = linear(t, 0, movTime, ref[1] - ofst, value2);

}

[ref[0], y]

 

 

 

 

If you have more than one singer you can add a layer index multiplier to the expression so that the one singing is always on top.

RickGerard_0-1661677263039.gif

You could use the same approach to control text animators, opacity, or any other kind of movement you want. With a little modification, you could stack as many text layers as you want for vocalists and have the current person singing will always be on top. All you have to do is add the markers and name them. If you save the expression as an animation preset, you can use it any time to create this kind of project. 

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Aug 28, 2022 Aug 28, 2022

Copy link to clipboard

Copied

Thank you so much! This helped me get a better understanding of the code. 

 

I didn't think to add screenshots, but here are some if you were looking for them :

 

Screen Shot 2022-08-28 at 8.48.54 AM.pngScreen Shot 2022-08-28 at 8.49.23 AM.pngScreen Shot 2022-08-28 at 8.49.38 AM.pngScreen Shot 2022-08-28 at 8.50.00 AM.png

 

As you can see, Singer 1 has been singing, and each time her number (which is a slider control that I connect to source text to control the numbers manually) passes the singer above her, they change positions. For an entire song, it currently takes me around 30-45 minutes to keyframe all these movements, but I generally wanted to switch it to an automated animation. 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 28, 2022 Aug 28, 2022

Copy link to clipboard

Copied

LATEST

Everything I can gather from your screenshots tells me comp could be created with a single animation preset applied to each layer. From what I am seeing, the progress bar shows the entire song length, but it is only visible on the singer's bar when the active singer is singing. When a singer starts to sing, they move up in the stack. I'm not sure how far they go. The timer looks like the total time for each singer so far. It also looks like a circle appears around the active singer.

 

Have I got that right?

 

If you reference the total height of the stack of singers, you can keep them in order by counting the number of times they have been singing before the current time. You can also control the visibility of the Progress Bar and run an accumulating total of the total time the singer's name has been on a marker. Everything you are showing me can be automated without needing a single keyframe. All you need is a layer (the audio layer) with markers and names. I would make each layer 3D so the moving layer could always be brought one or two pixels toward the camera in Z so it will stay in front while moving.

 

I'm not sure you are telling the story in a very effective way. I would consider your general design and analyze your eye movement as the song progresses. A single progress bar that changes color while a singer is active and a vertical instead of a horizontal stack of the singers with the current singer on the right may be a more effective design. The current singer would always be farthest to the right, and all singers would stay in the order of their last appearance. 

 

Another idea would be to have a row or column of singers' names and photos, then have them move from their default position to the end of the progress bar. Maybe even a clock instead of a progress bar. When designing any kind of animated chart or timeline, it is very important to analyze the best way to present the information so that it is easy to understand and the eyes move comfortably through the whole movement.

 

I don't have time to put together the entire string of expressions for you for free, but the basics would include using sourceRectAtTime() to get the size and position of each text layer and background, an accumulator like the one I used at the start of the position expression to count the markers and return their name and the marker's time. I have been using layer in and out-points, layer markers, and audio levels to automate these kinds of animations for about 20 years.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines