We have a QT application that renders programmatically generated QPixmaps one by one to the display and we would like to save this output to a video file.
I know that in the past people have recommended using ffmpeg or opencv with Qt to do this. In Qt 5, however, the new QtMultimedia module seems to expose some of this type of functionality.
It is now possible, for example, to save video from a camera source in Qt 5 by using the QMediaRecorder as described in http://doc.qt.io/qt-5/qmediarecorder.html#details.
With this new functionality, is there any way to use Qt 5 to save our programmatically generated video, or am I still better off using a third party library?
This is actually possible as early as Qt 4.7 through the use of QVideoFrame and QAbstractVideoSurface. Qt even has this excellent example for creating a Video Widget that can display programmatically constructed QVideoFrames:
http://qt-project.org/doc/qt-4.8/multimedia-videowidget.html
You can combine this widget with the mapping capabilities of QVideoFrame to fill individual video frames with properly formatted data. That should look like something like this:
Instantiate your videoWidget:
VideoWidgetSurface * videoWidget = new VideoWidgetSurface();
QSize videoSize(500,500); // supplement with your video dimensions
// look at VideoWidgetSurface::supportedPixelFormats for supported formats
QVideoSurfaceFormat format( videoSize, QVideoFrame::Format_RGB32, QAbstractVideoBuffer::QPixmapHandle)
// possibly fill with initial frame?
videoWidget->start(format);
... and when you want to update the current frame of the video widget:
// If you don't need the data in any past frames you can probably just create one frame
// and just use it repeadtly (as VideoWidgetSurface only keeps track of one frame at a time)
QVideoFrame aFrame(32 * format.frameWidth() * format.frameHeight(),format.frameSize(), 32 * format.frameWidth(),format.pixelFormat());
aFrame.map(QAbstractVideoBuffer::WriteOnly);
QRgb * pixels = aFrame.bits();
// perform pixel manipulation here...
aFrame.unmap();
videoWidget->present(aFrame);
.. and to end playback...
videoWidget.stop();
[... Three years later]. As clarified above, the question is about generating video FILES (e.g. .avi, .mpeg, animated .gif, and/or .mp4).
It looks like FFmpeg is really NOT an option for commercial applications -- See for example: https://www.ffmpeg.org/legal.html (the "Note that FFmpeg ..." sentence and the last two paragraphs on the page).
It really looks like Qt still has no native capability to generate video FILES (e.g. .avi, .mpeg, animated .gif, and/or .mp4) -- See update below.
AM I right about this? (with Qt 5.5.1 being the latest available Qt release at this time).
OR ARE THERE any licensable (for a fee) packages which can be used with a Qt/C++ Windows application which can create video FILES? (from a sequence of programmatically generated QPixmaps or QImages -- or at least with the possibility of receiving frame image data from those Qt classes?).
(We currently don't need any audio in video files generated from our Qt application).
UPDATE: Unfortunately, Qt commercial license support folks are confirming that, currently (as of Qt 5.6), there is no way to get a sequence of programmatically generated QImages (e.g. renders from an application QWidget) into the QMediaRecorder class -- or any other way of generating synthetic animations and saving them as video files. ("There is no API for that").
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With