Lots of changes.
This commit is contained in:
parent
08e9fcf55a
commit
67df0fd242
|
@ -33,7 +33,7 @@ unix {
|
|||
|
||||
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
|
||||
|
|
|
@ -4,11 +4,9 @@
|
|||
#include <mpv/client.h>
|
||||
|
||||
#if MPV_CLIENT_API_VERSION >= MPV_MAKE_VERSION(1, 28)
|
||||
#define USE_RENDER
|
||||
// good
|
||||
#else
|
||||
#warning "Using deprecated MPV..."
|
||||
#error "Old MPV versions without render API are not supported."
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
#ifdef USE_RENDER
|
||||
void on_mpv_redraw(void *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)));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
class MpvRenderer : public QQuickFramebufferObject::Renderer
|
||||
{
|
||||
#ifdef USE_RENDER
|
||||
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
|
||||
MpvObject *obj;
|
||||
|
||||
public:
|
||||
|
||||
#ifdef USE_RENDER
|
||||
|
||||
MpvRenderer(MpvObject *new_obj)
|
||||
: obj{new_obj}
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
virtual ~MpvRenderer() {}
|
||||
|
||||
// This function is called when a new FBO is needed.
|
||||
|
@ -99,28 +83,10 @@ public:
|
|||
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()
|
||||
{
|
||||
|
||||
#ifdef USE_RENDER
|
||||
obj->window()->resetOpenGLState();
|
||||
|
||||
QOpenGLFramebufferObject *fbo = framebufferObject();
|
||||
|
@ -141,68 +107,33 @@ public:
|
|||
// other API details.
|
||||
mpv_render_context_render(obj->mpv_gl, params);
|
||||
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)
|
||||
#ifdef USE_RENDER
|
||||
: 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)
|
||||
throw std::runtime_error("could not create mpv context");
|
||||
|
||||
mpv_set_option_string(mpv, "terminal", "yes");
|
||||
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?
|
||||
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, "input-vo-keyboard", "yes");
|
||||
mpv_set_option_string(mpv, "slang", "en");
|
||||
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::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");
|
||||
mpv_set_option_string(mpv, "sub-back-color", "#C0080808");
|
||||
|
||||
|
||||
|
||||
|
@ -217,32 +148,22 @@ MpvObject::MpvObject(QQuickItem * parent)
|
|||
|
||||
mpv_set_wakeup_callback(mpv, wakeup, this);
|
||||
|
||||
#ifndef USE_RENDER
|
||||
mpv_gl = (mpv_opengl_cb_context *)mpv_get_sub_api(mpv, MPV_SUB_API_OPENGL_CB);
|
||||
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");
|
||||
if (mpv_initialize(mpv) < 0)
|
||||
throw std::runtime_error("could not initialize mpv context");
|
||||
|
||||
connect(this, &MpvObject::onUpdate, this, &MpvObject::doUpdate,
|
||||
Qt::QueuedConnection);
|
||||
|
||||
}
|
||||
|
||||
MpvObject::~MpvObject()
|
||||
{
|
||||
#ifdef USE_RENDER
|
||||
if (mpv_gl)
|
||||
{
|
||||
mpv_render_context_free(mpv_gl);
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -332,9 +253,6 @@ QQuickFramebufferObject::Renderer *MpvObject::createRenderer() const
|
|||
{
|
||||
window()->setPersistentOpenGLContext(true);
|
||||
window()->setPersistentSceneGraph(true);
|
||||
#ifdef USE_RENDER
|
||||
|
||||
return new MpvRenderer(const_cast<MpvObject *>(this));
|
||||
#else
|
||||
return new MpvRenderer(this);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -3,15 +3,9 @@
|
|||
|
||||
#include <QQuickFramebufferObject>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <mpv/client.h>
|
||||
|
||||
#ifdef USE_RENDER
|
||||
#include <mpv/render_gl.h>
|
||||
#else
|
||||
#include <mpv/opengl_cb.h>
|
||||
#endif
|
||||
|
||||
#include <mpv/qthelper.hpp>
|
||||
|
||||
|
@ -25,20 +19,14 @@
|
|||
#include <QtQuick/QQuickWindow>
|
||||
#include <QtQuick/QQuickView>
|
||||
|
||||
#include <QProcess>
|
||||
|
||||
class MpvRenderer;
|
||||
|
||||
class MpvObject : public QQuickFramebufferObject
|
||||
{
|
||||
Q_OBJECT
|
||||
#ifdef USE_RENDER
|
||||
mpv_handle *mpv;
|
||||
mpv_render_context *mpv_gl;
|
||||
#else
|
||||
mpv::qt::Handle mpv;
|
||||
mpv_opengl_cb_context *mpv_gl;
|
||||
#endif
|
||||
|
||||
friend class MpvRenderer;
|
||||
|
||||
|
|
|
@ -134,6 +134,17 @@ Window {
|
|||
source: "fonts/NotoSans.ttf"
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: initTimer
|
||||
interval: 2000
|
||||
running: false
|
||||
repeat: false
|
||||
onTriggered: {
|
||||
renderer.startPlayer()
|
||||
}
|
||||
}
|
||||
Component.onCompleted: { initTimer.start() }
|
||||
|
||||
function startPlayer() {
|
||||
var args = Qt.application.arguments
|
||||
var len = Qt.application.arguments.length
|
||||
|
@ -158,7 +169,7 @@ Window {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
renderer.command(["loadfile", argument, "append-play"])
|
||||
renderer.command(["loadfile", argument])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -191,11 +202,13 @@ Window {
|
|||
}
|
||||
|
||||
function hideControls() {
|
||||
renderer.setOption("sub-margin-y", "22")
|
||||
controlsBar.visible = false
|
||||
controlsBackground.visible = false
|
||||
titleBar.visible = false
|
||||
titleBackground.visible = false
|
||||
if (! subtitlesMenu.visible) {
|
||||
renderer.setOption("sub-margin-y", "22")
|
||||
controlsBar.visible = false
|
||||
controlsBackground.visible = false
|
||||
titleBar.visible = false
|
||||
titleBackground.visible = false
|
||||
}
|
||||
}
|
||||
|
||||
function showControls() {
|
||||
|
@ -211,17 +224,51 @@ Window {
|
|||
Dialog {
|
||||
id: loadDialog
|
||||
title: "URL / File Path"
|
||||
standardButtons: StandardButton.Cancel | StandardButton.Open
|
||||
|
||||
onAccepted: {
|
||||
renderer.command(["loadfile", pathText.text])
|
||||
pathText.text = ""
|
||||
FileDialog {
|
||||
id: fileDialog
|
||||
title: "Please choose a file"
|
||||
folder: shortcuts.home
|
||||
onAccepted: {
|
||||
renderer.command(["loadfile", String(fileDialog.fileUrl)])
|
||||
loadDialog.close()
|
||||
}
|
||||
onRejected: {
|
||||
fileDialog.close()
|
||||
}
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: pathText
|
||||
text: "/home/kitteh/test.mkv"
|
||||
placeholderText: qsTr("URL / File Path")
|
||||
contentItem: Rectangle {
|
||||
implicitWidth: 150
|
||||
implicitHeight: 200
|
||||
anchors.fill: parent
|
||||
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.topMargin: 0
|
||||
hoverEnabled: true
|
||||
onClicked: loadDialog.open()
|
||||
onClicked: {
|
||||
renderer.command(["cycle", "pause"])
|
||||
updateControls()
|
||||
}
|
||||
onDoubleClicked: {
|
||||
loadDialog.open()
|
||||
}
|
||||
Timer {
|
||||
id: mouseAreaPlayerTimer
|
||||
interval: 1000
|
||||
|
@ -692,6 +745,5 @@ Window {
|
|||
updateControls()
|
||||
}
|
||||
}
|
||||
Component.onCompleted: { startPlayer() }
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue