From 82d6594562f3659e8c456f657dee50c0326ba57c Mon Sep 17 00:00:00 2001 From: KG Date: Fri, 21 Jun 2024 00:40:26 +1000 Subject: [PATCH 1/9] changed WCHAR to char if on Qt 5.15.13+ to get it compiling on the mac. also references to network_downloader.h and download_manager.h removed since they don't exist yet --- src/draudiostream.cpp | 4 ++++ src/lobby.cpp | 3 +++ src/modules/managers/audio_manager.cpp | 3 +++ src/modules/scenes/replay_scene.cpp | 3 +++ 4 files changed, 13 insertions(+) diff --git a/src/draudiostream.cpp b/src/draudiostream.cpp index 2466a55fc..8c650120f 100644 --- a/src/draudiostream.cpp +++ b/src/draudiostream.cpp @@ -226,7 +226,11 @@ bool DRAudioStream::ensure_init() if(!m_url.isEmpty()) { +#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 13) + l_hstream = BASS_StreamCreateURL(reinterpret_cast(m_url.utf16()), 0, 0, nullptr, nullptr); +#else l_hstream = BASS_StreamCreateURL(reinterpret_cast(m_url.utf16()), 0, 0, nullptr, nullptr); +#endif } else if (m_filename.isEmpty()) { diff --git a/src/lobby.cpp b/src/lobby.cpp index d921eb648..44cc55579 100644 --- a/src/lobby.cpp +++ b/src/lobby.cpp @@ -41,7 +41,10 @@ #include +#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 13) +#else #include +#endif Lobby::Lobby(AOApplication *p_ao_app) : QMainWindow() diff --git a/src/modules/managers/audio_manager.cpp b/src/modules/managers/audio_manager.cpp index bdab330af..e17d5f904 100644 --- a/src/modules/managers/audio_manager.cpp +++ b/src/modules/managers/audio_manager.cpp @@ -2,7 +2,10 @@ #include "aoapplication.h" #include #include +#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 13) +#else #include +#endif AudioManager AudioManager::s_Instance; diff --git a/src/modules/scenes/replay_scene.cpp b/src/modules/scenes/replay_scene.cpp index e719d4270..4de197f4f 100644 --- a/src/modules/scenes/replay_scene.cpp +++ b/src/modules/scenes/replay_scene.cpp @@ -8,8 +8,11 @@ #include #include +#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 13) +#else #include #include +#endif ReplayScene::ReplayScene(AOApplication *p_ao_app, QWidget *parent) : QWidget(parent) { From 3a42123d381c51af7f4c71a4b747692c7f0d34eb Mon Sep 17 00:00:00 2001 From: KG Date: Mon, 1 Jul 2024 02:15:00 +1000 Subject: [PATCH 2/9] libvlc integration for video playback --- dronline-client.pro | 5 ++ res/ui/config_panel.ui | 34 ++++++++-- src/aoapplication.h | 3 +- src/aoconfig.cpp | 26 ++++++++ src/aoconfig.h | 12 ++++ src/aoconfigpanel.cpp | 13 ++++ src/aoconfigpanel.h | 3 + src/courtroom.cpp | 8 ++- src/courtroom.h | 1 + src/drmediatester.cpp | 30 +++++++-- src/drmediatester.h | 9 +++ src/mk2/graphicsvideoscreen.cpp | 109 ++++++++++++++++++++++++++++---- src/mk2/graphicsvideoscreen.h | 22 +++++++ 13 files changed, 254 insertions(+), 21 deletions(-) diff --git a/dronline-client.pro b/dronline-client.pro index e6b82e7e7..706e40bd6 100644 --- a/dronline-client.pro +++ b/dronline-client.pro @@ -296,3 +296,8 @@ FORMS += \ # Mac stuff QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.13 ICON = icon.icns + +macx { +LIBS += -F$$PWD/3rd/ -framework VLCQtCore -framework VLCQtWidgets +QMAKE_APPLE_DEVICE_ARCHS = x86_64 +} diff --git a/res/ui/config_panel.ui b/res/ui/config_panel.ui index 522052b1d..8e743e48f 100644 --- a/res/ui/config_panel.ui +++ b/res/ui/config_panel.ui @@ -7,7 +7,7 @@ 0 0 890 - 544 + 572 @@ -62,7 +62,7 @@ - 3 + 0 @@ -116,6 +116,32 @@ + + + + + 0 + 60 + + + + Video + + + + + 10 + 30 + 691 + 20 + + + + Use libvlc to play videos (better support for MacOS) + + + + @@ -1628,8 +1654,8 @@ 10 190 - 247 - 26 + 262 + 32 diff --git a/src/aoapplication.h b/src/aoapplication.h index ddd936b85..8bf3350de 100644 --- a/src/aoapplication.h +++ b/src/aoapplication.h @@ -41,6 +41,8 @@ class AOApplication : public QApplication AOApplication(int &argc, char **argv); ~AOApplication(); + AOConfig *ao_config = nullptr; + int get_client_id() const; void set_client_id(int id); @@ -218,7 +220,6 @@ public slots: void server_status_changed(ServerStatus); private: - AOConfig *ao_config = nullptr; AOConfigPanel *ao_config_panel = nullptr; DRDiscord *dr_discord = nullptr; diff --git a/src/aoconfig.cpp b/src/aoconfig.cpp index 3f31a021a..9545b8460 100644 --- a/src/aoconfig.cpp +++ b/src/aoconfig.cpp @@ -118,6 +118,9 @@ private slots: int fade_duration; bool blank_blips; + // video + bool is_video_backend_vlc; + // audio sync DRAudioEngine *audio_engine = nullptr; }; @@ -240,6 +243,13 @@ void AOConfigPrivate::load_file() SceneManager::get().setFadeDuration(fade_duration); blank_blips = cfg.value("blank_blips").toBool(); + // video +#ifdef Q_OS_MAC + is_video_backend_vlc = cfg.value("video_backend", "vlc").toString() == "vlc"; +#else + is_video_backend_vlc = cfg.value("video_backend", "qt").toString() == "vlc"; +#endif + // audio update audio_engine->set_volume(master_volume); audio_engine->get_family(DRAudio::Family::FSystem)->set_volume(system_volume); @@ -351,6 +361,9 @@ void AOConfigPrivate::save_file() cfg.setValue("fade_duration", fade_duration); cfg.setValue("blank_blips", blank_blips); + // video + cfg.setValue("video_backend", is_video_backend_vlc ? "vlc" : "qt"); + cfg.remove("character_ini"); { // ini swap cfg.beginGroup("character_ini"); @@ -751,6 +764,11 @@ int AOConfig::fade_duration() const return d->fade_duration; } +bool AOConfig::video_backend_vlc() const +{ + return d->is_video_backend_vlc; +} + void AOConfig::load_file() { d->load_file(); @@ -1252,5 +1270,13 @@ void AOConfig::setFadeDuration(int duration) d->invoke_signal("fade_duration_changed", Q_ARG(int, duration)); } +void AOConfig::set_video_backend_vlc(bool p_video_backend_vlc) +{ + if (d->is_video_backend_vlc == p_video_backend_vlc) + return; + d->is_video_backend_vlc = p_video_backend_vlc; + d->invoke_signal("fade_duration_changed", Q_ARG(bool, d->is_video_backend_vlc)); +} + // moc #include "aoconfig.moc" diff --git a/src/aoconfig.h b/src/aoconfig.h index f5e6918b9..2236783f0 100644 --- a/src/aoconfig.h +++ b/src/aoconfig.h @@ -2,6 +2,7 @@ #define AOCONFIG_H #include "datatypes.h" +#include "aoapplication.h" #include @@ -15,6 +16,8 @@ class AOConfig : public QObject AOConfig(QObject *p_parent = nullptr); ~AOConfig(); + AOApplication* ao_app = nullptr; + // generic getters QString get_string(QString p_name, QString p_default = nullptr) const; bool get_bool(QString p_name, bool p_default = false) const; @@ -85,6 +88,9 @@ class AOConfig : public QObject double theme_resize() const; int fade_duration() const; + // video + bool video_backend_vlc() const; + // io public slots: void load_file(); @@ -155,6 +161,9 @@ public slots: void setThemeResize(double resize); void setFadeDuration(int duration); + // video + void set_video_backend_vlc(bool p_video_backend_vlc); + // signals signals: // meta @@ -226,6 +235,9 @@ public slots: void punctuation_delay_changed(int); void blank_blips_changed(bool); + // video + void video_backend_vlc_changed(bool); + //Theme void theme_resize_changed(double); void fade_duration_changed(int); diff --git a/src/aoconfigpanel.cpp b/src/aoconfigpanel.cpp index 05879ebea..b0b29a1c4 100644 --- a/src/aoconfigpanel.cpp +++ b/src/aoconfigpanel.cpp @@ -175,6 +175,12 @@ AOConfigPanel::AOConfigPanel(AOApplication *p_ao_app, QWidget *p_parent) {ui_blip, ui_blip_value} }; + // video + ui_video_backend_vlc = AO_GUI_WIDGET(QCheckBox, "video_backend_vlc"); +#ifdef Q_OS_MAC + // ui_video_backend_vlc->setDisabled(true); +#endif + // about ui_about = AO_GUI_WIDGET(QLabel, "about_label"); @@ -255,6 +261,9 @@ AOConfigPanel::AOConfigPanel(AOApplication *p_ao_app, QWidget *p_parent) connect(m_engine, SIGNAL(device_list_changed(QVector)), this, SLOT(on_audio_device_list_changed(QVector))); connect(m_engine, SIGNAL(favorite_device_changed(DRAudioDevice)), this, SLOT(on_favorite_audio_device_changed(DRAudioDevice))); + // video + connect(m_config, SIGNAL(video_backend_vlc_changed(bool)), ui_video_backend_vlc, SLOT(setChecked(bool))); + // meta connect(ui_close, SIGNAL(clicked()), this, SLOT(close())); connect(ui_save, SIGNAL(clicked()), m_config, SLOT(save_file())); @@ -333,6 +342,8 @@ AOConfigPanel::AOConfigPanel(AOApplication *p_ao_app, QWidget *p_parent) connect(ui_punctuation_delay, SIGNAL(valueChanged(int)), m_config, SLOT(set_punctuation_delay(int))); connect(ui_blank_blips, SIGNAL(toggled(bool)), m_config, SLOT(set_blank_blips(bool))); + connect(ui_video_backend_vlc, &QAbstractButton::toggled, m_config, &AOConfig::set_video_backend_vlc); + connect(ui_theme_resize, SIGNAL(valueChanged(double)), m_config, SLOT(setThemeResize(double))); connect(ui_fade_duration, SIGNAL(valueChanged(int)), m_config, SLOT(setFadeDuration(int))); @@ -427,6 +438,8 @@ AOConfigPanel::AOConfigPanel(AOApplication *p_ao_app, QWidget *p_parent) ui_punctuation_delay->setValue(m_config->punctuation_delay()); ui_blank_blips->setChecked(m_config->blank_blips_enabled()); + ui_video_backend_vlc->setChecked(m_config->video_backend_vlc()); + ui_theme_resize->setValue(m_config->theme_resize()); ui_fade_duration->setValue(m_config->fade_duration()); diff --git a/src/aoconfigpanel.h b/src/aoconfigpanel.h index 21f7a6fb7..a2fa8c63b 100644 --- a/src/aoconfigpanel.h +++ b/src/aoconfigpanel.h @@ -203,6 +203,9 @@ private slots: QLabel *ui_blip_value = nullptr; QPushButton *ui_reload_audiotracks = nullptr; + // video + QCheckBox *ui_video_backend_vlc = nullptr; + // about QLabel *ui_about = nullptr; diff --git a/src/courtroom.cpp b/src/courtroom.cpp index d81729294..35ab56a19 100644 --- a/src/courtroom.cpp +++ b/src/courtroom.cpp @@ -75,6 +75,7 @@ Courtroom::Courtroom(AOApplication *p_ao_app, QWidget *parent) { ao_app = p_ao_app; ao_config = new AOConfig(this); + ao_app->m_courtroom = this; m_preloader_sync = new mk2::SpriteReaderSynchronizer(this); m_preloader_sync->set_threshold(ao_config->caching_threshold()); @@ -102,7 +103,7 @@ Courtroom::Courtroom(AOApplication *p_ao_app, QWidget *parent) set_char_select(); load_audiotracks(); reset_viewport(); - PairManager::get().SetUserPair(-1, 480); + PairManager::get().SetUserPair(-1, 480); } Courtroom::~Courtroom() @@ -817,6 +818,11 @@ bool Courtroom::is_spectating() return m_chr_id == SpectatorId; } +QRect Courtroom::get_video_rect() +{ + return ui_viewport->geometry(); +} + void Courtroom::on_showname_placeholder_changed(QString p_showname_placeholder) { const QString l_showname(p_showname_placeholder.trimmed().isEmpty() ? LocalizationManager::get().getLocalizationText("TEXTBOX_SHOWNAME") : p_showname_placeholder); diff --git a/src/courtroom.h b/src/courtroom.h index c8862f6e9..b8f5a889d 100644 --- a/src/courtroom.h +++ b/src/courtroom.h @@ -302,6 +302,7 @@ private slots: public: AOConfig *ao_config = nullptr; bool is_spectating(); + QRect get_video_rect(); private: bool m_first_theme_loading = true; diff --git a/src/drmediatester.cpp b/src/drmediatester.cpp index bb6569bb4..27253a3c6 100644 --- a/src/drmediatester.cpp +++ b/src/drmediatester.cpp @@ -1,4 +1,6 @@ #include "drmediatester.h" +#include "aoapplication.h" +#include "aoconfig.h" #include @@ -7,11 +9,24 @@ DRMediaTester::DRMediaTester(QObject *parent) : QObject(parent) { - m_player.setMuted(true); + AOApplication* ap_app = static_cast(parent); + if (ap_app->ao_config->video_backend_vlc()) + { + _vlcInstance = new VlcInstance(VlcCommon::args(), this); + _vlcPlayer = new VlcMediaPlayer(_vlcInstance); + + connect(_vlcPlayer, SIGNAL(error()), this, SLOT(p_vlc_error())); + _vlcMedia = new VlcMedia(QUrl("qrc:/data/sample.avi").toLocalFile(), true, _vlcInstance); + _vlcPlayer->open(_vlcMedia); + } + else + { + m_player.setMuted(true); - connect(&m_player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)), this, SLOT(p_check_status(QMediaPlayer::MediaStatus))); + connect(&m_player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)), this, SLOT(p_check_status(QMediaPlayer::MediaStatus))); - m_player.setMedia(QUrl("qrc:/data/sample.avi")); + m_player.setMedia(QUrl("qrc:/data/sample.avi")); + } } DRMediaTester::~DRMediaTester() @@ -24,7 +39,8 @@ void DRMediaTester::p_check_status(QMediaPlayer::MediaStatus p_status) case QMediaPlayer::InvalidMedia: call_warning("Your operating system appears to not currently support video playback. The video " "playback will not work properly.

