Lots of changes.
This commit is contained in:
parent
08e9fcf55a
commit
67df0fd242
|
@ -33,7 +33,7 @@ unix {
|
||||||
|
|
||||||
INSTALLS += target
|
INSTALLS += target
|
||||||
|
|
||||||
HEADERS += src/main.h src/mpvobject.h src/config.h
|
HEADERS += src/mpvobject.h src/config.h
|
||||||
|
|
||||||
|
|
||||||
DISTFILES += KittehPlayer.desktop KittehPlayer.png README.md LICENSE.txt
|
DISTFILES += KittehPlayer.desktop KittehPlayer.png README.md LICENSE.txt
|
||||||
|
|
|
@ -4,11 +4,9 @@
|
||||||
#include <mpv/client.h>
|
#include <mpv/client.h>
|
||||||
|
|
||||||
#if MPV_CLIENT_API_VERSION >= MPV_MAKE_VERSION(1, 28)
|
#if MPV_CLIENT_API_VERSION >= MPV_MAKE_VERSION(1, 28)
|
||||||
#define USE_RENDER
|
// good
|
||||||
#else
|
#else
|
||||||
#warning "Using deprecated MPV..."
|
#error "Old MPV versions without render API are not supported."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif // CONFIG_H
|
#endif // CONFIG_H
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
#ifndef MAIN_H
|
|
||||||
#define MAIN_H
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif // MAIN_H
|
|
|
@ -29,7 +29,6 @@ void wakeup(void *ctx)
|
||||||
QMetaObject::invokeMethod((MpvObject*)ctx, "on_mpv_events", Qt::QueuedConnection);
|
QMetaObject::invokeMethod((MpvObject*)ctx, "on_mpv_events", Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_RENDER
|
|
||||||
void on_mpv_redraw(void *ctx)
|
void on_mpv_redraw(void *ctx)
|
||||||
{
|
{
|
||||||
MpvObject::on_update(ctx);
|
MpvObject::on_update(ctx);
|
||||||
|
@ -44,37 +43,22 @@ static void *get_proc_address_mpv(void *ctx, const char *name)
|
||||||
|
|
||||||
return reinterpret_cast<void *>(glctx->getProcAddress(QByteArray(name)));
|
return reinterpret_cast<void *>(glctx->getProcAddress(QByteArray(name)));
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class MpvRenderer : public QQuickFramebufferObject::Renderer
|
class MpvRenderer : public QQuickFramebufferObject::Renderer
|
||||||
{
|
{
|
||||||
#ifdef USE_RENDER
|
|
||||||
MpvObject *obj;
|
MpvObject *obj;
|
||||||
#else
|
|
||||||
static void *get_proc_address(void *ctx, const char *name) {
|
|
||||||
(void)ctx;
|
|
||||||
QOpenGLContext *glctx = QOpenGLContext::currentContext();
|
|
||||||
if (!glctx)
|
|
||||||
return NULL;
|
|
||||||
return (void *)glctx->getProcAddress(QByteArray(name));
|
|
||||||
}
|
|
||||||
mpv::qt::Handle mpv;
|
|
||||||
QQuickWindow *window;
|
|
||||||
mpv_opengl_cb_context *mpv_gl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
#ifdef USE_RENDER
|
|
||||||
|
|
||||||
MpvRenderer(MpvObject *new_obj)
|
MpvRenderer(MpvObject *new_obj)
|
||||||
: obj{new_obj}
|
: obj{new_obj}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual ~MpvRenderer() {}
|
virtual ~MpvRenderer() {}
|
||||||
|
|
||||||
// This function is called when a new FBO is needed.
|
// This function is called when a new FBO is needed.
|
||||||
|
@ -99,28 +83,10 @@ public:
|
||||||
return QQuickFramebufferObject::Renderer::createFramebufferObject(size);
|
return QQuickFramebufferObject::Renderer::createFramebufferObject(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
MpvRenderer(const MpvObject *obj)
|
|
||||||
: mpv(obj->mpv), window(obj->window()), mpv_gl(obj->mpv_gl)
|
|
||||||
{
|
|
||||||
int r = mpv_opengl_cb_init_gl(mpv_gl, NULL, get_proc_address, NULL);
|
|
||||||
if (r < 0)
|
|
||||||
throw std::runtime_error("could not initialize OpenGL");
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~MpvRenderer() {
|
|
||||||
mpv_opengl_cb_uninit_gl(mpv_gl);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void render()
|
void render()
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifdef USE_RENDER
|
|
||||||
obj->window()->resetOpenGLState();
|
obj->window()->resetOpenGLState();
|
||||||
|
|
||||||
QOpenGLFramebufferObject *fbo = framebufferObject();
|
QOpenGLFramebufferObject *fbo = framebufferObject();
|
||||||
|
@ -141,68 +107,33 @@ public:
|
||||||
// other API details.
|
// other API details.
|
||||||
mpv_render_context_render(obj->mpv_gl, params);
|
mpv_render_context_render(obj->mpv_gl, params);
|
||||||
obj->window()->resetOpenGLState();
|
obj->window()->resetOpenGLState();
|
||||||
#else
|
|
||||||
QOpenGLFramebufferObject *fbo = framebufferObject();
|
|
||||||
window->resetOpenGLState();
|
|
||||||
mpv_opengl_cb_draw(mpv_gl, fbo->handle(), fbo->width(), fbo->height());
|
|
||||||
window->resetOpenGLState();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
MpvObject::MpvObject(QQuickItem * parent)
|
MpvObject::MpvObject(QQuickItem * parent)
|
||||||
#ifdef USE_RENDER
|
|
||||||
: QQuickFramebufferObject(parent), mpv{mpv_create()}, mpv_gl(nullptr)
|
: QQuickFramebufferObject(parent), mpv{mpv_create()}, mpv_gl(nullptr)
|
||||||
#else
|
|
||||||
: QQuickFramebufferObject(parent), mpv_gl(0)
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
#ifndef USE_RENDER
|
|
||||||
mpv = mpv::qt::Handle::FromRawHandle(mpv_create());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
if (!mpv)
|
if (!mpv)
|
||||||
throw std::runtime_error("could not create mpv context");
|
throw std::runtime_error("could not create mpv context");
|
||||||
|
|
||||||
mpv_set_option_string(mpv, "terminal", "yes");
|
mpv_set_option_string(mpv, "terminal", "yes");
|
||||||
mpv_set_option_string(mpv, "msg-level", "all=v");
|
mpv_set_option_string(mpv, "msg-level", "all=v");
|
||||||
|
|
||||||
if (mpv_initialize(mpv) < 0)
|
|
||||||
throw std::runtime_error("could not initialize mpv context");
|
|
||||||
|
|
||||||
#ifndef USE_RENDER
|
|
||||||
mpv::qt::set_option_variant(mpv, "vo", "opengl-cb");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Enable default bindings, because we're lazy. Normally, a player using
|
|
||||||
// mpv as backend would implement its own key bindings.
|
|
||||||
// mpv_set_option_string(mpv, "input-default-bindings", "yes");
|
|
||||||
|
|
||||||
// Enable keyboard input on the X11 window. For the messy details, see
|
|
||||||
// --input-vo-keyboard on the manpage.
|
|
||||||
// mpv_set_option_string(mpv, "input-vo-keyboard", "yes");
|
|
||||||
|
|
||||||
// Fix?
|
// Fix?
|
||||||
mpv::qt::set_option_variant(mpv, "ytdl", "yes");
|
//mpv_set_option_string(mpv, "ytdl", "yes");
|
||||||
|
mpv_set_option_string(mpv, "vo", "libmpv");
|
||||||
|
|
||||||
mpv_set_option_string(mpv, "input-default-bindings", "yes");
|
mpv_set_option_string(mpv, "slang", "en");
|
||||||
mpv_set_option_string(mpv, "input-vo-keyboard", "yes");
|
mpv_set_option_string(mpv, "sub-font", "Noto Sans");
|
||||||
|
mpv_set_option_string(mpv, "sub-ass-override", "force");
|
||||||
|
mpv_set_option_string(mpv, "sub-ass", "off");
|
||||||
|
mpv_set_option_string(mpv, "sub-border-size", "0");
|
||||||
|
mpv_set_option_string(mpv, "sub-bold", "off");
|
||||||
|
mpv_set_option_string(mpv, "sub-scale-by-window", "on");
|
||||||
|
mpv_set_option_string(mpv, "sub-scale-with-window", "on");
|
||||||
|
|
||||||
|
mpv_set_option_string(mpv, "sub-back-color", "#C0080808");
|
||||||
mpv::qt::set_option_variant(mpv, "hwdec", "off");
|
|
||||||
mpv::qt::set_option_variant(mpv, "slang", "en");
|
|
||||||
mpv::qt::set_option_variant(mpv, "sub-font", "Noto Sans");
|
|
||||||
mpv::qt::set_option_variant(mpv, "sub-ass-override", "force");
|
|
||||||
mpv::qt::set_option_variant(mpv, "sub-ass", "off");
|
|
||||||
mpv::qt::set_option_variant(mpv, "sub-border-size", "0");
|
|
||||||
mpv::qt::set_option_variant(mpv, "sub-bold", "off");
|
|
||||||
mpv::qt::set_option_variant(mpv, "sub-scale-by-window", "on");
|
|
||||||
mpv::qt::set_option_variant(mpv, "sub-scale-with-window", "on");
|
|
||||||
|
|
||||||
mpv::qt::set_option_variant(mpv, "sub-back-color", "#C0080808");
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -217,32 +148,22 @@ MpvObject::MpvObject(QQuickItem * parent)
|
||||||
|
|
||||||
mpv_set_wakeup_callback(mpv, wakeup, this);
|
mpv_set_wakeup_callback(mpv, wakeup, this);
|
||||||
|
|
||||||
#ifndef USE_RENDER
|
if (mpv_initialize(mpv) < 0)
|
||||||
mpv_gl = (mpv_opengl_cb_context *)mpv_get_sub_api(mpv, MPV_SUB_API_OPENGL_CB);
|
throw std::runtime_error("could not initialize mpv context");
|
||||||
if (!mpv_gl)
|
|
||||||
throw std::runtime_error("OpenGL not compiled in");
|
|
||||||
mpv_opengl_cb_set_update_callback(mpv_gl, MpvObject::on_update, (void *)this);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
mpv::qt::set_option_variant(mpv, "idle", "once");
|
|
||||||
|
|
||||||
connect(this, &MpvObject::onUpdate, this, &MpvObject::doUpdate,
|
connect(this, &MpvObject::onUpdate, this, &MpvObject::doUpdate,
|
||||||
Qt::QueuedConnection);
|
Qt::QueuedConnection);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MpvObject::~MpvObject()
|
MpvObject::~MpvObject()
|
||||||
{
|
{
|
||||||
#ifdef USE_RENDER
|
|
||||||
if (mpv_gl)
|
if (mpv_gl)
|
||||||
{
|
{
|
||||||
mpv_render_context_free(mpv_gl);
|
mpv_render_context_free(mpv_gl);
|
||||||
}
|
}
|
||||||
|
|
||||||
mpv_terminate_destroy(mpv);
|
mpv_terminate_destroy(mpv);
|
||||||
#else
|
|
||||||
if (mpv_gl)
|
|
||||||
mpv_opengl_cb_set_update_callback(mpv_gl, NULL, NULL);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MpvObject::on_update(void *ctx)
|
void MpvObject::on_update(void *ctx)
|
||||||
|
@ -332,9 +253,6 @@ QQuickFramebufferObject::Renderer *MpvObject::createRenderer() const
|
||||||
{
|
{
|
||||||
window()->setPersistentOpenGLContext(true);
|
window()->setPersistentOpenGLContext(true);
|
||||||
window()->setPersistentSceneGraph(true);
|
window()->setPersistentSceneGraph(true);
|
||||||
#ifdef USE_RENDER
|
|
||||||
return new MpvRenderer(const_cast<MpvObject *>(this));
|
return new MpvRenderer(const_cast<MpvObject *>(this));
|
||||||
#else
|
|
||||||
return new MpvRenderer(this);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,15 +3,9 @@
|
||||||
|
|
||||||
#include <QQuickFramebufferObject>
|
#include <QQuickFramebufferObject>
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
#include <mpv/client.h>
|
#include <mpv/client.h>
|
||||||
|
|
||||||
#ifdef USE_RENDER
|
|
||||||
#include <mpv/render_gl.h>
|
#include <mpv/render_gl.h>
|
||||||
#else
|
|
||||||
#include <mpv/opengl_cb.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <mpv/qthelper.hpp>
|
#include <mpv/qthelper.hpp>
|
||||||
|
|
||||||
|
@ -25,20 +19,14 @@
|
||||||
#include <QtQuick/QQuickWindow>
|
#include <QtQuick/QQuickWindow>
|
||||||
#include <QtQuick/QQuickView>
|
#include <QtQuick/QQuickView>
|
||||||
|
|
||||||
#include <QProcess>
|
|
||||||
|
|
||||||
class MpvRenderer;
|
class MpvRenderer;
|
||||||
|
|
||||||
class MpvObject : public QQuickFramebufferObject
|
class MpvObject : public QQuickFramebufferObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
#ifdef USE_RENDER
|
|
||||||
mpv_handle *mpv;
|
mpv_handle *mpv;
|
||||||
mpv_render_context *mpv_gl;
|
mpv_render_context *mpv_gl;
|
||||||
#else
|
|
||||||
mpv::qt::Handle mpv;
|
|
||||||
mpv_opengl_cb_context *mpv_gl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
friend class MpvRenderer;
|
friend class MpvRenderer;
|
||||||
|
|
||||||
|
|
|
@ -134,6 +134,17 @@ Window {
|
||||||
source: "fonts/NotoSans.ttf"
|
source: "fonts/NotoSans.ttf"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: initTimer
|
||||||
|
interval: 2000
|
||||||
|
running: false
|
||||||
|
repeat: false
|
||||||
|
onTriggered: {
|
||||||
|
renderer.startPlayer()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Component.onCompleted: { initTimer.start() }
|
||||||
|
|
||||||
function startPlayer() {
|
function startPlayer() {
|
||||||
var args = Qt.application.arguments
|
var args = Qt.application.arguments
|
||||||
var len = Qt.application.arguments.length
|
var len = Qt.application.arguments.length
|
||||||
|
@ -158,7 +169,7 @@ Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
renderer.command(["loadfile", argument, "append-play"])
|
renderer.command(["loadfile", argument])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -191,11 +202,13 @@ Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
function hideControls() {
|
function hideControls() {
|
||||||
renderer.setOption("sub-margin-y", "22")
|
if (! subtitlesMenu.visible) {
|
||||||
controlsBar.visible = false
|
renderer.setOption("sub-margin-y", "22")
|
||||||
controlsBackground.visible = false
|
controlsBar.visible = false
|
||||||
titleBar.visible = false
|
controlsBackground.visible = false
|
||||||
titleBackground.visible = false
|
titleBar.visible = false
|
||||||
|
titleBackground.visible = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function showControls() {
|
function showControls() {
|
||||||
|
@ -211,17 +224,51 @@ Window {
|
||||||
Dialog {
|
Dialog {
|
||||||
id: loadDialog
|
id: loadDialog
|
||||||
title: "URL / File Path"
|
title: "URL / File Path"
|
||||||
standardButtons: StandardButton.Cancel | StandardButton.Open
|
FileDialog {
|
||||||
|
id: fileDialog
|
||||||
onAccepted: {
|
title: "Please choose a file"
|
||||||
renderer.command(["loadfile", pathText.text])
|
folder: shortcuts.home
|
||||||
pathText.text = ""
|
onAccepted: {
|
||||||
|
renderer.command(["loadfile", String(fileDialog.fileUrl)])
|
||||||
|
loadDialog.close()
|
||||||
|
}
|
||||||
|
onRejected: {
|
||||||
|
fileDialog.close()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
contentItem: Rectangle {
|
||||||
TextField {
|
implicitWidth: 150
|
||||||
id: pathText
|
implicitHeight: 200
|
||||||
text: "/home/kitteh/test.mkv"
|
anchors.fill: parent
|
||||||
placeholderText: qsTr("URL / File Path")
|
TextField {
|
||||||
|
id: pathText
|
||||||
|
placeholderText: qsTr("URL / File Path")
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
id: fileChooserButton
|
||||||
|
flat: false
|
||||||
|
anchors.top: pathText.bottom;
|
||||||
|
text: "File Chooser"
|
||||||
|
onClicked: fileDialog.open()
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
flat: false
|
||||||
|
id: loadOKButton
|
||||||
|
anchors.top: fileChooserButton.bottom;
|
||||||
|
text: "OK"
|
||||||
|
onClicked: {
|
||||||
|
renderer.command(["loadfile", pathText.text])
|
||||||
|
loadDialog.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
flat: false
|
||||||
|
anchors.top: loadOKButton.bottom;
|
||||||
|
text: "Cancel"
|
||||||
|
onClicked: {
|
||||||
|
loadDialog.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,7 +298,13 @@ Window {
|
||||||
anchors.top: titleBar.bottom
|
anchors.top: titleBar.bottom
|
||||||
anchors.topMargin: 0
|
anchors.topMargin: 0
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
onClicked: loadDialog.open()
|
onClicked: {
|
||||||
|
renderer.command(["cycle", "pause"])
|
||||||
|
updateControls()
|
||||||
|
}
|
||||||
|
onDoubleClicked: {
|
||||||
|
loadDialog.open()
|
||||||
|
}
|
||||||
Timer {
|
Timer {
|
||||||
id: mouseAreaPlayerTimer
|
id: mouseAreaPlayerTimer
|
||||||
interval: 1000
|
interval: 1000
|
||||||
|
@ -692,6 +745,5 @@ Window {
|
||||||
updateControls()
|
updateControls()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Component.onCompleted: { startPlayer() }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue