File indexing completed on 2024-05-19 05:04:04
0001 /* 0002 SPDX-FileCopyrightText: 2020-2024 Laurent Montel <montel@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "createvideomessagewidget.h" 0008 #include <KMessageWidget> 0009 #include <QAudioInput> 0010 #include <QCamera> 0011 #include <QCameraDevice> 0012 #include <QComboBox> 0013 #include <QHBoxLayout> 0014 #include <QLabel> 0015 #include <QMediaDevices> 0016 #include <QToolButton> 0017 #include <QVBoxLayout> 0018 #include <QVideoWidget> 0019 0020 #include <KConfigGroup> 0021 #include <KLocalizedString> 0022 #include <KSharedConfig> 0023 #include <QDir> 0024 #include <QMediaFormat> 0025 0026 namespace 0027 { 0028 const char myVideoGroupName[] = "Message Video"; 0029 } 0030 CreateVideoMessageWidget::CreateVideoMessageWidget(QWidget *parent) 0031 : QWidget(parent) 0032 , mVideoWidget(new QVideoWidget(this)) 0033 , mCamera(new QCamera(this)) 0034 , mListCamera(new QComboBox(this)) 0035 , mRecordButton(new QToolButton(this)) 0036 , mPauseButton(new QToolButton(this)) 0037 , mStopButton(new QToolButton(this)) 0038 , mDurationLabel(new QLabel(this)) 0039 , mMessageWidget(new KMessageWidget(this)) 0040 { 0041 auto mainLayout = new QVBoxLayout(this); 0042 mainLayout->setObjectName(QStringLiteral("mainLayout")); 0043 mainLayout->setContentsMargins({}); 0044 0045 mMessageWidget->setObjectName(QStringLiteral("mMessageWidget")); 0046 mainLayout->addWidget(mMessageWidget); 0047 mMessageWidget->setVisible(false); 0048 mMessageWidget->setCloseButtonVisible(false); 0049 mMessageWidget->setMessageType(KMessageWidget::Information); 0050 mMessageWidget->setWordWrap(true); 0051 0052 mListCamera->setObjectName(QStringLiteral("mListCamera")); 0053 mainLayout->addWidget(mListCamera); 0054 0055 mVideoWidget->setObjectName(QStringLiteral("mVideoWidget")); 0056 mainLayout->addWidget(mVideoWidget, 1); 0057 0058 auto hboxLayout = new QHBoxLayout; 0059 hboxLayout->setObjectName(QStringLiteral("hboxLayout")); 0060 hboxLayout->setContentsMargins({}); 0061 0062 mStopButton->setObjectName(QStringLiteral("mStopButton")); 0063 mStopButton->setIcon(QIcon::fromTheme(QStringLiteral("media-playback-stop"))); 0064 hboxLayout->addWidget(mStopButton); 0065 connect(mStopButton, &QToolButton::clicked, this, &CreateVideoMessageWidget::stop); 0066 0067 mPauseButton->setObjectName(QStringLiteral("mPauseButton")); 0068 mPauseButton->setIcon(QIcon::fromTheme(QStringLiteral("media-playback-pause"))); 0069 hboxLayout->addWidget(mPauseButton); 0070 connect(mPauseButton, &QToolButton::clicked, this, &CreateVideoMessageWidget::pause); 0071 0072 mRecordButton->setObjectName(QStringLiteral("mRecordButton")); 0073 mRecordButton->setIcon(QIcon::fromTheme(QStringLiteral("media-record"))); 0074 hboxLayout->addWidget(mRecordButton); 0075 mRecordButton->setEnabled(false); 0076 connect(mRecordButton, &QToolButton::clicked, this, &CreateVideoMessageWidget::record); 0077 0078 mDurationLabel->setObjectName(QStringLiteral("mDurationLabel")); 0079 hboxLayout->addWidget(mDurationLabel); 0080 mainLayout->addLayout(hboxLayout); 0081 0082 updateCameras(); 0083 setCamera(QMediaDevices::defaultVideoInput()); 0084 if (QMediaDevices::defaultVideoInput().isNull()) { 0085 mRecordButton->setEnabled(false); 0086 mPauseButton->setEnabled(false); 0087 } 0088 connect(mListCamera, &QComboBox::activated, this, [this]() { 0089 setCamera(mListCamera->itemData(mListCamera->currentIndex()).value<QCameraDevice>()); 0090 }); 0091 } 0092 0093 CreateVideoMessageWidget::~CreateVideoMessageWidget() 0094 { 0095 delete mTemporaryFile; 0096 } 0097 0098 void CreateVideoMessageWidget::loadSettings() 0099 { 0100 KConfigGroup group(KSharedConfig::openConfig(), QLatin1String(myVideoGroupName)); 0101 const QByteArray deviceIdentifier = group.readEntry("VideoDevice", QByteArray()); 0102 if (!deviceIdentifier.isEmpty()) { 0103 for (int i = 0; i < mListCamera->count(); ++i) { 0104 const QCameraDevice videoDevice = mListCamera->itemData(i).value<QCameraDevice>(); 0105 if (videoDevice.id() == deviceIdentifier) { 0106 mListCamera->setCurrentIndex(i); 0107 break; 0108 } 0109 } 0110 } 0111 } 0112 0113 void CreateVideoMessageWidget::saveSettings() 0114 { 0115 KConfigGroup group(KSharedConfig::openConfig(), QLatin1String(myVideoGroupName)); 0116 const auto device = mListCamera->itemData(mListCamera->currentIndex()).value<QCameraDevice>(); 0117 if (!device.isNull()) { 0118 const QByteArray deviceIdentifier = device.id(); 0119 group.writeEntry("VideoDevice", deviceIdentifier); 0120 } 0121 } 0122 0123 QUrl CreateVideoMessageWidget::temporaryFilePath() const 0124 { 0125 // qDebug() << " XCCCCCCCCCCCCCCCCCCC" << mMediaRecorder->outputLocation() << " dd " << mMediaRecorder->actualLocation(); 0126 return mMediaRecorder->actualLocation(); 0127 } 0128 0129 void CreateVideoMessageWidget::updateCameras() 0130 { 0131 const QList<QCameraDevice> availableCameras = QMediaDevices::videoInputs(); 0132 for (const QCameraDevice &cameraDevice : availableCameras) { 0133 mListCamera->addItem(cameraDevice.description(), QVariant::fromValue(cameraDevice)); 0134 } 0135 } 0136 0137 void CreateVideoMessageWidget::setCamera(const QCameraDevice &cameraDevice) 0138 { 0139 mCamera.reset(new QCamera(cameraDevice)); 0140 mCaptureSession.setCamera(mCamera.data()); 0141 0142 mAudioInput.reset(new QAudioInput); 0143 mCaptureSession.setAudioInput(mAudioInput.get()); 0144 0145 connect(mCamera.data(), &QCamera::activeChanged, this, &CreateVideoMessageWidget::updateCameraActive); 0146 connect(mCamera.data(), &QCamera::errorOccurred, this, &CreateVideoMessageWidget::displayCameraError); 0147 0148 if (!mMediaRecorder) { 0149 mMediaRecorder.reset(new QMediaRecorder); 0150 mTemporaryFile = new QTemporaryFile(QDir::tempPath() + QLatin1String("/ruqola_XXXXXX")); // TODO fix extension 0151 mTemporaryFile->setAutoRemove(false); 0152 mTemporaryFile->open(); 0153 // QMediaFormat format; 0154 // format.setFileFormat(QMediaFormat::FileFormat::AVI); 0155 // mMediaRecorder->setMediaFormat(format); 0156 // Define url temporary file. 0157 mMediaRecorder->setOutputLocation(QUrl::fromLocalFile(mTemporaryFile->fileName())); 0158 // qDebug() << " store " << mTemporaryFile->fileName(); 0159 mCaptureSession.setRecorder(mMediaRecorder.data()); 0160 connect(mMediaRecorder.data(), &QMediaRecorder::recorderStateChanged, this, 0161 &CreateVideoMessageWidget::updateRecorderState); 0162 connect(mMediaRecorder.data(), &QMediaRecorder::durationChanged, this, 0163 &CreateVideoMessageWidget::updateRecordTime); 0164 connect(mMediaRecorder.data(), &QMediaRecorder::errorChanged, this, 0165 &CreateVideoMessageWidget::displayRecorderError); 0166 } 0167 mCaptureSession.setVideoOutput(mVideoWidget); 0168 updateCameraActive(mCamera->isActive()); 0169 updateRecorderState(mMediaRecorder->recorderState()); 0170 0171 mCamera->start(); 0172 } 0173 0174 void CreateVideoMessageWidget::displayCameraError() 0175 { 0176 if (mCamera->error() != QCamera::NoError) { 0177 mMessageWidget->setText(mCamera->errorString()); 0178 mMessageWidget->animatedShow(); 0179 } 0180 } 0181 0182 void CreateVideoMessageWidget::updateRecorderState(QMediaRecorder::RecorderState state) 0183 { 0184 switch (state) { 0185 case QMediaRecorder::StoppedState: 0186 mRecordButton->setEnabled(true); 0187 mPauseButton->setEnabled(true); 0188 mStopButton->setEnabled(false); 0189 break; 0190 case QMediaRecorder::PausedState: 0191 mRecordButton->setEnabled(true); 0192 mPauseButton->setEnabled(false); 0193 mStopButton->setEnabled(true); 0194 break; 0195 case QMediaRecorder::RecordingState: 0196 mRecordButton->setEnabled(false); 0197 mPauseButton->setEnabled(true); 0198 mStopButton->setEnabled(true); 0199 break; 0200 } 0201 } 0202 0203 void CreateVideoMessageWidget::updateCameraActive(bool active) 0204 { 0205 if (active) { 0206 mRecordButton->setEnabled(false); 0207 mStopButton->setEnabled(true); 0208 } else { 0209 mRecordButton->setEnabled(true); 0210 mStopButton->setEnabled(false); 0211 } 0212 } 0213 0214 void CreateVideoMessageWidget::displayRecorderError() 0215 { 0216 if (mMediaRecorder->error() != QMediaRecorder::NoError) { 0217 mMessageWidget->setText(mMediaRecorder->errorString()); 0218 mMessageWidget->animatedShow(); 0219 } 0220 } 0221 0222 void CreateVideoMessageWidget::record() 0223 { 0224 mMediaRecorder->record(); 0225 updateRecordTime(); 0226 } 0227 0228 void CreateVideoMessageWidget::pause() 0229 { 0230 mMediaRecorder->pause(); 0231 } 0232 0233 void CreateVideoMessageWidget::stop() 0234 { 0235 mMediaRecorder->stop(); 0236 Q_EMIT recordDone(); 0237 } 0238 0239 void CreateVideoMessageWidget::updateRecordTime() 0240 { 0241 const QString str = i18n("Recorded %1 sec", mMediaRecorder->duration() / 1000); 0242 mDurationLabel->setText(str); 0243 } 0244 0245 #include "moc_createvideomessagewidget.cpp"