adding back mpv into git

This commit is contained in:
Chris Cochrun 2025-08-04 15:00:48 -05:00
parent 4e71739f38
commit e52cc3eb29
4 changed files with 404 additions and 1 deletions

1
.gitignore vendored
View file

@ -11,4 +11,3 @@ target
/log.txt /log.txt
.env .env
clippy.toml clippy.toml
src/cpp/

244
src/cpp/mpv/mpvitem.cpp Normal file
View file

@ -0,0 +1,244 @@
/*
* SPDX-FileCopyrightText: 2023 George Florea Bănuș <georgefb899@gmail.com>
*
* SPDX-License-Identifier: MIT
*/
#include "mpvitem.h"
#include <MpvController>
#include "mpvproperties.h"
MpvItem::MpvItem(QQuickItem *parent)
: MpvAbstractItem(parent)
{
observeProperty(MpvProperties::self()->MediaTitle, MPV_FORMAT_STRING);
observeProperty(MpvProperties::self()->Position, MPV_FORMAT_DOUBLE);
observeProperty(MpvProperties::self()->Duration, MPV_FORMAT_DOUBLE);
observeProperty(MpvProperties::self()->Pause, MPV_FORMAT_FLAG);
observeProperty(MpvProperties::self()->Volume, MPV_FORMAT_INT64);
setupConnections();
// since this is async the effects are not immediately visible
// to do something after the property was set do it in onAsyncReply
// use the id to identify the correct call
setPropertyAsync(QStringLiteral("volume"), 99, static_cast<int>(MpvItem::AsyncIds::SetVolume));
setProperty(QStringLiteral("mute"), true);
// since this is async the effects are not immediately visible
// to get the value do it in onGetPropertyReply
// use the id to identify the correct call
getPropertyAsync(MpvProperties::self()->Volume, static_cast<int>(MpvItem::AsyncIds::GetVolume));
}
void MpvItem::setupConnections()
{
// clang-format off
connect(mpvController(), &MpvController::propertyChanged,
this, &MpvItem::onPropertyChanged, Qt::QueuedConnection);
connect(mpvController(), &MpvController::fileStarted,
this, &MpvItem::fileStarted, Qt::QueuedConnection);
connect(mpvController(), &MpvController::fileLoaded,
this, &MpvItem::fileLoaded, Qt::QueuedConnection);
connect(mpvController(), &MpvController::endFile,
this, &MpvItem::endFile, Qt::QueuedConnection);
connect(mpvController(), &MpvController::videoReconfig,
this, &MpvItem::videoReconfig, Qt::QueuedConnection);
connect(mpvController(), &MpvController::asyncReply,
this, &MpvItem::onAsyncReply, Qt::QueuedConnection);
// clang-format on
}
void MpvItem::onPropertyChanged(const QString &property, const QVariant &value)
{
if (property == MpvProperties::self()->MediaTitle) {
Q_EMIT mediaTitleChanged();
} else if (property == MpvProperties::self()->Position) {
m_formattedPosition = formatTime(value.toDouble());
Q_EMIT positionChanged();
} else if (property == MpvProperties::self()->Duration) {
m_formattedDuration = formatTime(value.toDouble());
Q_EMIT durationChanged();
} else if (property == MpvProperties::self()->Pause) {
Q_EMIT pauseChanged();
} else if (property == MpvProperties::self()->Volume) {
Q_EMIT volumeChanged();
} else if (property == MpvProperties::self()->Mute) {
Q_EMIT mutedChanged();
}
}
void MpvItem::onAsyncReply(const QVariant &data, mpv_event event)
{
switch (static_cast<AsyncIds>(event.reply_userdata)) {
case AsyncIds::None: {
break;
}
case AsyncIds::SetVolume: {
qDebug() << "onSetPropertyReply" << event.reply_userdata;
break;
}
case AsyncIds::GetVolume: {
qDebug() << "onGetPropertyReply" << event.reply_userdata << data;
break;
}
case AsyncIds::ExpandText: {
qDebug() << "onGetPropertyReply" << event.reply_userdata << data;
break;
}
}
}
QString MpvItem::formatTime(const double time)
{
int totalNumberOfSeconds = static_cast<int>(time);
int seconds = totalNumberOfSeconds % 60;
int minutes = (totalNumberOfSeconds / 60) % 60;
int hours = (totalNumberOfSeconds / 60 / 60);
QString timeString =
QStringLiteral("%1:%2:%3").arg(hours, 2, 10, QLatin1Char('0')).arg(minutes, 2, 10, QLatin1Char('0')).arg(seconds, 2, 10, QLatin1Char('0'));
return timeString;
}
void MpvItem::loadFile(const QString &file)
{
auto url = QUrl::fromUserInput(file);
if (m_currentUrl != url) {
m_currentUrl = url;
Q_EMIT currentUrlChanged();
Q_EMIT sourceChanged();
}
Q_EMIT command(QStringList() << QStringLiteral("loadfile") << m_currentUrl.toString(QUrl::PreferLocalFile));
}
void MpvItem::seek(const double &value)
{
setPosition(value);
}
QString MpvItem::mediaTitle()
{
return getProperty(MpvProperties::self()->MediaTitle).toString();
}
double MpvItem::position()
{
return getProperty(MpvProperties::self()->Position).toDouble();
}
void MpvItem::setPosition(double value)
{
if (qFuzzyCompare(value, position())) {
return;
}
Q_EMIT setPropertyAsync(MpvProperties::self()->Position, value);
}
double MpvItem::duration()
{
return getProperty(MpvProperties::self()->Duration).toDouble();
}
bool MpvItem::pause()
{
return getProperty(MpvProperties::self()->Pause).toBool();
}
void MpvItem::setPause(bool value)
{
if (value == pause()) {
return;
}
Q_EMIT setPropertyAsync(MpvProperties::self()->Pause, value);
}
int MpvItem::volume()
{
return getProperty(MpvProperties::self()->Volume).toInt();
}
void MpvItem::setVolume(int value)
{
if (value == volume()) {
return;
}
Q_EMIT setPropertyAsync(MpvProperties::self()->Volume, value);
}
bool MpvItem::muted()
{
return getProperty(MpvProperties::self()->Mute).toBool();
}
void MpvItem::setMuted(bool value)
{
Q_EMIT setPropertyAsync(MpvProperties::self()->Mute, value);
}
bool MpvItem::loop()
{
return getProperty(MpvProperties::self()->Loop).toBool();
}
void MpvItem::setLoop(bool value)
{
Q_EMIT setPropertyAsync(MpvProperties::self()->Loop, value);
}
QString MpvItem::formattedDuration() const
{
return m_formattedDuration;
}
QString MpvItem::formattedPosition() const
{
return m_formattedPosition;
}
QUrl MpvItem::currentUrl() const
{
return m_currentUrl;
}
QUrl MpvItem::source() const
{
return m_currentUrl;
}
void MpvItem::setSource(const QUrl &source)
{
if (m_currentUrl != source) {
m_currentUrl = source;
Q_EMIT currentUrlChanged();
Q_EMIT sourceChanged();
}
Q_EMIT command(QStringList() << QStringLiteral("loadfile") << m_currentUrl.toString(QUrl::PreferLocalFile));
}
void MpvItem::playPause()
{
if (getProperty(MpvProperties::self()->Pause).toBool()) {
Q_EMIT setPropertyAsync(MpvProperties::self()->Pause, false);
} else {
Q_EMIT setPropertyAsync(MpvProperties::self()->Pause, true);
}
}
#include "moc_mpvitem.cpp"

104
src/cpp/mpv/mpvitem.h Normal file
View file

@ -0,0 +1,104 @@
/*
* SPDX-FileCopyrightText: 2023 George Florea Bănuș <georgefb899@gmail.com>
*
* SPDX-License-Identifier: MIT
*/
#ifndef MPVOBJECT_H
#define MPVOBJECT_H
#include <MpvAbstractItem>
#include <qqmlintegration.h>
class MpvRenderer;
class MpvItem : public MpvAbstractItem
{
Q_OBJECT
QML_ELEMENT
public:
explicit MpvItem(QQuickItem *parent = nullptr);
~MpvItem() = default;
enum class AsyncIds {
None,
SetVolume,
GetVolume,
ExpandText,
};
Q_ENUM(AsyncIds)
Q_PROPERTY(QString mediaTitle READ mediaTitle NOTIFY mediaTitleChanged)
QString mediaTitle();
Q_PROPERTY(double position READ position WRITE setPosition NOTIFY positionChanged)
double position();
void setPosition(double value);
Q_PROPERTY(double duration READ duration NOTIFY durationChanged)
double duration();
Q_PROPERTY(QString formattedPosition READ formattedPosition NOTIFY positionChanged)
QString formattedPosition() const;
Q_PROPERTY(QString formattedDuration READ formattedDuration NOTIFY durationChanged)
QString formattedDuration() const;
Q_PROPERTY(bool pause READ pause WRITE setPause NOTIFY pauseChanged)
bool pause();
void setPause(bool value);
Q_PROPERTY(int volume READ volume WRITE setVolume NOTIFY volumeChanged)
int volume();
void setVolume(int value);
Q_PROPERTY(bool muted READ muted WRITE setMuted NOTIFY mutedChanged)
bool muted();
void setMuted(bool value);
Q_PROPERTY(bool loop READ loop WRITE setLoop NOTIFY loopChanged)
bool loop();
void setLoop(bool value);
Q_PROPERTY(QUrl currentUrl READ currentUrl NOTIFY currentUrlChanged)
QUrl currentUrl() const;
Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
QUrl source() const;
void setSource(const QUrl &source);
Q_INVOKABLE void loadFile(const QString &file);
Q_INVOKABLE void seek(const double &value);
Q_INVOKABLE void playPause();
Q_SIGNALS:
void mediaTitleChanged();
void currentUrlChanged();
void positionChanged();
void durationChanged();
void pauseChanged();
void volumeChanged();
void mutedChanged();
void sourceChanged();
void loopChanged();
void fileStarted();
void fileLoaded();
void endFile(QString reason);
void videoReconfig();
private:
void setupConnections();
void onPropertyChanged(const QString &property, const QVariant &value);
void onAsyncReply(const QVariant &data, mpv_event event);
QString formatTime(const double time);
double m_position{0.0};
QString m_formattedPosition;
double m_duration{0.0};
QString m_formattedDuration;
QUrl m_currentUrl;
bool m_loop;
};
#endif // MPVOBJECT_H

