Skip to content
Extraits de code Groupes Projets
Vérifiée Valider dff5224e rédigé par Kubat's avatar Kubat
Parcourir les fichiers

UI: Handle MPV events + set locale correctly for MPV

parent 55afbdc4
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
Ce commit fait partie de la requête de fusion !15. Les commentaires créés ici seront créés dans le contexte de cette requête de fusion.
......@@ -26,22 +26,35 @@ MpvContainer::MpvContainer()
mpv_set_option_string(mpv, "input-default-bindings", "no");
mpv_set_option_string(mpv, "input-vo-keyboard", "no");
mpv_request_log_messages(mpv, "info");
mpv_observe_property(mpv, 0, "pause", MPV_FORMAT_FLAG);
mpv_observe_property(mpv, 0, "duration", MPV_FORMAT_DOUBLE);
mpv_observe_property(mpv, 0, "time-pos", MPV_FORMAT_DOUBLE);
connect(this, &MpvContainer::mpvEvent, this, &MpvContainer::onMpvEvent, Qt::QueuedConnection);
mpv_set_wakeup_callback(mpv, &MpvContainer::mpvEventWakeUpCB, this);
if (mpv_initialize(mpv) < 0)
if (int rc = mpv_initialize(mpv); rc < 0) {
printMpvError(rc);
throw std::runtime_error("Failed to initialize the mpv context");
}
}
void
MpvContainer::registerMpvTimeCallback(void (*callback)(double)) noexcept
{
if (mpv_time_callback)
qWarning() << "Override a previous mpv callback, was" << mpv_time_callback
if (mpvTimeCallback)
qWarning() << "Override a previous mpv callback, was" << mpvTimeCallback
<< "and now will be" << callback;
mpv_time_callback = callback;
mpvTimeCallback = callback;
}
void
MpvContainer::registerMpvDurationCallback(void (*callback)(double)) noexcept
{
if (mpvDurationCallback)
qWarning() << "Override a previous mpv callback, was" << mpvDurationCallback
<< "and now will be" << callback;
mpvDurationCallback = callback;
}
void
......@@ -49,6 +62,7 @@ MpvContainer::closeMpv() noexcept
{
if (mpv) {
registerMpvTimeCallback(nullptr);
registerMpvDurationCallback(nullptr);
mpv_handle *tmp_mpv = mpv;
mpv = nullptr; // Stop all other callbacks here
mpv_destroy(tmp_mpv);
......@@ -65,17 +79,24 @@ MpvContainer::handleMpvEvent(mpv_event *event) noexcept
{
// Declare here variables that can be used in the switch-case statements
qint64 w, h;
double time;
union {
mpv_event_log_message *msg;
mpv_event_property *prop;
};
auto checkProp = [](mpv_event_property *prop, const std::string &str,
int format) noexcept -> bool {
return (prop->name == str) && (prop->format == format);
};
switch (event->event_id) {
case MPV_EVENT_SHUTDOWN:
closeMpv();
break;
case MPV_EVENT_VIDEO_RECONFIG:
// TODO: Those are sync calls, prefer async calls
if (mpv_get_property(mpv, "dwidth", MPV_FORMAT_INT64, &w) >= 0 &&
mpv_get_property(mpv, "dheight", MPV_FORMAT_INT64, &h) >= 0 && (w > 0 && h > 0)) {
qDebug() << "Reconfigure video to" << w << "x" << h;
......@@ -89,14 +110,37 @@ MpvContainer::handleMpvEvent(mpv_event *event) noexcept
case MPV_EVENT_PROPERTY_CHANGE:
prop = reinterpret_cast<mpv_event_property *>(event->data);
if (prop->name == "time-pos"s) {
if (prop->format == MPV_FORMAT_DOUBLE) {
double time = *reinterpret_cast<double *>(prop->data);
qDebug() << "Playback time:" << time;
} else {
qCritical() << "Got playback time but not a double!";
if (checkProp(prop, "time-pos"s, MPV_FORMAT_DOUBLE) && mpvTimeCallback) {
time = *reinterpret_cast<double *>(prop->data);
mpvTimeCallback(time);
}
else if (checkProp(prop, "duration"s, MPV_FORMAT_DOUBLE) && mpvDurationCallback) {
time = *reinterpret_cast<double *>(prop->data);
mpvDurationCallback(time);
}
else if (checkProp(prop, "pause"s, MPV_FORMAT_FLAG)) {
isPlaybackPaused = *reinterpret_cast<bool *>(prop->data);
emit mpvPlaybackToggled(!isPlaybackPaused);
}
break;
case MPV_EVENT_PAUSE:
isPlaybackPaused = true;
break;
case MPV_EVENT_UNPAUSE:
isPlaybackPaused = false;
break;
case MPV_EVENT_START_FILE:
qDebug() << "MPV: Begin of file";
break;
case MPV_EVENT_END_FILE:
qDebug() << "MPV: Reached end of file!";
break;
// Explicitly ignored
......@@ -104,14 +148,10 @@ MpvContainer::handleMpvEvent(mpv_event *event) noexcept
case MPV_EVENT_GET_PROPERTY_REPLY:
case MPV_EVENT_SET_PROPERTY_REPLY:
case MPV_EVENT_COMMAND_REPLY:
case MPV_EVENT_START_FILE:
case MPV_EVENT_END_FILE:
case MPV_EVENT_FILE_LOADED:
case MPV_EVENT_TRACKS_CHANGED:
case MPV_EVENT_TRACK_SWITCHED:
case MPV_EVENT_IDLE:
case MPV_EVENT_PAUSE:
case MPV_EVENT_UNPAUSE:
case MPV_EVENT_TICK:
case MPV_EVENT_SCRIPT_INPUT_DISPATCH:
case MPV_EVENT_CLIENT_MESSAGE:
......@@ -131,8 +171,46 @@ MpvContainer::onMpvEvent() noexcept
{
while (mpv) {
mpv_event *event = mpv_wait_event(mpv, 0);
if (event->event_id == MPV_EVENT_NONE)
if (event == nullptr || event->event_id == MPV_EVENT_NONE)
break;
handleMpvEvent(event);
}
}
void
MpvContainer::loadFile(const QString &filename) noexcept
{
const QByteArray c_filename = filename.toUtf8();
const char *args[] = { "loadfile", c_filename.data(), nullptr };
printMpvError(mpv_command_async(mpv, 0, args));
}
void
MpvContainer::printMpvError(int rc) const noexcept
{
if (rc == MPV_ERROR_SUCCESS)
return;
qCritical() << "MPV error:" << mpv_error_string(rc);
}
void
MpvContainer::mpvPlay() noexcept
{
if (isPlaybackPaused)
mpvTogglePlayback();
}
void
MpvContainer::mpvPause() noexcept
{
if (!isPlaybackPaused)
mpvTogglePlayback();
}
void
MpvContainer::mpvTogglePlayback() noexcept
{
const char *cmd[] = { "cycle", "pause", "up", nullptr };
printMpvError(mpv_command_async(mpv, 0, cmd));
}
......@@ -18,27 +18,39 @@ class MpvContainer : public QWidget {
VIVY_UNMOVABLE_OBJECT(MpvContainer)
private:
bool isPlaybackPaused{ true };
mpv_handle *mpv{ nullptr };
void (*mpv_time_callback)(double){ nullptr };
void (*mpvTimeCallback)(double){ nullptr };
void (*mpvDurationCallback)(double){ nullptr };
public:
explicit MpvContainer();
~MpvContainer() noexcept override;
void loadFile(const QString &) noexcept;
// Register a callback for time change, don't use Qt's signals for that.
void registerMpvTimeCallback(void (*)(double)) noexcept;
void registerMpvDurationCallback(void (*)(double)) noexcept;
private:
void handleMpvEvent(mpv_event *) noexcept;
void closeMpv() noexcept;
void printMpvError(int) const noexcept;
// Must be static to be passed as a function ptr
static void mpvEventWakeUpCB(void *) noexcept;
public slots:
void mpvPlay() noexcept;
void mpvPause() noexcept;
void mpvTogglePlayback() noexcept;
private slots:
void onMpvEvent() noexcept;
signals:
void mpvEvent();
void mpvPlaybackToggled(bool isPlaying);
};
}
......@@ -4,6 +4,7 @@
#include <QtGlobal>
#include <QIcon>
#include <QFontDatabase>
#include <locale>
using namespace Vivy;
......@@ -34,6 +35,9 @@ VivyApplication::setTheme(Theme theme) noexcept
int
VivyApplication::exec() noexcept
{
// For MPV
std::setlocale(LC_NUMERIC, "C");
// Add fonts
fontIdMonospace = QFontDatabase::addApplicationFont(":/fonts/FiraCode-Regular.ttf");
fontIdMonospaceBold = QFontDatabase::addApplicationFont(":/fonts/FiraCode-Bold.ttf");
......
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Veuillez vous inscrire ou vous pour commenter