diff --git a/rsc/VivyRessources.qrc b/rsc/VivyRessources.qrc index f86514d871aa19755d64bb9729a9771dad6b6240..339d6316139e709454293e73863364962515a386 100644 --- a/rsc/VivyRessources.qrc +++ b/rsc/VivyRessources.qrc @@ -40,6 +40,7 @@ <file alias="media-pause.svg">icons/breeze-dark/media-playback-pause.svg</file> <file alias="media-play.svg">icons/breeze-dark/media-playback-start.svg</file> <file alias="media-stop.svg">icons/breeze-dark/media-playback-stop.svg</file> + <file alias="run.svg">icons/breeze-dark/run-build-file.svg</file> </qresource> <qresource prefix="icons/light"> <file alias="document-new.svg">icons/breeze-light/document-new.svg</file> @@ -53,6 +54,7 @@ <file alias="media-pause.svg">icons/breeze-light/media-playback-pause.svg</file> <file alias="media-play.svg">icons/breeze-light/media-playback-start.svg</file> <file alias="media-stop.svg">icons/breeze-light/media-playback-stop.svg</file> + <file alias="run.svg">icons/breeze-light/run-build-file.svg</file> </qresource> <!-- QDarkStyle style sheet, MIT Licence --> diff --git a/src/UI/DocumentViews/MpvContainer.cc b/src/UI/DocumentViews/MpvContainer.cc index b0e712e1368b9ca8807b80cbac990369e8f0c663..dc0fc9f112d706aa3e7706d5a4c98a4ba0fab88d 100644 --- a/src/UI/DocumentViews/MpvContainer.cc +++ b/src/UI/DocumentViews/MpvContainer.cc @@ -19,10 +19,12 @@ MpvContainer::MpvContainer(QWidget *parent) setAttribute(Qt::WA_DontCreateNativeAncestors); setAttribute(Qt::WA_NativeWindow); + + initializeMpv(); } void -MpvContainer::intializeMpv() +MpvContainer::initializeMpv() { if (isMpvAlreadyInitialized) throw std::logic_error("MPV is already initialized!"); @@ -42,13 +44,24 @@ MpvContainer::intializeMpv() mpv_observe_property(mpv, 0, "duration", MPV_FORMAT_DOUBLE); 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 (int rc = mpv_initialize(mpv); rc < 0) { printMpvError(rc); throw std::runtime_error("Failed to initialize the mpv context"); } +} - connect(this, &MpvContainer::mpvEvent, this, &MpvContainer::onMpvEvent, Qt::QueuedConnection); - mpv_set_wakeup_callback(mpv, &MpvContainer::mpvEventWakeUpCB, this); +void +MpvContainer::reCreateMpvContext() +{ + closeMpv(); + mpv = mpv_create(); + if (mpv == nullptr) + throw std::runtime_error("Failed to create the MPV context"); + initializeMpv(); + loadFile(previousLoadedFile); } void @@ -74,11 +87,10 @@ MpvContainer::closeMpv() noexcept qDebug() << "Closing the MPV context"; registerMpvTimeCallback(nullptr); registerMpvDurationCallback(nullptr); - mpv_handle *tmp_mpv = mpv; - mpv = nullptr; // Stop all other callbacks here - mpv_destroy(tmp_mpv); - // mpv_wait_async_requests(tmp_mpv); - // mpv_terminate_destroy(tmp_mpv); + mpv_wait_async_requests(mpv); + mpv_terminate_destroy(mpv); + mpv = nullptr; // Stop all other callbacks here + isMpvAlreadyInitialized = false; // De-init } } @@ -233,10 +245,12 @@ MpvContainer::onMpvEvent() noexcept void MpvContainer::loadFile(const QString &filename) noexcept { - qDebug() << "Loading file" << filename; if (filename.size() == 0) return; + qDebug() << "Loading file" << filename; + if (previousLoadedFile != filename) + previousLoadedFile = filename; const QByteArray cFileName = filename.toUtf8(); asyncCommand(AsyncCmdType::LoadFile, { "loadfile", cFileName.data(), nullptr }); } diff --git a/src/UI/DocumentViews/MpvContainer.hh b/src/UI/DocumentViews/MpvContainer.hh index f44d2359b595720ba8c542f71d592c861146ef7c..58f9ce9418218b5e0fc294e7d47fd9f716155d84 100644 --- a/src/UI/DocumentViews/MpvContainer.hh +++ b/src/UI/DocumentViews/MpvContainer.hh @@ -27,17 +27,8 @@ class MpvContainer final : public QWidget { TogglePlayback }; -private: - bool isPlaybackPaused{ true }; - bool isMpvAlreadyInitialized{ false }; - mpv_handle *volatile mpv{ nullptr }; - qint64 sid{ -1 }; - std::function<void(double)> mpvTimeCallback{ nullptr }; - std::function<void(double)> mpvDurationCallback{ nullptr }; - public: explicit MpvContainer(QWidget *parent); - void intializeMpv(); ~MpvContainer() noexcept override; void loadFile(const QString &) noexcept; @@ -52,6 +43,7 @@ public: void registerMpvDurationCallback(std::function<void(double)>) noexcept; private: + void initializeMpv(); void handleMpvEvent(const mpv_event *const) noexcept; void closeMpv() noexcept; void printMpvError(int) const noexcept; @@ -63,10 +55,19 @@ private: // Must be static to be passed as a function ptr static void mpvEventWakeUpCB(void *) noexcept; + bool isPlaybackPaused{ true }; + bool isMpvAlreadyInitialized{ false }; + mpv_handle *volatile mpv{ nullptr }; + qint64 sid{ -1 }; + QString previousLoadedFile{}; + std::function<void(double)> mpvTimeCallback{ nullptr }; + std::function<void(double)> mpvDurationCallback{ nullptr }; + public slots: void mpvPlay() noexcept; void mpvPause() noexcept; void mpvTogglePlayback() noexcept; + void reCreateMpvContext(); private slots: void onMpvEvent() noexcept; diff --git a/src/UI/DocumentViews/MpvControls.cc b/src/UI/DocumentViews/MpvControls.cc index 931239ac66d8dd4ed04255ac40f46ca73699c50c..01d4cabe04e293bb16b9fb0b1e20147db57c100f 100644 --- a/src/UI/DocumentViews/MpvControls.cc +++ b/src/UI/DocumentViews/MpvControls.cc @@ -9,6 +9,8 @@ MpvControls::MpvControls(MpvContainer *passedContainer, QWidget *parent) noexcep { auto *progressBar = new QSlider(this); auto *togglePlaybackButton = new QPushButton(playIcon, "", this); // Be default MPV is paused + auto *reCreateMpvButton = new QPushButton( + reCreateMpvIcon, "", this); // Recreate the MPV context if something went wrong progressBar->setTracking(false); progressBar->setOrientation(Qt::Horizontal); @@ -55,6 +57,7 @@ MpvControls::MpvControls(MpvContainer *passedContainer, QWidget *parent) noexcep }); connect(togglePlaybackButton, &QAbstractButton::clicked, mpv, &MpvContainer::mpvTogglePlayback); + connect(reCreateMpvButton, &QAbstractButton::clicked, mpv, &MpvContainer::reCreateMpvContext); connect(mpv, &MpvContainer::mpvPlaybackToggled, this, [this, togglePlaybackButton](bool isPlay) noexcept -> void { togglePlaybackButton->setIcon(isPlay ? pauseIcon : playIcon); @@ -62,6 +65,7 @@ MpvControls::MpvControls(MpvContainer *passedContainer, QWidget *parent) noexcep auto *centralLayout = new QHBoxLayout(this); centralLayout->addWidget(togglePlaybackButton); + centralLayout->addWidget(reCreateMpvButton); centralLayout->addWidget(progressBar, 1); setLayout(centralLayout); } diff --git a/src/UI/DocumentViews/MpvControls.hh b/src/UI/DocumentViews/MpvControls.hh index 51b1e127450c31a2fd291c46db08b5663aa05f38..ab628ffcd73145cd6d082e31382767cb00f45444 100644 --- a/src/UI/DocumentViews/MpvControls.hh +++ b/src/UI/DocumentViews/MpvControls.hh @@ -23,6 +23,7 @@ private: const QIcon playIcon{ VIVY_ICON_PLAY }; const QIcon pauseIcon{ VIVY_ICON_PAUSE }; + const QIcon reCreateMpvIcon{ VIVY_ICON_RUN }; public: explicit MpvControls(MpvContainer *mpv, QWidget *parent) noexcept; diff --git a/src/UI/DocumentViews/VideoView.cc b/src/UI/DocumentViews/VideoView.cc index 2e45fcfdb9c6d354cef88da731a80c19d971122c..30eee0e0863deaac58c2187232336f20395939a0 100644 --- a/src/UI/DocumentViews/VideoView.cc +++ b/src/UI/DocumentViews/VideoView.cc @@ -14,8 +14,6 @@ VideoView::VideoView(QWidget *parent) noexcept centralLayout->addWidget(new MpvControls(mpv, this)); setLayout(centralLayout); - - mpv->intializeMpv(); } void diff --git a/src/VivyApplication.hh b/src/VivyApplication.hh index 0bfa830a8a20267695db7d08faf19f7ed076da55..a9c78372a827e2e36aa1e2eb9aa14995a95f0c06 100644 --- a/src/VivyApplication.hh +++ b/src/VivyApplication.hh @@ -23,6 +23,7 @@ #define VIVY_ICON_PLAY ":icons/dark/media-play.svg" #define VIVY_ICON_PAUSE ":icons/dark/media-pause.svg" #define VIVY_ICON_STOP ":icons/dark/media-stop.svg" +#define VIVY_ICON_RUN ":icons/dark/run.svg" // Detect MacOS #if defined(Q_OS_DARWIN) || defined(Q_OS_MACOS)