Log in

View Full Version : How to get current frame number as variable?


Atak_Snajpera
15th April 2023, 19:23
I need to grab current frame number and store it as variable in order to perform simple calculation.

something like this

CurrentFrameNumber=GetCurrentFrameNumber(video)
CurrentFrameNumber=CurrentFrameNumber+1000
Subtitle( String(CurrentFrameNumber) )

Is this possible in avisynth?

johnmeyer
15th April 2023, 22:15
"current_frame" is a runtime variable. If you do some research on "current_frame" and "runtime" I think you will find that there is a way to get the frame number into a variable outside the runtime and use in your script. I just don't remember how to do it at the moment.

DTL
16th April 2023, 00:53
There exist the function to display frame number - http://avisynth.nl/index.php/ShowFrameNumber

The script itself may be not very friendly to operating with frame num because of multithreading. The script is typically a connection of filters for running environment and only environment in frame-based multithreading may somehow keep track on frame number (also different threads process different frame number groups ?). The filters internally can request frame number n from previous filter. But I not sure if it possible somehow easy in AVS+ MT in scripting.

Emulgator
16th April 2023, 22:53
A snippet from one of my bergwerks ;-)


#[*#.....................................................................................Print Source-Framenumber Top/Bottom.....................................................................................................
function PrintSourceFrameNumberATop(clip a) {
ScriptClip(a, """Subtitle("Source Frame "+string(current_frame), size=OverlayFontSize+2, align=5, x=(width*1/8)+12, y=OverlayFontSize+10, font_width=OverlayFontWidth, text_color=$00AAAAFF)""")
}
function PrintSourceFrameNumberABottom(clip a) {
ScriptClip(a, """Subtitle("Source Frame "+string(current_frame), size=OverlayFontSize+2, align=5, x=(width*1/8)+12, y=height-12, font_width=OverlayFontWidth, text_color=$00AAAAFF)""")
}
FrameCounterOverlay>=1 ? PrintSourceFrameNumberATop(last) : NOP
FrameCounterOverlay>=1 ? PrintSourceFrameNumberABottom(last) : NOP
#*]#.........................................................................................End of Source-Framenumber Top/Bottom..............................................................................................

DTL
16th April 2023, 23:02
current_frame

is environment variable ? It lists in examples at http://avisynth.nl/index.php/Internal_functions but where is it documented ?

johnmeyer
17th April 2023, 03:36
Yes, current_frame is a runtime environment variable. I use it all the time.

However, I'm not sure how to make it available outside the runtime environment.

StainlessS
21st April 2023, 14:18
Current_frame is not available outside of the runtime environment, and dont make much sense there either.
But, (probably not of use in required case) you can hack a one time use (on a single frame) just by setting
it to that frame number, eg


blankclip(length=100,pixel_type="YV12")
C = Last.BlankClip(length=0) # zero len clip, same characteristics as Last clip
For(n=0,FrameCount-1) {
current_frame = n # HACK for below AverageLuma
Y = AverageLuma # access frame n
T = Trim(n,-1)
T = T.Subtitle(String(n) + String(Y," : %f"),align=5)
C = C ++ T # add single frame n, to clip so far
}

C # Play C


current_frame is set only for use within runtime (eg by ScriptClip) where it is initialised before each frame that is processed by
the script arg of Scriptclip. Hacking current_frame to some number just allows to use some runtime func (eg AverageLuma), on that SINGLE frame.

EDIT:
Nuther script of limited use

blankclip(length=100,pixel_type="YV12")

Function SomeFunc(clip c, int n) { # Dont think current_frame is visible within this func, but can be provide by caller in n
current_frame = n
Y = c.AverageLuma
Return Y
}

SSS="""
Y = SomeFunc(Last,current_frame)
return Subtitle(String(current_frame) + String(Y," : %f"))
"""

ScriptClip(SSS)


EDIT: Some stuff.


