MpvQt no video output with working audio output

Hi all,

I’ve decided to create a file previewer (yes, another one) since it seems like everyone wants one and KiView unfortunately seems stagnant and doesn’t even work for me.

So far I’ve been able to create all of the previewers I could, but I cannot for the life of me get video to play. I’ve tried with QtMultimedia, but NVIDIA says no, so I looked towards libmpv with the MpvQt wrapper that Haruna uses. I can’t seem to get video output though, and I’ve read through the source code of Haruna multiple times now and can’t find an issue. Audio works fine, I can also control the volume.

This is how it looks like:

It is fully black, which leads me to believe it is a video output issue, not that the window is too small to render.

I’ll attach some code now, but be warned: I am completely new to Qt and a lot of it was suggestions of AI. If you see any bad practices, please tell me. I’d love to get this working properly.

Here is my Main.qml:

Kirigami.ApplicationWindow
{
    id: root

    width: 1280
    height: 720

    title: i18nc("@title:window", "Maki Preview")

    Loader
    {
        width: parent.width
        height: parent.width       

        source:
        {
            switch(WindowManager.FileType)
            {
                case "image": return "ImagePreview.qml"
                case "text" : return "TextPreview.qml"
                case "audio": return "AudioPreview.qml"
                case "video": return "VideoPreview.qml"
                case "pdf"  : return "DocumentPreview.qml"
                default: return "FallbackPreview.qml"
            }
        }
    }
}

VideoPreview.qml:

import QtQuick
import QtQuick.Controls

MpvItem
{
    id: videoPlayer

    width: parent.width
    height: parent.height

    Component.onCompleted:
    {
        console.log("Videofile URL ", WindowManager.URL)

        loadFile(WindowManager.URL)
    }
}

MpvItem is my MpvAbstractItem subclass:

//Header

#pragma once

#include <MpvAbstractItem>

class MpvItem : public MpvAbstractItem
{
    Q_OBJECT
    QML_ELEMENT

public:
    explicit MpvItem(QQuickItem *parent = nullptr);

    Q_INVOKABLE void loadFile(const QUrl &url);
};

//Source
#include "MpvItem.h"

MpvItem::MpvItem(QQuickItem *parent)
    : MpvAbstractItem(parent)
{
    Q_EMIT setProperty(QStringLiteral("vo"), QStringLiteral("libmpv"));
    Q_EMIT setProperty(QStringLiteral("hwdec"), QStringLiteral("auto-safe"));
}

void MpvItem::loadFile(const QUrl &url)
{
    qWarning() << "test";

    Q_EMIT setProperty(QStringLiteral("keep-open"), QStringLiteral("always"));

    setPropertyBlocking(QStringLiteral("start"), QString::number(0));

    setPropertyBlocking(QStringLiteral("mute"), true);
    
    Q_EMIT command(QStringList() << QStringLiteral("loadfile") << url.toLocalFile());

    setPropertyBlocking(QStringLiteral("mute"), false);
}

And also my main.cpp if you need it:

#include <QApplication>
#include <QQmlApplicationEngine>
#include <QtQml>
#include <QUrl>
#include <QQuickWindow>
#include <KLocalizedContext>
#include <KLocalizedString>
#include <KIconTheme>

#include "backend/WindowManager.h"

int main(int argc, char* argv[])
{
    QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGL);
    
    KIconTheme::initTheme();

    QApplication app(argc, argv);
    QApplication::setOrganizationName  (QStringLiteral("FluxMusic"));
    QApplication::setOrganizationDomain(QStringLiteral("FluxMusic.github.io"));
    QApplication::setApplicationName   (QStringLiteral("Maki"));

    QApplication::setStyle(QStringLiteral("breeze"));

    QQmlApplicationEngine engine;

    MakiImageProvider* imageProvider = new MakiImageProvider();
    
    engine.addImageProvider(QStringLiteral("Maki"), imageProvider);
    engine.rootContext()->setContextObject(new KLocalizedContext(&engine));
    engine.loadFromModule("io.github.FluxMusic.Maki", "Main");
    
    WindowManager* manager = engine.singletonInstance<WindowManager*>("io.github.FluxMusic.Maki", "WindowManager");
    
    if (manager)
    {
        manager->setImageProvider(imageProvider);

        if (app.arguments().size() > 1)
        {
            manager->setURL(QUrl::fromUserInput(app.arguments()[1]));
        }
        else
        {
            qWarning() << "no arguments provided";
        }
    }
    else
    {
        qWarning() << "nullptr";
    }

    return app.exec();
}

As you can probably see, I’ve gone completely out of my comfort zone, I haven’t used libmpv before either.

If there is anything else you need, please let me know. I’d really like to fix this.

MpvItem
{
    id: videoPlayer

    Component.onCompleted:
    {
        loadFile(WindowManager.URL)
    }
}

Don’t use Component.onCompleted use onReady

Thank you so much! That was the issue.

I do have to apologize. I completely missed the comment in the wrapper where they specify not to load from Component.onCompleted. I’m sorry.

I’ll finish this and then open a new post to show the program, maybe I can actually get this to work as a proper file previewer.