20#include <QDirIterator>
23#include <QtMultimedia/QMediaCaptureSession>
24#include <QtMultimedia/QVideoFrame>
25#include <QtMultimedia/QVideoFrameInput>
27#include "moc_qgsvideoexporter.cpp"
29using namespace Qt::StringLiterals;
33#if QT_VERSION < QT_VERSION_CHECK( 6, 8, 0 )
41 : mFileName( filename )
70 QDirIterator it( directory, pattern.isEmpty() ? QStringList() : QStringList{ pattern }, QDir::AllEntries | QDir::NoSymLinks | QDir::NoDotAndDotDot, QDirIterator::NoIteratorFlags );
72 while ( it.hasNext() )
74 const QString fullPath = it.next();
75 mInputFiles << fullPath;
78 std::sort( mInputFiles.begin(), mInputFiles.end() );
118#if QT_VERSION < QT_VERSION_CHECK( 6, 8, 0 )
121 mSession = std::make_unique< QMediaCaptureSession >();
122 mRecorder = std::make_unique< QMediaRecorder >();
123 mVideoInput = std::make_unique< QVideoFrameInput >();
124 mSession->setVideoFrameInput( mVideoInput.get() );
125 mSession->setRecorder( mRecorder.get() );
126 mRecorder->setOutputLocation( QUrl::fromLocalFile( mFileName ) );
128 QMediaFormat mediaFormat;
129 mediaFormat.setFileFormat( mFormat );
130 mediaFormat.setVideoCodec( mCodec );
131 mRecorder->setMediaFormat( mediaFormat );
134 mRecorder->setQuality( QMediaRecorder::Quality::VeryHighQuality );
135 mRecorder->setVideoBitRate( 2000 );
136 mRecorder->setEncodingMode( QMediaRecorder::EncodingMode::TwoPassEncoding );
138 mRecorder->setVideoResolution( mSize );
139 mRecorder->setVideoFrameRate( mFramesPerSecond );
141 QObject::connect( mVideoInput.get(), &QVideoFrameInput::readyToSendVideoFrame,
this, &QgsVideoExporter::feedFrames );
142 QObject::connect( mRecorder.get(), &QMediaRecorder::recorderStateChanged,
this, &QgsVideoExporter::checkStatus );
143 QObject::connect( mRecorder.get(), &QMediaRecorder::errorOccurred,
this, &QgsVideoExporter::handleError );
149 mFeedback->setProgress( 0 );
155void QgsVideoExporter::feedFrames()
157#if QT_VERSION >= QT_VERSION_CHECK( 6, 8, 0 )
160 || mRecorder->recorderState() != QMediaRecorder::RecorderState::RecordingState )
163 while ( mCurrentFrameIndex < mInputFiles.count() )
165 const QImage frame( mInputFiles.at( mCurrentFrameIndex ) );
166 QVideoFrame videoFrame( frame );
167 const qint64 startUs = mCurrentFrameIndex * mFrameDurationUs;
168 videoFrame.setStartTime( startUs );
169 videoFrame.setEndTime( startUs + mFrameDurationUs );
171 const bool sent = mVideoInput->sendVideoFrame( videoFrame );
175 mCurrentFrameIndex++;
179 mFeedback->setProgress( 100.0 *
static_cast< double >( mCurrentFrameIndex ) /
static_cast< double >( mInputFiles.count() ) );
180 if ( mFeedback->isCanceled() )
188 if ( mCurrentFrameIndex >= mInputFiles.count() )
195void QgsVideoExporter::checkStatus( QMediaRecorder::RecorderState state )
199 case QMediaRecorder::StoppedState:
201 if ( mCurrentFrameIndex >= mInputFiles.count() )
208 case QMediaRecorder::RecordingState:
209 case QMediaRecorder::PausedState:
214void 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.