Open tottaka opened 2 years ago
Both VideoStream and AudioStream wrappers have a Seek
function that you can pass a timestamp to in the form of a TimeSpan value. Simply pass TimeSpan.Zero
and then call TryGetNextFrame as normal.
Hope this helps :)
For anyone stumbling across this: I couldn't find the Seek
function (might've been a change in the library, might've been me being stupid). What I found to work was simply calling GetFrame
with TimeSpan.Zero
. Subsequent calls to GetNextFrame
were providing frames from the beginning again!
For anyone stumbling across this: I couldn't find the
Seek
function (might've been a change in the library, might've been me being stupid). What I found to work was simply callingGetFrame
withTimeSpan.Zero
. Subsequent calls toGetNextFrame
were providing frames from the beginning again!
I'm pretty sure you can save a reference to the video FileStream(or any stream) and directly call the seek function of the stream.
What I ended up doing was essentially wrapping a ConcurrentQueue
for successful decoded frames, and reading/displaying the queue as needed.
System.IO.FileStream videoStream = System.IO.File.Open("video.mp4", System.IO.FileMode.Open);
FFMediaToolkit.Decoding.MediaFile VideoFile = MediaFile.Open(SourceStream);
// Seek in the "stream"...
videoStream.Seek(0, System.IO.SeekOrigin.Begin);
@tottaka @Saalvage glad you guys have found some workarounds, I'm surprised the built-in Seek
method doesn't exist anymore? I am too lazy to verify so I will take your word for it xD
Regardless, I think that the former of those suggested would be considered the "best practice" for FFMediaToolkit. This is because FFmpeg uses its own internal caches and buffers to keep track of a container's various streams and how they flow through your application. I fear that manually seeking the FileStream
via the managed handle could inadvertently invalidate FFmpeg's internal caches without explicitly notifying native code (dangerous in terms of memory management!!). You also are then missing out on the added benefit of passing a timestamp rather than a raw pointer value.
I'm sure FFmpeg's developer docs have some guidance about this as well, as seeking streams is a very common and well-defined operation. Traditionally I've seen it done via libavcodec
wrappers instead of using the raw pointer, which is exactly what the GetFrame
overload does.
Cheers!
Thank you very much for the insights!
The only mystery that remains is that of Seek
, I looked through the commit history, couldn't find it! Closest is Seek
on the internal AvioStream
class. Internal InputContainer
has SeekFile
and MediaStream
's internal GetFrame
method is documented as "Seeks the stream".
However, in the end it doesn't really matter, as I'm perfectly contempt with the GetFrame
solution :)
Hi, is it possible to reset the media file video and audio streams back to beginning once they reach the end? For example to make the video loop back to the beginning once all frames have been consumed.
I tried TryGetFrame with the timestamp of the beginning of the video, but that doesn't seem to "reset the internal stream" if there even is one.
Do I have to just call
MediaFile.Open
again or is there a better method of doing this?