Log in

View Full Version : writefileif and timestamp


dark76
7th December 2022, 20:35
Hello, i explain what i wanna do...
I would like to have a txt with timestamp of dark frames from a film. I can't find (or I'm not able to use) the internal function to write the timestamp on a file. I see that exist SHOWTIME(), but i guess it only shows the timestamp on the video.

At the moment I've this situation

#Specify the name and location of the output file
global filename = "blank_frames.txt"

#Specify the threshold that will be considered black (0 = pure black)
global blankthreshold=17
src="C:\file.mkv"

FFvideosource(src)
#framerate
global f=framerate(last)
#Only look at half the fields (speeds up processing)
i=separatefields.selectodd.ConvertToYV12()

#Write the frame number
i.WriteFileIf( filename, "(AverageLuma(i)<blankthreshold)", "current_frame+1", """ time(" %H:%M:%S") """, append = false)

This doesn't work cause it writes the actual time and not the frame timestamp.

I've tried this function

function timecode (int cf,float fr) #cf=current_frame,fr=framerate
{
hh=int(cf/3600/fr)
mm=int((cf-hh*3600*fr)/60/fr)
ss=int((cf-hh*3600*fr-mm*60*fr)/fr)
ff=int((cf-hh*3600*fr-mm*60*fr-ss*fr))
smpte=string(hh,"%02.0f")+":"+string(mm,"%02.0f")+":"+string(ss,"%02.0f")+":"+string(ff,"%0"+string(int(log(fr)/log(10)))+".0f")

smpte
}

but I would like to have HH.MM.SS.milliseconds while this function gives HH.MM.SS.frame and I'm flipping my brian with mathematics to change it :confused: Any help, please? Thank you!

StainlessS
8th December 2022, 01:31
I shall try to helpout tomorrow, bit pissed at the moment.
Love and kisses XXX

dark76
8th December 2022, 12:04
Ahem, this morning I wake up and I realized was much simpler than I thought yesterday evening :D
In the end i finished like this

function timecode (int cf,float fr) #cf=current_frame,fr=framerate
{
hh=int(cf/3600/fr)
mm=int((cf-hh*3600*fr)/60/fr)
ss=int((cf-hh*3600*fr-mm*60*fr)/fr)
ff=int((cf-hh*3600*fr-mm*60*fr-ss*fr))
ms=((cf/fr)-int(cf/fr))*1000
#smpte=string(hh,"%02.0f")+":"+string(mm,"%02.0f")+":"+string(ss,"%02.0f")+":"+string(ff,"%0"+string(int(log(fr)/log(10)))+".0f")
smpte=string(hh,"%02.0f")+":"+string(mm,"%02.0f")+":"+string(ss,"%02.0f")+":"+string(ms,"%03.0f")
smpte
}


I use this function here

#Specify the name and location of the output file
global filename = "blank_frames.txt"

#Specify the threshold that will be considered black (0 = pure black)
global blankthreshold=17
src="C:\file.mkv"
FFvideosource(src)
#framerate
global f=framerate(last)
#Only look at half the fields (speeds up processing
i=separatefields.selectodd.ConvertToYV12()

#Write the timecode using a custom function
i.WriteFileIf( filename, "(AverageLuma(i)<blankthreshold)", "timecode(current_frame,f)", append = false)

#run Video Analysis on AVSPMOD

I'm going to use this to manually generate some chapterfile for the mkv :)
Thanks for the attention Stainless :thanks:

VoodooFX
8th December 2022, 12:19
Or you can try "Frame2TimeFX(current_frame,f)" instead of "timecode(current_frame,f)".
Frame2TimeFX is function from InpaintDelogo.avsi.

dark76
8th December 2022, 14:00
Or you can try "Frame2TimeFX(current_frame,f)" instead of "timecode(current_frame,f)".
Frame2TimeFX is function from InpaintDelogo.avsi.

I just tried Frame2TimeFX and looks like it's little faster. 2 minutes and 43 seconds against 2 minutes and 48 seconds of mine :thanks:

StainlessS
8th December 2022, 17:56
Some more stuff, took me ages to find it.

See from here(post #28):- https://forum.doom9.org/showthread.php?p=1951503#post1951503
Through to post #40.

EDIT: And here:- https://forum.doom9.org/showthread.php?p=1950602#post1950602


EDIT: From above 2nd link [dont think your +string(ff,"%0"+string(int(log(fr)/log(10)))+".0f", is quite right {although I aint tried it}]


Function nDigits(Int n) { return Int(Log10(Max(n,1)))+1 } # ssS, Log10 v2.60+ [ Log10(n) = Log(n)/Log(10) ]



Function nDigits(Int n) { return int(Log(Max(n,1))/Log(10))+1 } # ssS, v2.58 Ver$

Above, missing important nDigits bits in BLUE.
{eg, Log10(0) = ERROR: Although FrameRate is unlikely to be 0 : Also Log10(1) would result in 0, need add 1 to result ie 1 digit : Log10(10) would result in 1, need add 1 to result ie 2 digits, etc for 100, 1000, 10000 ...}

ie,

I've tried this function

function timecode (int cf,float fr) #cf=current_frame,fr=framerate
{
hh=int(cf/3600/fr)
mm=int((cf-hh*3600*fr)/60/fr)
ss=int((cf-hh*3600*fr-mm*60*fr)/fr)
ff=int((cf-hh*3600*fr-mm*60*fr-ss*fr))
smpte=string(hh,"%02.0f")+":"+string(mm,"%02.0f")+":"+string(ss,"%02.0f")+":"+string(ff,"%0"+string(int(log(fr)/log(10)))+".0f")

smpte
}


EDIT: Yep, your code seems to be taken from tsp function (which did not quite work correctly)
something like this?


avisource("c:\clip.avi")
global f=framerate(last)
logfile="c:\smpte.txt"
writefile(logfile,"showsmpte(current_frame,f)")

function showsmpte(int cf,float fr) #cf=current_frame,fr=framerate
{
hh=int(cf/3600/fr)
mm=int((cf-hh*3600*fr)/60/fr)
ss=int((cf-hh*3600*fr-mm*60*fr)/fr)
ff=int((cf-hh*3600*fr-mm*60*fr-ss*fr))
smpte=string(hh,"%02.0f")+":"+string(mm,"%02.0f")+":"+string(ss,"%02.0f")+":"+string(ff,"%0"+string(int(log(fr)/log(10)))+".0f")
smpte
}


EDIT: I think below would work ok in your/tsp original script (untested).

smpte=string(hh,"%02.0f")+":"+string(mm,"%02.0f")+":"+string(ss,"%02.0f")+":"+string(ff,"%0"+string(int(log(Max(fr,1))/log(10))+1)+".0f")

Can test with FrameRate of 0.5, 0.9, 1, 1.1, 9, 10, 11, 99, 100, 101. (with and without fix : test with 0 would produce Divsion by Zero in other parts of script)

StainlessS
8th December 2022, 21:38
Some/Most of previous post is total twaddle, [ :( ]

nDigits does work exactly as intended, HOWEVER, max framenumber part has got to be 1 less than framerate, so the +1 thingy in blue is wrong-ish.
but, the original tsp code is also not 100% working proper.


Function showsmpte(int cf,float fr) { #cf=current_frame,fr=framerate {
hh=int(cf/3600/fr)
mm=int((cf-hh*3600*fr)/60/fr)
ss=int((cf-hh*3600*fr-mm*60*fr)/fr)
ff=int((cf-hh*3600*fr-mm*60*fr-ss*fr))
smpte=string(hh,"%02.0f")+":"+string(mm,"%02.0f")+":"+string(ss,"%02.0f")+":"+string(ff,"%0"+string(int(log(fr)/log(10)))+".0f")
smpte
}

Function showsmpte_Mod(int cf,float fr) { #cf=current_frame,fr=framerate {
hh=int(cf/3600/fr)
mm=int((cf-hh*3600*fr)/60/fr)
ss=int((cf-hh*3600*fr-mm*60*fr)/fr)
ff=int((cf-hh*3600*fr-mm*60*fr-ss*fr))
Return string(hh,"%02.0f")+":"+string(mm,"%02.0f")+":"+string(ss,"%02.0f")+":"+string(ff,"%0"+string(int(log(Max(fr,1))/log(10))+1)+".0f")
}



For(i=0,9) {
FRate = Select(i, 0.5, 0.9, 1.0, 1.1, 9.0, 10.0, 11.0, 99.0, 100.0, 101.0)
FrameNo = int(FRate*2)
S1 = showsmpte(FrameNo-1,FRate)
S2 = showsmpte_Mod(FrameNo-1,FRate)
RT_DebugF("%d:%.1f] '%s' : '%s' %s",FrameNo-1,FRate, S1,S2,S1==S2?"SAME":"")
S1 = showsmpte(FrameNo,FRate)
S2 = showsmpte_Mod(FrameNo,FRate)
RT_DebugF("%d:%.1f] '%s' : '%s' %s",FrameNo,FRate, S1,S2,S1==S2?"SAME":"")
S1 = showsmpte(FrameNo+1,FRate)
S2 = showsmpte_Mod(FrameNo+1,FRate)
RT_DebugF("%d:%.1f] '%s' : '%s' %s",FrameNo+1,FRate, S1,S2,S1==S2?"SAME":"")
}

return MessageClip("Done")


DebugView output

00002427 20:28:02.108 RT_DebugF: 0:0.5] '00:00:00:0' : '00:00:00:0' SAME
00002428 20:28:02.108 RT_DebugF: 1:0.5] '00:00:02:0' : '00:00:02:0' SAME
00002429 20:28:02.108 RT_DebugF: 2:0.5] '00:00:04:0' : '00:00:04:0' SAME
00002430 20:28:02.108 RT_DebugF: 0:0.9] '00:00:00:0' : '00:00:00:0' SAME
00002431 20:28:02.108 RT_DebugF: 1:0.9] '00:00:01:0' : '00:00:01:0' SAME
00002432 20:28:02.108 RT_DebugF: 2:0.9] '00:00:02:0' : '00:00:02:0' SAME
00002433 20:28:02.108 RT_DebugF: 1:1.0] '00:00:01:0' : '00:00:01:0' SAME
00002434 20:28:02.108 RT_DebugF: 2:1.0] '00:00:02:0' : '00:00:02:0' SAME
00002435 20:28:02.108 RT_DebugF: 3:1.0] '00:00:03:0' : '00:00:03:0' SAME
00002436 20:28:02.108 RT_DebugF: 1:1.1] '00:00:00:1' : '00:00:00:1' SAME
00002437 20:28:02.108 RT_DebugF: 2:1.1] '00:00:01:0' : '00:00:01:0' SAME
00002438 20:28:02.108 RT_DebugF: 3:1.1] '00:00:02:0' : '00:00:02:0' SAME
00002439 20:28:02.108 RT_DebugF: 17:9.0] '00:00:01:8' : '00:00:01:8' SAME
00002440 20:28:02.108 RT_DebugF: 18:9.0] '00:00:02:0' : '00:00:02:0' SAME
00002441 20:28:02.108 RT_DebugF: 19:9.0] '00:00:02:1' : '00:00:02:1' SAME
00002442 20:28:02.108 RT_DebugF: 19:10.0] '00:00:01:9' : '00:00:01:09'
00002443 20:28:02.108 RT_DebugF: 20:10.0] '00:00:02:0' : '00:00:02:00'
00002444 20:28:02.108 RT_DebugF: 21:10.0] '00:00:02:1' : '00:00:02:01'
00002445 20:28:02.108 RT_DebugF: 21:11.0] '00:00:01:10' : '00:00:01:10' SAME
00002446 20:28:02.108 RT_DebugF: 22:11.0] '00:00:02:0' : '00:00:02:00'
00002447 20:28:02.108 RT_DebugF: 23:11.0] '00:00:02:1' : '00:00:02:01'
00002448 20:28:02.124 RT_DebugF: 197:99.0] '00:00:01:98' : '00:00:01:98' SAME
00002449 20:28:02.124 RT_DebugF: 198:99.0] '00:00:02:0' : '00:00:02:00'
00002450 20:28:02.124 RT_DebugF: 199:99.0] '00:00:02:1' : '00:00:02:01'
00002451 20:28:02.124 RT_DebugF: 199:100.0] '00:00:01:99' : '00:00:01:099'
00002452 20:28:02.124 RT_DebugF: 200:100.0] '00:00:02:00' : '00:00:02:000'
00002453 20:28:02.124 RT_DebugF: 201:100.0] '00:00:02:01' : '00:00:02:001'
00002454 20:28:02.124 RT_DebugF: 201:101.0] '00:00:01:100' : '00:00:01:100' SAME
00002455 20:28:02.124 RT_DebugF: 202:101.0] '00:00:02:00' : '00:00:02:000'
00002456 20:28:02.124 RT_DebugF: 203:101.0] '00:00:02:01' : '00:00:02:001'


I gotta figure this out.

StainlessS
8th December 2022, 22:03
nDigits does work exactly as intended, HOWEVER, max framenumber part has got to be 1 less than framerate, so the +1 thingy in blue is wrong-ish.
max framenumber part has got to be 1 less than ceil(framerate) {but the +1 thingy is not wrong-ish}.

Mod,

Function showsmpte(int cf,float fr) { #cf=current_frame,fr=framerate {
hh=int(cf/3600/fr)
mm=int((cf-hh*3600*fr)/60/fr)
ss=int((cf-hh*3600*fr-mm*60*fr)/fr)
ff=int((cf-hh*3600*fr-mm*60*fr-ss*fr))
smpte=string(hh,"%02.0f")+":"+string(mm,"%02.0f")+":"+string(ss,"%02.0f")+":"+string(ff,"%0"+string(int(log(fr)/log(10)))+".0f")
smpte
}

Function showsmpte_Mod(int cf,float fr) { #cf=current_frame,fr=framerate {
hh=int(cf/3600/fr)
mm=int((cf-hh*3600*fr)/60/fr)
ss=int((cf-hh*3600*fr-mm*60*fr)/fr)
ff=int((cf-hh*3600*fr-mm*60*fr-ss*fr))
Return string(hh,"%02.0f")+":"+string(mm,"%02.0f")+":"+string(ss,"%02.0f")+":"+string(ff,"%0"+string(int(log(Max(ceil(fr)-1,1))/log(10))+1)+".0f")
}



For(i=0,9) {
FRate = Select(i, 0.5, 0.9, 1.0, 1.1, 9.0, 10.0, 11.0, 99.0, 100.0, 101.0)
spFrm = 1.0 / FRate
FrameNo = int(FRate*2)
S1 = showsmpte(FrameNo-1,FRate)
S2 = showsmpte_Mod(FrameNo-1,FRate)
RT_DebugF("%6d:%8.1f] %-20s : %-20s %s # (%f)",FrameNo-1,FRate, S1,S2,S1==S2?"SAME":" ",(FrameNo-1)*spFrm)
S1 = showsmpte(FrameNo,FRate)
S2 = showsmpte_Mod(FrameNo,FRate)
RT_DebugF("%6d:%8.1f] %-20s : %-20s %s # (%f)",FrameNo,FRate, S1,S2,S1==S2?"SAME":" ",FrameNo*spFrm)
S1 = showsmpte(FrameNo+1,FRate)
S2 = showsmpte_Mod(FrameNo+1,FRate)
RT_DebugF("%6d:%8.1f] %-20s : %-20s %s # (%f)",FrameNo+1,FRate, S1,S2,S1==S2?"SAME":" ",(FrameNo+1)*spFrm)
}

return MessageClip("Done")


DebugView

00002342 22:15:25.818 RT_DebugF: 0: 0.5] 00:00:00:0 : 00:00:00:0 SAME # (0.000000)
00002343 22:15:25.818 RT_DebugF: 1: 0.5] 00:00:02:0 : 00:00:02:0 SAME # (2.000000)
00002344 22:15:25.818 RT_DebugF: 2: 0.5] 00:00:04:0 : 00:00:04:0 SAME # (4.000000)
00002345 22:15:25.818 RT_DebugF: 0: 0.9] 00:00:00:0 : 00:00:00:0 SAME # (0.000000)
00002346 22:15:25.818 RT_DebugF: 1: 0.9] 00:00:01:0 : 00:00:01:0 SAME # (1.111111 ???)
00002347 22:15:25.818 RT_DebugF: 2: 0.9] 00:00:02:0 : 00:00:02:0 SAME # (2.222222 ???)
00002348 22:15:25.818 RT_DebugF: 1: 1.0] 00:00:01:0 : 00:00:01:0 SAME # (1.000000)
00002349 22:15:25.818 RT_DebugF: 2: 1.0] 00:00:02:0 : 00:00:02:0 SAME # (2.000000)
00002350 22:15:25.818 RT_DebugF: 3: 1.0] 00:00:03:0 : 00:00:03:0 SAME # (3.000000)
00002351 22:15:25.818 RT_DebugF: 1: 1.1] 00:00:00:1 : 00:00:00:1 SAME # (0.909091)
00002352 22:15:25.818 RT_DebugF: 2: 1.1] 00:00:01:0 : 00:00:01:0 SAME # (1.818182 ???)
00002353 22:15:25.818 RT_DebugF: 3: 1.1] 00:00:02:0 : 00:00:02:0 SAME # (2.727273 ???)
00002354 22:15:25.818 RT_DebugF: 17: 9.0] 00:00:01:8 : 00:00:01:8 SAME # (1.888889)
00002355 22:15:25.818 RT_DebugF: 18: 9.0] 00:00:02:0 : 00:00:02:0 SAME # (2.000000)
00002356 22:15:25.818 RT_DebugF: 19: 9.0] 00:00:02:1 : 00:00:02:1 SAME # (2.111111)
00002357 22:15:25.818 RT_DebugF: 19: 10.0] 00:00:01:9 : 00:00:01:9 SAME # (1.900000)
00002358 22:15:25.818 RT_DebugF: 20: 10.0] 00:00:02:0 : 00:00:02:0 SAME # (2.000000)
00002359 22:15:25.818 RT_DebugF: 21: 10.0] 00:00:02:1 : 00:00:02:1 SAME # (2.100000)
00002360 22:15:25.818 RT_DebugF: 21: 11.0] 00:00:01:10 : 00:00:01:10 SAME # (1.909091)
00002361 22:15:25.818 RT_DebugF: 22: 11.0] 00:00:02:0 : 00:00:02:00 # (2.000000)
00002362 22:15:25.818 RT_DebugF: 23: 11.0] 00:00:02:1 : 00:00:02:01 # (2.090909)
00002363 22:15:25.818 RT_DebugF: 197: 99.0] 00:00:01:98 : 00:00:01:98 SAME # (1.989899)
00002364 22:15:25.818 RT_DebugF: 198: 99.0] 00:00:02:0 : 00:00:02:00 # (2.000000)
00002365 22:15:25.818 RT_DebugF: 199: 99.0] 00:00:02:1 : 00:00:02:01 # (2.010101)
00002366 22:15:25.818 RT_DebugF: 199: 100.0] 00:00:01:99 : 00:00:01:99 SAME # (1.990000)
00002367 22:15:25.818 RT_DebugF: 200: 100.0] 00:00:02:00 : 00:00:02:00 SAME # (2.000000)
00002368 22:15:25.818 RT_DebugF: 201: 100.0] 00:00:02:01 : 00:00:02:01 SAME # (2.010000)
00002369 22:15:25.818 RT_DebugF: 201: 101.0] 00:00:01:100 : 00:00:01:100 SAME # (1.990099)
00002370 22:15:25.818 RT_DebugF: 202: 101.0] 00:00:02:00 : 00:00:02:000 # (2.000000)
00002371 22:15:25.833 RT_DebugF: 203: 101.0] 00:00:02:01 : 00:00:02:001 # (2.009901)


from Wiki,


ShowSMPTE
Note:
With certain exceptions, SMPTE timecode has no concept of fractional frame rates (like 24.5 fps for example).

ShowSMPTE source clips must have an integer framerate (18, 24, 25, 30, 31,...) or a drop-frame rate ('29.97' being the most common). Supported drop-frame rates are listed in the table below. If that's not the case an error will be thrown.

If the framerate is not integral or drop-frame (let's call it "nonstandard" for short), use ShowFrameNumber or ShowTime instead.

You may encounter media sources that are almost at a standard framerate, but not quite – perhaps due to an error in processing at some point, or perhaps the source was something like a security camera or a video game console. In this case you should force the clip to the nearest standard framerate with AssumeFPS.


ShowSMPTE automatically assumes drop-frame timecode given certain input framerate ranges, as listed in the table below. For example, if the input framerate is > 29.969 and < 29.971 fps, the framerate is assumed to be 30×1000/1001 for time calculation, and drop-frame counting is used.
input fps (bounds excluded) *assumed rate nominal rate
23.975 – 23.977 24×1000/1001 23.98
29.969 – 29.971 30×1000/1001 29.97
47.951 – 47.953 48×1000/1001 47.95
59.939 – 59.941 60×1000/1001 59.94
119.879 - 119.881 120×1000/1001 119.88

So, SMPTE times codes dont really work proper with fractional FPS, especially low FPS.
Above mentioned "Supported drop-frame rates" must be handled especially carefully in ShowSMPTE(), and in at least 64 bit.