Revision control

Copy as Markdown

// Copyright (C) 2022 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qscreencapture.h"
#include <QtMultimedia/qmediacapturesession.h>
#include <QtMultimedia/private/qplatformmediaintegration_p.h>
#include <QtMultimedia/private/qplatformsurfacecapture_p.h>
#include <QtMultimedia/private/qscreencapture_p.h>
QT_BEGIN_NAMESPACE
static QScreenCapture::Error toScreenCaptureError(QPlatformSurfaceCapture::Error error)
{
return static_cast<QScreenCapture::Error>(error);
}
/*!
\class QScreenCapture
\inmodule QtMultimedia
\ingroup multimedia
\ingroup multimedia_video
\since 6.5
\brief This class is used for capturing a screen.
The class captures a screen. It is managed by
the \l QMediaCaptureSession class where the captured screen can be displayed
in a video preview object or recorded to a file.
The following snippet shows how to capture the primary screen and display
the result in a QVideoWidget:
\snippet multimedia-snippets/screencapturesnippets.cpp Basic setup
\include qscreencapture-limitations.qdocinc {content} {Q}
\sa QWindowCapture, QMediaCaptureSession
*/
/*!
\qmltype ScreenCapture
\nativetype QScreenCapture
\brief This type is used for capturing a screen.
\inqmlmodule QtMultimedia
\ingroup multimedia_qml
\ingroup multimedia_video_qml
\since 6.5
ScreenCapture captures a screen. It is managed by
\l{QtMultimedia::CaptureSession}{CaptureSession} where the captured
screen can be displayed in a video preview object or recorded to a
file.
The code below shows a simple capture session with ScreenCapture playing
back the captured primary screen view in \l {QtMultimedia::VideoOutput}{VideoOutput}.
\snippet multimedia-snippets/screencapturesnippets.qml Basic setup
\include qscreencapture-limitations.qdocinc {content} {}
\sa WindowCapture, CaptureSession
*/
QScreenCapture::QScreenCapture(QObject *parent)
: QObject(*new QScreenCapturePrivate, parent)
{
Q_D(QScreenCapture);
auto platformCapture = QPlatformMediaIntegration::instance()->createScreenCapture(this);
if (platformCapture) {
connect(platformCapture, &QPlatformSurfaceCapture::activeChanged, this,
&QScreenCapture::activeChanged);
connect(platformCapture, &QPlatformSurfaceCapture::errorChanged, this,
&QScreenCapture::errorChanged);
connect(platformCapture, &QPlatformSurfaceCapture::errorOccurred, this,
[this](QPlatformSurfaceCapture::Error error, const QString &errorString) {
Q_EMIT errorOccurred(toScreenCaptureError(error), errorString);
});
connect(platformCapture,
qOverload<QPlatformSurfaceCapture::ScreenSource>(
&QPlatformSurfaceCapture::sourceChanged),
this, &QScreenCapture::screenChanged);
connect(platformCapture, &QPlatformSurfaceCapture::frameRateChanged, this,
&QScreenCapture::maximumFrameRateChanged);
d->platformScreenCapture.reset(platformCapture);
}
}
QScreenCapture::~QScreenCapture()
{
Q_D(QScreenCapture);
// Reset platformScreenCapture in the destructor to avoid having broken ref in the object.
d->platformScreenCapture.reset();
if (d->captureSession)
d->captureSession->setScreenCapture(nullptr);
}
/*!
\enum QScreenCapture::Error
Enumerates error codes that can be signaled by the QScreenCapture class.
errorString() provides detailed information about the error cause.
\value NoError No error
\value InternalError Internal screen capturing driver error
\value CapturingNotSupported Capturing is not supported
\value CaptureFailed Capturing screen failed
\value NotFound Selected screen not found
*/
/*!
Returns the capture session this QScreenCapture is connected to.
Use QMediaCaptureSession::setScreenCapture() to connect the screen capture
to a session.
*/
QMediaCaptureSession *QScreenCapture::captureSession() const
{
Q_D(const QScreenCapture);
return d->captureSession;
}
/*!
\qmlproperty bool QtMultimedia::ScreenCapture::active
Describes whether the capturing is currently active.
\sa start(), stop()
*/
/*!
\property QScreenCapture::active
\brief whether the capturing is currently active.
\sa start(), stop()
*/
void QScreenCapture::setActive(bool active)
{
Q_D(QScreenCapture);
if (d->platformScreenCapture)
d->platformScreenCapture->setActive(active);
}
bool QScreenCapture::isActive() const
{
Q_D(const QScreenCapture);
return d->platformScreenCapture && d->platformScreenCapture->isActive();
}
/*!
\qmlproperty Screen QtMultimedia::ScreenCapture::screen
Describes the screen for capturing.
If null \c Screen is set, the primary screen will be selected
when the \c ScreenCapture instance gets activated.
\sa {QtQuick::Application::screens}{Application.screens}
*/
/*!
\property QScreenCapture::screen
\brief the screen for capturing.
If null \l QScreen is set, \l QGuiApplication::primaryScreen will be selected
when the \c QScreenCapture instance gets activated.
\sa QGuiApplication::screens(), QGuiApplication::primaryScreen()
*/
void QScreenCapture::setScreen(QScreen *screen)
{
Q_D(QScreenCapture);
if (d->platformScreenCapture)
d->platformScreenCapture->setSource(QPlatformSurfaceCapture::ScreenSource(screen));
}
QScreen *QScreenCapture::screen() const
{
Q_D(const QScreenCapture);
return d->platformScreenCapture
? d->platformScreenCapture->source<QPlatformSurfaceCapture::ScreenSource>()
: nullptr;
}
/*!
\qmlsignal QtMultimedia::ScreenCapture::errorChanged()
This signal is emitted when the \l{error} or \l{errorString} properties are changed.
This signal is not emitted whenever multiple identical errors are raised. To track such
errors, use the signal \l errorOccurred.
*/
/*!
\fn void QScreenCapture::errorChanged()
This signal is emitted when the \l{error} or \l{errorString} properties are changed.
This signal is not emitted whenever multiple identical errors are raised. To track such
errors, use the signal \l errorOccurred.
*/
/*!
\qmlproperty enumeration QtMultimedia::ScreenCapture::error
Returns a code of the last error.
\qmlenumeratorsfrom QScreenCapture::Error
*/
/*!
\property QScreenCapture::error
\brief the code of the last error.
*/
QScreenCapture::Error QScreenCapture::error() const
{
Q_D(const QScreenCapture);
return d->platformScreenCapture ? toScreenCaptureError(d->platformScreenCapture->error())
: CapturingNotSupported;
}
/*!
\qmlsignal QtMultimedia::ScreenCapture::errorOccurred(int error, string errorString)
Signals when an \a error occurs, along with the \a errorString.
For the error parameter, see the enumeration table in
\l {QtMultimedia::ScreenCapture::error}{error} for what values may
be passed.
\sa {QtMultimedia::ScreenCapture::error}{error}
*/
/*!
\fn void QScreenCapture::errorOccurred(QScreenCapture::Error error, const QString &errorString)
Signals when an \a error occurs, along with the \a errorString.
*/
/*!
\qmlproperty string QtMultimedia::ScreenCapture::errorString
Returns a human readable string describing the cause of error.
*/
/*!
\property QScreenCapture::errorString
\brief a human readable string describing the cause of error.
*/
QString QScreenCapture::errorString() const
{
Q_D(const QScreenCapture);
return d->platformScreenCapture ? d->platformScreenCapture->errorString()
: QLatin1StringView("Capturing is not supported on this platform");
}
/*!
\since 6.12
\property QScreenCapture::maximumFrameRate
\brief The screen capture frame rate upper limit.
This can be set to override the capture frame rate used by default based on
e.g. display refresh rate, but only as an upper limit since screen capture
produces frames at a variable rate. Setting this higher than the display
refresh rate is not recommended and can cause errors.
Any changes to this property are applied the next time the QScreenCapture
goes active.
*/
void QScreenCapture::setMaximumFrameRate(std::optional<qreal> frameRate)
{
Q_D(QScreenCapture);
if (d->platformScreenCapture)
d->platformScreenCapture->setFrameRate(frameRate);
}
std::optional<qreal> QScreenCapture::maximumFrameRate() const
{
Q_D(const QScreenCapture);
return d->platformScreenCapture ? d->platformScreenCapture->frameRate() : std::nullopt;
}
/*!
\qmlmethod void QtMultimedia::ScreenCapture::start()
Starts capturing the \l screen.
This is equivalent to setting the \l active property to \c true.
*/
/*!
\fn void QScreenCapture::start()
Starts capturing the \l screen.
This is equivalent to setting the \l active property to true.
*/
/*!
\qmlmethod void QtMultimedia::ScreenCapture::stop()
Stops capturing.
This is equivalent to setting the \l active property to \c false.
*/
/*!
\fn void QScreenCapture::stop()
Stops capturing.
This is equivalent to setting the \l active property to false.
*/
/*!
\internal
*/
void QScreenCapture::setCaptureSession(QMediaCaptureSession *captureSession)
{
Q_D(QScreenCapture);
d->captureSession = captureSession;
}
/*!
\internal
*/
class QPlatformSurfaceCapture *QScreenCapture::platformScreenCapture() const
{
Q_D(const QScreenCapture);
return d->platformScreenCapture.get();
}
void QScreenCapturePrivate::setIgnoreCursor(bool ignore)
{
if (!platformScreenCapture)
return;
platformScreenCapture->setIgnoreCursor(ignore);
}
QT_END_NAMESPACE
#include "moc_qscreencapture.cpp"