Function Sub(clip c,string Tit,Bool "ShowFrameNo",int "first_frame", int "last_frame",string "font",float "size",int "text_color",
\ int "halo_color",int "align",int "spc",float "font_width",float "font_angle",Int "BackColor") {
/*
Stack Overhead Subtitle Text, with optional FrameNumber shown
http://forum.doom9.org/showthread.php?p=1813402#post1813402
Title bar is Round(size+2) pixels hi (default 20).
Dont use align=4,5,6, better use 1,2,3,7,8,or 9.
*/
ShowFrameNo=Default(ShowFrameNo,False) first_frame=Default(first_frame,0) last_frame=Default(last_frame,c.FrameCount-1)
font=default(font,"Ariel") size=Default(size,18.0) text_color=Default(text_color,$00FFFF00)
halo_color=Default(halo_color,$00000000) align=default(align,7) spc=Default(spc,0)
font_width=Default(font_width,0) font_angle=Default(font_angle,0.0) BackColor=Default(BackColor,$00000000)
c.BlankClip(height=round(size+2.0),Color=BackColor)
(ShowFrameNo)
\ ? ScriptClip("""Subtitle(String(current_frame,"%.0f] ")+"""+Chr(34)+Tit+Chr(34)+String(first_frame,",first_frame=%.0f")+
\ String(last_frame,",last_frame=%.0f,font=")+Chr(34)+font+Chr(34)+String(size,",size=%.3f")+String(text_color,",text_color=%.0f")+
\ String(halo_color,",halo_color=%.0f")+String(align,",align=%.0f")+String(spc,",spc=%.0f")+String(font_width,",font_width=%.3f")+
\ String(font_angle,",font_angle=%.3f)"))
\ : Subtitle(Tit,first_frame=first_frame,last_frame=last_frame,font=font,size=size,text_color=text_color,halo_color=halo_color,align=align,
\ spc=spc,font_width=font_width,font_angle=font_angle)
Return StackVertical(c).AudioDubEx(c)
}


# Stack Overhead RT_Subtitle Text, with optional FrameNumber shown.
Function RtSub(clip c,string Tit, Bool "ShowFrameNo") {
c.BlankClip(height=20)
(Default(ShowFrameNo,False)) ? ScriptClip("""RT_Subtitle("%d] %s",current_frame,""""+Tit+"""")""") : RT_Subtitle("%s",Tit)
Return StackVertical(c).AudioDubEx(c)
}

# Stack Overhead Subtitle Text, with optional FrameNumber shown.
Function TSub(clip c,string Tit,Bool "ShowFrameNo",Int "Col"){
c.BlankClip(height=20,Color=Default(Col,0))
(Default(ShowFrameNo,False))?ScriptClip("""Subtitle(String(current_frame,"%.f] """+Tit+""""))"""):Trim(0,-1).Subtitle(Tit)
Return StackVertical(c).AudioDubEx(c)
}


EDIT:

TitleBar() - by StainlessS @ Doom9:- https://forum.doom9.org/showthread.php?t=176062

Requires VS2008 CPP Runtimes.

VIDEO: Planar, YUY2, RGB32, & RGB24.

Plugin's for both Avisynth v2.58 and v2.6 (avs+ x86 & x64).

Filter to Add a 20 pixel Black TitleBar to top of clip, and to write a title string and optional Frame Number to each frame.
Uses DDigit text renderer & where showing FrameNumber, does not require ScriptClip() filter call.

Titlebar(clip c,String "Tit"="",Bool "ShowFrameNo"=False,Int "Col"=$000000,String "ColChr"="",Bool "Esc"=True)

Tit, Default "", Title string to write above video clip to the TitleBar.
The Tit title string may also contain Escape codes if Esc Arg is True, see later.

ShowFrameNo, Default FALSE. If True, then also writes Frame Number as in eg "1234] My Title String".

Col, Default $000000. RGB color of the TitleBar background.

