Screenshot questions

Started by MrPenska, September 25, 2014, 07:47:28 PM

Previous topic - Next topic

MrPenska

I have a normal 29 Frames Per Second Video of a successful field goal that barely makes it over the crossbar.  I'm trying to capture the exact moment that the football crosses the bar, but even at the slowest motion that I can get VLC to play, it is hard for me to hit the "Print Scrn" button at the exact moment.  I thought that maybe Winbatch could come to the rescue.

I found the stock code to take a screenshot:

Snapshot(0)
size=BinaryClipGet(0,8)
bb=BinaryAlloc(size)
BinaryClipGet(bb,8)

bb2=BinaryAlloc(size+14)
BinaryPokeStr(bb2,0,"BM")
BinaryPoke4(bb2,2,size+14)
tableloc=BinaryPeek4(bb,0)+14
BinaryPoke4(bb2,10,tableloc+12)
BinaryCopy(bb2,14,bb,0,size)
BinaryWrite(bb2,"c:\temp\screenshot.bmp")
BinaryFree(bb)
BinaryFree(bb2)
Message("All","Done")

This shouldn't be too hard to invoke from a loop and save time stamped pictures to a directory, but I have a few questions:

1 - While playing the video, how many screenshots can Winbatch reliably take and save each second?

2 - I am not a video professional but I am guessing that at 29 Frames Per second, it would be overkill (assuming I am playing the video at normal speed) to take more than 1 picture every 0.483 seconds.  Can somebody confirm this?  If Winbatch would have performance problems with this frequency, I should be able to just slow down the playback and decrease the frequency of the screenshots accordingly.

I'm hoping to be able to launch a Winbatch script, play my video near the end and have it take screenshots while the video is playing.  Hopefully, one of them will be the picture I am looking for.

I can play with the timing and speed of the playback, but was hoping that a Winbatch Tech or Guru could answer question #1 to save me time.

Thanks

td

Question 1 is impossible to answer because there are too many system variables involved.  You can answer the question for yourself with a little simple experimentation. 

You might consider using SnapShot request 1 or 3 instead of 0 to get a better bmp image.

"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

MrPenska

My first attempt is to take screenshots as fast as Winbatch can process them.  I tried this infinite loop, but Winbatch returns error 1015 - filerename failed:

while 1
Snapshot(1)
size=BinaryClipGet(0,8)
bb=BinaryAlloc(size)
BinaryClipGet(bb,8)
bb2=BinaryAlloc(size+14)
BinaryPokeStr(bb2,0,"BM")
BinaryPoke4(bb2,2,size+14)
tableloc=BinaryPeek4(bb,0)+14
BinaryPoke4(bb2,10,tableloc+12)
BinaryCopy(bb2,14,bb,0,size)
BinaryWrite(bb2,"c:\temp\screenshot")
BinaryFree(bb)
BinaryFree(bb2)
target = ("C:\temp\screenshot")
a = timeymdhms()
b = strreplace(a, ":", "")
c = strcat(b,".bmp")
filerename (target,c)
endwhile


I'm very tired now and am sure I'm making a silly mistake, but can't figure out what it is.  Please correct my code mistake.

Thanks


td

You will need to fix your problem.  All we can do is offer suggestions.  There are several reasons why your script would generate the error.  The first that comes to mind is that not enough time has elapsed between renames so that you are attempting to rename to an existing file.  Perhaps try using GetTickCount instead of TimeYMDHMS as it will provide finer elapse time granularity.

You could also use FileMove as it will allow you to rename over the top of an existing file but you would be loosing the contents of the existing file.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

MrPenska

Getting a little closer.

If I insert:

timedelay (1)

Before the filerename, the code works, however it dumps the screenshots to my desktop which is the location of the executable.  Even when it crashes without the timedelay, one screenshot is placed on the desktop.  Not a big deal, but can you explain why the files are not put into c:\temp?

Also, what is the smallest increment that timedelay will honor.  For my goal, I obviously want this to work with the least amount of time between screenshots.  Does stuff like

timedelay (0.2)  or timedelay (0.05) get recognized by Winbatch?

Thanks

td

Quote from: MrPenska on September 26, 2014, 12:20:17 PM
Getting a little closer.

If I insert:

timedelay (1)

Before the filerename, the code works, however it dumps the screenshots to my desktop which is the location of the executable.  Even when it crashes without the timedelay, one screenshot is placed on the desktop.  Not a big deal, but can you explain why the files are not put into c:\temp?