View file

@ -0,0 +1,56 @@
/*
* SPDX-FileCopyrightText: 2023 George Florea Bănuș <georgefb899@gmail.com>
*
* SPDX-License-Identifier: MIT
*/
#ifndef MPVPROPERTIES_H
#define MPVPROPERTIES_H
#include <QObject>
#include <qqmlintegration.h>
class MpvProperties : public QObject
{
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
public:
explicit MpvProperties(QObject *parent = nullptr)
: QObject(parent)
{
}
static MpvProperties *self()
{
static MpvProperties p;
return &p;
}
Q_PROPERTY(QString MediaTitle MEMBER MediaTitle CONSTANT)
const QString MediaTitle{QStringLiteral("media-title")};
Q_PROPERTY(QString Position MEMBER Position CONSTANT)
const QString Position{QStringLiteral("time-pos")};
Q_PROPERTY(QString Duration MEMBER Duration CONSTANT)
const QString Duration{QStringLiteral("duration")};
Q_PROPERTY(QString Pause MEMBER Pause CONSTANT)
const QString Pause{QStringLiteral("pause")};
Q_PROPERTY(QString Volume MEMBER Volume CONSTANT)
const QString Volume{QStringLiteral("volume")};
Q_PROPERTY(QString Mute MEMBER Mute CONSTANT)
const QString Mute{QStringLiteral("mute")};
Q_PROPERTY(QString Loop MEMBER Loop CONSTANT)
const QString Loop{QStringLiteral("loop")};
private:
Q_DISABLE_COPY_MOVE(MpvProperties)
};
#endif // MPVPROPERTIES_H