File indexing completed on 2024-05-05 04:50:49
0001 /* 0002 * SPDX-FileCopyrightText: 2021 George Florea Bănuș <georgefb899@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-3.0-or-later 0005 */ 0006 0007 #include "mediaplayer2player.h" 0008 0009 #include <KFileMetaData/ExtractorCollection> 0010 #include <KFileMetaData/SimpleExtractionResult> 0011 0012 #include <QBuffer> 0013 #include <QDBusConnection> 0014 #include <QDBusMessage> 0015 #include <QDBusObjectPath> 0016 #include <QImage> 0017 0018 #include "application.h" 0019 #include "mpvitem.h" 0020 #include "mpvproperties.h" 0021 #include "videosettings.h" 0022 #include "worker.h" 0023 0024 MediaPlayer2Player::MediaPlayer2Player(QObject *parent) 0025 : QDBusAbstractAdaptor(parent) 0026 , m_mpv{static_cast<MpvItem *>(parent)} 0027 { 0028 connect(m_mpv, &MpvItem::fileLoaded, this, [=]() { 0029 if (m_mpv->currentUrl().isLocalFile()) { 0030 Q_EMIT requestMprisThumbnail(m_mpv->currentUrl().toLocalFile(), 250); 0031 } 0032 }); 0033 0034 connect(this, &MediaPlayer2Player::requestMprisThumbnail, Worker::instance(), &Worker::mprisThumbnail); 0035 0036 connect(Worker::instance(), &Worker::mprisThumbnailSuccess, this, [=](const QImage &image) { 0037 m_image = image; 0038 propertiesChanged(QStringLiteral("Metadata"), Metadata()); 0039 Q_EMIT metadataChanged(); 0040 }); 0041 0042 connect(m_mpv, &MpvItem::mediaTitleChanged, this, [=]() { 0043 auto title = m_mpv->mediaTitle(); 0044 if (title.isEmpty() || title.startsWith(QStringLiteral("watch"))) { 0045 return; 0046 } 0047 m_image = QImage(); 0048 propertiesChanged(QStringLiteral("Metadata"), Metadata()); 0049 Q_EMIT metadataChanged(); 0050 }); 0051 0052 connect(m_mpv, &MpvItem::durationChanged, this, [=]() { 0053 m_metadata.insert(QStringLiteral("mpris:length"), m_mpv->duration() * 1000 * 1000); 0054 propertiesChanged(QStringLiteral("Metadata"), m_metadata); 0055 }); 0056 0057 connect(m_mpv, &MpvItem::pauseChanged, this, [=]() { 0058 propertiesChanged(QStringLiteral("PlaybackStatus"), PlaybackStatus()); 0059 Q_EMIT playbackStatusChanged(); 0060 }); 0061 0062 connect(m_mpv, &MpvItem::volumeChanged, this, [=]() { 0063 propertiesChanged(QStringLiteral("Volume"), Volume()); 0064 Q_EMIT volumeChanged(); 0065 }); 0066 } 0067 0068 void MediaPlayer2Player::propertiesChanged(const QString &property, const QVariant &value) 0069 { 0070 QVariantMap properties; 0071 properties[property] = value; 0072 0073 QDBusMessage msg = QDBusMessage::createSignal(QStringLiteral("/org/mpris/MediaPlayer2"), 0074 QStringLiteral("org.freedesktop.DBus.Properties"), 0075 QStringLiteral("PropertiesChanged")); 0076 msg << QStringLiteral("org.mpris.MediaPlayer2.Player") << properties << QStringList(); 0077 0078 QDBusConnection::sessionBus().send(msg); 0079 } 0080 0081 QVariantMap MediaPlayer2Player::Metadata() 0082 { 0083 auto url = m_mpv->currentUrl(); 0084 0085 m_metadata.insert(QStringLiteral("xesam:title"), m_mpv->mediaTitle()); 0086 m_metadata.insert(QStringLiteral("mpris:trackid"), QVariant::fromValue<QDBusObjectPath>(QDBusObjectPath(QStringLiteral("/org/kde/haruna")))); 0087 m_metadata.insert(QStringLiteral("mpris:artUrl"), getThumbnail(url.toLocalFile())); 0088 m_metadata.insert(QStringLiteral("xesam:url"), url.toString()); 0089 0090 return m_metadata; 0091 } 0092 0093 QString MediaPlayer2Player::getThumbnail(const QString &path) 0094 { 0095 auto url = QUrl::fromUserInput(path); 0096 if (!url.isLocalFile()) { 0097 return QString(); 0098 } 0099 0100 QString mimeType = Application::mimeType(url); 0101 KFileMetaData::ExtractorCollection exCol; 0102 QList<KFileMetaData::Extractor *> extractors = exCol.fetchExtractors(mimeType); 0103 KFileMetaData::SimpleExtractionResult result(path, mimeType, KFileMetaData::ExtractionResult::ExtractImageData); 0104 0105 if (extractors.size() > 0) { 0106 KFileMetaData::Extractor *ex = extractors.first(); 0107 ex->extract(&result); 0108 QString base64 = QStringLiteral("data:image/png;base64,"); 0109 auto imageData = result.imageData(); 0110 if (!imageData.isEmpty()) { 0111 // look for image inside the file 0112 using namespace KFileMetaData; 0113 if (imageData.contains(EmbeddedImageData::MovieScreenCapture)) { 0114 return base64.append(QString::fromUtf8(imageData[EmbeddedImageData::MovieScreenCapture].toBase64())); 0115 } else if (imageData.contains(EmbeddedImageData::FrontCover)) { 0116 return base64.append(QString::fromUtf8(imageData[EmbeddedImageData::FrontCover].toBase64())); 0117 } else if (imageData.contains(EmbeddedImageData::BackCover)) { 0118 return base64.append(QString::fromUtf8(imageData[EmbeddedImageData::BackCover].toBase64())); 0119 } else if (imageData.contains(EmbeddedImageData::Other)) { 0120 return base64.append(QString::fromUtf8(imageData[EmbeddedImageData::Other].toBase64())); 0121 } else { 0122 return base64.append(QString::fromUtf8(imageData[EmbeddedImageData::Unknown].toBase64())); 0123 } 0124 } else { 0125 QImage image = m_image; 0126 if (image.isNull()) { 0127 return VideoSettings::defaultCover(); 0128 } else { 0129 QByteArray byteArray; 0130 QBuffer buffer(&byteArray); 0131 image.save(&buffer, "JPEG"); 0132 return base64.append(QString::fromUtf8(byteArray.toBase64().data())); 0133 } 0134 } 0135 } 0136 return QString(); 0137 } 0138 0139 void MediaPlayer2Player::Next() 0140 { 0141 Q_EMIT next(); 0142 } 0143 0144 void MediaPlayer2Player::Previous() 0145 { 0146 Q_EMIT previous(); 0147 } 0148 0149 void MediaPlayer2Player::Pause() 0150 { 0151 Q_EMIT pause(); 0152 } 0153 0154 void MediaPlayer2Player::PlayPause() 0155 { 0156 Q_EMIT playpause(); 0157 } 0158 0159 void MediaPlayer2Player::Stop() 0160 { 0161 Q_EMIT stop(); 0162 } 0163 0164 void MediaPlayer2Player::Play() 0165 { 0166 Q_EMIT play(); 0167 } 0168 0169 void MediaPlayer2Player::Seek(qlonglong offset) 0170 { 0171 Q_EMIT seek(offset / 1000 / 1000); 0172 } 0173 0174 void MediaPlayer2Player::SetPosition(const QDBusObjectPath &trackId, qlonglong pos) 0175 { 0176 Q_UNUSED(trackId) 0177 m_mpv->setProperty(MpvProperties::self()->Position, pos / 1000 / 1000); 0178 } 0179 0180 void MediaPlayer2Player::OpenUri(const QString &uri) 0181 { 0182 Q_EMIT openUri(uri); 0183 } 0184 0185 QString MediaPlayer2Player::PlaybackStatus() 0186 { 0187 bool isPaused = m_mpv->pause(); 0188 double position = m_mpv->position(); 0189 0190 return isPaused && position == 0 ? QStringLiteral("Stopped") : (isPaused ? QStringLiteral("Paused") : QStringLiteral("Playing")); 0191 } 0192 0193 double MediaPlayer2Player::Volume() 0194 { 0195 return m_mpv->volume() / 100; 0196 } 0197 0198 void MediaPlayer2Player::setVolume(double vol) 0199 { 0200 m_mpv->setProperty(MpvProperties::self()->Volume, vol * 100); 0201 } 0202 0203 qlonglong MediaPlayer2Player::Position() 0204 { 0205 return m_mpv->position() * 1000 * 1000; 0206 } 0207 0208 void MediaPlayer2Player::setPosition(int pos) 0209 { 0210 m_mpv->setProperty(MpvProperties::self()->Position, pos); 0211 } 0212 0213 bool MediaPlayer2Player::CanGoNext() 0214 { 0215 return true; 0216 } 0217 0218 bool MediaPlayer2Player::CanGoPrevious() 0219 { 0220 return true; 0221 } 0222 0223 bool MediaPlayer2Player::CanPlay() 0224 { 0225 return true; 0226 } 0227 0228 bool MediaPlayer2Player::CanPause() 0229 { 0230 return true; 0231 } 0232 0233 bool MediaPlayer2Player::CanSeek() 0234 { 0235 return true; 0236 } 0237 0238 bool MediaPlayer2Player::CanControl() 0239 { 0240 return true; 0241 } 0242 0243 #include "moc_mediaplayer2player.cpp"