Move stuff to MPVCommon namespace for shareding across MPV backends.
This commit is contained in:
parent
299ee556a9
commit
f7167ee478
|
@ -50,6 +50,7 @@ set(SOURCES
|
||||||
src/ThumbnailCache.cpp
|
src/ThumbnailCache.cpp
|
||||||
src/logger.cpp
|
src/logger.cpp
|
||||||
src/qmldebugger.cpp
|
src/qmldebugger.cpp
|
||||||
|
src/Backends/MPVCommon/MPVCommon.cpp
|
||||||
src/Backends/MPV/MPVBackend.cpp
|
src/Backends/MPV/MPVBackend.cpp
|
||||||
src/Backends/MPVNoFBO/MPVNoFBOBackend.cpp
|
src/Backends/MPVNoFBO/MPVNoFBOBackend.cpp
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
#include "src/Backends/MPV/MPVBackend.hpp"
|
#include "src/Backends/MPV/MPVBackend.hpp"
|
||||||
#include "src/logger.h"
|
|
||||||
#include "src/utils.hpp"
|
#include "src/utils.hpp"
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QElapsedTimer>
|
#include <QElapsedTimer>
|
||||||
|
@ -19,11 +18,11 @@
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
#include <qpa/qplatformnativeinterface.h>
|
#include <qpa/qplatformnativeinterface.h>
|
||||||
|
|
||||||
|
#include "src/Backends/MPVCommon/MPVCommon.hpp"
|
||||||
|
|
||||||
|
|
||||||
bool usedirect = false;
|
bool usedirect = false;
|
||||||
|
|
||||||
auto mpvLogger = initLogger("mpv");
|
|
||||||
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -140,10 +139,10 @@ MPVBackend::MPVBackend(QQuickItem* parent)
|
||||||
if (!mpv)
|
if (!mpv)
|
||||||
throw std::runtime_error("could not create mpv context");
|
throw std::runtime_error("could not create mpv context");
|
||||||
|
|
||||||
std::cout << QString("Direct: ").toUtf8().constData() << QString(usedirect ? "true" : "false").toUtf8().constData();
|
QSettings settings;
|
||||||
|
usedirect = settings.value("Backend/direct", false).toBool();
|
||||||
|
|
||||||
|
mpv_set_option_string(mpv, "terminal", "false");
|
||||||
mpv_set_option_string(mpv, "terminal", "on");
|
|
||||||
mpv_set_option_string(mpv, "msg-level", "all=v");
|
mpv_set_option_string(mpv, "msg-level", "all=v");
|
||||||
|
|
||||||
// Fix?
|
// Fix?
|
||||||
|
@ -170,7 +169,7 @@ MPVBackend::MPVBackend(QQuickItem* parent)
|
||||||
mpv_observe_property(mpv, 0, "playlist", MPV_FORMAT_NODE);
|
mpv_observe_property(mpv, 0, "playlist", MPV_FORMAT_NODE);
|
||||||
mpv_observe_property(mpv, 0, "speed", MPV_FORMAT_DOUBLE);
|
mpv_observe_property(mpv, 0, "speed", MPV_FORMAT_DOUBLE);
|
||||||
|
|
||||||
mpv_request_log_messages(mpv, "verbose");
|
mpv_request_log_messages(mpv, "v");
|
||||||
|
|
||||||
mpv_set_wakeup_callback(mpv, wakeup, this);
|
mpv_set_wakeup_callback(mpv, wakeup, this);
|
||||||
|
|
||||||
|
@ -210,10 +209,10 @@ MPVBackend::~MPVBackend()
|
||||||
Utils::SetDPMS(true);
|
Utils::SetDPMS(true);
|
||||||
command("write-watch-later-config");
|
command("write-watch-later-config");
|
||||||
|
|
||||||
if (usedirect) {
|
if (usedirect && mpv_gl_cb) {
|
||||||
|
mpv_opengl_cb_uninit_gl(mpv_gl_cb);
|
||||||
|
} else if (mpv_gl){
|
||||||
mpv_render_context_free(mpv_gl);
|
mpv_render_context_free(mpv_gl);
|
||||||
} else {
|
|
||||||
mpv_opengl_cb_set_update_callback(mpv_gl_cb, NULL, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mpv_terminate_destroy(mpv);
|
mpv_terminate_destroy(mpv);
|
||||||
|
@ -269,171 +268,23 @@ MPVBackend::playerCommand(const Enums::Commands& cmd)
|
||||||
QVariant
|
QVariant
|
||||||
MPVBackend::playerCommand(const Enums::Commands& cmd, const QVariant& args)
|
MPVBackend::playerCommand(const Enums::Commands& cmd, const QVariant& args)
|
||||||
{
|
{
|
||||||
switch (cmd) {
|
return MPVCommon::playerCommand(this, cmd, args);
|
||||||
case Enums::Commands::TogglePlayPause: {
|
|
||||||
command(QVariantList() << "cycle"
|
|
||||||
<< "pause");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Enums::Commands::ToggleMute: {
|
|
||||||
command(QVariantList() << "cycle"
|
|
||||||
<< "mute");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Enums::Commands::SetAudioDevice: {
|
|
||||||
setProperty("audio-device", args.toString());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Enums::Commands::SetVolume: {
|
|
||||||
command(QVariantList() << "set"
|
|
||||||
<< "volume" << args);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case Enums::Commands::AddVolume: {
|
QString
|
||||||
|
MPVBackend::getStats()
|
||||||
command(QVariantList() << "add"
|
{
|
||||||
<< "volume" << args);
|
return MPVCommon::getStats(this);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case Enums::Commands::AddSpeed: {
|
|
||||||
|
|
||||||
QString speedString =
|
void
|
||||||
QString::number(getProperty("speed").toDouble() + args.toDouble());
|
MPVBackend::updateDurationString(int numTime)
|
||||||
QVariant newSpeed =
|
{
|
||||||
QVariant(speedString.left(speedString.lastIndexOf('.') + 2));
|
QMetaMethod metaMethod = sender()->metaObject()->method(senderSignalIndex());
|
||||||
|
MPVCommon::updateDurationString(this, numTime, metaMethod);
|
||||||
playerCommand(Enums::Commands::SetSpeed, newSpeed);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case Enums::Commands::SubtractSpeed: {
|
|
||||||
|
|
||||||
QString speedString =
|
|
||||||
QString::number(getProperty("speed").toDouble() - args.toDouble());
|
|
||||||
QVariant newSpeed =
|
|
||||||
QVariant(speedString.left(speedString.lastIndexOf('.') + 2));
|
|
||||||
playerCommand(Enums::Commands::SetSpeed, newSpeed);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Enums::Commands::ChangeSpeed: {
|
|
||||||
|
|
||||||
playerCommand(
|
|
||||||
Enums::Commands::SetSpeed,
|
|
||||||
QVariant(getProperty("speed").toDouble() * args.toDouble()));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Enums::Commands::SetSpeed: {
|
|
||||||
|
|
||||||
command(QVariantList() << "set"
|
|
||||||
<< "speed" << args.toString());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Enums::Commands::ToggleStats: {
|
|
||||||
|
|
||||||
command(QVariantList() << "script-binding"
|
|
||||||
<< "stats/display-stats-toggle");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Enums::Commands::NextAudioTrack: {
|
|
||||||
|
|
||||||
command(QVariantList() << "cycle"
|
|
||||||
<< "audio");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Enums::Commands::NextSubtitleTrack: {
|
|
||||||
|
|
||||||
command(QVariantList() << "cycle"
|
|
||||||
<< "sub");
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Enums::Commands::NextVideoTrack: {
|
|
||||||
command(QVariantList() << "cycle"
|
|
||||||
<< "video");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Enums::Commands::PreviousPlaylistItem: {
|
|
||||||
|
|
||||||
command(QVariantList() << "playlist-prev");
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Enums::Commands::NextPlaylistItem: {
|
|
||||||
|
|
||||||
command(QVariantList() << "playlist-next"
|
|
||||||
<< "force");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Enums::Commands::LoadFile: {
|
|
||||||
command(QVariantList() << "loadfile" << args);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Enums::Commands::AppendFile: {
|
|
||||||
|
|
||||||
command(QVariantList() << "loadfile" << args << "append-play");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Enums::Commands::Seek: {
|
|
||||||
|
|
||||||
command(QVariantList() << "seek" << args);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Enums::Commands::SeekAbsolute: {
|
|
||||||
|
|
||||||
command(QVariantList() << "seek" << args << "absolute");
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Enums::Commands::ForwardFrame: {
|
|
||||||
|
|
||||||
command(QVariantList() << "frame-step");
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Enums::Commands::BackwardFrame: {
|
|
||||||
|
|
||||||
command(QVariantList() << "frame-back-step");
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Enums::Commands::SetTrack: {
|
|
||||||
|
|
||||||
command(QVariantList() << "set" << args.toList()[0] << args.toList()[1]);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Enums::Commands::SetPlaylistPos: {
|
|
||||||
|
|
||||||
command(QVariantList() << "set"
|
|
||||||
<< "playlist-pos" << args);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Enums::Commands::ForcePause: {
|
|
||||||
|
|
||||||
command(QVariantList() << "set"
|
|
||||||
<< "pause"
|
|
||||||
<< "yes");
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default: {
|
|
||||||
qDebug() << "Command not found: " << cmd;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return QVariant("NoOutput");
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
MPVBackend::toggleOnTop()
|
MPVBackend::toggleOnTop()
|
||||||
|
@ -463,335 +314,16 @@ MPVBackend::on_mpv_events()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
MPVBackend::updateDurationString(int numTime)
|
|
||||||
{
|
|
||||||
QVariant speed = getProperty("speed");
|
|
||||||
QMetaMethod metaMethod = sender()->metaObject()->method(senderSignalIndex());
|
|
||||||
if (metaMethod.name() == "positionChanged") {
|
|
||||||
if (speed != lastSpeed) {
|
|
||||||
lastSpeed = speed.toDouble();
|
|
||||||
} else {
|
|
||||||
if (numTime == lastTime) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lastTime = numTime;
|
|
||||||
lastPositionString = Utils::createTimestamp(lastTime);
|
|
||||||
} else if (metaMethod.name() == "durationChanged") {
|
|
||||||
totalDurationString = Utils::createTimestamp(numTime);
|
|
||||||
}
|
|
||||||
QString durationString;
|
|
||||||
durationString += lastPositionString;
|
|
||||||
durationString += " / ";
|
|
||||||
durationString += totalDurationString;
|
|
||||||
if (lastSpeed != 1) {
|
|
||||||
if (settings.value("Appearance/themeName", "").toString() !=
|
|
||||||
"RoosterTeeth") {
|
|
||||||
durationString += " (" + speed.toString() + "x)";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
emit durationStringChanged(durationString);
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariantMap
|
QVariantMap
|
||||||
MPVBackend::getAudioDevices(const QVariant& drivers) const
|
MPVBackend::getAudioDevices(const QVariant& drivers) const
|
||||||
{
|
{
|
||||||
QVariantMap newDrivers;
|
return MPVCommon::getAudioDevices(drivers);
|
||||||
|
|
||||||
QSequentialIterable iterable = drivers.value<QSequentialIterable>();
|
|
||||||
foreach (const QVariant& v, iterable) {
|
|
||||||
QVariantMap item = v.toMap();
|
|
||||||
newDrivers[item["description"].toString()] = item;
|
|
||||||
}
|
|
||||||
return newDrivers;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MPVBackend::handle_mpv_event(mpv_event* event)
|
MPVBackend::handle_mpv_event(mpv_event* event)
|
||||||
{
|
{
|
||||||
switch (event->event_id) {
|
MPVCommon::handle_mpv_event(this, event);
|
||||||
case MPV_EVENT_PROPERTY_CHANGE: {
|
|
||||||
mpv_event_property* prop = (mpv_event_property*)event->data;
|
|
||||||
if (strcmp(prop->name, "time-pos") == 0) {
|
|
||||||
if (prop->format == MPV_FORMAT_DOUBLE) {
|
|
||||||
double time = *(double*)prop->data;
|
|
||||||
emit positionChanged(time);
|
|
||||||
}
|
|
||||||
} else if (strcmp(prop->name, "duration") == 0) {
|
|
||||||
if (prop->format == MPV_FORMAT_DOUBLE) {
|
|
||||||
double time = *(double*)prop->data;
|
|
||||||
emit durationChanged(time);
|
|
||||||
}
|
|
||||||
} else if (strcmp(prop->name, "mute") == 0 ||
|
|
||||||
strcmp(prop->name, "volume") == 0) {
|
|
||||||
double volume = getProperty("volume").toDouble();
|
|
||||||
bool mute = getProperty("mute").toBool();
|
|
||||||
if (mute || volume == 0) {
|
|
||||||
emit volumeStatusChanged(Enums::VolumeStatus::Muted);
|
|
||||||
} else {
|
|
||||||
if (volume < 25) {
|
|
||||||
emit volumeStatusChanged(Enums::VolumeStatus::Low);
|
|
||||||
} else {
|
|
||||||
emit volumeStatusChanged(Enums::VolumeStatus::Normal);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// emit volumeChanged(volume);
|
|
||||||
} else if (strcmp(prop->name, "media-title") == 0) {
|
|
||||||
if (prop->format == MPV_FORMAT_STRING) {
|
|
||||||
char* title = *(char**)prop->data;
|
|
||||||
emit titleChanged(QString(title));
|
|
||||||
}
|
|
||||||
} else if (strcmp(prop->name, "sub-text") == 0) {
|
|
||||||
if (prop->format == MPV_FORMAT_STRING) {
|
|
||||||
char* subs = *(char**)prop->data;
|
|
||||||
emit subtitlesChanged(QString(subs));
|
|
||||||
}
|
|
||||||
} else if (strcmp(prop->name, "demuxer-cache-duration") == 0) {
|
|
||||||
if (prop->format == MPV_FORMAT_DOUBLE) {
|
|
||||||
double duration = *(double*)prop->data;
|
|
||||||
emit cachedDurationChanged(duration);
|
|
||||||
}
|
|
||||||
} else if (strcmp(prop->name, "playlist-pos") == 0) {
|
|
||||||
if (prop->format == MPV_FORMAT_DOUBLE) {
|
|
||||||
double pos = *(double*)prop->data;
|
|
||||||
emit playlistPositionChanged(pos);
|
|
||||||
}
|
|
||||||
} else if (strcmp(prop->name, "pause") == 0) {
|
|
||||||
mpv_node* nod = (mpv_node*)prop->data;
|
|
||||||
if (mpv::qt::node_to_variant(nod).toBool()) {
|
|
||||||
emit playStatusChanged(Enums::PlayStatus::Paused);
|
|
||||||
// Utils::SetScreensaver(window()->winId(), true);
|
|
||||||
} else {
|
|
||||||
emit playStatusChanged(Enums::PlayStatus::Playing);
|
|
||||||
// Utils::SetScreensaver(window()->winId(), false);
|
|
||||||
}
|
|
||||||
} else if (strcmp(prop->name, "track-list") == 0) {
|
|
||||||
mpv_node* nod = (mpv_node*)prop->data;
|
|
||||||
emit tracksChanged(mpv::qt::node_to_variant(nod).toList());
|
|
||||||
} else if (strcmp(prop->name, "audio-device-list") == 0) {
|
|
||||||
mpv_node* nod = (mpv_node*)prop->data;
|
|
||||||
emit audioDevicesChanged(
|
|
||||||
getAudioDevices(mpv::qt::node_to_variant(nod)));
|
|
||||||
} else if (strcmp(prop->name, "playlist") == 0) {
|
|
||||||
mpv_node* nod = (mpv_node*)prop->data;
|
|
||||||
emit playlistChanged(mpv::qt::node_to_variant(nod).toList());
|
|
||||||
} else if (strcmp(prop->name, "chapter-list") == 0) {
|
|
||||||
mpv_node* nod = (mpv_node*)prop->data;
|
|
||||||
emit chaptersChanged(mpv::qt::node_to_variant(nod).toList());
|
|
||||||
} else if (strcmp(prop->name, "speed") == 0) {
|
|
||||||
double speed = *(double*)prop->data;
|
|
||||||
emit speedChanged(speed);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case MPV_EVENT_LOG_MESSAGE: {
|
|
||||||
if (m_logging) {
|
|
||||||
struct mpv_event_log_message* msg =
|
|
||||||
(struct mpv_event_log_message*)event->data;
|
|
||||||
QString logMsg = "[" + QString(msg->prefix) + "] " + QString(msg->text);
|
|
||||||
QString msgLevel = QString(msg->level);
|
|
||||||
if (msgLevel.startsWith("d") || msgLevel.startsWith("t")) {
|
|
||||||
mpvLogger->info("{}", logMsg.toStdString());
|
|
||||||
} else if (msgLevel.startsWith("v") || msgLevel.startsWith("i")) {
|
|
||||||
mpvLogger->info("{}", logMsg.toStdString());
|
|
||||||
} else {
|
|
||||||
mpvLogger->debug("{}", logMsg.toStdString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MPV_EVENT_SHUTDOWN: {
|
|
||||||
qApp->exit();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString
|
|
||||||
MPVBackend::getStats()
|
|
||||||
{
|
|
||||||
QString stats;
|
|
||||||
stats =
|
|
||||||
"<style> blockquote { text-indent: 0px; margin-left:40px; margin-top: 0px; "
|
|
||||||
"margin-bottom: 0px; padding-bottom: 0px; padding-top: 0px; padding-left: "
|
|
||||||
"0px; } b span p br { margin-bottom: 0px; margin-top: 0px; padding-top: "
|
|
||||||
"0px; padding-botom: 0px; text-indent: 0px; } </style>";
|
|
||||||
QString filename = getProperty("filename").toString();
|
|
||||||
// File Info
|
|
||||||
stats += "<b>File:</b> " + filename;
|
|
||||||
stats += "<blockquote>";
|
|
||||||
QString title = getProperty("media-title").toString();
|
|
||||||
if (title != filename) {
|
|
||||||
stats += "<b>Title:</b> " + title + "<br>";
|
|
||||||
}
|
|
||||||
QString fileFormat = getProperty("file-format").toString();
|
|
||||||
stats += "<b>Format/Protocol:</b> " + fileFormat + "<br>";
|
|
||||||
QLocale a;
|
|
||||||
// a.formattedDataSize(
|
|
||||||
double cacheUsed = getProperty("cache-used").toDouble();
|
|
||||||
// Utils::createTimestamp(
|
|
||||||
int demuxerSecs = getProperty("demuxer-cache-duration").toInt();
|
|
||||||
QVariantMap demuxerState = getProperty("demuxer-cache-state").toMap();
|
|
||||||
int demuxerCache = demuxerState.value("fw-bytes", QVariant(0)).toInt();
|
|
||||||
|
|
||||||
if (demuxerSecs + demuxerCache + cacheUsed > 0) {
|
|
||||||
QString cacheStats;
|
|
||||||
cacheStats += "<b>Total Cache:</b> ";
|
|
||||||
cacheStats += a.formattedDataSize(demuxerCache + cacheUsed);
|
|
||||||
cacheStats += " (<b>Demuxer:</b> ";
|
|
||||||
|
|
||||||
cacheStats += a.formattedDataSize(demuxerCache);
|
|
||||||
cacheStats += ", ";
|
|
||||||
cacheStats += QString::number(demuxerSecs) + "s) ";
|
|
||||||
double cacheSpeed = getProperty("cache-speed").toDouble();
|
|
||||||
if (cacheSpeed > 0) {
|
|
||||||
cacheStats += "<b>Speed:</b> ";
|
|
||||||
cacheStats += a.formattedDataSize(demuxerSecs);
|
|
||||||
cacheStats += "/s";
|
|
||||||
}
|
|
||||||
cacheStats += "<br>";
|
|
||||||
stats += cacheStats;
|
|
||||||
}
|
|
||||||
QString fileSize =
|
|
||||||
a.formattedDataSize(getProperty("file-size").toInt()).remove("-");
|
|
||||||
stats += "<b>Size:</b> " + fileSize + "<br>";
|
|
||||||
|
|
||||||
stats += "</blockquote>";
|
|
||||||
// Video Info
|
|
||||||
QVariant videoParams = getProperty("video-params");
|
|
||||||
if (videoParams.isNull()) {
|
|
||||||
videoParams = getProperty("video-out-params");
|
|
||||||
}
|
|
||||||
if (!videoParams.isNull()) {
|
|
||||||
stats += "<b>Video:</b> " + getProperty("video-codec").toString();
|
|
||||||
stats += "<blockquote>";
|
|
||||||
QString avsync = QString::number(getProperty("avsync").toDouble(), 'f', 3);
|
|
||||||
stats += "<b>A-V:</b> " + QString(avsync) + "<br>";
|
|
||||||
|
|
||||||
stats += "<b>Dropped Frames:</b> ";
|
|
||||||
int dFDC = getProperty("decoder-frame-drop-count").toInt();
|
|
||||||
if (dFDC > 0) {
|
|
||||||
stats += QString::number(dFDC) + " (decoder) ";
|
|
||||||
}
|
|
||||||
int fDC = getProperty("frame-drop-count").toInt();
|
|
||||||
if (fDC > 0) {
|
|
||||||
stats += QString::number(fDC) + " (output)";
|
|
||||||
}
|
|
||||||
stats += "<br>";
|
|
||||||
|
|
||||||
int dFPS = getProperty("display-fps").toInt();
|
|
||||||
int eDFPS = getProperty("estimated-display-fps").toInt();
|
|
||||||
if ((dFPS + eDFPS) > 0) {
|
|
||||||
stats += "<b>Display FPS:</b> ";
|
|
||||||
|
|
||||||
if (dFPS > 0) {
|
|
||||||
stats += QString::number(dFPS);
|
|
||||||
stats += " (specified) ";
|
|
||||||
}
|
|
||||||
if (eDFPS > 0) {
|
|
||||||
stats += QString::number(eDFPS);
|
|
||||||
stats += " (estimated)";
|
|
||||||
}
|
|
||||||
stats += "<br>";
|
|
||||||
}
|
|
||||||
|
|
||||||
int cFPS = getProperty("container-fps").toInt();
|
|
||||||
int eVFPS = getProperty("estimated-vf-fps").toInt();
|
|
||||||
if ((cFPS + eVFPS) > 0) {
|
|
||||||
stats += "<b>FPS:</b> ";
|
|
||||||
|
|
||||||
if (cFPS > 0) {
|
|
||||||
stats += QString::number(cFPS);
|
|
||||||
stats += " (specified) ";
|
|
||||||
}
|
|
||||||
if (eVFPS > 0) {
|
|
||||||
stats += QString::number(eVFPS);
|
|
||||||
stats += " (estimated)";
|
|
||||||
}
|
|
||||||
stats += "<br>";
|
|
||||||
}
|
|
||||||
QVariantMap vPM = videoParams.toMap();
|
|
||||||
stats += "<b>Native Resolution:</b> ";
|
|
||||||
stats += vPM["w"].toString() + " x " + vPM["h"].toString();
|
|
||||||
stats += "<br>";
|
|
||||||
|
|
||||||
stats += "<b>Window Scale:</b> ";
|
|
||||||
stats += vPM["window-scale"].toString();
|
|
||||||
stats += "<br>";
|
|
||||||
|
|
||||||
stats += "<b>Aspect Ratio:</b> ";
|
|
||||||
stats += vPM["aspect"].toString();
|
|
||||||
stats += "<br>";
|
|
||||||
|
|
||||||
stats += "<b>Pixel Format:</b> ";
|
|
||||||
stats += vPM["pixelformat"].toString();
|
|
||||||
stats += "<br>";
|
|
||||||
|
|
||||||
stats += "<b>Primaries:</b> ";
|
|
||||||
stats += vPM["primaries"].toString();
|
|
||||||
stats += " <b>Colormatrix:</b> ";
|
|
||||||
stats += vPM["colormatrix"].toString();
|
|
||||||
stats += "<br>";
|
|
||||||
|
|
||||||
stats += "<b>Levels:</b> ";
|
|
||||||
stats += vPM["colorlevels"].toString();
|
|
||||||
double sigPeak = vPM.value("sig-peak", QVariant(0.0)).toInt();
|
|
||||||
if (sigPeak > 0) {
|
|
||||||
stats += " (HDR Peak: " + QString::number(sigPeak) + ")";
|
|
||||||
}
|
|
||||||
stats += "<br>";
|
|
||||||
|
|
||||||
stats += "<b>Gamma:</b> ";
|
|
||||||
stats += vPM["gamma"].toString();
|
|
||||||
stats += "<br>";
|
|
||||||
|
|
||||||
int pVB = getProperty("packet-video-bitrate").toInt();
|
|
||||||
if (pVB > 0) {
|
|
||||||
stats += "<b>Bitrate:</b> ";
|
|
||||||
stats += a.formattedDataSize(pVB) + "/s";
|
|
||||||
stats += "<br>";
|
|
||||||
}
|
|
||||||
|
|
||||||
stats += "</blockquote>";
|
|
||||||
}
|
|
||||||
QVariant audioParams = getProperty("audio-params");
|
|
||||||
if (audioParams.isNull()) {
|
|
||||||
audioParams = getProperty("audio-out-params");
|
|
||||||
}
|
|
||||||
if (!audioParams.isNull()) {
|
|
||||||
stats += "<b>Audio:</b> " + getProperty("audio-codec").toString();
|
|
||||||
stats += "<blockquote>";
|
|
||||||
QVariantMap aPM = audioParams.toMap();
|
|
||||||
|
|
||||||
stats += "<b>Format:</b> ";
|
|
||||||
stats += aPM["format"].toString();
|
|
||||||
stats += "<br>";
|
|
||||||
|
|
||||||
stats += "<b>Sample Rate:</b> ";
|
|
||||||
stats += aPM["samplerate"].toString() + " Hz";
|
|
||||||
stats += "<br>";
|
|
||||||
|
|
||||||
stats += "<b>Channels:</b> ";
|
|
||||||
stats += aPM["chanel-count"].toString();
|
|
||||||
stats += "<br>";
|
|
||||||
|
|
||||||
int pAB = getProperty("packet-audio-bitrate").toInt();
|
|
||||||
if (pAB > 0) {
|
|
||||||
stats += "<b>Bitrate:</b> ";
|
|
||||||
stats += a.formattedDataSize(pAB) + "/s";
|
|
||||||
stats += "<br>";
|
|
||||||
}
|
|
||||||
|
|
||||||
stats += "</blockquote>";
|
|
||||||
}
|
|
||||||
|
|
||||||
return stats;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QQuickFramebufferObject::Renderer*
|
QQuickFramebufferObject::Renderer*
|
||||||
|
|
|
@ -15,8 +15,6 @@
|
||||||
#include "src/enums.hpp"
|
#include "src/enums.hpp"
|
||||||
#include "src/utils.hpp"
|
#include "src/utils.hpp"
|
||||||
|
|
||||||
extern bool usedirect;
|
|
||||||
|
|
||||||
class MpvRenderer;
|
class MpvRenderer;
|
||||||
|
|
||||||
class MPVBackend
|
class MPVBackend
|
||||||
|
@ -36,11 +34,6 @@ class MPVBackend
|
||||||
bool onTop = false;
|
bool onTop = false;
|
||||||
bool m_logging = true;
|
bool m_logging = true;
|
||||||
|
|
||||||
int lastTime = 0;
|
|
||||||
double lastSpeed = 0;
|
|
||||||
QString totalDurationString;
|
|
||||||
QString lastPositionString;
|
|
||||||
|
|
||||||
friend class MpvRenderer;
|
friend class MpvRenderer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -58,6 +51,11 @@ public:
|
||||||
}
|
}
|
||||||
bool logging() const { return m_logging; }
|
bool logging() const { return m_logging; }
|
||||||
|
|
||||||
|
int lastTime = 0;
|
||||||
|
double lastSpeed = 0;
|
||||||
|
QString totalDurationString;
|
||||||
|
QString lastPositionString;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
QVariant playerCommand(const Enums::Commands& command, const QVariant& args);
|
QVariant playerCommand(const Enums::Commands& command, const QVariant& args);
|
||||||
QVariant playerCommand(const Enums::Commands& command);
|
QVariant playerCommand(const Enums::Commands& command);
|
||||||
|
|
504
src/Backends/MPVCommon/MPVCommon.cpp
Normal file
504
src/Backends/MPVCommon/MPVCommon.cpp
Normal file
|
@ -0,0 +1,504 @@
|
||||||
|
#include "src/Backends/MPVCommon/MPVCommon.hpp"
|
||||||
|
#include "src/utils.hpp"
|
||||||
|
#include <QSettings>
|
||||||
|
#include <mpv/qthelper.hpp>
|
||||||
|
#include "src/logger.h"
|
||||||
|
|
||||||
|
|
||||||
|
auto mpvLogger = initLogger("mpv");
|
||||||
|
|
||||||
|
|
||||||
|
namespace MPVCommon {
|
||||||
|
QString getStats(BackendInterface *b) {
|
||||||
|
QString stats;
|
||||||
|
stats =
|
||||||
|
"<style> blockquote { text-indent: 0px; margin-left:40px; margin-top: 0px; "
|
||||||
|
"margin-bottom: 0px; padding-bottom: 0px; padding-top: 0px; padding-left: "
|
||||||
|
"0px; } b span p br { margin-bottom: 0px; margin-top: 0px; padding-top: "
|
||||||
|
"0px; padding-botom: 0px; text-indent: 0px; } </style>";
|
||||||
|
QString filename = b->getProperty("filename").toString();
|
||||||
|
// File Info
|
||||||
|
stats += "<b>File:</b> " + filename;
|
||||||
|
stats += "<blockquote>";
|
||||||
|
QString title = b->getProperty("media-title").toString();
|
||||||
|
if (title != filename) {
|
||||||
|
stats += "<b>Title:</b> " + title + "<br>";
|
||||||
|
}
|
||||||
|
QString fileFormat = b->getProperty("file-format").toString();
|
||||||
|
stats += "<b>Format/Protocol:</b> " + fileFormat + "<br>";
|
||||||
|
QLocale a;
|
||||||
|
// a.formattedDataSize(
|
||||||
|
double cacheUsed = b->getProperty("cache-used").toDouble();
|
||||||
|
// Utils::createTimestamp(
|
||||||
|
int demuxerSecs = b->getProperty("demuxer-cache-duration").toInt();
|
||||||
|
QVariantMap demuxerState = b->getProperty("demuxer-cache-state").toMap();
|
||||||
|
int demuxerCache = demuxerState.value("fw-bytes", QVariant(0)).toInt();
|
||||||
|
|
||||||
|
if (demuxerSecs + demuxerCache + cacheUsed > 0) {
|
||||||
|
QString cacheStats;
|
||||||
|
cacheStats += "<b>Total Cache:</b> ";
|
||||||
|
cacheStats += a.formattedDataSize(demuxerCache + cacheUsed);
|
||||||
|
cacheStats += " (<b>Demuxer:</b> ";
|
||||||
|
|
||||||
|
cacheStats += a.formattedDataSize(demuxerCache);
|
||||||
|
cacheStats += ", ";
|
||||||
|
cacheStats += QString::number(demuxerSecs) + "s) ";
|
||||||
|
double cacheSpeed = b->getProperty("cache-speed").toDouble();
|
||||||
|
if (cacheSpeed > 0) {
|
||||||
|
cacheStats += "<b>Speed:</b> ";
|
||||||
|
cacheStats += a.formattedDataSize(demuxerSecs);
|
||||||
|
cacheStats += "/s";
|
||||||
|
}
|
||||||
|
cacheStats += "<br>";
|
||||||
|
stats += cacheStats;
|
||||||
|
}
|
||||||
|
QString fileSize =
|
||||||
|
a.formattedDataSize(b->getProperty("file-size").toInt()).remove("-");
|
||||||
|
stats += "<b>Size:</b> " + fileSize + "<br>";
|
||||||
|
|
||||||
|
stats += "</blockquote>";
|
||||||
|
// Video Info
|
||||||
|
QVariant videoParams = b->getProperty("video-params");
|
||||||
|
if (videoParams.isNull()) {
|
||||||
|
videoParams = b->getProperty("video-out-params");
|
||||||
|
}
|
||||||
|
if (!videoParams.isNull()) {
|
||||||
|
stats += "<b>Video:</b> " + b->getProperty("video-codec").toString();
|
||||||
|
stats += "<blockquote>";
|
||||||
|
QString avsync = QString::number(b->getProperty("avsync").toDouble(), 'f', 3);
|
||||||
|
stats += "<b>A-V:</b> " + QString(avsync) + "<br>";
|
||||||
|
|
||||||
|
stats += "<b>Dropped Frames:</b> ";
|
||||||
|
int dFDC = b->getProperty("decoder-frame-drop-count").toInt();
|
||||||
|
if (dFDC > 0) {
|
||||||
|
stats += QString::number(dFDC) + " (decoder) ";
|
||||||
|
}
|
||||||
|
int fDC = b->getProperty("frame-drop-count").toInt();
|
||||||
|
if (fDC > 0) {
|
||||||
|
stats += QString::number(fDC) + " (output)";
|
||||||
|
}
|
||||||
|
stats += "<br>";
|
||||||
|
|
||||||
|
int dFPS = b->getProperty("display-fps").toInt();
|
||||||
|
int eDFPS = b->getProperty("estimated-display-fps").toInt();
|
||||||
|
if ((dFPS + eDFPS) > 0) {
|
||||||
|
stats += "<b>Display FPS:</b> ";
|
||||||
|
|
||||||
|
if (dFPS > 0) {
|
||||||
|
stats += QString::number(dFPS);
|
||||||
|
stats += " (specified) ";
|
||||||
|
}
|
||||||
|
if (eDFPS > 0) {
|
||||||
|
stats += QString::number(eDFPS);
|
||||||
|
stats += " (estimated)";
|
||||||
|
}
|
||||||
|
stats += "<br>";
|
||||||
|
}
|
||||||
|
|
||||||
|
int cFPS = b->getProperty("container-fps").toInt();
|
||||||
|
int eVFPS = b->getProperty("estimated-vf-fps").toInt();
|
||||||
|
if ((cFPS + eVFPS) > 0) {
|
||||||
|
stats += "<b>FPS:</b> ";
|
||||||
|
|
||||||
|
if (cFPS > 0) {
|
||||||
|
stats += QString::number(cFPS);
|
||||||
|
stats += " (specified) ";
|
||||||
|
}
|
||||||
|
if (eVFPS > 0) {
|
||||||
|
stats += QString::number(eVFPS);
|
||||||
|
stats += " (estimated)";
|
||||||
|
}
|
||||||
|
stats += "<br>";
|
||||||
|
}
|
||||||
|
QVariantMap vPM = videoParams.toMap();
|
||||||
|
stats += "<b>Native Resolution:</b> ";
|
||||||
|
stats += vPM["w"].toString() + " x " + vPM["h"].toString();
|
||||||
|
stats += "<br>";
|
||||||
|
|
||||||
|
stats += "<b>Window Scale:</b> ";
|
||||||
|
stats += vPM["window-scale"].toString();
|
||||||
|
stats += "<br>";
|
||||||
|
|
||||||
|
stats += "<b>Aspect Ratio:</b> ";
|
||||||
|
stats += vPM["aspect"].toString();
|
||||||
|
stats += "<br>";
|
||||||
|
|
||||||
|
stats += "<b>Pixel Format:</b> ";
|
||||||
|
stats += vPM["pixelformat"].toString();
|
||||||
|
stats += "<br>";
|
||||||
|
|
||||||
|
stats += "<b>Primaries:</b> ";
|
||||||
|
stats += vPM["primaries"].toString();
|
||||||
|
stats += " <b>Colormatrix:</b> ";
|
||||||
|
stats += vPM["colormatrix"].toString();
|
||||||
|
stats += "<br>";
|
||||||
|
|
||||||
|
stats += "<b>Levels:</b> ";
|
||||||
|
stats += vPM["colorlevels"].toString();
|
||||||
|
double sigPeak = vPM.value("sig-peak", QVariant(0.0)).toInt();
|
||||||
|
if (sigPeak > 0) {
|
||||||
|
stats += " (HDR Peak: " + QString::number(sigPeak) + ")";
|
||||||
|
}
|
||||||
|
stats += "<br>";
|
||||||
|
|
||||||
|
stats += "<b>Gamma:</b> ";
|
||||||
|
stats += vPM["gamma"].toString();
|
||||||
|
stats += "<br>";
|
||||||
|
|
||||||
|
int pVB = b->getProperty("packet-video-bitrate").toInt();
|
||||||
|
if (pVB > 0) {
|
||||||
|
stats += "<b>Bitrate:</b> ";
|
||||||
|
stats += a.formattedDataSize(pVB) + "/s";
|
||||||
|
stats += "<br>";
|
||||||
|
}
|
||||||
|
|
||||||
|
stats += "</blockquote>";
|
||||||
|
}
|
||||||
|
QVariant audioParams = b->getProperty("audio-params");
|
||||||
|
if (audioParams.isNull()) {
|
||||||
|
audioParams = b->getProperty("audio-out-params");
|
||||||
|
}
|
||||||
|
if (!audioParams.isNull()) {
|
||||||
|
stats += "<b>Audio:</b> " + b->getProperty("audio-codec").toString();
|
||||||
|
stats += "<blockquote>";
|
||||||
|
QVariantMap aPM = audioParams.toMap();
|
||||||
|
|
||||||
|
stats += "<b>Format:</b> ";
|
||||||
|
stats += aPM["format"].toString();
|
||||||
|
stats += "<br>";
|
||||||
|
|
||||||
|
stats += "<b>Sample Rate:</b> ";
|
||||||
|
stats += aPM["samplerate"].toString() + " Hz";
|
||||||
|
stats += "<br>";
|
||||||
|
|
||||||
|
stats += "<b>Channels:</b> ";
|
||||||
|
stats += aPM["chanel-count"].toString();
|
||||||
|
stats += "<br>";
|
||||||
|
|
||||||
|
int pAB = b->getProperty("packet-audio-bitrate").toInt();
|
||||||
|
if (pAB > 0) {
|
||||||
|
stats += "<b>Bitrate:</b> ";
|
||||||
|
stats += a.formattedDataSize(pAB) + "/s";
|
||||||
|
stats += "<br>";
|
||||||
|
}
|
||||||
|
|
||||||
|
stats += "</blockquote>";
|
||||||
|
}
|
||||||
|
|
||||||
|
return stats;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant playerCommand(BackendInterface *b, const Enums::Commands& cmd, const QVariant& args)
|
||||||
|
{
|
||||||
|
switch (cmd) {
|
||||||
|
case Enums::Commands::TogglePlayPause: {
|
||||||
|
b->command(QVariantList() << "cycle"
|
||||||
|
<< "pause");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Enums::Commands::ToggleMute: {
|
||||||
|
b->command(QVariantList() << "cycle"
|
||||||
|
<< "mute");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Enums::Commands::SetAudioDevice: {
|
||||||
|
b->setProperty("audio-device", args.toString());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Enums::Commands::SetVolume: {
|
||||||
|
b->command(QVariantList() << "set"
|
||||||
|
<< "volume" << args);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Enums::Commands::AddVolume: {
|
||||||
|
|
||||||
|
b->command(QVariantList() << "add"
|
||||||
|
<< "volume" << args);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Enums::Commands::AddSpeed: {
|
||||||
|
|
||||||
|
QString speedString =
|
||||||
|
QString::number(b->getProperty("speed").toDouble() + args.toDouble());
|
||||||
|
QVariant newSpeed =
|
||||||
|
QVariant(speedString.left(speedString.lastIndexOf('.') + 2));
|
||||||
|
|
||||||
|
b->playerCommand(Enums::Commands::SetSpeed, newSpeed);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Enums::Commands::SubtractSpeed: {
|
||||||
|
|
||||||
|
QString speedString =
|
||||||
|
QString::number(b->getProperty("speed").toDouble() - args.toDouble());
|
||||||
|
QVariant newSpeed =
|
||||||
|
QVariant(speedString.left(speedString.lastIndexOf('.') + 2));
|
||||||
|
b->playerCommand(Enums::Commands::SetSpeed, newSpeed);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Enums::Commands::ChangeSpeed: {
|
||||||
|
|
||||||
|
b->playerCommand(
|
||||||
|
Enums::Commands::SetSpeed,
|
||||||
|
QVariant(b->getProperty("speed").toDouble() * args.toDouble()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Enums::Commands::SetSpeed: {
|
||||||
|
|
||||||
|
b->command(QVariantList() << "set"
|
||||||
|
<< "speed" << args.toString());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Enums::Commands::ToggleStats: {
|
||||||
|
|
||||||
|
b->command(QVariantList() << "script-binding"
|
||||||
|
<< "stats/display-stats-toggle");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Enums::Commands::NextAudioTrack: {
|
||||||
|
|
||||||
|
b->command(QVariantList() << "cycle"
|
||||||
|
<< "audio");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Enums::Commands::NextSubtitleTrack: {
|
||||||
|
|
||||||
|
b->command(QVariantList() << "cycle"
|
||||||
|
<< "sub");
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Enums::Commands::NextVideoTrack: {
|
||||||
|
b->command(QVariantList() << "cycle"
|
||||||
|
<< "video");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Enums::Commands::PreviousPlaylistItem: {
|
||||||
|
|
||||||
|
b->command(QVariantList() << "playlist-prev");
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Enums::Commands::NextPlaylistItem: {
|
||||||
|
|
||||||
|
b->command(QVariantList() << "playlist-next"
|
||||||
|
<< "force");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Enums::Commands::LoadFile: {
|
||||||
|
b->command(QVariantList() << "loadfile" << args);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Enums::Commands::AppendFile: {
|
||||||
|
|
||||||
|
b->command(QVariantList() << "loadfile" << args << "append-play");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Enums::Commands::Seek: {
|
||||||
|
|
||||||
|
b->command(QVariantList() << "seek" << args);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Enums::Commands::SeekAbsolute: {
|
||||||
|
|
||||||
|
b->command(QVariantList() << "seek" << args << "absolute");
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Enums::Commands::ForwardFrame: {
|
||||||
|
|
||||||
|
b->command(QVariantList() << "frame-step");
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Enums::Commands::BackwardFrame: {
|
||||||
|
|
||||||
|
b->command(QVariantList() << "frame-back-step");
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Enums::Commands::SetTrack: {
|
||||||
|
|
||||||
|
b->command(QVariantList() << "set" << args.toList()[0] << args.toList()[1]);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Enums::Commands::SetPlaylistPos: {
|
||||||
|
|
||||||
|
b->command(QVariantList() << "set"
|
||||||
|
<< "playlist-pos" << args);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Enums::Commands::ForcePause: {
|
||||||
|
|
||||||
|
b->command(QVariantList() << "set"
|
||||||
|
<< "pause"
|
||||||
|
<< "yes");
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default: {
|
||||||
|
qDebug() << "Command not found: " << cmd;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QVariant("NoOutput");
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateDurationString(BackendInterface *b, int numTime, QMetaMethod metaMethod)
|
||||||
|
{
|
||||||
|
QVariant speed = b->getProperty("speed");
|
||||||
|
QSettings settings;
|
||||||
|
if (metaMethod.name() == "positionChanged") {
|
||||||
|
if (speed != b->lastSpeed) {
|
||||||
|
b->lastSpeed = speed.toDouble();
|
||||||
|
} else {
|
||||||
|
if (numTime == b->lastTime) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
b->lastTime = numTime;
|
||||||
|
b->lastPositionString = Utils::createTimestamp(b->lastTime);
|
||||||
|
} else if (metaMethod.name() == "durationChanged") {
|
||||||
|
b->totalDurationString = Utils::createTimestamp(numTime);
|
||||||
|
}
|
||||||
|
QString durationString;
|
||||||
|
durationString += b->lastPositionString;
|
||||||
|
durationString += " / ";
|
||||||
|
durationString += b->totalDurationString;
|
||||||
|
if (b->lastSpeed != 1) {
|
||||||
|
if (settings.value("Appearance/themeName", "").toString() !=
|
||||||
|
"RoosterTeeth") {
|
||||||
|
durationString += " (" + speed.toString() + "x)";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
emit b->durationStringChanged(durationString);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
handle_mpv_event(BackendInterface *b, mpv_event* event)
|
||||||
|
{
|
||||||
|
switch (event->event_id) {
|
||||||
|
case MPV_EVENT_PROPERTY_CHANGE: {
|
||||||
|
mpv_event_property* prop = (mpv_event_property*)event->data;
|
||||||
|
if (strcmp(prop->name, "time-pos") == 0) {
|
||||||
|
if (prop->format == MPV_FORMAT_DOUBLE) {
|
||||||
|
double time = *(double*)prop->data;
|
||||||
|
emit b->positionChanged(time);
|
||||||
|
}
|
||||||
|
} else if (strcmp(prop->name, "duration") == 0) {
|
||||||
|
if (prop->format == MPV_FORMAT_DOUBLE) {
|
||||||
|
double time = *(double*)prop->data;
|
||||||
|
emit b->durationChanged(time);
|
||||||
|
}
|
||||||
|
} else if (strcmp(prop->name, "mute") == 0 ||
|
||||||
|
strcmp(prop->name, "volume") == 0) {
|
||||||
|
double volume = b->getProperty("volume").toDouble();
|
||||||
|
bool mute = b->getProperty("mute").toBool();
|
||||||
|
if (mute || volume == 0) {
|
||||||
|
emit b->volumeStatusChanged(Enums::VolumeStatus::Muted);
|
||||||
|
} else {
|
||||||
|
if (volume < 25) {
|
||||||
|
emit b->volumeStatusChanged(Enums::VolumeStatus::Low);
|
||||||
|
} else {
|
||||||
|
emit b->volumeStatusChanged(Enums::VolumeStatus::Normal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// emit volumeChanged(volume);
|
||||||
|
} else if (strcmp(prop->name, "media-title") == 0) {
|
||||||
|
if (prop->format == MPV_FORMAT_STRING) {
|
||||||
|
char* title = *(char**)prop->data;
|
||||||
|
emit b->titleChanged(QString(title));
|
||||||
|
}
|
||||||
|
} else if (strcmp(prop->name, "sub-text") == 0) {
|
||||||
|
if (prop->format == MPV_FORMAT_STRING) {
|
||||||
|
char* subs = *(char**)prop->data;
|
||||||
|
emit b->subtitlesChanged(QString(subs));
|
||||||
|
}
|
||||||
|
} else if (strcmp(prop->name, "demuxer-cache-duration") == 0) {
|
||||||
|
if (prop->format == MPV_FORMAT_DOUBLE) {
|
||||||
|
double duration = *(double*)prop->data;
|
||||||
|
emit b->cachedDurationChanged(duration);
|
||||||
|
}
|
||||||
|
} else if (strcmp(prop->name, "playlist-pos") == 0) {
|
||||||
|
if (prop->format == MPV_FORMAT_DOUBLE) {
|
||||||
|
double pos = *(double*)prop->data;
|
||||||
|
emit b->playlistPositionChanged(pos);
|
||||||
|
}
|
||||||
|
} else if (strcmp(prop->name, "pause") == 0) {
|
||||||
|
mpv_node* nod = (mpv_node*)prop->data;
|
||||||
|
if (mpv::qt::node_to_variant(nod).toBool()) {
|
||||||
|
emit b->playStatusChanged(Enums::PlayStatus::Paused);
|
||||||
|
// Utils::SetScreensaver(window()->winId(), true);
|
||||||
|
} else {
|
||||||
|
emit b->playStatusChanged(Enums::PlayStatus::Playing);
|
||||||
|
// Utils::SetScreensaver(window()->winId(), false);
|
||||||
|
}
|
||||||
|
} else if (strcmp(prop->name, "track-list") == 0) {
|
||||||
|
mpv_node* nod = (mpv_node*)prop->data;
|
||||||
|
emit b->tracksChanged(mpv::qt::node_to_variant(nod).toList());
|
||||||
|
} else if (strcmp(prop->name, "audio-device-list") == 0) {
|
||||||
|
mpv_node* nod = (mpv_node*)prop->data;
|
||||||
|
emit b->audioDevicesChanged(b->getAudioDevices(mpv::qt::node_to_variant(nod)));
|
||||||
|
} else if (strcmp(prop->name, "playlist") == 0) {
|
||||||
|
mpv_node* nod = (mpv_node*)prop->data;
|
||||||
|
emit b->playlistChanged(mpv::qt::node_to_variant(nod).toList());
|
||||||
|
} else if (strcmp(prop->name, "chapter-list") == 0) {
|
||||||
|
mpv_node* nod = (mpv_node*)prop->data;
|
||||||
|
emit b->chaptersChanged(mpv::qt::node_to_variant(nod).toList());
|
||||||
|
} else if (strcmp(prop->name, "speed") == 0) {
|
||||||
|
double speed = *(double*)prop->data;
|
||||||
|
emit b->speedChanged(speed);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case MPV_EVENT_LOG_MESSAGE: {
|
||||||
|
struct mpv_event_log_message* msg =
|
||||||
|
(struct mpv_event_log_message*)event->data;
|
||||||
|
QString logMsg = "[" + QString(msg->prefix) + "] " + QString(msg->text);
|
||||||
|
QString msgLevel = QString(msg->level);
|
||||||
|
if (msgLevel.startsWith("d") || msgLevel.startsWith("t")) {
|
||||||
|
mpvLogger->info("{}", logMsg.toStdString());
|
||||||
|
} else if (msgLevel.startsWith("v") || msgLevel.startsWith("i")) {
|
||||||
|
mpvLogger->info("{}", logMsg.toStdString());
|
||||||
|
} else {
|
||||||
|
mpvLogger->debug("{}", logMsg.toStdString());
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MPV_EVENT_SHUTDOWN: {
|
||||||
|
qApp->exit();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariantMap getAudioDevices(const QVariant& drivers)
|
||||||
|
{
|
||||||
|
QVariantMap newDrivers;
|
||||||
|
|
||||||
|
QSequentialIterable iterable = drivers.value<QSequentialIterable>();
|
||||||
|
foreach (const QVariant& v, iterable) {
|
||||||
|
QVariantMap item = v.toMap();
|
||||||
|
newDrivers[item["description"].toString()] = item;
|
||||||
|
}
|
||||||
|
return newDrivers;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
19
src/Backends/MPVCommon/MPVCommon.hpp
Normal file
19
src/Backends/MPVCommon/MPVCommon.hpp
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#ifndef MPVCommon_H
|
||||||
|
#define MPVCommon_H
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
#include "src/backendinterface.hpp"
|
||||||
|
#include <mpv/client.h>
|
||||||
|
|
||||||
|
namespace MPVCommon {
|
||||||
|
|
||||||
|
QString getStats(BackendInterface *b);
|
||||||
|
QVariant playerCommand(BackendInterface *b, const Enums::Commands& cmd, const QVariant& args);
|
||||||
|
void updateDurationString(BackendInterface *b, int numTime, QMetaMethod metaMethod);
|
||||||
|
void handle_mpv_event(BackendInterface *b, mpv_event* event);
|
||||||
|
QVariantMap getAudioDevices(const QVariant& drivers);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -14,6 +14,9 @@
|
||||||
#include <QSequentialIterable>
|
#include <QSequentialIterable>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "src/Backends/MPVCommon/MPVCommon.hpp"
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
wakeup(void* ctx)
|
wakeup(void* ctx)
|
||||||
{
|
{
|
||||||
|
@ -232,162 +235,7 @@ QVariant
|
||||||
MPVNoFBOBackend::playerCommand(const Enums::Commands& cmd,
|
MPVNoFBOBackend::playerCommand(const Enums::Commands& cmd,
|
||||||
const QVariant& args)
|
const QVariant& args)
|
||||||
{
|
{
|
||||||
switch (cmd) {
|
return MPVCommon::playerCommand(this, cmd, args);
|
||||||
case Enums::Commands::TogglePlayPause: {
|
|
||||||
command(QVariantList() << "cycle"
|
|
||||||
<< "pause");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Enums::Commands::ToggleMute: {
|
|
||||||
command(QVariantList() << "cycle"
|
|
||||||
<< "mute");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Enums::Commands::SetAudioDevice: {
|
|
||||||
setProperty("audio-device", args.toString());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Enums::Commands::SetVolume: {
|
|
||||||
command(QVariantList() << "set"
|
|
||||||
<< "volume" << args);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Enums::Commands::AddVolume: {
|
|
||||||
|
|
||||||
command(QVariantList() << "add"
|
|
||||||
<< "volume" << args);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Enums::Commands::AddSpeed: {
|
|
||||||
|
|
||||||
QString speedString =
|
|
||||||
QString::number(getProperty("speed").toDouble() + args.toDouble());
|
|
||||||
QVariant newSpeed =
|
|
||||||
QVariant(speedString.left(speedString.lastIndexOf('.') + 2));
|
|
||||||
|
|
||||||
playerCommand(Enums::Commands::SetSpeed, newSpeed);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Enums::Commands::SubtractSpeed: {
|
|
||||||
|
|
||||||
QString speedString =
|
|
||||||
QString::number(getProperty("speed").toDouble() - args.toDouble());
|
|
||||||
QVariant newSpeed =
|
|
||||||
QVariant(speedString.left(speedString.lastIndexOf('.') + 2));
|
|
||||||
playerCommand(Enums::Commands::SetSpeed, newSpeed);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Enums::Commands::ChangeSpeed: {
|
|
||||||
|
|
||||||
playerCommand(
|
|
||||||
Enums::Commands::SetSpeed,
|
|
||||||
QVariant(getProperty("speed").toDouble() * args.toDouble()));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Enums::Commands::SetSpeed: {
|
|
||||||
|
|
||||||
command(QVariantList() << "set"
|
|
||||||
<< "speed" << args.toString());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Enums::Commands::ToggleStats: {
|
|
||||||
|
|
||||||
command(QVariantList() << "script-binding"
|
|
||||||
<< "stats/display-stats-toggle");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Enums::Commands::NextAudioTrack: {
|
|
||||||
|
|
||||||
command(QVariantList() << "cycle"
|
|
||||||
<< "audio");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Enums::Commands::NextSubtitleTrack: {
|
|
||||||
|
|
||||||
command(QVariantList() << "cycle"
|
|
||||||
<< "sub");
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Enums::Commands::NextVideoTrack: {
|
|
||||||
command(QVariantList() << "cycle"
|
|
||||||
<< "video");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Enums::Commands::PreviousPlaylistItem: {
|
|
||||||
|
|
||||||
command(QVariantList() << "playlist-prev");
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Enums::Commands::NextPlaylistItem: {
|
|
||||||
|
|
||||||
command(QVariantList() << "playlist-next"
|
|
||||||
<< "force");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Enums::Commands::LoadFile: {
|
|
||||||
command(QVariantList() << "loadfile" << args);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Enums::Commands::AppendFile: {
|
|
||||||
|
|
||||||
command(QVariantList() << "loadfile" << args << "append-play");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Enums::Commands::Seek: {
|
|
||||||
|
|
||||||
command(QVariantList() << "seek" << args);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Enums::Commands::SeekAbsolute: {
|
|
||||||
|
|
||||||
command(QVariantList() << "seek" << args << "absolute");
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Enums::Commands::ForwardFrame: {
|
|
||||||
|
|
||||||
command(QVariantList() << "frame-step");
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Enums::Commands::BackwardFrame: {
|
|
||||||
|
|
||||||
command(QVariantList() << "frame-back-step");
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Enums::Commands::SetTrack: {
|
|
||||||
|
|
||||||
command(QVariantList() << "set" << args.toList()[0] << args.toList()[1]);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Enums::Commands::SetPlaylistPos: {
|
|
||||||
|
|
||||||
command(QVariantList() << "set"
|
|
||||||
<< "playlist-pos" << args);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default: {
|
|
||||||
qDebug() << "Command not found: " << cmd;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return QVariant("NoOutput");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -444,322 +292,26 @@ MPVNoFBOBackend::on_mpv_events()
|
||||||
void
|
void
|
||||||
MPVNoFBOBackend::updateDurationString(int numTime)
|
MPVNoFBOBackend::updateDurationString(int numTime)
|
||||||
{
|
{
|
||||||
QVariant speed = getProperty("speed");
|
|
||||||
QMetaMethod metaMethod = sender()->metaObject()->method(senderSignalIndex());
|
QMetaMethod metaMethod = sender()->metaObject()->method(senderSignalIndex());
|
||||||
if (metaMethod.name() == "positionChanged") {
|
MPVCommon::updateDurationString(this, numTime, metaMethod);
|
||||||
if (speed != lastSpeed) {
|
|
||||||
lastSpeed = speed.toDouble();
|
|
||||||
} else {
|
|
||||||
if (numTime == lastTime) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lastTime = numTime;
|
|
||||||
lastPositionString = Utils::createTimestamp(lastTime);
|
|
||||||
} else if (metaMethod.name() == "durationChanged") {
|
|
||||||
totalDurationString = Utils::createTimestamp(numTime);
|
|
||||||
}
|
|
||||||
QString durationString;
|
|
||||||
durationString += lastPositionString;
|
|
||||||
durationString += " / ";
|
|
||||||
durationString += totalDurationString;
|
|
||||||
if (lastSpeed != 1) {
|
|
||||||
if (settings.value("Appearance/themeName", "").toString() !=
|
|
||||||
"RoosterTeeth") {
|
|
||||||
durationString += " (" + speed.toString() + "x)";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
emit durationStringChanged(durationString);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariantMap
|
QVariantMap
|
||||||
MPVNoFBOBackend::getAudioDevices() const
|
MPVNoFBOBackend::getAudioDevices(const QVariant& drivers) const
|
||||||
{
|
{
|
||||||
QVariant drivers = getProperty("audio-device-list");
|
return MPVCommon::getAudioDevices(drivers);
|
||||||
QVariant currentDevice = getProperty("audio-device");
|
|
||||||
|
|
||||||
QVariantMap newDrivers;
|
|
||||||
|
|
||||||
QSequentialIterable iterable = drivers.value<QSequentialIterable>();
|
|
||||||
foreach (const QVariant& v, iterable) {
|
|
||||||
QVariantMap item = v.toMap();
|
|
||||||
item["selected"] = currentDevice == item["name"];
|
|
||||||
newDrivers[item["description"].toString()] = item;
|
|
||||||
}
|
|
||||||
QMap<QString, QVariant> pulseItem;
|
|
||||||
pulseItem["name"] = "pulse";
|
|
||||||
pulseItem["description"] = "Default (pulseaudio)";
|
|
||||||
pulseItem["selected"] = currentDevice == "pulse";
|
|
||||||
newDrivers[pulseItem["description"].toString()] = pulseItem;
|
|
||||||
return newDrivers;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MPVNoFBOBackend::handle_mpv_event(mpv_event* event)
|
MPVNoFBOBackend::handle_mpv_event(mpv_event* event)
|
||||||
{
|
{
|
||||||
switch (event->event_id) {
|
MPVCommon::handle_mpv_event(this, event);
|
||||||
case MPV_EVENT_PROPERTY_CHANGE: {
|
|
||||||
mpv_event_property* prop = (mpv_event_property*)event->data;
|
|
||||||
if (strcmp(prop->name, "time-pos") == 0) {
|
|
||||||
if (prop->format == MPV_FORMAT_DOUBLE) {
|
|
||||||
double time = *(double*)prop->data;
|
|
||||||
emit positionChanged(time);
|
|
||||||
}
|
|
||||||
} else if (strcmp(prop->name, "duration") == 0) {
|
|
||||||
if (prop->format == MPV_FORMAT_DOUBLE) {
|
|
||||||
double time = *(double*)prop->data;
|
|
||||||
emit durationChanged(time);
|
|
||||||
}
|
|
||||||
} else if (strcmp(prop->name, "mute") == 0 ||
|
|
||||||
strcmp(prop->name, "volume") == 0) {
|
|
||||||
double volume = getProperty("volume").toDouble();
|
|
||||||
bool mute = getProperty("mute").toBool();
|
|
||||||
if (mute || volume == 0) {
|
|
||||||
emit volumeStatusChanged(Enums::VolumeStatus::Muted);
|
|
||||||
} else {
|
|
||||||
if (volume < 25) {
|
|
||||||
emit volumeStatusChanged(Enums::VolumeStatus::Low);
|
|
||||||
} else {
|
|
||||||
emit volumeStatusChanged(Enums::VolumeStatus::Normal);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// emit volumeChanged(volume);
|
|
||||||
} else if (strcmp(prop->name, "media-title") == 0) {
|
|
||||||
if (prop->format == MPV_FORMAT_STRING) {
|
|
||||||
char* title = *(char**)prop->data;
|
|
||||||
emit titleChanged(QString(title));
|
|
||||||
}
|
|
||||||
} else if (strcmp(prop->name, "sub-text") == 0) {
|
|
||||||
if (prop->format == MPV_FORMAT_STRING) {
|
|
||||||
char* subs = *(char**)prop->data;
|
|
||||||
emit subtitlesChanged(QString(subs));
|
|
||||||
}
|
|
||||||
} else if (strcmp(prop->name, "demuxer-cache-duration") == 0) {
|
|
||||||
if (prop->format == MPV_FORMAT_DOUBLE) {
|
|
||||||
double duration = *(double*)prop->data;
|
|
||||||
emit cachedDurationChanged(duration);
|
|
||||||
}
|
|
||||||
} else if (strcmp(prop->name, "playlist-pos") == 0) {
|
|
||||||
if (prop->format == MPV_FORMAT_DOUBLE) {
|
|
||||||
double pos = *(double*)prop->data;
|
|
||||||
emit playlistPositionChanged(pos);
|
|
||||||
}
|
|
||||||
} else if (strcmp(prop->name, "pause") == 0) {
|
|
||||||
mpv_node* nod = (mpv_node*)prop->data;
|
|
||||||
if (mpv::qt::node_to_variant(nod).toBool()) {
|
|
||||||
emit playStatusChanged(Enums::PlayStatus::Paused);
|
|
||||||
Utils::SetScreensaver(window()->winId(), true);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
emit playStatusChanged(Enums::PlayStatus::Playing);
|
|
||||||
Utils::SetScreensaver(window()->winId(), true);
|
|
||||||
}
|
|
||||||
} else if (strcmp(prop->name, "track-list") == 0) {
|
|
||||||
mpv_node* nod = (mpv_node*)prop->data;
|
|
||||||
emit tracksChanged(mpv::qt::node_to_variant(nod).toList());
|
|
||||||
} else if (strcmp(prop->name, "audio-device-list") == 0) {
|
|
||||||
emit audioDevicesChanged(getAudioDevices());
|
|
||||||
} else if (strcmp(prop->name, "playlist") == 0) {
|
|
||||||
mpv_node* nod = (mpv_node*)prop->data;
|
|
||||||
emit playlistChanged(mpv::qt::node_to_variant(nod).toList());
|
|
||||||
} else if (strcmp(prop->name, "chapter-list") == 0) {
|
|
||||||
mpv_node* nod = (mpv_node*)prop->data;
|
|
||||||
emit chaptersChanged(mpv::qt::node_to_variant(nod).toList());
|
|
||||||
} else if (strcmp(prop->name, "speed") == 0) {
|
|
||||||
double speed = *(double*)prop->data;
|
|
||||||
emit speedChanged(speed);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MPV_EVENT_SHUTDOWN: {
|
|
||||||
qApp->exit();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString
|
QString
|
||||||
MPVNoFBOBackend::getStats()
|
MPVNoFBOBackend::getStats()
|
||||||
{
|
{
|
||||||
QString stats;
|
return MPVCommon::getStats(this);
|
||||||
stats =
|
|
||||||
"<style> blockquote { text-indent: 0px; margin-left:40px; margin-top: 0px; "
|
|
||||||
"margin-bottom: 0px; padding-bottom: 0px; padding-top: 0px; padding-left: "
|
|
||||||
"0px; } b span p br { margin-bottom: 0px; margin-top: 0px; padding-top: "
|
|
||||||
"0px; padding-botom: 0px; text-indent: 0px; } </style>";
|
|
||||||
QString filename = getProperty("filename").toString();
|
|
||||||
// File Info
|
|
||||||
stats += "<b>File:</b> " + filename;
|
|
||||||
stats += "<blockquote>";
|
|
||||||
QString title = getProperty("media-title").toString();
|
|
||||||
if (title != filename) {
|
|
||||||
stats += "<b>Title:</b> " + title + "<br>";
|
|
||||||
}
|
|
||||||
QString fileFormat = getProperty("file-format").toString();
|
|
||||||
stats += "<b>Format/Protocol:</b> " + fileFormat + "<br>";
|
|
||||||
QLocale a;
|
|
||||||
// a.formattedDataSize(
|
|
||||||
double cacheUsed = getProperty("cache-used").toDouble();
|
|
||||||
// Utils::createTimestamp(
|
|
||||||
int demuxerSecs = getProperty("demuxer-cache-duration").toInt();
|
|
||||||
QVariantMap demuxerState = getProperty("demuxer-cache-state").toMap();
|
|
||||||
int demuxerCache = demuxerState.value("fw-bytes", QVariant(0)).toInt();
|
|
||||||
|
|
||||||
if (demuxerSecs + demuxerCache + cacheUsed > 0) {
|
|
||||||
QString cacheStats;
|
|
||||||
cacheStats += "<b>Total Cache:</b> ";
|
|
||||||
cacheStats += a.formattedDataSize(demuxerCache + cacheUsed);
|
|
||||||
cacheStats += " (<b>Demuxer:</b> ";
|
|
||||||
|
|
||||||
cacheStats += a.formattedDataSize(demuxerCache);
|
|
||||||
cacheStats += ", ";
|
|
||||||
cacheStats += QString::number(demuxerSecs) + "s) ";
|
|
||||||
double cacheSpeed = getProperty("cache-speed").toDouble();
|
|
||||||
if (cacheSpeed > 0) {
|
|
||||||
cacheStats += "<b>Speed:</b> ";
|
|
||||||
cacheStats += a.formattedDataSize(demuxerSecs);
|
|
||||||
cacheStats += "/s";
|
|
||||||
}
|
|
||||||
cacheStats += "<br>";
|
|
||||||
stats += cacheStats;
|
|
||||||
}
|
|
||||||
QString fileSize =
|
|
||||||
a.formattedDataSize(getProperty("file-size").toInt()).remove("-");
|
|
||||||
stats += "<b>Size:</b> " + fileSize + "<br>";
|
|
||||||
|
|
||||||
stats += "</blockquote>";
|
|
||||||
// Video Info
|
|
||||||
QVariant videoParams = getProperty("video-params");
|
|
||||||
if (videoParams.isNull()) {
|
|
||||||
videoParams = getProperty("video-out-params");
|
|
||||||
}
|
|
||||||
if (!videoParams.isNull()) {
|
|
||||||
stats += "<b>Video:</b> " + getProperty("video-codec").toString();
|
|
||||||
stats += "<blockquote>";
|
|
||||||
QString avsync = QString::number(getProperty("avsync").toDouble(), 'f', 3);
|
|
||||||
stats += "<b>A-V:</b> " + QString(avsync) + "<br>";
|
|
||||||
|
|
||||||
stats += "<b>Dropped Frames:</b> ";
|
|
||||||
int dFDC = getProperty("decoder-frame-drop-count").toInt();
|
|
||||||
if (dFDC > 0) {
|
|
||||||
stats += QString::number(dFDC) + " (decoder) ";
|
|
||||||
}
|
|
||||||
int fDC = getProperty("frame-drop-count").toInt();
|
|
||||||
if (fDC > 0) {
|
|
||||||
stats += QString::number(fDC) + " (output)";
|
|
||||||
}
|
|
||||||
stats += "<br>";
|
|
||||||
|
|
||||||
int dFPS = getProperty("display-fps").toInt();
|
|
||||||
int eDFPS = getProperty("estimated-display-fps").toInt();
|
|
||||||
if ((dFPS + eDFPS) > 0) {
|
|
||||||
stats += "<b>Display FPS:</b> ";
|
|
||||||
|
|
||||||
if (dFPS > 0) {
|
|
||||||
stats += QString::number(dFPS);
|
|
||||||
stats += " (specified) ";
|
|
||||||
}
|
|
||||||
if (eDFPS > 0) {
|
|
||||||
stats += QString::number(eDFPS);
|
|
||||||
stats += " (estimated)";
|
|
||||||
}
|
|
||||||
stats += "<br>";
|
|
||||||
}
|
|
||||||
|
|
||||||
int cFPS = getProperty("container-fps").toInt();
|
|
||||||
int eVFPS = getProperty("estimated-vf-fps").toInt();
|
|
||||||
if ((cFPS + eVFPS) > 0) {
|
|
||||||
stats += "<b>FPS:</b> ";
|
|
||||||
|
|
||||||
if (cFPS > 0) {
|
|
||||||
stats += QString::number(cFPS);
|
|
||||||
stats += " (specified) ";
|
|
||||||
}
|
|
||||||
if (eVFPS > 0) {
|
|
||||||
stats += QString::number(eVFPS);
|
|
||||||
stats += " (estimated)";
|
|
||||||
}
|
|
||||||
stats += "<br>";
|
|
||||||
}
|
|
||||||
QVariantMap vPM = videoParams.toMap();
|
|
||||||
stats += "<b>Native Resolution:</b> ";
|
|
||||||
stats += vPM["w"].toString() + " x " + vPM["h"].toString();
|
|
||||||
stats += "<br>";
|
|
||||||
|
|
||||||
stats += "<b>Window Scale:</b> ";
|
|
||||||
stats += vPM["window-scale"].toString();
|
|
||||||
stats += "<br>";
|
|
||||||
|
|
||||||
stats += "<b>Aspect Ratio:</b> ";
|
|
||||||
stats += vPM["aspect"].toString();
|
|
||||||
stats += "<br>";
|
|
||||||
|
|
||||||
stats += "<b>Pixel Format:</b> ";
|
|
||||||
stats += vPM["pixelformat"].toString();
|
|
||||||
stats += "<br>";
|
|
||||||
|
|
||||||
stats += "<b>Primaries:</b> ";
|
|
||||||
stats += vPM["primaries"].toString();
|
|
||||||
stats += " <b>Colormatrix:</b> ";
|
|
||||||
stats += vPM["colormatrix"].toString();
|
|
||||||
stats += "<br>";
|
|
||||||
|
|
||||||
stats += "<b>Levels:</b> ";
|
|
||||||
stats += vPM["colorlevels"].toString();
|
|
||||||
double sigPeak = vPM.value("sig-peak", QVariant(0.0)).toInt();
|
|
||||||
if (sigPeak > 0) {
|
|
||||||
stats += " (HDR Peak: " + QString::number(sigPeak) + ")";
|
|
||||||
}
|
|
||||||
stats += "<br>";
|
|
||||||
|
|
||||||
stats += "<b>Gamma:</b> ";
|
|
||||||
stats += vPM["gamma"].toString();
|
|
||||||
stats += "<br>";
|
|
||||||
|
|
||||||
int pVB = getProperty("packet-video-bitrate").toInt();
|
|
||||||
if (pVB > 0) {
|
|
||||||
stats += "<b>Bitrate:</b> ";
|
|
||||||
stats += a.formattedDataSize(pVB) + "/s";
|
|
||||||
stats += "<br>";
|
|
||||||
}
|
|
||||||
|
|
||||||
stats += "</blockquote>";
|
|
||||||
}
|
|
||||||
QVariant audioParams = getProperty("audio-params");
|
|
||||||
if (audioParams.isNull()) {
|
|
||||||
audioParams = getProperty("audio-out-params");
|
|
||||||
}
|
|
||||||
if (!audioParams.isNull()) {
|
|
||||||
stats += "<b>Audio:</b> " + getProperty("audio-codec").toString();
|
|
||||||
stats += "<blockquote>";
|
|
||||||
QVariantMap aPM = audioParams.toMap();
|
|
||||||
|
|
||||||
stats += "<b>Format:</b> ";
|
|
||||||
stats += aPM["format"].toString();
|
|
||||||
stats += "<br>";
|
|
||||||
|
|
||||||
stats += "<b>Sample Rate:</b> ";
|
|
||||||
stats += aPM["samplerate"].toString() + " Hz";
|
|
||||||
stats += "<br>";
|
|
||||||
|
|
||||||
stats += "<b>Channels:</b> ";
|
|
||||||
stats += aPM["chanel-count"].toString();
|
|
||||||
stats += "<br>";
|
|
||||||
|
|
||||||
int pAB = getProperty("packet-audio-bitrate").toInt();
|
|
||||||
if (pAB > 0) {
|
|
||||||
stats += "<b>Bitrate:</b> ";
|
|
||||||
stats += a.formattedDataSize(pAB) + "/s";
|
|
||||||
stats += "<br>";
|
|
||||||
}
|
|
||||||
|
|
||||||
stats += "</blockquote>";
|
|
||||||
}
|
|
||||||
|
|
||||||
return stats;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -44,11 +44,7 @@ class MPVNoFBOBackend
|
||||||
mpv_opengl_cb_context* mpv_gl;
|
mpv_opengl_cb_context* mpv_gl;
|
||||||
MPVNoFBORenderer* renderer;
|
MPVNoFBORenderer* renderer;
|
||||||
bool onTop = false;
|
bool onTop = false;
|
||||||
int lastTime = 0;
|
|
||||||
double lastSpeed = 0;
|
|
||||||
bool m_logging = true;
|
bool m_logging = true;
|
||||||
QString totalDurationString;
|
|
||||||
QString lastPositionString;
|
|
||||||
QSettings settings;
|
QSettings settings;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -65,6 +61,11 @@ public:
|
||||||
MPVNoFBOBackend(QQuickItem* parent = 0);
|
MPVNoFBOBackend(QQuickItem* parent = 0);
|
||||||
virtual ~MPVNoFBOBackend();
|
virtual ~MPVNoFBOBackend();
|
||||||
|
|
||||||
|
int lastTime = 0;
|
||||||
|
double lastSpeed = 0;
|
||||||
|
QString totalDurationString;
|
||||||
|
QString lastPositionString;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
QVariant playerCommand(const Enums::Commands& command, const QVariant& args);
|
QVariant playerCommand(const Enums::Commands& command, const QVariant& args);
|
||||||
QVariant playerCommand(const Enums::Commands& command);
|
QVariant playerCommand(const Enums::Commands& command);
|
||||||
|
@ -82,7 +83,9 @@ public slots:
|
||||||
void cleanup();
|
void cleanup();
|
||||||
|
|
||||||
// Just used for adding missing audio devices to list.
|
// Just used for adding missing audio devices to list.
|
||||||
QVariantMap getAudioDevices() const;
|
QVariantMap getAudioDevices(const QVariant& drivers) const;
|
||||||
|
|
||||||
|
|
||||||
bool event(QEvent* event);
|
bool event(QEvent* event);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
|
@ -11,6 +11,10 @@ class BackendInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~BackendInterface(){};
|
virtual ~BackendInterface(){};
|
||||||
|
int lastTime = 0;
|
||||||
|
double lastSpeed = 0;
|
||||||
|
QString totalDurationString;
|
||||||
|
QString lastPositionString;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
// All 5 required for Player API
|
// All 5 required for Player API
|
||||||
|
@ -23,6 +27,8 @@ public slots:
|
||||||
virtual void setProperty(const QString& name, const QVariant& value) = 0;
|
virtual void setProperty(const QString& name, const QVariant& value) = 0;
|
||||||
virtual void setOption(const QString& name, const QVariant& value) = 0;
|
virtual void setOption(const QString& name, const QVariant& value) = 0;
|
||||||
virtual QVariant getProperty(const QString& name) const = 0;
|
virtual QVariant getProperty(const QString& name) const = 0;
|
||||||
|
virtual QVariantMap getAudioDevices(const QVariant& drivers) const = 0;
|
||||||
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
// All below required for Player API
|
// All below required for Player API
|
||||||
|
|
|
@ -52,7 +52,8 @@ Window {
|
||||||
id: backendSettings
|
id: backendSettings
|
||||||
category: "Backend"
|
category: "Backend"
|
||||||
property string backend: "mpv"
|
property string backend: "mpv"
|
||||||
property bool checkForUpdatesOnLaunch: true
|
property bool fbo: true
|
||||||
|
property bool direct: false
|
||||||
}
|
}
|
||||||
|
|
||||||
Settings {
|
Settings {
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
#include <QtCore>
|
#include <QtCore>
|
||||||
#include <QtNetwork>
|
#include <QtNetwork>
|
||||||
|
|
||||||
#ifdef __linux__
|
#if defined(__linux__) || defined(__FreeBSD__)
|
||||||
#ifdef ENABLE_X11
|
#ifdef ENABLE_X11
|
||||||
#include <QX11Info>
|
#include <QX11Info>
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
|
@ -83,7 +83,7 @@ SetScreensaver(WId wid, bool on)
|
||||||
void
|
void
|
||||||
SetDPMS(bool on)
|
SetDPMS(bool on)
|
||||||
{
|
{
|
||||||
#ifdef __linux__
|
#if defined(__linux__) || defined(__FreeBSD__)
|
||||||
if (getPlatformName() != "xcb") {
|
if (getPlatformName() != "xcb") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -112,13 +112,13 @@ SetDPMS(bool on)
|
||||||
void
|
void
|
||||||
AlwaysOnTop(WId wid, bool on)
|
AlwaysOnTop(WId wid, bool on)
|
||||||
{
|
{
|
||||||
#ifdef __linux__
|
#if defined(__linux__) || defined(__FreeBSD__)
|
||||||
#ifdef ENABLE_X11
|
#ifdef ENABLE_X11
|
||||||
Display* display = QX11Info::display();
|
Display* display = QX11Info::display();
|
||||||
XEvent event;
|
XEvent event;
|
||||||
event.xclient.type = ClientMessage;
|
event.xclient.type = ClientMessage;
|
||||||
event.xclient.serial = 0;
|
event.xclient.serial = 0;
|
||||||
event.xclient.send_event = True;
|
event.xclient.send_event = true;
|
||||||
event.xclient.display = display;
|
event.xclient.display = display;
|
||||||
event.xclient.window = wid;
|
event.xclient.window = wid;
|
||||||
event.xclient.message_type = XInternAtom(display, "_NET_WM_STATE", False);
|
event.xclient.message_type = XInternAtom(display, "_NET_WM_STATE", False);
|
||||||
|
|
Loading…
Reference in a new issue