Skip to content
Extraits de code Groupes Projets

Video playback with mpv

Fusionnées Kubat a demandé de fusionner mpv vers master
2 files
+ 113
2
Comparer les modifications
  • Côte à côte
  • En ligne

Fichiers

+ 101
0
#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);
}
}
Chargement en cours