Skip to content
Extraits de code Groupes Projets
MpvContainer.hh 1,96 Kio
#pragma once

#ifndef __cplusplus
#error "This is a C++ header"
#endif

#include "../../Lib/Utils.hh"

#include <functional>
#include <initializer_list>

extern "C" {
struct mpv_handle;
struct mpv_event;
}

namespace Vivy
{
class MpvContainer final : public QWidget {
    Q_OBJECT
    VIVY_UNMOVABLE_OBJECT(MpvContainer)

    enum AsyncCmdType : uint64_t {
        None,
        LoadFile,
        LoadAssFile,
        ReloadAss,
        UnloadAss,
        SeekTime,
        TogglePlayback,
    };

private:
    bool isPlaybackPaused{ true };
    mpv_handle *mpv{ nullptr };
    qint64 sid{ -1 };
    std::function<void(double)> mpvTimeCallback{ nullptr };
    std::function<void(double)> mpvDurationCallback{ nullptr };

public:
    explicit MpvContainer(QWidget *parent);
    ~MpvContainer() noexcept override;

    void loadFile(const QString &) noexcept;
    void loadAssFile(const QString &) noexcept;
    void reloadAssFile() noexcept;

    void seekInFile(const chrono::seconds time) noexcept;

    // Register a callback for time change, don't use Qt's signals for that.
    // Here the function will likely be moved if necessary (I hope...).
    void registerMpvTimeCallback(std::function<void(double)>) noexcept;
    void registerMpvDurationCallback(std::function<void(double)>) noexcept;

private:
    void handleMpvEvent(mpv_event *) noexcept;
    void closeMpv() noexcept;
    void printMpvError(int) const noexcept;
    void asyncCommand(const AsyncCmdType, std::initializer_list<const char *>) noexcept;
    void unloadAssFile() noexcept;
    void handleMpvEventCommandReply(const AsyncCmdType) noexcept;
    int getAssSid() const noexcept;

    // Must be static to be passed as a function ptr
    static void mpvEventWakeUpCB(void *) noexcept;

public slots:
    void mpvPlay() noexcept;
    void mpvPause() noexcept;
    void mpvTogglePlayback() noexcept;

private slots:
    void onMpvEvent() noexcept;

signals:
    void mpvEvent();
    void mpvPlaybackToggled(bool isPlaying);
};
}