ColChr, Default "" (Starting Color = default). A single character as a string which sets the Starting color used for printing the FrameNumber/Title text.
If the ColChr string contains more than a single character, it will throw an error.
Valid single character can be any one of these (upper or lower case):-
"0123456789ABCDEF" # 16 Color character codes '0' to 'F'
"GHIJKLMNOPQRSTUV" # 16 Greyscale character codes in ascending order of lightness 'G' to 'V' ($00 -> $FF)
"-!*" # 3 Specials,
# '-' = Default color. : As '7' [White] in Color colorspace : As 'S' [Near white $CC] in Y8.
# '!' = HiLite color. : As 'A' [Orange] in Color colorspace : As 'V' [White $FF] in Y8.
# '*' = Silently converted to '-', ie Default color. (Only has real meaning embedded in the Tit title string).

Esc, Default True. If True, then Escape codes "\a?", and "\x??" can be used to embed data into Tit Title string (The 'a' and 'x' MUST BE LOWERCASE).
Where "\a?", '?' is any character valid as in above ColChr, enables changing color on title bar, within the Tit title string.
In such a case, "\a*" switches to the OnEntry or Starting color, ie same color as set via ColChr.
Where "\x??", each '?' character MUST BE an UPPERCASE hex digit '0' -> 'F'. Enables embedding 8 bit Hex character code into the Tit title string.
You can use eg "\\x00" to embed a literal sequence of "\x00" into the title string, ie "\\" embeds a single backslash and so does not interpret as hex insertion code.
Use similar to avoid color escape code eg "\\a-" to embed literal "\a-".
Esc=False, does NOT process color Escape codes nor Hex insertion Escape code.
NOTE, the only character in range 0->31 that can be used in Tit title string is BEL [chr(7)] (where "\a" is converted to BEL color switch code), all other codes
in range 0->31 (eg chr(9) TAB) are converted to SPACE character. Also, CarriageReturn(13) and Newline(10) will terminate the title string early, eg you cannot
use Newline(10) to print on the input clip [neither as "\n" nor Chr(10)].
Likewise, characters $E0 -> $FF will be converted to SPACE character (they also do not exist in font).

eg,

# Chr(137) [$C9]is Copyright symbol (c). # EDIT: C9 should read $89
ColChr = "!" # Hilite Code (takes effect from FrameNumber as ShowFrameNumber=True)
Return ColorBars.Titlebar("TitleBar \a-\xC9 StainlessS \a*2019",True,ColChr,Esc=true) # FrmNo=Hilite, copyright in Default, Year in same as FrmNo

COLOR TABLE:-
# Ordinal Color ColChr or eg("\a0" for embedded DARKGRAY)
00) DARKGRAY "0"
01) DODGERBLUE "1"
02) ORANGERED "2"
03) ORCHID "3"
04) LIME "4"
05) AQUAMARINE "5"
06) YELLOW "6"
07) WHITE "7"
08) SILVER "8"
09) CORNFLOWERBLUE "9"
10) ORANGE "A"
11) PLUM "B"
12) CHARTREUSE "C"
13) POWDERBLUE "D"
14) GOLD "E"
15) GAINSBORO "F"
#
# Grey ColChr
16) $00 "G"
17) $11 "H"
18) $22 "I"
19) $33 "J"
20) $44 "K"
21) $55 "L"
22) $66 "M"
23) $77 "N"
24) $88 "O"
25) $99 "P"
26) $AA "Q"
27) $BB "R"
28) $CC "S"
29) $DD "T"
30) $EE "U"
31) $FF "V"
# Specials
DEFAULT "-"
HILITE "!"
ON_ENTRY "*"
###################################

TitleBarTest.avs
############
ColorBars(width=1024)
# Chr(137) [$89]is Copyright symbol (c).
SHOWFRAMENO = true
COLCHR = "!" # Hilite Code (takes effect from FrameNumber if ShowFrameNumber=True, Else takes effect on Tit title string)
ESC = True
Titlebar("Title\aDBar \a-\x89 \a2S\a3t\a4a\a5i\a6n\a8l\a9e\aAs\aBs\aCS \a*2019",ShowFrameNo=SHOWFRAMENO,ColChr=COLCHR,Esc=ESC)
############

StainlessS

http://forum.doom9.org/showthread.php?p=1864202
https://i.postimg.cc/NKbwVGYZ/Titlebar-Test.jpg (https://postimg.cc/NKbwVGYZ)

TitleBar() Characterset
https://i.postimg.cc/3dFM4ryW/Titlebar-Character-Set.jpg (https://postimg.cc/3dFM4ryW)

TitleBar() Colors
https://i.postimg.cc/fSQFy1Dx/Show-Color-Codes.jpg (https://postimg.cc/fSQFy1Dx)

EDIT: A bit more,

blankclip(length=500,pixel_type="YV12")

SSS="""
Y = AverageLuma() # Uses current_frame
n = current_frame
return Subtitle(String(n) + String(Y," : %f"))
"""

ScriptClip(SSS)



blankclip(length=500,pixel_type="YV12")
Offset = 100
SSS="""
n = Min(current_frame + Offset,FrameCount-1) # Add an offset for whatever reason, restrict to valid frameNo
current_frame = n
Y = AverageLuma() # Uses current_frame
return Subtitle(String(n) + String(Y," : %f"))
"""

ScriptClip(SSS)

Can use Offset in main level script above, but if below was defined local in function, then offset not available within scriptclip script,
so requires Offset Import via Grunt Args arg.

blankclip(length=500,pixel_type="YV12")

Function test(clip c) {
c
Offset = 100 # REQUIRES GRUNT Args arg.
SSS="""
n = Min(current_frame + Offset,FrameCount-1) # Add an offset for whatever reason, restrict to valid frameNo
current_frame = n
Y = AverageLuma() # Uses current_frame
return Subtitle(String(n) + String(Y," : %f"))
"""
# Return ScriptClip(SSS) # DONT WORK
Return ScriptClip(SSS,Args="Offset") # args arg Req Grunt when Offset defined local within function [Global Offset=100, would probably work, untested]
}

Test(Last)



blankclip(length=500,pixel_type="YV12")

Offset = 100 # Grunt not required

Function test(clip c) {
c
SSS="""
n = Min(current_frame + Offset,FrameCount-1) # Add an offset for whatever reason, restrict to valid frameNo
current_frame = n
Y = AverageLuma() # Uses current_frame
return Subtitle(String(n) + String(Y," : %f"))
"""
Return ScriptClip(SSS) # Grunt Not required when Offset Defined at main script level
}

Test(Last)

Or as required in OP

blankclip(length=500,pixel_type="YV12")

Function ShowFrameNumberWithOffset(clip c,int "Offset") {
c
Offset = Default(Offset,0)
return ScriptClip("Subtitle(String((current_frame + Offset).Max(0).Min(FrameCount-1)))",Args="Offset") # Req Grunt for Args="Offset"
}

ShowFrameNumberWithOffset(100)


EDIT: Got rid of Grunt requirement.

blankclip(length=500,pixel_type="YV12")

Function ShowFrameNumberWithOffset(clip c,int "Offset") {
c
Offset = Default(Offset,0)
return ScriptClip("Subtitle(String((current_frame + "+String(Offset)+").Max(0).Min(FrameCount-1)))")
}

ShowFrameNumberWithOffset(100)


And a little bit of twiddle (When Verbose, also shows real/actual frame number, and actual restricted Offset)

blankclip(length=500,pixel_type="YV12")

Function ShowFrameNumberWithOffset(clip c,int "Offset", Bool "Verbose") {
c
Offset = Default(Offset,0)
Verbose = Default(Verbose,False)
SSS1 = "Subtitle(String((current_frame + "+String(Offset)+").Max(0).Min(FrameCount-1)))"
SSS2 = """
n = (current_frame + """+String(Offset)+""").Max(0).Min(FrameCount-1)
Subtitle(String(n)+String(current_frame," (%.0f : ") + String(n-current_frame,"%.0f)"))
"""
return ScriptClip(Verbose?SSS2:SSS1)
}

Verb = True

ShowFrameNumberWithOffset(100,Verb)