Not without knowing more. Generally, WinBatch will use the current working directory (CWD) when no directory is specified and the CWD can change for multiple reasons.  But if you want the file to go into a specific folder, you should specify that folder.  For example, if you want the file to go into the scripts location use DirScript() to obtain the path and prepend it to the file name.

Quote
Also, what is the smallest increment that timedelay will honor.  For my goal, I obviously want this to work with the least amount of time between screenshots.  Does stuff like

timedelay (0.2)  or timedelay (0.05) get recognized by Winbatch?

It is not question of what is recognized by WinBatch.  You could use any valid double precision floating point number you want. But at some point then number of clock ticks necessary to execute the machine instructions or the granularity of the sytems kernel timers will be greater than the interval specified.    Those limits very from system to system but something in the neighborhood of 20 milliseconds (.02) can be considered a fairly reasonable effective minimum.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

MrPenska

Thanks - I could use a dirchange, but am now simply launching to program from the directory that I want the pictures on.  I'm now running this on a different PC than when I was earlier testing and the results vary.

When I first launched it with a 1 second time delay, it crashed with the same file rename error, then I was able to get it to work with a 5 second delay.  Then I again tried a 1 second delay and it outputted files for 10 seconds or so before I killed the process.  Them, I tried as little as timedelay(0.3) and ran the program a few times.  Once, it created 2 bitmaps (+ the original non-timestamped bitmap in the directory) before crashing with the file rename error, and another time, it crashed after only creating one timestamped bitmap (+ the original non-timestamped bitmap in the directory).  With the same 0.3 timedelay, I set Exclusive(@ON) at the beginning of the script, but this didn't help, as it replicated the original 0.3 time delay and it crashed after creating 2 timestamped bitmap (+ the original non-timestamped bitmap in the directory).

I'll queue up my video at the end and keep playing with the timing until I (hopefully) get what I want.  I'll try disabling antivirus and stopping unneeded programs and services before I try to see if this will free up resources for Winbatch to be able to keep looping and taking the screenshots with the small time increment. 

What is the specific timing issue.  When the program crashes, unable to rename the file, is BinaryFree(bb2) not finished doing what it needs to do and is BinaryWrite(bb2,"c:\temp\screenshot") still holding on to the file?


td

As previously mentioned if you are still using TimeYMDHMS then your script is attempting to rename a file to the name of an existing file. You cannot do that using FileRename. The pseudo random nature of the eventual error is the result of some combination of the millisecond within the second that the script happens to start, the occurrence of various system interrupts and the activity of other threads and processes on the system including your video display software.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

MrPenska

Yes  - I get it.

This code works, taking around 570 pictures every minute.  It looks like I'm going to have to throw in some time delays, as when I run the code while my video is running, after a few seconds, the video stops (although the audio continues).

An interesting observation:

1 - I don't need to kill the process.  I can simply get it to crash with the failed renaming error if I double click on the clock in my system tray.


while 1
a=GetTickCount( )
Snapshot(1)
size=BinaryClipGet(0,8)
bb=BinaryAlloc(size)
BinaryClipGet(bb,8)
bb2=BinaryAlloc(size+14)
BinaryPokeStr(bb2,0,"BM")
BinaryPoke4(bb2,2,size+14)
tableloc=BinaryPeek4(bb,0)+14
BinaryPoke4(bb2,10,tableloc+12)
BinaryCopy(bb2,14,bb,0,size)
BinaryWrite(bb2,"c:\screenshots\screenshot")
BinaryFree(bb)
BinaryFree(bb2)
target = ("C:\screenshots\screenshot")
c = strcat(a,".bmp")
filerename (target,c)
endwhile




MrPenska

I was able to get the money shot.

Thanks for your help.

....IFICantBYTE

Or you could have just used VLC's frame by frame button (the one that looks like a little blue piece of film with a red arrow over it).
Oh well.
Regards,
....IFICantBYTE

Nothing sucks more than that moment during an argument when you realize you're wrong. :)

td

"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

MrPenska

Quote from: ....IFICantBYTE on September 26, 2014, 07:36:30 PM
Or you could have just used VLC's frame by frame button (the one that looks like a little blue piece of film with a red arrow over it).
Oh well.


LOL!

Thanks - I wasn't showing the advanced controls so I didn't notice the button :)

The best screenshot that I got from Winbatch is the exact picture that I was able to get from taking a manual screenshot after getting to the frame that I needed.

This was a fun exercise and I don't regret having taken it.  I got to:

Meet td
Meet you
Learn about the GetTickCount( ) function
Learn about the VLC frame by frame button
Realize that I am sometimes dopey, like when I need to be told that renaming files using the TimeYMDHMS function when some may be taken during the same second is a bug :)