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 )
67 QDirIterator it( directory, pattern.isEmpty() ? QStringList() : QStringList { pattern }, QDir::AllEntries | QDir::NoSymLinks | QDir::NoDotAndDotDot, QDirIterator::NoIteratorFlags );
69 while ( it.hasNext() )
71 const QString fullPath = it.next();
72 mInputFiles << fullPath;
75 std::sort( mInputFiles.begin(), mInputFiles.end() );
115#if QT_VERSION < QT_VERSION_CHECK( 6, 8, 0 )
118 mSession = std::make_unique< QMediaCaptureSession >();
119 mRecorder = std::make_unique< QMediaRecorder >();
120 mVideoInput = std::make_unique< QVideoFrameInput >();
121 mSession->setVideoFrameInput( mVideoInput.get() );
122 mSession->setRecorder( mRecorder.get() );
123 mRecorder->setOutputLocation( QUrl::fromLocalFile( mFileName ) );
125 QMediaFormat mediaFormat;
126 mediaFormat.setFileFormat( mFormat );
127 mediaFormat.setVideoCodec( mCodec );
128 mRecorder->setMediaFormat( mediaFormat );
131 mRecorder->setQuality( QMediaRecorder::Quality::VeryHighQuality );
132 mRecorder->setVideoBitRate( 2000 );
133 mRecorder->setEncodingMode( QMediaRecorder::EncodingMode::TwoPassEncoding );
135 mRecorder->setVideoResolution( mSize );
136 mRecorder->setVideoFrameRate( mFramesPerSecond );
138 QObject::connect( mVideoInput.get(), &QVideoFrameInput::readyToSendVideoFrame,
this, &QgsVideoExporter::feedFrames );
139 QObject::connect( mRecorder.get(), &QMediaRecorder::recorderStateChanged,
this, &QgsVideoExporter::checkStatus );
140 QObject::connect( mRecorder.get(), &QMediaRecorder::errorOccurred,
this, &QgsVideoExporter::handleError );
146 mFeedback->setProgress( 0 );
152void QgsVideoExporter::feedFrames()
154#if QT_VERSION >= QT_VERSION_CHECK( 6, 8, 0 )
155 if ( !mRecorder || !mVideoInput || mRecorder->recorderState() != QMediaRecorder::RecorderState::RecordingState )
158 while ( mCurrentFrameIndex < mInputFiles.count() )
160 const QImage frame( mInputFiles.at( mCurrentFrameIndex ) );
161 QVideoFrame videoFrame( frame );
162 const qint64 startUs = mCurrentFrameIndex * mFrameDurationUs;
163 videoFrame.setStartTime( startUs );
164 videoFrame.setEndTime( startUs + mFrameDurationUs );
166 const bool sent = mVideoInput->sendVideoFrame( videoFrame );
170 mCurrentFrameIndex++;
174 mFeedback->setProgress( 100.0 *
static_cast< double >( mCurrentFrameIndex ) /
static_cast< double >( mInputFiles.count() ) );
175 if ( mFeedback->isCanceled() )
183 if ( mCurrentFrameIndex >= mInputFiles.count() )
190void QgsVideoExporter::checkStatus( QMediaRecorder::RecorderState state )
194 case QMediaRecorder::StoppedState:
196 if ( mCurrentFrameIndex >= mInputFiles.count() )
203 case QMediaRecorder::RecordingState:
204 case QMediaRecorder::PausedState:
209void 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.