Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion. Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules. |
|
9th December 2023, 17:55 | #1 | Link |
Registered User
Join Date: Sep 2002
Location: Italy
Posts: 108
|
Using ffmpeg to capture frame by number
I need to capture several video frames as .png from .mkv files in an automated way, starting from the frame numbers.
I use the following .bat file (windows) which extracts e.g. 4 frames from a .mkv with yuv video. Code:
set "f1=12345" set "f2=55555" set "f3=111111" set "f4=141414" ffmpeg -y -bitexact -i "myvideo.mkv" -map 0:v -vf "select='eq(n,%f1%)+eq(n,%f2%)+eq(n,%f3%)+eq(n,%f4%)'" -fps_mode passthrough -sws_flags accurate_rnd+full_chroma_int -bitexact "im_%%d.png" Is there a way to do that in a fast way without calculating the exact timestamp of the frames? If needed I can also switch to another command-line windows utility, as long as it is well tested and the yuv-->rgb conversion is accurate. Thanks HG |
10th December 2023, 23:43 | #2 | Link |
Big Bit Savings Now !
Join Date: Feb 2007
Location: close to the wall
Posts: 1,738
|
You want precisely that frame you are specifying decoded, and bitexact, so ffmpeg needs to precisely parse the unknown .mkv, which can only mean indexing, searching, decoding.
Given the complexity of codecs in ffmpeg toolbox I can not imagine any fast way hoping to take shortcuts and assuming a hopefully correct frame. Any other software would have to perform the same.
__________________
"To bypass shortcuts and find suffering...is called QUALity" (Die toten Augen von Friedrichshain) "Data reduction ? Yep, Sir. We're that issue working on. Synce invntoin uf lingöage..." |
11th December 2023, 22:07 | #3 | Link |
Registered User
Join Date: Sep 2002
Location: Italy
Posts: 108
|
It is not true. Virtualdub2 opens a .mkv in less than a second, and can jump immediately to a given frame by number (just click on the "Frame" label at bottom). This is the standard way I take screenshots when I have to compare two same frames of different encodings, but I also have to copy the frame to clipboard, open an Image utility, paste and save, then open a new file in VD2. If I can do it automatically it is better, especially if I have several different files to compare.
PS: the 'bitexact' option, as a general ffmpeg flag and outside the -sws_flags parameter, is only for deterministic output (and input/decoding). It allows me to check if an option has any effect by hash, and remove any unwanted and potentially personal information from the output, such as timestamps. Last edited by hellgauss; 11th December 2023 at 22:10. Reason: typo |
12th December 2023, 20:15 | #4 | Link |
Big Bit Savings Now !
Join Date: Feb 2007
Location: close to the wall
Posts: 1,738
|
Well, VD2 uses avlib-1.vdplugin as decoder, and behind that sits: The very same mother ffmpeg, what else. ;-)
https://forum.doom9.org/showthread.p...89#post1994989 Just no lengthy indexing, rather trusting the container- if that hits the correct frame, one may use that. (Here it was not, BTW. DGDecoders are the gold standard here, and they do need indexing.) BTW, if one prefers VD: no image utility needed. VD can export frames: single, sequences, and this can be scripted. And AvsPmod can do that too, with Macros.
__________________
"To bypass shortcuts and find suffering...is called QUALity" (Die toten Augen von Friedrichshain) "Data reduction ? Yep, Sir. We're that issue working on. Synce invntoin uf lingöage..." Last edited by Emulgator; 12th December 2023 at 20:29. |
13th December 2023, 21:04 | #5 | Link |
Registered User
Join Date: Sep 2002
Location: Italy
Posts: 108
|
Thanks a lot for info and tips!
I cannot find the way to script single image export with VD2, bit i managed it with export image sequence. The following script seems to do a good job. Perhaps it needs some tweak with strange characters in file name. It needs Virtualdub2 folder in windows PATH Code:
set "f1=12345" set "f2=55555" set "f3=111111" set "f4=141414" set "input=test_(test)\myvideo.mkv" call :vdgrab %input%, %f1%, 1 call :vdgrab %input%, %f2%, 2 call :vdgrab %input%, %f3%, 3 call :vdgrab %input%, %f4%, 4 pause exit :vdgrab rem usage (3 params): vdgrab input_video frame_number output rem virtualdub2 folder must be in windows PATH rem output is without .png extension SETLOCAL set "input=%1" set "input=%input:\=\\%" set /A n1=%2 set /A n2=n1+1 ( echo VirtualDub.Open^("%input%","",0^); echo VirtualDub.audio.SetSource^(1^); echo VirtualDub.audio.SetMode^(0^); echo VirtualDub.audio.SetInterleave^(1,500,1,0,0^); echo VirtualDub.audio.SetClipMode^(1,1^); echo VirtualDub.audio.SetEditMode^(1^); echo VirtualDub.audio.SetConversion^(0,0,0,0,0^); echo VirtualDub.audio.SetVolume^(^); echo VirtualDub.audio.SetCompression^(^); echo VirtualDub.audio.EnableFilterGraph^(0^); echo VirtualDub.video.SetInputFormat^(0^); echo VirtualDub.video.SetOutputFormat^(7^); echo VirtualDub.video.SetMode^(3^); echo VirtualDub.video.SetSmartRendering^(0^); echo VirtualDub.video.SetPreserveEmptyFrames^(0^); echo VirtualDub.video.SetFrameRate2^(0,0,1^); echo VirtualDub.video.SetIVTC^(0, 0, 0, 0^); echo VirtualDub.video.SetCompression^(^); echo VirtualDub.SaveFormatAVI^(^); echo VirtualDub.SaveAudioFormat^(""^); echo VirtualDub.video.filters.BeginUpdate^(^); echo VirtualDub.video.filters.Clear^(^); echo VirtualDub.video.filters.EndUpdate^(^); echo VirtualDub.audio.filters.Clear^(^); echo VirtualDub.video.SetRangeFrames^(%n1%,%n2%^); echo VirtualDub.project.ClearTextInfo^(^); echo VirtualDub.SaveImageSequence2^("%3_", ".png", 1, 0, 3, 100^); echo VirtualDub.Close^(^); ) > %1_%2_%3.tmp start /min /wait virtualdub64.exe /x /s %1_%2_%3.tmp rename "%3_0.png" "%3.png" del %1_%2_%3.tmp ENDLOCAL exit /B 0 |
Tags |
ffmpeg, frames |
Thread Tools | Search this Thread |
Display Modes | |
|
|