20#include <QDirIterator>
23#include "moc_qgsvideoexporter.cpp"
25#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 )
26#include <QtMultimedia/QMediaCaptureSession>
27#include <QtMultimedia/QVideoFrameInput>
28#include <QtMultimedia/QVideoFrame>
35#if QT_VERSION < QT_VERSION_CHECK( 6, 8, 0 )
43 : mFileName( filename )
72 QDirIterator it( directory, pattern.isEmpty() ? QStringList() : QStringList{ pattern }, QDir::AllEntries | QDir::NoSymLinks | QDir::NoDotAndDotDot, QDirIterator::NoIteratorFlags );
74 while ( it.hasNext() )
76 const QString fullPath = it.next();
77 mInputFiles << fullPath;
80 std::sort( mInputFiles.begin(), mInputFiles.end() );
88#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 )
122#if QT_VERSION < QT_VERSION_CHECK( 6, 8, 0 )
125 mSession = std::make_unique< QMediaCaptureSession >();
126 mRecorder = std::make_unique< QMediaRecorder >();
127 mVideoInput = std::make_unique< QVideoFrameInput >();
128 mSession->setVideoFrameInput( mVideoInput.get() );
129 mSession->setRecorder( mRecorder.get() );
130 mRecorder->setOutputLocation( QUrl::fromLocalFile( mFileName ) );
132 QMediaFormat mediaFormat;
133 mediaFormat.setFileFormat( mFormat );
134 mediaFormat.setVideoCodec( mCodec );
135 mRecorder->setMediaFormat( mediaFormat );
138 mRecorder->setQuality( QMediaRecorder::Quality::VeryHighQuality );
139 mRecorder->setVideoBitRate( 2000 );
140 mRecorder->setEncodingMode( QMediaRecorder::EncodingMode::TwoPassEncoding );
142 mRecorder->setVideoResolution( mSize );
143 mRecorder->setVideoFrameRate( mFramesPerSecond );
145 QObject::connect( mVideoInput.get(), &QVideoFrameInput::readyToSendVideoFrame,
this, &QgsVideoExporter::feedFrames );
146 QObject::connect( mRecorder.get(), &QMediaRecorder::recorderStateChanged,
this, &QgsVideoExporter::checkStatus );
147 QObject::connect( mRecorder.get(), &QMediaRecorder::errorOccurred,
this, &QgsVideoExporter::handleError );
153 mFeedback->setProgress( 0 );
159void QgsVideoExporter::feedFrames()
161#if QT_VERSION >= QT_VERSION_CHECK( 6, 8, 0 )
164 || mRecorder->recorderState() != QMediaRecorder::RecorderState::RecordingState )
167 while ( mCurrentFrameIndex < mInputFiles.count() )
169 const QImage frame( mInputFiles.at( mCurrentFrameIndex ) );
170 QVideoFrame videoFrame( frame );
171 const qint64 startUs = mCurrentFrameIndex * mFrameDurationUs;
172 videoFrame.setStartTime( startUs );
173 videoFrame.setEndTime( startUs + mFrameDurationUs );
175 const bool sent = mVideoInput->sendVideoFrame( videoFrame );
179 mCurrentFrameIndex++;
183 mFeedback->setProgress( 100.0 *
static_cast< double >( mCurrentFrameIndex ) /
static_cast< double >( mInputFiles.count() ) );
184 if ( mFeedback->isCanceled() )
192 if ( mCurrentFrameIndex >= mInputFiles.count() )
199#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 )
200void QgsVideoExporter::checkStatus( QMediaRecorder::RecorderState state )
204 case QMediaRecorder::StoppedState:
206 if ( mCurrentFrameIndex >= mInputFiles.count() )
213 case QMediaRecorder::RecordingState:
214 case QMediaRecorder::PausedState:
219void QgsVideoExporter::handleError( QMediaRecorder::Error error,
const QString &errorString )
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Custom exception class which is raised when an operation is not supported.
void setInputFiles(const QStringList &files)
Sets the list of input image files.
void finished()
Emitted when the video export finishes.
QMediaRecorder::Error error() const
Returns the last error received while writing the video.
QString errorString() const
Returns the string describing the last error received while writing the video.
~QgsVideoExporter() override
QgsVideoExporter(const QString &filename, QSize size, double framesPerSecond)
Constructor for QgsVideoExporter.
QStringList inputFiles() const
Returns the list of input image files.
double framesPerSecond() const
Returns the output video frames per second.
void writeVideo()
Starts the video export operation.
static bool isAvailable()
Returns true if the video export functionality is available on the current system.
QMediaFormat::VideoCodec videoCodec() const
Returns the output video codec.
void setInputFilesByPattern(const QString &directory, const QString &pattern)
Sets the input image files by searching a directory for files matching a pattern.
void setVideoCodec(QMediaFormat::VideoCodec codec)
Sets the output video codec.
void setFileFormat(QMediaFormat::FileFormat format)
Sets the output file format.
QMediaFormat::FileFormat fileFormat() const
Returns the output file format.
void setFeedback(QgsFeedback *feedback)
Sets an optional feedback object, for progress reports and cancellation support.
QSize size() const
Returns the output video frame size.
QgsFeedback * feedback()
Returns the optional feedback object.