<p>Use</p>

<pre><code>ffmpeg -i C:\src\assets\video\base.mp4 -i C:\card.png -y \
       -filter_complex "[0:v][1:v]overlay=x='if(eq(n,439),300,0)':y='if(eq(n,439),300,0)':enable='eq(n,438)+eq(n,439)'[out]" \
       -map [out] -map 0:a -ss 17 C:\temp\j7kthb0v\composit.mp4
</code></pre>

<p>You may need to escape the commas in filters depending on your shell i.e. <code>n,438</code> -> <code>n\,438</code></p>

CC BY-SA 4.0
2018-06-26T05:45:38.403Z
That's awesome, thankyou, much simpler than multiple overlays
Shannon Hochkins
CC BY-SA 4.0
2018-06-26T06:55:34.040Z
I didn't ask this in the original post, but I'm using this solution for animation, I want to basically specify a position for X & Y, based on a frame number. 

I can achieve this doing nested if else hell. but is there a nicer way?
Shannon Hochkins
CC BY-SA 4.0
2018-06-26T07:25:50.207Z
Not really. The filter isn't meant for animation like that. You can simplify it somewhat like this: `x='0*eq(n,438)+300*eq(n,439)+X*eq(n,567)+...'`
Gyan
CC BY-SA 4.0
2018-06-26T07:41:54.977Z
I've been playing around with the variable n, in overlay if I were to do: `overlay=x='( 605 + -0.8023952095808383 * n)':y='( 406 + -0.4365269461077843 * n)':enable='between(t,438/25,605/25)'`, does this mean the n would equal 0 and incremented for every frame it's visible for ? (605 - 438)
Shannon Hochkins
CC BY-SA 4.0
2018-06-26T07:46:47.643Z
Those expressions mean the overlay starts at (605,406). With each frame, (0.80,0.43) is subtracted and then rounded. But it's only visible (at the computed positions) between times 17.56 and 24.20
Gyan
CC BY-SA 4.0
2018-06-26T07:53:27.643Z
Thanks, I  understood that part, but does: n == 0 at frame 438 and n == 1 at frame 439?
Shannon Hochkins
CC BY-SA 4.0
2018-06-26T07:55:48.390Z
No, `n` is the frame no. First frame is n = 0.
Gyan
CC BY-SA 4.0
2018-06-26T08:02:01.227Z
So in my example n would equal 438 when it is first visible?
Shannon Hochkins
CC BY-SA 4.0
2018-06-26T09:49:36.417Z
That's right...
Gyan
CC BY-SA 4.0
2018-06-26T11:14:15.253Z
Are you able to give me advice on the zoompan? I'm basically trying to tack onto the end of the overlay, a zoom effect that zooms out of the image after the start frame (438 and increments to a zoom out of 0.43

This is what Ive tried but it doesnt seem to apply any zoom

`zoompan=z='if(gte(in,438),min(pzoom-0.04,0.43),1)':d=1`
Shannon Hochkins
CC BY-SA 4.0
2018-06-26T11:31:18.220Z
zoompan can't zoom out to a canvas larger than the input. You'll have to pad the video beforehand.
Gyan
CC BY-SA 4.0
2018-06-26T11:35:27.547Z
I don't understand what you mean by that mate
Shannon Hochkins
CC BY-SA 4.0
2018-06-26T11:47:50.737Z
Also, the zoom is on a layer with an overlay image, so isn't the zoom onlya pplied to that?
Shannon Hochkins
CC BY-SA 4.0
2018-06-26T11:48:41.420Z
Actually I can see the background animated now too, dammit
Shannon Hochkins
CC BY-SA 4.0
2018-06-26T11:56:29.187Z
The `zoom` represents the amount of zoom if input width is 100 then zoom=2 crops out  a window of width 50 pixels. zoom can't go below 1. You have to pad the subject frame with extra pixels (which can be transparent) and then zoom out on that padded frame.
Gyan
CC BY-SA 4.0
2018-06-26T12:02:38.587Z
So if the input width is actually 1659, and the main video is 1920, I have to pad the difference between the two?
Shannon Hochkins
CC BY-SA 4.0
2018-06-26T12:17:31.507Z
zoompan operates upon a single input. If that input is the result of an overlay filter, zoompan doesn't know anything about that. All it sees is the composite image. Maybe post a new Q with an illustration of what you are trying to do.
Gyan
CC BY-SA 4.0
2018-06-26T22:30:22.477Z
I've done this, https://video.stackexchange.com/questions/24339/apply-scale-to-an-overlay-on-existing-background-video if you wouldn't mind having a look, working on adding a gif to that post now
Shannon Hochkins
CC BY-SA 4.0
2018-06-26T05:38:33.747Z
2018-06-26T05:38:33.747Z
Gyan
<p>The folliwng <em>should</em> basically have an image appear on frame 438, and then the same image move to a different position on frame 339, then basically disappear for the rest of the video. </p>

