View Full Version : How to get current frame number in AviSynth?
zee944
13th October 2008, 15:17
Can anyone tell me how can I have the current frame number in AviSynth?
Within ScriptClip command, I can display it such as:
ScriptClip("subtitle(string(current_frame))")
...but AviSynth doesn't recognize a stand-alone 'current_frame'.
What I actually want to do is to increase saturation from zero to maximum during playback. The first frame is B&W, the last has the original saturation. If 'current_frame' would work, my line would look like this:
Tweak(sat=(current_frame/FrameCount)*1.00)
Could anybody help?
Sagekilla
13th October 2008, 16:07
Try animate (http://avisynth.org/mediawiki/Animate):
ColorBars().ConvertToYV12()
src = last
start_frame = 0
end_frame = 99
src.Animate(start_frame,end_frame, "Tweak", 0,0.0, 0,1.0)
J_Darnley
13th October 2008, 16:16
Cast the frames to floats so that you don't use integer division and then put it all in a ScriptClip().
ScriptClip( "Tweak( sat=( float(current_frame)/float(FrameCount) )*1.0 )" )
Gavino
13th October 2008, 17:11
...but AviSynth doesn't recognize a stand-alone 'current_frame'
current_frame is only visible within the run-time environment provided by filters such as ScriptClip.
Hence J_Darnley's solution is closest to your original idea (though clearly the 1.0 is redundant). However, for a case like this, I prefer Sagekilla's approach with Animate.
IanB
13th October 2008, 22:54
MergeChroma(FadeIn0(100))
zee944
14th October 2008, 15:44
ScriptClip( "Tweak( sat=( float(current_frame)/float(FrameCount) )*1.0 )" )
Thank you for all of you. This one worked damn perfectly, so I didn't even try the others! :)
stickboy
15th October 2008, 00:06
The other approaches are better...
Sagekilla
15th October 2008, 00:15
If you look at it speedwise, I believe IanB's would be the fastest. A copy of the chroma channel is faster than multiplying the saturation by some float (which is calculated based on what frame you're on and the total frame count, another calculation) I think.
I think all methods are fast enough that decoding is slower still, though.
stickboy
15th October 2008, 08:30
IanB's is also the most AviSynth-like.
The ScriptClip way encourages wrong thinking.
Sagekilla
16th October 2008, 06:35
Not to mention the most elegant for that matter, No need to futz around with worrying about types or anything. Just two function calls :)
blausand
3rd December 2008, 13:14
To be honest, the absence of current_frame still really gets me down from time to time. And stickboy, i agree that all of these Scriptclip-solutions feel conceptually wrong whenever i hassle around with them.
look at this:
clp = AVISource("some.avi")
import("someNumberedStrings.txt")
index = ((current_frame+3) % 20) > 10 ? int(current_frame/20) : 0
topSlate = Eval("topslate_"+string(index, "%03d"))
bottomSlate = Eval("bottomslate_"+string(index, "%03d"))
subtitle(bottomSlate, align=2)
subtitle(topSlate, align=8)
I need some math-munging to evaluate the right slates. Then i tried to put everything in a function.
Both approaches yield the error: "I don't know what 'current_frame' is."
I also tried to relate current_frame to a clip: clp.current_frame, and that yields:
"There's no function named 'current_frame' "
And even wrapping everything in FrameEvaluates didn't solve anything.
Is there no workaround to get a current_frame integer based on a specified clip?
Gavino
3rd December 2008, 14:31
Is there no workaround to get a current_frame integer based on a specified clip?
It normally makes no sense to talk of the 'current' frame of a clip because Avisynth deals in complete clips, not individual frames.
The only place it does makes sense is inside a "run-time" script as processed by ScriptClip, as these are (re-)evaluated for every frame of their surrounding 'normal' script. Even here, the processing required can most often be done without caring what the actual frame number is.
See here (http://avisynth.org/mediawiki/ConditionalReader#Returning_Strings)for an example of how to solve your problem using ConditionalReader.
stickboy
3rd December 2008, 20:16
To be honest, the absence of current_frame still really gets me down from time to time. And stickboy, i agree that all of these Scriptclip-solutions feel conceptually wrong whenever i hassle around with them.
...
subtitle(bottomSlate, align=2)
subtitle(topSlate, align=8)
I need some math-munging to evaluate the right slates. Then i tried to put everything in a function.
Both approaches yield the error: "I don't know what 'current_frame' is."
I also tried to relate current_frame to a clip: clp.current_frame, and that yields:
"There's no function named 'current_frame' "
And even wrapping everything in FrameEvaluates didn't solve anything.
Is there no workaround to get a current_frame integer based on a specified clip?Why do you need current_frame at all? Why not use ApplyRange?
Gavino
3rd December 2008, 21:19
Why do you need current_frame at all? Why not use ApplyRange?
ApplyRange won't do it easily because he wants the thing to be dynamic.
But it could be done with Animate something like this:
function DoTitles(clip c, int index) {
topSlate = Eval("topslate_"+string(index, "%03d"))
bottomSlate = Eval("bottomslate_"+string(index, "%03d"))
c
subtitle(bottomSlate, align=2)
subtitle(topSlate, align=8)
}
import("someNumberedStrings.txt") # needs to declare strings global
nTitles = ... # no of titles
start = ... #start frame
end = ... #end frame
clp = AVISource("some.avi")
Animate(clp, start, end, "DoTitles", 1, nTitles)
@blausand
Instead of thinking in terms of current_frame, it is usually better to use a built-in filter that produces a dynamic effect, eg Animate, FadeIn, Dissolve, etc.
vBulletin® v3.8.5, Copyright ©2000-2012, Jelsoft Enterprises Ltd.