Capturing still images from QMediaPlayer
-
Hi everyone,
I am using Qt 6.2.3 with Qt Creator 6.0.2.
This subject is already mentioned in one way or another but i could not find any solutions that satisfy me.
I am using a QMediaPlayer object, inside a custom class that does a bunch of different things, likeso:videoWidget = new QVideoWidget(parent);
mplayer = new QMediaPlayer();
mplayer->setVideoOutput(videoWidget);So far i can playback MJPEG video just fine.
I have setup signals/slots as far as stop/pause/play which also works fine.What i want is to capture still images after i call pause() on the QMediaPlayer.
The pause function works fine but when i try to capture/grab a still frame i do not get the expected result.
I tried a few things as follows:
Since i have a pointer to a QVideoWidget object i found out in the class that i could simply do (Attempt #1):
QRect rect(0, 0, 1280, 720); QPixmap pixmap = videoWidget->grab(rect); pixmap.save("/home/user/video_snapshot.jpg", "JPEG");
This did save a jpeg file with the resolution i wanted (1280x720) but it was a white background image and nothing more.
My next attempt (Attempt #2) was using the QVideoSink class:
QVideoSink sink; mplayer->setVideoSink(&sink); QVideoFrame frame = sink.videoFrame(); QImage image = frame.toImage(); image.save("/home/user/video_snapshot.jpg", "JPEG");
This did not save anything to the filesystem at all. While debugging the QImage object i saw that Qt Qreator was saying "invalid image" so there was definitely something wrong with the code there as well.
My next attempt (Attempt #3) was to use QGraphicsVideoItem class as an assignee with setVideoOutput():
QGraphicsVideoItem *local_item = new QGraphicsVideoItem(); QGraphicsView *local_view = new QGraphicsView(); QGraphicsScene *local_scene = new QGraphicsScene(); local_view->setScene(local_scene); local_scene->addItem(local_item); mplayer->setVideoOutput(local_item); mplayer->setPosition(300); QRect rect(0, 0, 1280, 720); QPixmap frame = local_view->grab(rect); frame.save("/home/manos/video_snapshot.jpg", "JPEG"); mplayer->setVideoOutput(videoWidget); delete local_item; delete local_scene; delete local_view;
This attempt produced again an empty jpeg file of desired resolution and a smaller white rectangle probably the QGraphicsVideoItem object.
I really cannot think of anything else.
Any help would be highly appreciated.
Thanks and regards
Manos -
Many thanks Bonnie,
This happens when you don't understand what you're doing (i mean me).
This was the culprit. A huge thanks to Bonnie!The complete code is:
// Get the video sink from the current mplayer pointer QVideoSink *sink = mplayer->videoSink(); // Get a video frame from the sink obj QVideoFrame frame = sink->videoFrame(); // Extract a QImage obj from the frame obj QImage image = frame.toImage(); // Finally save the image to the fs image.save("/home/manos/video_snapshot.jpg", "JPEG");
Again, thanks for the prompt response.
Regards
Manos -