<pre><code>ffmpeg -i C:\src\assets\video\base.mp4 -r 25 -i C:\card.png -y \
    -filter_complex [1:v]setpts=PTS-STARTPTS+(1/TB)[1v]; \
    [0:v][1v]overlay=x=0:y=0:enable='between(t,438/25,439/25)'[1v]; \
    [0:v][1v]overlay=x=300:y=300:enable='between(t,439/25,440/25)'[2v]; \
    [1v][2v]concat=n=2:v=1:a=0[out] -map [out] -map 0:a -ss 17 C:\temp\j7kthb0v\composit.mp4
</code></pre>

<p>I can't seem to get the actual command correct or output anything that resembles what I need. </p>

<p>I know I'm close, I can get one frame overlayed, but I can't get more than that. </p>

<video><ffmpeg><animation><animation-rendering>
How to have an overlay move to specific points at specific frames using ffmpeg
Shannon Hochkins
# How to have an overlay move to specific points at specific frames using ffmpeg

(Asked by: username_0 on 2018-06-26)

The folliwng should basically have an image appear on frame 438, and then the same image move to a different position on frame 339, then basically disappear for the rest of the video. 
ffmpeg -i C:\src\assets\video\base.mp4 -r 25 -i C:\card.png -y \
    -filter_complex [1:v]setpts=PTS-STARTPTS+(1/TB)[1v]; \
    [0:v][1v]overlay=x=0:y=0:enable='between(t,438/25,439/25)'[1v]; \
    [0:v][1v]overlay=x=300:y=300:enable='between(t,439/25,440/25)'[2v]; \
    [1v][2v]concat=n=2:v=1:a=0[out] -map [out] -map 0:a -ss 17 C:\temp\j7kthb0v\composit.mp4

I can't seem to get the actual command correct or output anything that resembles what I need. 
I know I'm close, I can get one frame overlayed, but I can't get more than that.

**Tags:** video, ffmpeg, animation, animation-rendering


---

## 1 answers

### Answer by username_1 on 2018-06-26. Score: 2 | Accepted answer

Use
ffmpeg -i C:\src\assets\video\base.mp4 -i C:\card.png -y \
       -filter_complex "[0:v][1:v]overlay=x='if(eq(n,439),300,0)':y='if(eq(n,439),300,0)':enable='eq(n,438)+eq(n,439)'[out]" \
       -map [out] -map 0:a -ss 17 C:\temp\j7kthb0v\composit.mp4

You may need to escape the commas in filters depending on your shell i.e. n,438 -> n\,438

> **Comments:**
> **username_0**: That's awesome, thankyou, much simpler than multiple overlays  
> **username_0**: I didn't ask this in the original post, but I'm using this solution for animation, I want to basically specify a position for X & Y, based on a frame number.   I can achieve this doing nested if else hell. but is there a nicer way?  
> **username_1**: Not really. The filter isn't meant for animation like that. You can simplify it somewhat like this: `x='0*eq(n,438)+300*eq(n,439)+X*eq(n,567)+...'`  
> **username_0**: I've been playing around with the variable n, in overlay if I were to do: `overlay=x='( 605 + -0.8023952095808383 * n)':y='( 406 + -0.4365269461077843 * n)':enable='between(t,438/25,605/25)'`, does this mean the n would equal 0 and incremented for every frame it's visible for ? (605 - 438)  
> **username_1**: Those expressions mean the overlay starts at (605,406). With each frame, (0.80,0.43) is subtracted and then rounded. But it's only visible (at the computed positions) between times 17.56 and 24.20  
> **username_0**: Thanks, I  understood that part, but does: n == 0 at frame 438 and n == 1 at frame 439?  
> **username_1**: No, `n` is the frame no. First frame is n = 0.  
> **username_0**: So in my example n would equal 438 when it is first visible?  
> **username_1**: That's right...  
> **username_0**: Are you able to give me advice on the zoompan? I'm basically trying to tack onto the end of the overlay, a zoom effect that zooms out of the image after the start frame (438 and increments to a zoom out of 0.43  This is what Ive tried but it doesnt seem to apply any zoom  `zoompan=z='if(gte(in,438),min(pzoom-0.04,0.43),1)':d=1`  
> **username_1**: zoompan can't zoom out to a canvas larger than the input. You'll have to pad the video beforehand.  
> **username_0**: I don't understand what you mean by that mate  
> **username_0**: Also, the zoom is on a layer with an overlay image, so isn't the zoom onlya pplied to that?  
> **username_0**: Actually I can see the background animated now too, dammit  
> **username_1**: The `zoom` represents the amount of zoom if input width is 100 then zoom=2 crops out  a window of width 50 pixels. zoom can't go below 1. You have to pad the subject frame with extra pixels (which can be transparent) and then zoom out on that padded frame.  
> **username_0**: So if the input width is actually 1659, and the main video is 1920, I have to pad the difference between the two?  
> **username_1**: zoompan operates upon a single input. If that input is the result of an overlay filter, zoompan doesn't know anything about that. All it sees is the composite image. Maybe post a new Q with an illustration of what you are trying to do.  
> **username_0**: I've done this, https://video.stackexchange.com/questions/24339/apply-scale-to-an-overlay-on-existing-background-video if you wouldn't mind having a look, working on adding a gif to that post now  

---