In order for the feature to function properly, you " - "will need to install additional codecs.

For more information visit " + "will need to install additional codecs or use libvlc in settings.

" + "For more information visit " "https://www.danganronpaonline.com"); emit done(); break; @@ -37,3 +53,9 @@ void DRMediaTester::p_check_status(QMediaPlayer::MediaStatus p_status) break; } } + +void DRMediaTester::p_vlc_error() +{ + call_warning("libVLC has failed to initialize"); + emit done(); +} diff --git a/src/drmediatester.h b/src/drmediatester.h index c8ee9bc3c..a7c13dad7 100644 --- a/src/drmediatester.h +++ b/src/drmediatester.h @@ -2,6 +2,10 @@ #include #include +#include +#include +#include +#include class DRMediaTester : public QObject { @@ -16,7 +20,12 @@ class DRMediaTester : public QObject private: QMediaPlayer m_player; + VlcInstance *_vlcInstance; + VlcMedia *_vlcMedia; + VlcMediaPlayer *_vlcPlayer; + private slots: void p_check_status(QMediaPlayer::MediaStatus p_status); + void p_vlc_error(); }; diff --git a/src/mk2/graphicsvideoscreen.cpp b/src/mk2/graphicsvideoscreen.cpp index 4a4b6d781..681d635fa 100644 --- a/src/mk2/graphicsvideoscreen.cpp +++ b/src/mk2/graphicsvideoscreen.cpp @@ -18,6 +18,7 @@ ** **************************************************************************/ #include "graphicsvideoscreen.h" +#include "courtroom.h" #include #include @@ -25,6 +26,8 @@ #include #include +#include + DRVideoScreen::DRVideoScreen(AOApplication *ao_app, QGraphicsItem *parent) : QGraphicsVideoItem(parent) , ao_app(ao_app) @@ -38,6 +41,19 @@ DRVideoScreen::DRVideoScreen(AOApplication *ao_app, QGraphicsItem *parent) { setAspectRatioMode(Qt::KeepAspectRatioByExpanding); + // Setup libvlc + _vlcInstance = new VlcInstance(VlcCommon::args(), this); + _vlcPlayer = new VlcMediaPlayer(_vlcInstance); + + _widget = ao_app->m_courtroom; + _vlcWidget = new VlcWidgetVideo(_widget); + _vlcWidget->setMediaPlayer(_vlcPlayer); + _vlcPlayer->setVideoWidget(_vlcWidget); + + connect(_vlcPlayer, SIGNAL(stateChanged()), this, SLOT(vlc_stateChanged())); + connect(_vlcPlayer, SIGNAL(mediaChanged()), this, SLOT(vlc_mediaChanged(libvlc_media_t*))); + + // Setup Qt Media Player m_player->setVideoOutput(this); connect(m_player, SIGNAL(videoAvailableChanged(bool)), this, SLOT(update_video_availability(bool))); @@ -64,10 +80,10 @@ QString DRVideoScreen::get_file_name() const void DRVideoScreen::set_file_name(QString p_file_name) { - if (m_file_name == p_file_name) - { - return; - } + // if (m_file_name == p_file_name) + // { + // return; + // } stop(); qInfo() << "loading media file" << p_file_name; m_scanned = false; @@ -77,7 +93,15 @@ void DRVideoScreen::set_file_name(QString p_file_name) { m_scanned = true; } - m_player->setMedia(QUrl::fromLocalFile(m_file_name)); + if (ao_app->ao_config->video_backend_vlc()) + { + _vlcMedia = new VlcMedia(m_file_name, true, _vlcInstance); + _vlcPlayer->open(_vlcMedia); + } + else + { + m_player->setMedia(QUrl::fromLocalFile(m_file_name)); + } } void DRVideoScreen::play_character_video(QString p_character, QString p_video) @@ -119,12 +143,56 @@ void DRVideoScreen::play() void DRVideoScreen::stop() { m_running = false; + + if ( _vlcPlayer->state() == Vlc::State::Playing) + { + _vlcPlayer->stop(); + } if (m_player->state() != QMediaPlayer::StoppedState) { m_player->stop(); } } +void DRVideoScreen::vlc_stateChanged() +{ + if (m_vlc_state == _vlcPlayer->state()) + { + return; + } + // qDebug() << "//// STATE: " << _vlcPlayer->state() << " VLCMEDIA: " << _vlcMedia; + m_vlc_state = _vlcPlayer->state(); + switch (m_vlc_state) + { + case Vlc::State::Error: + m_scanned = true; + qWarning() << "error: media file is invalid:" << m_file_name; + finish_playback(); + break; + + case Vlc::State::Playing: + emit started(); + start_playback(); + break; + + case Vlc::State::Ended: + finish_playback(); + _vlcMedia->deleteLater(); + _vlcMedia = nullptr; + _vlcWidget->hide(); + break; + + default: + break; + } +} + +void DRVideoScreen::vlc_mediaChanged(libvlc_media_t* media) +{ + //qDebug() << "//// STATE: " << _vlcPlayer->state() << " MEDIA: " << media << " VLCMEDIA: " << _vlcMedia; + // Currently this signal is not being called. Ignored for now. +} + void DRVideoScreen::update_video_availability(bool p_video_available) { m_video_available = p_video_available; @@ -186,11 +254,23 @@ void DRVideoScreen::check_state(QMediaPlayer::State p_state) void DRVideoScreen::start_playback() { - if (m_player->state() == QMediaPlayer::StoppedState) + if (ao_app->ao_config->video_backend_vlc()) + { + _vlcPlayer->setPosition(0); + update_volume(); + _vlcWidget->setGeometry(ao_app->m_courtroom->get_video_rect()); + _vlcWidget->show(); + _vlcWidget->activateWindow(); + _vlcWidget->raise(); + } + else { - update_audio_output(); + if (m_player->state() == QMediaPlayer::StoppedState) + { + update_audio_output(); - m_player->play(); + m_player->play(); + } } } @@ -250,9 +330,16 @@ void DRVideoScreen::update_volume() l_volume = 0; } - if (m_player->volume() == l_volume) + if (m_player->volume() != l_volume) { - return; + m_player->setVolume(l_volume); + } + + // improve audio volume scaling for vlc since it's different from QMediaPlayer + int transformed_volume = sqrt(sqrt(l_volume) * 10) * 10; + if (_vlcPlayer->audio()->volume() != transformed_volume) + { + // qDebug() << "//// SET VOLUME " << l_volume << " LOG VOLUME " << transformed_volume; + _vlcPlayer->audio()->setVolume(transformed_volume); } - m_player->setVolume(l_volume); } diff --git a/src/mk2/graphicsvideoscreen.h b/src/mk2/graphicsvideoscreen.h index af9f7ff13..3940be277 100644 --- a/src/mk2/graphicsvideoscreen.h +++ b/src/mk2/graphicsvideoscreen.h @@ -26,6 +26,14 @@ #include #include +#include +#include + +#include +#include +#include +#include +#include class DRVideoScreen : public QGraphicsVideoItem { @@ -36,6 +44,7 @@ class DRVideoScreen : public QGraphicsVideoItem ~DRVideoScreen(); QString get_file_name() const; + QWidget *_widget; public slots: void set_file_name(QString file_name); @@ -70,11 +79,24 @@ public slots: QMediaPlayer *m_player; + VlcInstance *_vlcInstance; + VlcMedia *_vlcMedia; + VlcMediaPlayer *_vlcPlayer; + VlcWidgetVideo *_vlcWidget; + QGraphicsProxyWidget *_widgetProxy; + void start_playback(); void finish_playback(); + Vlc::State m_vlc_state; + private slots: + // libvlc slots + void vlc_stateChanged(); + void vlc_mediaChanged(libvlc_media_t* media); + + // Qt Media Player slots void update_video_availability(bool); void check_status(QMediaPlayer::MediaStatus); From 425585b0052231c5709858e3adc6e110f994c341 Mon Sep 17 00:00:00 2001 From: sagittaeri Date: Mon, 1 Jul 2024 16:17:43 +1000 Subject: [PATCH 3/9] made backwards compatible --- dronline-client.pro | 19 ++++++++++++++----- src/drmediatester.h | 8 ++++---- src/mk2/graphicsvideoscreen.cpp | 1 + 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/dronline-client.pro b/dronline-client.pro index be49a40ec..118736150 100644 --- a/dronline-client.pro +++ b/dronline-client.pro @@ -288,6 +288,20 @@ SOURCES += \ # in the same way as BASS. Discord RPC uses CMake, which does not play nicely with # QMake, so this step must be manual. LIBS += -L$$PWD/3rd -lbass -lbassopus -ldiscord-rpc +# 3. You need to get VLC-Qt and place them in the 3rd folder too. Be sure to include the +# plugins folder too which contains all the codecs that VLC uses. If you're compiling +# on MacOS, copy the framework folders directly +win32 { +LIBS += -lVLCQtCore -lVLCQtWidgets +} +win64 { +LIBS += -lVLCQtCore -lVLCQtWidgets +} +macx { +LIBS += -F$$PWD/3rd/ -framework VLCQtCore -framework VLCQtWidgets +QMAKE_APPLE_DEVICE_ARCHS = x86_64 +} + RESOURCES += \ res.qrc @@ -304,8 +318,3 @@ FORMS += \ # Mac stuff QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.13 ICON = icon.icns - -macx { -LIBS += -F$$PWD/3rd/ -framework VLCQtCore -framework VLCQtWidgets -QMAKE_APPLE_DEVICE_ARCHS = x86_64 -} diff --git a/src/drmediatester.h b/src/drmediatester.h index a7c13dad7..03331397c 100644 --- a/src/drmediatester.h +++ b/src/drmediatester.h @@ -2,10 +2,10 @@ #include #include -#include -#include -#include -#include +#include +#include +#include +#include class DRMediaTester : public QObject { diff --git a/src/mk2/graphicsvideoscreen.cpp b/src/mk2/graphicsvideoscreen.cpp index 681d635fa..050d691f5 100644 --- a/src/mk2/graphicsvideoscreen.cpp +++ b/src/mk2/graphicsvideoscreen.cpp @@ -26,6 +26,7 @@ #include #include +#include #include DRVideoScreen::DRVideoScreen(AOApplication *ao_app, QGraphicsItem *parent) From 0495ff87be527bb1f1fe3c6f0b77bfc875ff7472 Mon Sep 17 00:00:00 2001 From: sagittaeri Date: Mon, 1 Jul 2024 20:56:56 +1000 Subject: [PATCH 4/9] reworked build process so it's more automated --- dronline-client.pro | 58 ++++++++++++++++++++++++++------------------ post-build-script.py | 39 +++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 24 deletions(-) create mode 100644 post-build-script.py diff --git a/dronline-client.pro b/dronline-client.pro index 118736150..aee413f86 100644 --- a/dronline-client.pro +++ b/dronline-client.pro @@ -8,8 +8,17 @@ TARGET = dro-client RC_ICONS = icon.ico -INCLUDEPATH += $$PWD/include $$PWD/src $$PWD/3rd -DEPENDPATH += $$PWD/include $$PWD/src $$PWD/3rd +INCLUDEPATH += $$PWD/include $$PWD/src +DEPENDPATH += $$PWD/include $$PWD/src + +win32 { +INCLUDEPATH += $$PWD/3rd/win32 +DEPENDPATH += $$PWD/3rd/win32 +} +macx { +INCLUDEPATH += $$PWD/3rd/macx64 +DEPENDPATH += $$PWD/3rd/macx64 +} HEADERS += \ src/aoapplication.h \ @@ -281,28 +290,6 @@ SOURCES += \ src/utils.cpp \ src/version.cpp -# 1. You need to get BASS and put the x86 bass DLL/headers in the project root folder -# AND the compilation output folder. If you want a static link, you'll probably -# need the .lib file too. MinGW-GCC is really finicky finding BASS, it seems. -# 2. You need to compile the Discord Rich Presence SDK separately and add the lib/headers -# in the same way as BASS. Discord RPC uses CMake, which does not play nicely with -# QMake, so this step must be manual. -LIBS += -L$$PWD/3rd -lbass -lbassopus -ldiscord-rpc -# 3. You need to get VLC-Qt and place them in the 3rd folder too. Be sure to include the -# plugins folder too which contains all the codecs that VLC uses. If you're compiling -# on MacOS, copy the framework folders directly -win32 { -LIBS += -lVLCQtCore -lVLCQtWidgets -} -win64 { -LIBS += -lVLCQtCore -lVLCQtWidgets -} -macx { -LIBS += -F$$PWD/3rd/ -framework VLCQtCore -framework VLCQtWidgets -QMAKE_APPLE_DEVICE_ARCHS = x86_64 -} - - RESOURCES += \ res.qrc @@ -318,3 +305,26 @@ FORMS += \ # Mac stuff QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.13 ICON = icon.icns + +# 1. You need to get BASS and put the x86 bass DLL/headers in the project root folder +# AND the compilation output folder. If you want a static link, you'll probably +# need the .lib file too. MinGW-GCC is really finicky finding BASS, it seems. +# 2. You need to compile the Discord Rich Presence SDK separately and add the lib/headers +# in the same way as BASS. Discord RPC uses CMake, which does not play nicely with +# QMake, so this step must be manual. +# 3. You need to get VLC-Qt and place them in the 3rd folder too. Be sure to include the +# plugins folder too which contains all the codecs that VLC uses. If you're compiling +# on MacOS, copy the framework folders directly +win32 { +LIBS += -L$$PWD/3rd/win32 -lbass -lbassopus -ldiscord-rpc -lVLCQtCore -lVLCQtWidgets +} +macx { +LIBS += -L$$PWD/3rd/macx64 -lbass -lbassopus -ldiscord-rpc +LIBS += -F$$PWD/3rd/macx64 -framework VLCQtCore -framework VLCQtWidgets +QMAKE_APPLE_DEVICE_ARCHS = x86_64 +} + +# Copying files after release builds +win32 { +QMAKE_POST_LINK += $$quote(python $$PWD/post-build-script.py$$escape_expand(\n\t)) +} diff --git a/post-build-script.py b/post-build-script.py new file mode 100644 index 000000000..0d7d0b2cc --- /dev/null +++ b/post-build-script.py @@ -0,0 +1,39 @@ +import os +import glob +import shutil + +pro_dir = os.path.dirname(os.path.realpath(__file__)) +build_dir = os.getcwd() +# print("//// PRO_DIR =", pro_dir, " BUILD_DIR =", build_dir) + +is_release = build_dir.endswith('-Release') +if not is_release: + print('Not a Release build, do not copy libraries') + exit(0) + +# Check what platform the build directory is +if glob.glob(build_dir + '/release/*.exe'): + platform = 'win' + print('Windows build detected. Proceeding to copy Windows libraries') +elif glob.glob(build_dir + '/release/*.app'): + platform = 'mac' + print('MacOS build detected. Proceeding to copy MacOS libraries') +else: + platform = 'unknown' + print('Unable to detect platform of build binary.') + exit(1) + +# Copies all the DLLs over +if platform == 'win': + for file in glob.glob(pro_dir + '/3rd/win32/*.dll'): + print('Copying', file) + shutil.copy2(file, build_dir + '/release/') + print('Copying plugins directory') + shutil.copytree(pro_dir + '/3rd/win32/plugins', build_dir + '/release/plugins', dirs_exist_ok=True) +elif platform == 'mac': + for file in glob.glob(pro_dir + '/3rd/macx64/*.dylib'): + print('Copying', file) + shutil.copy2(file, build_dir + '/release/') + for file in glob.glob(pro_dir + '/3rd/macx64/*.framework'): + print('Copying', file) + shutil.copytree(file, build_dir + '/release/', dirs_exist_ok=True) From 0e1587f65ae6502d22e06ee455b2b666c3b37ff6 Mon Sep 17 00:00:00 2001 From: KG Date: Mon, 1 Jul 2024 22:35:43 +1000 Subject: [PATCH 5/9] made mac builds work with automation, and also added macdeployqt --- dronline-client.pro | 18 +++++++++++++++--- post-build-script.py | 14 ++++++++++---- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/dronline-client.pro b/dronline-client.pro index aee413f86..671082edd 100644 --- a/dronline-client.pro +++ b/dronline-client.pro @@ -324,7 +324,19 @@ LIBS += -F$$PWD/3rd/macx64 -framework VLCQtCore -framework VLCQtWidgets QMAKE_APPLE_DEVICE_ARCHS = x86_64 } -# Copying files after release builds -win32 { -QMAKE_POST_LINK += $$quote(python $$PWD/post-build-script.py$$escape_expand(\n\t)) +CONFIG( debug, debug|release ) { + # debug, don't do anything +} else { + # release + + # Manually copy 3rd party libraries + QMAKE_POST_LINK += $$quote(python3 $$PWD/post-build-script.py$$escape_expand(\n\t)) + + # Run deployqt to copy Qt libraries + win32 { + QMAKE_POST_LINK += windeployqt $$shell_quote($$shell_path($${OUT_PWD}/release/$${TARGET}.exe))$$escape_expand(\n\t) + } + macx { + QMAKE_POST_LINK += macdeployqt $$shell_quote($$shell_path($${OUT_PWD}/$${TARGET}.app)) -dmg -always-overwrite$$escape_expand(\n\t) + } } diff --git a/post-build-script.py b/post-build-script.py index 0d7d0b2cc..6a830e9a3 100644 --- a/post-build-script.py +++ b/post-build-script.py @@ -15,8 +15,9 @@ if glob.glob(build_dir + '/release/*.exe'): platform = 'win' print('Windows build detected. Proceeding to copy Windows libraries') -elif glob.glob(build_dir + '/release/*.app'): +elif glob.glob(build_dir + '/*.app'): platform = 'mac' + macapp_dir = glob.glob(build_dir + '/*.app')[0] print('MacOS build detected. Proceeding to copy MacOS libraries') else: platform = 'unknown' @@ -29,11 +30,16 @@ print('Copying', file) shutil.copy2(file, build_dir + '/release/') print('Copying plugins directory') - shutil.copytree(pro_dir + '/3rd/win32/plugins', build_dir + '/release/plugins', dirs_exist_ok=True) + shutil.copytree(pro_dir + '/3rd/win32/plugins', build_dir + '/release/plugins', dirs_exist_ok=True, symlinks=True, ignore_dangling_symlinks=True) elif platform == 'mac': + if not os.path.isdir(macapp_dir + '/Contents/Frameworks/'): + os.makedirs(macapp_dir + '/Contents/Frameworks/') for file in glob.glob(pro_dir + '/3rd/macx64/*.dylib'): print('Copying', file) - shutil.copy2(file, build_dir + '/release/') + shutil.copy2(file, macapp_dir + '/Contents/Frameworks/') for file in glob.glob(pro_dir + '/3rd/macx64/*.framework'): print('Copying', file) - shutil.copytree(file, build_dir + '/release/', dirs_exist_ok=True) + dest_dir = macapp_dir + '/Contents/Frameworks/' + os.path.basename(file) + if os.path.isdir(dest_dir): + shutil.rmtree(dest_dir) + shutil.copytree(file, dest_dir, dirs_exist_ok=True, symlinks=True, ignore_dangling_symlinks=True) From 51f6e8889224bdc1a1bb09221662409a1098c45c Mon Sep 17 00:00:00 2001 From: sagittaeri Date: Tue, 2 Jul 2024 12:08:45 +1000 Subject: [PATCH 6/9] added win64 support in automation script, and added some instructions in the documentation --- README.md | 23 ++++++++++++++++++++++- dronline-client.pro | 26 +++++++++++++++++--------- post-build-script.py | 25 +++++++++++++++++-------- 3 files changed, 56 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 4c9a5fe80..e72cdffc1 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ This is the official client used, it is a derivative of [Attorney-Online-Client-Remake](https://github.com/AttorneyOnline/AO2-Client). ## Qt -This project uses Qt 5.15.2 (5.12.8 for Linux), which is licensed under the [GNU Lesser General Public License](https://www.gnu.org/licenses/lgpl-3.0.txt) with [certain licensing restrictions and exceptions](https://www.qt.io/qt-licensing-terms/). To comply with licensing requirements for static linking, object code is available if you would like to relink with an alternative version of Qt, and the source code for Qt may be found at https://github.com/qt/qtbase, http://code.qt.io/cgit/, or at https://qt.io. +This project uses Qt 5.15.2 (5.12.8 for Linux, and 5.15.13 for MacOS via [Homebrew](https://brew.sh/)), which is licensed under the [GNU Lesser General Public License](https://www.gnu.org/licenses/lgpl-3.0.txt) with [certain licensing restrictions and exceptions](https://www.qt.io/qt-licensing-terms/). To comply with licensing requirements for static linking, object code is available if you would like to relink with an alternative version of Qt, and the source code for Qt may be found at https://github.com/qt/qtbase, http://code.qt.io/cgit/, or at https://qt.io. Copyright (C) 2022 The Qt Company Ltd. @@ -10,3 +10,24 @@ Copyright (C) 2022 The Qt Company Ltd. This project uses [BASS shared library](http://www.un4seen.com/). Copyright (c) 1999-2022 Un4seen Developments Ltd. All rights reserved. + +## Discord-RPC +This project uses the deprecated [discord-rpc library](https://github.com/discord/discord-rpc). + +## VLC-Qt +This project uses [VLC-Qt 1.1.0](https://vlc-qt.tano.si/) in order to play videos with bundled codecs. You may find the source code and the binaries here: https://github.com/vlc-qt/vlc-qt + +Copyright (C) 2010-2016 Tadej Novak + +## Recommended Compilers in QtCreator + +For development work on Windows to make 64-bit binaries, please use the MSVC2019 compiler. You will need to install the MSVC2019 Build Tools from the following website: +https://learn.microsoft.com/en-au/visualstudio/releases/2019/history + +For development work on Windows to make 32-bit binaries, please use the MingW32-bit compiler. + +For development work on the Mac to make 64-bit Silicon binaries, please use Clang (C/C++ arm 64bit). + +For development work on the Mac to make 64-bit Intel binaries, please use Apple Clang (x64_64). + +NOTE: If you get a `windeployqt` or `macdeployqt` not found error, you need to manually go to "QtCreator > Projects > Edit Build Configuration (Release) > Build Environment > Edit Path" and add the folder containing the correct version of the deployqt script (be sure to use the one matching the compiler and Qt version). For example, on Windows if using the default installation path, the path for MSVC2019 64-bit is `C:\Qt\5.15.2\msvc2019_64\bin` diff --git a/dronline-client.pro b/dronline-client.pro index 671082edd..ea6d5fdcf 100644 --- a/dronline-client.pro +++ b/dronline-client.pro @@ -7,19 +7,27 @@ VERSION = 2.0.0 TARGET = dro-client RC_ICONS = icon.ico +TARGETPLATFORM = unknown INCLUDEPATH += $$PWD/include $$PWD/src DEPENDPATH += $$PWD/include $$PWD/src win32 { -INCLUDEPATH += $$PWD/3rd/win32 -DEPENDPATH += $$PWD/3rd/win32 + !contains(QMAKE_HOST.arch, x86_64) { + TARGETPLATFORM = win32 + } else { + TARGETPLATFORM = win64 + } } macx { -INCLUDEPATH += $$PWD/3rd/macx64 -DEPENDPATH += $$PWD/3rd/macx64 + TARGETPLATFORM = macx64 } +message("TARGETPLATFORM = $$TARGETPLATFORM") + +INCLUDEPATH += $$PWD/3rd/$$TARGETPLATFORM +DEPENDPATH += $$PWD/3rd/$$TARGETPLATFORM + HEADERS += \ src/aoapplication.h \ src/aoblipplayer.h \ @@ -316,12 +324,12 @@ ICON = icon.icns # plugins folder too which contains all the codecs that VLC uses. If you're compiling # on MacOS, copy the framework folders directly win32 { -LIBS += -L$$PWD/3rd/win32 -lbass -lbassopus -ldiscord-rpc -lVLCQtCore -lVLCQtWidgets + LIBS += -L$$PWD/3rd/$$TARGETPLATFORM -lbass -lbassopus -ldiscord-rpc -lVLCQtCore -lVLCQtWidgets } macx { -LIBS += -L$$PWD/3rd/macx64 -lbass -lbassopus -ldiscord-rpc -LIBS += -F$$PWD/3rd/macx64 -framework VLCQtCore -framework VLCQtWidgets -QMAKE_APPLE_DEVICE_ARCHS = x86_64 + LIBS += -L$$PWD/3rd/$$TARGETPLATFORM -lbass -lbassopus -ldiscord-rpc + LIBS += -F$$PWD/3rd/$$TARGETPLATFORM -framework VLCQtCore -framework VLCQtWidgets + QMAKE_APPLE_DEVICE_ARCHS = x86_64 } CONFIG( debug, debug|release ) { @@ -330,7 +338,7 @@ CONFIG( debug, debug|release ) { # release # Manually copy 3rd party libraries - QMAKE_POST_LINK += $$quote(python3 $$PWD/post-build-script.py$$escape_expand(\n\t)) + QMAKE_POST_LINK += $$quote(python3 $$PWD/post-build-script.py $$TARGETPLATFORM$$escape_expand(\n\t)) # Run deployqt to copy Qt libraries win32 { diff --git a/post-build-script.py b/post-build-script.py index 6a830e9a3..767266ae2 100644 --- a/post-build-script.py +++ b/post-build-script.py @@ -1,15 +1,21 @@ import os +import sys import glob import shutil +if len(sys.argv) != 2: + print('This script takes exactly one argument: win32, win64 or macx64') + exit(1) + +libs_dir = sys.argv[1] pro_dir = os.path.dirname(os.path.realpath(__file__)) build_dir = os.getcwd() -# print("//// PRO_DIR =", pro_dir, " BUILD_DIR =", build_dir) -is_release = build_dir.endswith('-Release') +# Assume this script is only run for release builds since there's no way to check +is_release = True if not is_release: print('Not a Release build, do not copy libraries') - exit(0) + exit(1) # Check what platform the build directory is if glob.glob(build_dir + '/release/*.exe'): @@ -26,18 +32,21 @@ # Copies all the DLLs over if platform == 'win': - for file in glob.glob(pro_dir + '/3rd/win32/*.dll'): + for file in glob.glob(pro_dir + '/3rd/' + libs_dir + '/*.dll'): + print('Copying', file) + shutil.copy2(file, build_dir + '/release/') + for file in glob.glob(pro_dir + '/3rd/' + libs_dir + '/*.lib'): print('Copying', file) shutil.copy2(file, build_dir + '/release/') - print('Copying plugins directory') - shutil.copytree(pro_dir + '/3rd/win32/plugins', build_dir + '/release/plugins', dirs_exist_ok=True, symlinks=True, ignore_dangling_symlinks=True) + print('Copying directory ' + pro_dir + '/3rd/' + libs_dir + '/plugins') + shutil.copytree(pro_dir + '/3rd/' + libs_dir + '/plugins', build_dir + '/release/plugins', dirs_exist_ok=True, symlinks=True, ignore_dangling_symlinks=True) elif platform == 'mac': if not os.path.isdir(macapp_dir + '/Contents/Frameworks/'): os.makedirs(macapp_dir + '/Contents/Frameworks/') - for file in glob.glob(pro_dir + '/3rd/macx64/*.dylib'): + for file in glob.glob(pro_dir + '/3rd/' + libs_dir + '/*.dylib'): print('Copying', file) shutil.copy2(file, macapp_dir + '/Contents/Frameworks/') - for file in glob.glob(pro_dir + '/3rd/macx64/*.framework'): + for file in glob.glob(pro_dir + '/3rd/' + libs_dir + '/*.framework'): print('Copying', file) dest_dir = macapp_dir + '/Contents/Frameworks/' + os.path.basename(file) if os.path.isdir(dest_dir): From 9d5ed86844dc47cb3bbd4bbc1fa7722f23101d3f Mon Sep 17 00:00:00 2001 From: sagittaeri Date: Tue, 2 Jul 2024 13:34:48 +1000 Subject: [PATCH 7/9] ensures the libraries are copied in debug versions too in windows builds --- dronline-client.pro | 9 +++++---- post-build-script.py | 19 +++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/dronline-client.pro b/dronline-client.pro index ea6d5fdcf..99f2b032d 100644 --- a/dronline-client.pro +++ b/dronline-client.pro @@ -333,11 +333,12 @@ macx { } CONFIG( debug, debug|release ) { - # debug, don't do anything + # debug, copy 3rd party libraries only for windows + win32 { + QMAKE_POST_LINK += $$quote(python3 $$PWD/post-build-script.py $$TARGETPLATFORM$$escape_expand(\n\t)) + } } else { - # release - - # Manually copy 3rd party libraries + # release, copy 3rd party libraries always QMAKE_POST_LINK += $$quote(python3 $$PWD/post-build-script.py $$TARGETPLATFORM$$escape_expand(\n\t)) # Run deployqt to copy Qt libraries diff --git a/post-build-script.py b/post-build-script.py index 767266ae2..ccb7dea4d 100644 --- a/post-build-script.py +++ b/post-build-script.py @@ -11,16 +11,15 @@ pro_dir = os.path.dirname(os.path.realpath(__file__)) build_dir = os.getcwd() -# Assume this script is only run for release builds since there's no way to check -is_release = True -if not is_release: - print('Not a Release build, do not copy libraries') - exit(1) - # Check what platform the build directory is if glob.glob(build_dir + '/release/*.exe'): platform = 'win' - print('Windows build detected. Proceeding to copy Windows libraries') + type_dir = 'release' + print('Windows release build detected. Proceeding to copy Windows libraries') +elif glob.glob(build_dir + '/debug/*.exe'): + platform = 'win' + type_dir = 'debug' + print('Windows debug build detected. Proceeding to copy Windows libraries') elif glob.glob(build_dir + '/*.app'): platform = 'mac' macapp_dir = glob.glob(build_dir + '/*.app')[0] @@ -34,12 +33,12 @@ if platform == 'win': for file in glob.glob(pro_dir + '/3rd/' + libs_dir + '/*.dll'): print('Copying', file) - shutil.copy2(file, build_dir + '/release/') + shutil.copy2(file, build_dir + '/' + type_dir + '/') for file in glob.glob(pro_dir + '/3rd/' + libs_dir + '/*.lib'): print('Copying', file) - shutil.copy2(file, build_dir + '/release/') + shutil.copy2(file, build_dir + '/' + type_dir + '/') print('Copying directory ' + pro_dir + '/3rd/' + libs_dir + '/plugins') - shutil.copytree(pro_dir + '/3rd/' + libs_dir + '/plugins', build_dir + '/release/plugins', dirs_exist_ok=True, symlinks=True, ignore_dangling_symlinks=True) + shutil.copytree(pro_dir + '/3rd/' + libs_dir + '/plugins', build_dir + '/' + type_dir + '/plugins', dirs_exist_ok=True, symlinks=True, ignore_dangling_symlinks=True) elif platform == 'mac': if not os.path.isdir(macapp_dir + '/Contents/Frameworks/'): os.makedirs(macapp_dir + '/Contents/Frameworks/') From 0347ffcb132ac48b871988686ef801de065660bb Mon Sep 17 00:00:00 2001 From: sagittaeri Date: Tue, 2 Jul 2024 19:07:48 +1000 Subject: [PATCH 8/9] automatically uncheck use vlc if MSVC detected just in case. defer initialisation of vlc if unchecked --- src/aoconfig.cpp | 17 ++++++- src/aoconfigpanel.cpp | 7 ++- src/drmediatester.cpp | 1 + src/mk2/graphicsvideoscreen.cpp | 90 ++++++++++++++++++++++++--------- src/mk2/graphicsvideoscreen.h | 7 ++- 5 files changed, 94 insertions(+), 28 deletions(-) diff --git a/src/aoconfig.cpp b/src/aoconfig.cpp index 9545b8460..faa28f5c1 100644 --- a/src/aoconfig.cpp +++ b/src/aoconfig.cpp @@ -243,11 +243,24 @@ void AOConfigPrivate::load_file() SceneManager::get().setFadeDuration(fade_duration); blank_blips = cfg.value("blank_blips").toBool(); - // video -#ifdef Q_OS_MAC +#ifdef QT_DEBUG + #ifdef Q_CC_MSVC + is_video_backend_vlc = false; + qWarning() << "NOTE: libvlc automatically turned off for MSVC debug mode because it VLC-Qt seems to crash with it."; + #else + #ifdef Q_OS_MAC is_video_backend_vlc = cfg.value("video_backend", "vlc").toString() == "vlc"; + #else + is_video_backend_vlc = cfg.value("video_backend", "qt").toString() == "vlc"; + #endif + #endif #else + // video + #ifdef Q_OS_MAC + is_video_backend_vlc = cfg.value("video_backend", "vlc").toString() == "vlc"; + #else is_video_backend_vlc = cfg.value("video_backend", "qt").toString() == "vlc"; + #endif #endif // audio update diff --git a/src/aoconfigpanel.cpp b/src/aoconfigpanel.cpp index b0b29a1c4..ca70fee3a 100644 --- a/src/aoconfigpanel.cpp +++ b/src/aoconfigpanel.cpp @@ -177,8 +177,11 @@ AOConfigPanel::AOConfigPanel(AOApplication *p_ao_app, QWidget *p_parent) // video ui_video_backend_vlc = AO_GUI_WIDGET(QCheckBox, "video_backend_vlc"); -#ifdef Q_OS_MAC - // ui_video_backend_vlc->setDisabled(true); +#ifdef QT_DEBUG + #ifdef Q_CC_MSVC + ui_video_backend_vlc->setChecked(false); + //ui_video_backend_vlc->setDisabled(true); + #endif #endif // about diff --git a/src/drmediatester.cpp b/src/drmediatester.cpp index 27253a3c6..605f56177 100644 --- a/src/drmediatester.cpp +++ b/src/drmediatester.cpp @@ -10,6 +10,7 @@ DRMediaTester::DRMediaTester(QObject *parent) : QObject(parent) { AOApplication* ap_app = static_cast(parent); + if (ap_app->ao_config->video_backend_vlc()) { _vlcInstance = new VlcInstance(VlcCommon::args(), this); diff --git a/src/mk2/graphicsvideoscreen.cpp b/src/mk2/graphicsvideoscreen.cpp index 050d691f5..20d6a003d 100644 --- a/src/mk2/graphicsvideoscreen.cpp +++ b/src/mk2/graphicsvideoscreen.cpp @@ -43,16 +43,9 @@ DRVideoScreen::DRVideoScreen(AOApplication *ao_app, QGraphicsItem *parent) setAspectRatioMode(Qt::KeepAspectRatioByExpanding); // Setup libvlc - _vlcInstance = new VlcInstance(VlcCommon::args(), this); - _vlcPlayer = new VlcMediaPlayer(_vlcInstance); - - _widget = ao_app->m_courtroom; - _vlcWidget = new VlcWidgetVideo(_widget); - _vlcWidget->setMediaPlayer(_vlcPlayer); - _vlcPlayer->setVideoWidget(_vlcWidget); - - connect(_vlcPlayer, SIGNAL(stateChanged()), this, SLOT(vlc_stateChanged())); - connect(_vlcPlayer, SIGNAL(mediaChanged()), this, SLOT(vlc_mediaChanged(libvlc_media_t*))); + _vlcInstance = nullptr; + vlc_initialized = false; + initialize_vlc(); // Setup Qt Media Player m_player->setVideoOutput(this); @@ -74,6 +67,36 @@ DRVideoScreen::DRVideoScreen(AOApplication *ao_app, QGraphicsItem *parent) DRVideoScreen::~DRVideoScreen() {} +float init_delay = 1000; +bool DRVideoScreen::initialize_vlc() +{ + if (_vlcInstance != nullptr) + return vlc_initialized; + if (!ao_app->ao_config->video_backend_vlc()) + return false; + + qDebug() << "//// INTIALIZING VLC for " << this; + _vlcInstance = new VlcInstance(VlcCommon::args(), this); + _vlcPlayer = new VlcMediaPlayer(_vlcInstance); + + _widget = ao_app->m_courtroom; + _vlcWidget = new VlcWidgetVideo(_widget); + _vlcWidget->setMediaPlayer(_vlcPlayer); + _vlcPlayer->setVideoWidget(_vlcWidget); + + connect(_vlcPlayer, SIGNAL(stateChanged()), this, SLOT(vlc_stateChanged())); + //connect(_vlcPlayer, SIGNAL(mediaChanged()), this, SLOT(vlc_mediaChanged(libvlc_media_t*))); + + QTimer::singleShot(init_delay, this, &DRVideoScreen::set_vlc_initialized); + return false; +} + +void DRVideoScreen::set_vlc_initialized() +{ + vlc_initialized = true; + qDebug() << "//// VLC INITIALIZED DONE for " << this; +} + QString DRVideoScreen::get_file_name() const { return m_file_name; @@ -81,10 +104,6 @@ QString DRVideoScreen::get_file_name() const void DRVideoScreen::set_file_name(QString p_file_name) { - // if (m_file_name == p_file_name) - // { - // return; - // } stop(); qInfo() << "loading media file" << p_file_name; m_scanned = false; @@ -96,6 +115,13 @@ void DRVideoScreen::set_file_name(QString p_file_name) } if (ao_app->ao_config->video_backend_vlc()) { + if (!initialize_vlc()) + { + QTimer::singleShot(init_delay, this, [p_file_name, this] () { + DRVideoScreen::set_file_name(p_file_name); + }); + return; + } _vlcMedia = new VlcMedia(m_file_name, true, _vlcInstance); _vlcPlayer->open(_vlcMedia); } @@ -145,14 +171,21 @@ void DRVideoScreen::stop() { m_running = false; - if ( _vlcPlayer->state() == Vlc::State::Playing) - { - _vlcPlayer->stop(); - } if (m_player->state() != QMediaPlayer::StoppedState) { m_player->stop(); } + if (ao_app->ao_config->video_backend_vlc()) + { + if (!initialize_vlc()) + { + return; + } + if ( _vlcPlayer->state() == Vlc::State::Playing) + { + _vlcPlayer->stop(); + } + } } void DRVideoScreen::vlc_stateChanged() @@ -257,6 +290,11 @@ void DRVideoScreen::start_playback() { if (ao_app->ao_config->video_backend_vlc()) { + if (!initialize_vlc()) + { + QTimer::singleShot(init_delay, this, &DRVideoScreen::start_playback); + return; + } _vlcPlayer->setPosition(0); update_volume(); _vlcWidget->setGeometry(ao_app->m_courtroom->get_video_rect()); @@ -336,11 +374,17 @@ void DRVideoScreen::update_volume() m_player->setVolume(l_volume); } - // improve audio volume scaling for vlc since it's different from QMediaPlayer - int transformed_volume = sqrt(sqrt(l_volume) * 10) * 10; - if (_vlcPlayer->audio()->volume() != transformed_volume) + if (ao_app->ao_config->video_backend_vlc()) { - // qDebug() << "//// SET VOLUME " << l_volume << " LOG VOLUME " << transformed_volume; - _vlcPlayer->audio()->setVolume(transformed_volume); + if (!initialize_vlc()) + { + return; + } + // improve audio volume scaling for vlc since it's different from QMediaPlayer + int transformed_volume = sqrt(sqrt(l_volume) * 10) * 10; + if (_vlcPlayer->audio()->volume() != transformed_volume) + { + _vlcPlayer->audio()->setVolume(transformed_volume); + } } } diff --git a/src/mk2/graphicsvideoscreen.h b/src/mk2/graphicsvideoscreen.h index 3940be277..4f24375e7 100644 --- a/src/mk2/graphicsvideoscreen.h +++ b/src/mk2/graphicsvideoscreen.h @@ -83,12 +83,17 @@ public slots: VlcMedia *_vlcMedia; VlcMediaPlayer *_vlcPlayer; VlcWidgetVideo *_vlcWidget; - QGraphicsProxyWidget *_widgetProxy; + + bool vlc_initialized; void start_playback(); void finish_playback(); + bool initialize_vlc(); + + void set_vlc_initialized(); + Vlc::State m_vlc_state; private slots: From 9c198ea06632db18ac40c270be3f45c268f26d60 Mon Sep 17 00:00:00 2001 From: KG Date: Tue, 2 Jul 2024 20:29:59 +1000 Subject: [PATCH 9/9] made libvlc video appear in the new resizable viewport --- src/courtroom.cpp | 2 ++ src/mk2/graphicsvideoscreen.cpp | 40 +++++++++++++++++++---- src/mk2/graphicsvideoscreen.h | 3 ++ src/modules/widgets/droviewportwidget.cpp | 15 +++++++++ src/modules/widgets/droviewportwidget.h | 5 ++- 5 files changed, 58 insertions(+), 7 deletions(-) diff --git a/src/courtroom.cpp b/src/courtroom.cpp index 1ba5a0e34..653a0ac28 100644 --- a/src/courtroom.cpp +++ b/src/courtroom.cpp @@ -820,6 +820,8 @@ bool Courtroom::is_spectating() QRect Courtroom::get_video_rect() { + if (ui_viewport == nullptr) + return QRect(); return ui_viewport->geometry(); } diff --git a/src/mk2/graphicsvideoscreen.cpp b/src/mk2/graphicsvideoscreen.cpp index 20d6a003d..1ff01b637 100644 --- a/src/mk2/graphicsvideoscreen.cpp +++ b/src/mk2/graphicsvideoscreen.cpp @@ -41,6 +41,7 @@ DRVideoScreen::DRVideoScreen(AOApplication *ao_app, QGraphicsItem *parent) , m_player(new QMediaPlayer(this, QMediaPlayer::LowLatency)) { setAspectRatioMode(Qt::KeepAspectRatioByExpanding); + _widget = nullptr; // Setup libvlc _vlcInstance = nullptr; @@ -75,11 +76,9 @@ bool DRVideoScreen::initialize_vlc() if (!ao_app->ao_config->video_backend_vlc()) return false; - qDebug() << "//// INTIALIZING VLC for " << this; + // qDebug() << "//// INTIALIZING VLC for " << this; _vlcInstance = new VlcInstance(VlcCommon::args(), this); _vlcPlayer = new VlcMediaPlayer(_vlcInstance); - - _widget = ao_app->m_courtroom; _vlcWidget = new VlcWidgetVideo(_widget); _vlcWidget->setMediaPlayer(_vlcPlayer); _vlcPlayer->setVideoWidget(_vlcWidget); @@ -94,7 +93,34 @@ bool DRVideoScreen::initialize_vlc() void DRVideoScreen::set_vlc_initialized() { vlc_initialized = true; - qDebug() << "//// VLC INITIALIZED DONE for " << this; + // qDebug() << "//// VLC INITIALIZED DONE for " << this; +} + +void DRVideoScreen::set_video_parent(QWidget* parent) +{ + _widget = parent; + if (!initialize_vlc()) + { + return; + } + if (_widget != nullptr) + { + _vlcWidget->setParent(_widget); + _vlcWidget->setGeometry(_widget->rect()); + } + else + { + if (ao_app->m_courtroom->get_video_rect() != QRect()) + { + _vlcWidget->setParent(ao_app->m_courtroom); + _vlcWidget->setGeometry(ao_app->m_courtroom->get_video_rect()); + } + } +} + +void DRVideoScreen::resized() +{ + set_video_parent(_widget); } QString DRVideoScreen::get_file_name() const @@ -105,7 +131,6 @@ QString DRVideoScreen::get_file_name() const void DRVideoScreen::set_file_name(QString p_file_name) { stop(); - qInfo() << "loading media file" << p_file_name; m_scanned = false; m_video_available = false; m_file_name = p_file_name; @@ -122,11 +147,13 @@ void DRVideoScreen::set_file_name(QString p_file_name) }); return; } + qInfo() << "loading media file" << p_file_name << " for " << this; _vlcMedia = new VlcMedia(m_file_name, true, _vlcInstance); _vlcPlayer->open(_vlcMedia); } else { + qInfo() << "loading media file" << p_file_name << " for " << this; m_player->setMedia(QUrl::fromLocalFile(m_file_name)); } } @@ -297,7 +324,8 @@ void DRVideoScreen::start_playback() } _vlcPlayer->setPosition(0); update_volume(); - _vlcWidget->setGeometry(ao_app->m_courtroom->get_video_rect()); + // qInfo() << "/// start playback for " << this << " at " << ao_app->m_courtroom->get_video_rect() << " on parent " << _vlcWidget->parentWidget(); + set_video_parent(_widget); _vlcWidget->show(); _vlcWidget->activateWindow(); _vlcWidget->raise(); diff --git a/src/mk2/graphicsvideoscreen.h b/src/mk2/graphicsvideoscreen.h index 4f24375e7..6028672c0 100644 --- a/src/mk2/graphicsvideoscreen.h +++ b/src/mk2/graphicsvideoscreen.h @@ -43,6 +43,7 @@ class DRVideoScreen : public QGraphicsVideoItem DRVideoScreen(AOApplication *ao_app, QGraphicsItem *parent = nullptr); ~DRVideoScreen(); + void set_video_parent(QWidget *parent); QString get_file_name() const; QWidget *_widget; @@ -55,6 +56,8 @@ public slots: void stop(); + void resized(); + signals: void started(); diff --git a/src/modules/widgets/droviewportwidget.cpp b/src/modules/widgets/droviewportwidget.cpp index d1ef00489..5b164a9fc 100644 --- a/src/modules/widgets/droviewportwidget.cpp +++ b/src/modules/widgets/droviewportwidget.cpp @@ -32,6 +32,10 @@ void DROViewportWidget::ConstructViewport(ThemeSceneType t_scene) this->scene()->addItem(m_VpShouts); this->scene()->addItem(m_VpWtce); + // Video player needs special treatment since VLC doesn't use graphics scene + m_VpVideo->set_video_parent(this); + connect(this, SIGNAL(Resized()), m_VpVideo, SLOT(resized())); + m_VpBackground->start(); m_VpPlayer->start(); @@ -44,6 +48,8 @@ void DROViewportWidget::ConstructViewport(ThemeSceneType t_scene) connect(m_VpPlayer, SIGNAL(done()), this, SLOT(OnPreanimDone())); ConstructUserInterface(); + + this->installEventFilter(this); } void DROViewportWidget::ProcessIncomingMessage(ICMessageData *t_IncomingMessage) @@ -253,3 +259,12 @@ void DROViewportWidget::OnPreanimDone() m_VpPlayer->start(); } } + +bool DROViewportWidget::eventFilter(QObject *obj, QEvent *event) +{ + // qDebug() << "//// EVENT " << event->type(); + if (event->type() == QEvent::Resize) + emit Resized(); + return QObject::eventFilter(obj, event); +} + diff --git a/src/modules/widgets/droviewportwidget.h b/src/modules/widgets/droviewportwidget.h index 4726e8f7c..c847f8f4a 100644 --- a/src/modules/widgets/droviewportwidget.h +++ b/src/modules/widgets/droviewportwidget.h @@ -45,14 +45,17 @@ class DROViewportWidget : public DRGraphicsView signals: void VideoDone(); void PreanimDone(); + void Resized(); public slots: void OnObjectionDone(); void OnVideoDone(); void OnPreanimDone(); -private: +protected: + bool eventFilter(QObject *obj, QEvent *event) override; +private: DRGraphicsView *m_UserInterface = nullptr; KeyframePlayer *m_ShoutsPlayer = nullptr;