mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-04-26 14:23:09 +00:00
Try to reduce the amount of preloaded objects that aren't needed until the quick setting is toggled. Also port the the kpipewire interaction parts to C++.
177 lines
No EOL
4.9 KiB
C++
177 lines
No EOL
4.9 KiB
C++
// SPDX-FileCopyrightText: 2022 Aleix Pol Gonzalez <aleixpol@kde.org>
|
|
// SPDX-FileCopyrightText: 2022-2025 by Devin Lin <devin@kde.org>
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
#include "recordutil.h"
|
|
|
|
#include <QDir>
|
|
#include <QFile>
|
|
#include <QStandardPaths>
|
|
|
|
#include <KFileUtils>
|
|
#include <KLocalizedString>
|
|
#include <KNotification>
|
|
|
|
using namespace Qt::StringLiterals;
|
|
|
|
RecordUtil::RecordUtil(QObject *parent)
|
|
: QObject{parent}
|
|
{
|
|
updateQuickSettingText();
|
|
updateQuickSettingStatus();
|
|
}
|
|
|
|
bool RecordUtil::startRecording(int nodeId)
|
|
{
|
|
if (!m_pipeWireRecord) {
|
|
createPipeWireRecord();
|
|
}
|
|
|
|
if (m_pipeWireRecord->isActive()) {
|
|
return false;
|
|
}
|
|
|
|
switch (m_pipeWireRecord->encoder()) {
|
|
case PipeWireRecord::H264Main:
|
|
case PipeWireRecord::H264Baseline:
|
|
m_pipeWireRecord->setOutput(videoLocation("screen-recording.mp4"));
|
|
break;
|
|
case PipeWireRecord::VP8:
|
|
case PipeWireRecord::VP9:
|
|
m_pipeWireRecord->setOutput(videoLocation("screen-recording.webm"));
|
|
break;
|
|
case PipeWireRecord::WebP:
|
|
m_pipeWireRecord->setOutput(videoLocation("screen-recording.webp"));
|
|
break;
|
|
case PipeWireRecord::Gif:
|
|
m_pipeWireRecord->setOutput(videoLocation("screen-recording.gif"));
|
|
break;
|
|
case PipeWireRecord::NoEncoder:
|
|
default:
|
|
m_quickSettingStatus = i18n("No encoders available for recording");
|
|
Q_EMIT quickSettingStatusChanged();
|
|
qWarning() << "No video encoders available for screen recording!";
|
|
return false;
|
|
}
|
|
|
|
m_pipeWireRecord->setNodeId(nodeId);
|
|
m_pipeWireRecord->start();
|
|
|
|
qDebug() << "Started recording screen with nodeId" << nodeId << "to file" << m_pipeWireRecord->output() << videoLocation("screen-recording.webm");
|
|
return true;
|
|
}
|
|
|
|
void RecordUtil::stopRecording()
|
|
{
|
|
if (!m_pipeWireRecord) {
|
|
return;
|
|
}
|
|
if (!m_pipeWireRecord->isActive()) {
|
|
return;
|
|
}
|
|
|
|
m_pipeWireRecord->stop();
|
|
showNotification(i18n("New Screen Recording"), i18n("New Screen Recording saved in %1", m_pipeWireRecord->output()), m_pipeWireRecord->output());
|
|
}
|
|
|
|
QString RecordUtil::quickSettingText() const
|
|
{
|
|
return m_quickSettingText;
|
|
}
|
|
|
|
QString RecordUtil::quickSettingStatus() const
|
|
{
|
|
return m_quickSettingStatus;
|
|
}
|
|
|
|
bool RecordUtil::isRecording() const
|
|
{
|
|
if (!m_pipeWireRecord) {
|
|
return false;
|
|
}
|
|
|
|
return m_pipeWireRecord->isActive();
|
|
}
|
|
|
|
QString RecordUtil::videoLocation(const QString &name)
|
|
{
|
|
const QString path = QStandardPaths::writableLocation(QStandardPaths::MoviesLocation);
|
|
if (!QDir(path).mkpath(u"."_s)) {
|
|
qWarning() << "Unable to create directory" << path;
|
|
}
|
|
QString newPath(path + '/' + name);
|
|
if (QFile::exists(newPath)) {
|
|
newPath = path + '/' + KFileUtils::suggestName(QUrl::fromLocalFile(newPath), name);
|
|
}
|
|
return newPath;
|
|
}
|
|
|
|
void RecordUtil::showNotification(const QString &title, const QString &text, const QString &filePath)
|
|
{
|
|
KNotification *notif = new KNotification("captured");
|
|
notif->setComponentName(QStringLiteral("plasma_mobile_quicksetting_record"));
|
|
notif->setTitle(title);
|
|
notif->setUrls({QUrl::fromLocalFile(filePath)});
|
|
notif->setText(text);
|
|
notif->sendEvent();
|
|
}
|
|
|
|
void RecordUtil::updateQuickSettingText()
|
|
{
|
|
QString defaultText = i18nc("@action:button", "Record Screen");
|
|
if (!m_pipeWireRecord) {
|
|
m_quickSettingText = defaultText;
|
|
Q_EMIT quickSettingTextChanged();
|
|
return;
|
|
}
|
|
|
|
switch (m_pipeWireRecord->state()) {
|
|
case PipeWireRecord::Recording:
|
|
m_quickSettingText = i18nc("@info:status", "Recording…");
|
|
break;
|
|
case PipeWireRecord::Rendering:
|
|
m_quickSettingText = i18nc("@info:status", "Writing…");
|
|
break;
|
|
case PipeWireRecord::Idle:
|
|
default:
|
|
m_quickSettingText = defaultText;
|
|
break;
|
|
}
|
|
|
|
Q_EMIT quickSettingTextChanged();
|
|
}
|
|
|
|
void RecordUtil::updateQuickSettingStatus()
|
|
{
|
|
QString defaultText = i18n("Tap to start recording");
|
|
|
|
if (!m_pipeWireRecord) {
|
|
m_quickSettingStatus = defaultText;
|
|
Q_EMIT quickSettingStatusChanged();
|
|
return;
|
|
}
|
|
|
|
switch (m_pipeWireRecord->state()) {
|
|
case PipeWireRecord::Recording:
|
|
m_quickSettingStatus = i18n("Screen is being captured…");
|
|
break;
|
|
case PipeWireRecord::Rendering:
|
|
m_quickSettingStatus = i18n("Please wait…");
|
|
break;
|
|
case PipeWireRecord::Idle:
|
|
default:
|
|
m_quickSettingStatus = defaultText;
|
|
break;
|
|
}
|
|
|
|
Q_EMIT quickSettingStatusChanged();
|
|
}
|
|
|
|
void RecordUtil::createPipeWireRecord()
|
|
{
|
|
m_pipeWireRecord = new PipeWireRecord{this};
|
|
|
|
connect(m_pipeWireRecord, &PipeWireRecord::stateChanged, this, &RecordUtil::updateQuickSettingText);
|
|
connect(m_pipeWireRecord, &PipeWireRecord::stateChanged, this, &RecordUtil::updateQuickSettingStatus);
|
|
connect(m_pipeWireRecord, &PipeWireRecord::activeChanged, this, &RecordUtil::isRecordingChanged);
|
|
} |