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

[WIP] UI: Base class for MpvContainer (not tested)

parent d228532a
Aucune branche associée trouvée
Aucune étiquette associée trouvée
1 requête de fusion!15Video playback with mpv
#include "MpvContainer.hh"
#include <mpv/client.h>
using namespace Vivy;
using namespace std::string_literals;
void
MpvContainer::mpvEventWakeUpCB(void *user)
{
MpvContainer *container = reinterpret_cast<MpvContainer *>(user);
emit container->mpvEvent();
}
MpvContainer::MpvContainer()
: mpv(mpv_create())
{
if (mpv == nullptr)
throw std::runtime_error("Failed to create the MPV context");
setAttribute(Qt::WA_DontCreateNativeAncestors);
setAttribute(Qt::WA_NativeWindow);
quint64 wid = winId();
mpv_set_option(mpv, "wid", MPV_FORMAT_INT64, &wid);
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, "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)
throw std::runtime_error("Failed to initialize the mpv context");
}
MpvContainer::~MpvContainer() noexcept
{
// TODO: Do that in a private method
if (mpv) {
mpv_handle *tmp_mpv = mpv;
mpv = nullptr; // Stop all other callbacks here
mpv_destroy(tmp_mpv);
}
}
void
MpvContainer::handleMpvEvent(mpv_event *event) noexcept
{
// Declare here variables that can be used in the switch-case statements
qint64 w, h;
union {
mpv_event_log_message *msg;
mpv_event_property *prop;
mpv_handle *tmp_mpv;
};
switch (event->event_id) {
case MPV_EVENT_SHUTDOWN:
tmp_mpv = mpv;
mpv = nullptr;
mpv_destroy(mpv);
break;
case MPV_EVENT_VIDEO_RECONFIG:
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;
}
break;
case MPV_EVENT_LOG_MESSAGE:
msg = reinterpret_cast<mpv_event_log_message *>(event->data);
qDebug() << "MPV message: [" << msg->prefix << "]" << msg->level << ":" << msg->text;
break;
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!";
}
}
break;
}
}
void
MpvContainer::onMpvEvent() noexcept
{
while (mpv) {
mpv_event *event = mpv_wait_event(mpv, 0);
if (event->event_id == MPV_EVENT_NONE)
break;
handleMpvEvent(event);
}
}
......@@ -6,21 +6,31 @@
#include "../../Lib/Utils.hh"
extern "C" {
struct mpv_handle;
struct mpv_event;
}
namespace Vivy
{
class MpvContainer : public QWidget {
Q_OBJECT
VIVY_UNMOVABLE_OBJECT(MpvContainer)
private:
quint64 wid{ 0 };
mpv_handle *mpv{ nullptr };
public:
explicit MpvContainer() noexcept;
explicit MpvContainer();
~MpvContainer() noexcept override;
private:
void handleMpvEvent(mpv_event *) noexcept;
static void mpvEventWakeUpCB(void *); // Must be static for function ptr
private slots:
void onMpvEvent() noexcept;
signals:
void mpvEvent();
};
......
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter