Searching for a method to extract from video stream (.m2t or .ts file) a certain frames as is, encoded. OpenCV also extracts frames easily but decodes them immediately. Given:
I need to read from the file all frames in the given interval and provide to another program as buffer frame by frame as they are. The catch here is to keep the frames encoded as they are, do not decode/encode/encapsulate them.
Picking a frame from the H.264 m2t to a pipe:
ffmpeg -ss 0:2:1.12 -i .\my_video.ts -c:v copy -f mpegts -frames:v 1 pipe: -y -hide_banner
Obviously, the time stamp is increasing for every next frame. From the pipe it is not a problem to convert it to a buffer.
Questions:
-f mpegts
really keeps the frame untouched. Is there better flag? (Maybe -f null
?)Thank you.
This answer slightly diverts the original question. However, it does the job and gives good enough result.
The original question requested to extract encoded video frame by frame. Suggested variants extract to the standar output a compressed videos in batches of several frames. This is easy to pick in software and process/concatenate later as needed.
This method gives really smooth video by concatenation of resulting chunks. This method consumes more CPU than the Variant 2. And processing of every next chunk in the movie takes longer and longer. Therefore, Variant 2 is way better in terms of performance.
ffmpeg.exe -y -nostdin -loglevel quiet -hide_banner -i "c:\\temp\\in.ts" -vf trim=<from_second>:<to_second> -f mpegts pipe:
The order of keys is important and means:
-y -nostdin -loglevel quiet -hide_banner
- don't ask questions, don't print excessive output.-vf x:y
- videofilter which trims out all the movie except the part between start and stop position of required video chunk from original file. These are floats.-f mpegts
- normally not needed if the output goes to the file: ffmpeg knows to derive format from the file name. In this case the result goes to the pipe to explicit specification of the output format needed.This method gives almost smooth video by concatenation of resulting chunks. Almost good is visible jumping video, so it is not perfect method in terms of quality.
ffmpeg.exe -y -nostdin -loglevel quiet -hide_banner -ss <from_second> -t <chunk_duration> -i "c:\\temp\\in.ts" -copyts -f mpegts pipe:
Not repeating the explained options in the variant 1, only new options:
-ss <from_second>
- skip the movie until specified position. It is important to give this key BEFORE the -i
to save processing time. Else the ffmpeg will read all the movie until specified position, not skipping it. This can be supplied in format h:mm:ss.ff
or just float seconds.-t <chunk_duration>
- required/optimal chunk size. This is float. If the GOP is known it's better to take chunks by the GOP size. This improves performance.-copyts
- keep the timestamps of video chunks from the original video. Without this key the result will play only forst frame of each chunk. Better interpretation/understanding is welcome.