21#include <QDirIterator>
24#include <QtMultimedia/QMediaCaptureSession>
25#include <QtMultimedia/QVideoFrame>
27#if QT_VERSION >= QT_VERSION_CHECK( 6, 8, 0 )
28#include <QtMultimedia/QVideoFrameInput>
31#include "moc_qgsvideoexporter.cpp"
33using namespace Qt::StringLiterals;
37#if QT_VERSION < QT_VERSION_CHECK( 6, 8, 0 )
45 : mFileName( filename )
71 QDirIterator it( directory, pattern.isEmpty() ? QStringList() : QStringList { pattern }, QDir::AllEntries | QDir::NoSymLinks | QDir::NoDotAndDotDot, QDirIterator::NoIteratorFlags );
73 while ( it.hasNext() )
75 const QString fullPath = it.next();
76 mInputFiles << fullPath;
79 std::sort( mInputFiles.begin(), mInputFiles.end() );
119#if QT_VERSION < QT_VERSION_CHECK( 6, 8, 0 )
122 mSession = std::make_unique< QMediaCaptureSession >();
123 mRecorder = std::make_unique< QMediaRecorder >();
124 mVideoInput = std::make_unique< QVideoFrameInput >();
125 mSession->setVideoFrameInput( mVideoInput.get() );
126 mSession->setRecorder( mRecorder.get() );
127 mRecorder->setOutputLocation( QUrl::fromLocalFile( mFileName ) );
129 QMediaFormat mediaFormat;
130 mediaFormat.setFileFormat( mFormat );
131 mediaFormat.setVideoCodec( mCodec );
132 mRecorder->setMediaFormat( mediaFormat );
135 mRecorder->setQuality( QMediaRecorder::Quality::VeryHighQuality );
136 mRecorder->setVideoBitRate( 2000 );
137 mRecorder->setEncodingMode( QMediaRecorder::EncodingMode::TwoPassEncoding );
139 mRecorder->setVideoResolution( mSize );
140 mRecorder->setVideoFrameRate( mFramesPerSecond );
142 QObject::connect( mVideoInput.get(), &QVideoFrameInput::readyToSendVideoFrame,
this, &QgsVideoExporter::feedFrames );
143 QObject::connect( mRecorder.get(), &QMediaRecorder::recorderStateChanged,
this, &QgsVideoExporter::checkStatus );
144 QObject::connect( mRecorder.get(), &QMediaRecorder::errorOccurred,
this, &QgsVideoExporter::handleError );
150 mFeedback->setProgress( 0 );
156void QgsVideoExporter::feedFrames()
158#if QT_VERSION >= QT_VERSION_CHECK( 6, 8, 0 )
159 if ( !mRecorder || !mVideoInput || mRecorder->recorderState() != QMediaRecorder::RecorderState::RecordingState )
162 while ( mCurrentFrameIndex < mInputFiles.count() )
164 const QImage frame( mInputFiles.at( mCurrentFrameIndex ) );
165 QVideoFrame videoFrame( frame );
166 const qint64 startUs = mCurrentFrameIndex * mFrameDurationUs;
167 videoFrame.setStartTime( startUs );
168 videoFrame.setEndTime( startUs + mFrameDurationUs );
170 const bool sent = mVideoInput->sendVideoFrame( videoFrame );
174 mCurrentFrameIndex++;
178 mFeedback->setProgress( 100.0 *
static_cast< double >( mCurrentFrameIndex ) /
static_cast< double >( mInputFiles.count() ) );
179 if ( mFeedback->isCanceled() )
187 if ( mCurrentFrameIndex >= mInputFiles.count() )
194void QgsVideoExporter::checkStatus( QMediaRecorder::RecorderState state )
198 case QMediaRecorder::StoppedState:
200 if ( mCurrentFrameIndex >= mInputFiles.count() )
207 case QMediaRecorder::RecordingState:
208 case QMediaRecorder::PausedState:
213void 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.