Frame by frame with QMediaPlayer - c++

I'm trying to implement a "frame by frame" function for users on the Video Widget from Qt Examples, but I didn't find how to do that with QMediaPlayer. I also want to get MetaData of a video file (e.g. how many frames per second, duration, etc...) but .metadata("Duration") function give nothing.
Is QMediaPlayer the right class to use ? If yes, how can I do what I want ?
If not what class do I have to use ?
Thanks for your help.

Related

Get accurate frame Number from QMediaplayer

I want to process frames with Qt. I use QMediaplayer to load a video.
I used the implmentation I found here. I have additional data stored as "frame by frame values" in a .csv file.
For this I want to get the exact frame number of the current frame which is processed in the "present" function of my QAbstractVideoSurface implementation. It works while playing/stopping and pausing the video, but not when I attach a slider to the video...it seems that the QMediaplayer is out of sync with the data which is displayed. I tried getting the current time of the QMediaplayer while being in the QAbstractVideoSurface::present() function but it just won't work. Setting the time from outside while the slider is being moved was also no success for me.
My main problem is that QVideoFrame::startTime() and QVideoFrame::stopTime() does not deliver correct results after QMediaPlayer::setPosition(int) was called!
Does anyone have ideas how I get the current frame number for a QVideoFrame?

How to intercept and modify video frames from QCamera before they are saved to video file

I'm trying to adapt the C++ non QML camera example in QT 5.11 so that it can intercept and add a visual time stamp to the video frames before they are written to the video file.
I want to achieve this without the use of QML.
There is a way to intercept the frames with QVideoprobe but the frame is passed in by const ref and so can't be modified.
Any suggestions except to use qml would be appreciated
Update - the typical way of doing this is to use QAbstractVideoFilter but all the examples I've found only show the filter being applied with QML so I'm initially looking to see how the filter can be applied to the QCamera pipeline in C++.

QMediaPlayer - modify audio on the fly

I'm researching options for creating a simple video player. What I'd like to do, is to apply some audio processing (e.g. low pass filter for simplicity) while playing back the video. I've looked at Qt multimedia API, so here's my main question:
How could I edit the audio output of a QMediaPlayer? Do I need some lower level APIs?
Additionally, if some other technologies would suit this purpose better or provide better open source libraries, feel free to suggest. I have experience with C# as well.
QMediaPlayer doesn't allow low-level access to the audio data.
I'd suggest to you to use the QAudioOutput and QAudioDecoder classes for your purpose.
The QAudioDecoder produces QAudioBuffer objects. You can access the data() of these objects, process it (modify it) and feed it to the QIODevice that is returned by the start() method of the QAudioOutput object.
This will be the audio playback path of your player.
For the video you'll still use a muted QMediaPlayer to decode the video frames from the same file and output them to a QAbstractVideoSurface. You'll then need an algorithm to sync the video and audio frames produced by the above two methods.

How do I get frames one by one from the video in Qt framework?

I got a video input with QMediaPlayer and then I wanted to read frames one by one and process all frames with other vision algorithms. But I didn't know how do I get frames one by one from the video and access each pixel of the frame...
In OpenCV library, I'm easily able to solve that problem with cv::VideoCapture and cv::Mat.
cv::VideoCapture capture(filename);
cv::Mat img;
capture >> img; // 'img' contains the first frame of the video.
capture >> img; // 'img' contains the second frame of the video.
If someone has already handle with this kind of problem, please help me.
Thanks a lot.
You could write your own implementation of the QAbstractVideoSurface and override its
present method to handle the video frame by frame.
Then you will have to set the video output of the QMediaPlayer via setVideoOutput.
For details how to access the frame data you should consult the QVideoFrame documentation.
A suggestion: you could use OpenCV. That would make things easier to play videos and process them without QImage->Mat conversion.
In order to process videos with OpenCV + Qt you must create a QThread connected to a QTimer signal. The QTimer signal emits every few milliseconds signals to a slot in the worker thread to fetch the next video frame from VideoCapture and work on the data.

Drawing items on VLC object

Recently I have tried to do some graphics on the top of VLC video using vlc-qt (which provides a video widget). The approach was trying to draw something on the widget. But it failed duo to the fact that vlc-qt's widget uses an internal widget to render video. (See more details here)
Now I'm trying to do something different. I want to try drawing text (or some rectangles) on the VLC media itself (not the widget). I suppose it's the way how VLC media player renders subtitles (isn't it?)
So the question is this: Having a vlc-qt interface, how can I access underlying vlc object and draw something on it [using libVLC API]?
I'm afraid the only way to do it with libvlc is to use libvlc_video_set_callbacks + libvlc_video_set_format_callbacks. It will decode media stream's frames to memory, which you could use as you wish.