From 088c367485edca9b638f62ea4816cac573df4eec Mon Sep 17 00:00:00 2001 From: Aline Gondim Santos <aline.gondimsantos@savoirfairelinux.com> Date: Tue, 3 Oct 2023 07:18:55 -0300 Subject: [PATCH] filesharing: integrate mediaplayer API GitLab: https://git.jami.net/savoirfairelinux/jami-daemon/-/issues/485 Change-Id: I148f19eb76a526a5ab38c5f4a83f45ea66e348e4 --- src/app/avadapter.cpp | 24 ++++++++- src/libclient/api/avmodel.h | 15 ++++++ src/libclient/avmodel.cpp | 51 +++++++++++++++++++ src/libclient/callbackshandler.cpp | 5 ++ src/libclient/callbackshandler.h | 6 ++- src/libclient/qtwrapper/instancemanager.cpp | 1 + src/libclient/qtwrapper/videomanager_wrap.cpp | 6 +++ src/libclient/qtwrapper/videomanager_wrap.h | 41 +++++++++++++++ 8 files changed, 146 insertions(+), 3 deletions(-) diff --git a/src/app/avadapter.cpp b/src/app/avadapter.cpp index c2c6a9021..53bbf71e7 100644 --- a/src/app/avadapter.cpp +++ b/src/app/avadapter.cpp @@ -195,8 +195,28 @@ AvAdapter::shareFile(const QString& filePath) auto callId = lrcInstance_->getCurrentCallId(); if (!callId.isEmpty()) { muteCamera_ = !isCapturing(); - lrcInstance_->getCurrentCallModel() - ->addMedia(callId, filePath, lrc::api::CallModel::MediaRequestType::FILESHARING); + auto resource = QString("%1%2%3") + .arg(libjami::Media::VideoProtocolPrefix::FILE) + .arg(libjami::Media::VideoProtocolPrefix::SEPARATOR) + .arg(QUrl(filePath).toLocalFile()); + + Utils::oneShotConnect(&lrcInstance_->avModel(), + &lrc::api::AVModel::fileOpened, + this, + [this, callId, filePath, resource](bool hasAudio, bool hasVideo) { + // TODO: add videos's audio while adding file sharing + if (hasVideo) { + lrcInstance_->avModel().pausePlayer(resource, false); + lrcInstance_->avModel().setAutoRestart(resource, true); + lrcInstance_->getCurrentCallModel() + ->addMedia(callId, filePath, lrc::api::CallModel::MediaRequestType::FILESHARING); + } else { + // Close media player because we are not going to start sharing + lrcInstance_->avModel().closeMediaPlayer(resource); + } + }); + + lrcInstance_->avModel().createMediaPlayer(resource); } } diff --git a/src/libclient/api/avmodel.h b/src/libclient/api/avmodel.h index 8f76d1deb..d6296ea5b 100644 --- a/src/libclient/api/avmodel.h +++ b/src/libclient/api/avmodel.h @@ -286,6 +286,15 @@ public: */ Q_SLOT void updateRenderersFPSInfo(QString rendererId); + QString createMediaPlayer(const QString& resource); + void closeMediaPlayer(const QString& resource); + Q_INVOKABLE bool pausePlayer(const QString& id, bool pause); + Q_INVOKABLE bool mutePlayerAudio(const QString& id, bool mute); + Q_INVOKABLE bool playerSeekToTime(const QString& id, int time); + Q_INVOKABLE qint64 getPlayerPosition(const QString& id); + Q_INVOKABLE qint64 getPlayerDuration(const QString& id); + Q_INVOKABLE void setAutoRestart(const QString& id, bool restart); + Q_SIGNALS: /** * Emitted after an update of renderer's fps @@ -332,6 +341,12 @@ Q_SIGNALS: * @param filePath */ void recordPlaybackStopped(const QString& filePath); + /** + * returns if Media Player has audio and/or video + * @param hasAudio + * @param hasVideo + */ + void fileOpened(bool hasAudio, bool hasVideo); private: std::unique_ptr<AVModelPimpl> pimpl_; diff --git a/src/libclient/avmodel.cpp b/src/libclient/avmodel.cpp index aa477673f..f6ac8c47e 100644 --- a/src/libclient/avmodel.cpp +++ b/src/libclient/avmodel.cpp @@ -795,6 +795,46 @@ AVModel::useDirectRenderer() const #endif } +QString AVModel::createMediaPlayer(const QString& resource) +{ + return VideoManager::instance().createMediaPlayer(resource); +} + +void AVModel::closeMediaPlayer(const QString& resource) +{ + VideoManager::instance().closeMediaPlayer(resource); +} + +bool AVModel::pausePlayer(const QString& id, bool pause) +{ + return VideoManager::instance().pausePlayer(id, pause); +} + +bool AVModel::mutePlayerAudio(const QString& id, bool mute) +{ + return VideoManager::instance().mutePlayerAudio(id, mute); +} + +bool AVModel::playerSeekToTime(const QString& id, int time) +{ + return VideoManager::instance().playerSeekToTime(id, time); +} + +qint64 AVModel::getPlayerPosition(const QString& id) +{ + return VideoManager::instance().getPlayerPosition(id); +} + +qint64 AVModel::getPlayerDuration(const QString& id) +{ + return VideoManager::instance().getPlayerDuration(id); +} + +void AVModel::setAutoRestart(const QString& id, bool restart) +{ + VideoManager::instance().setAutoRestart(id, restart); +} + AVModelPimpl::AVModelPimpl(AVModel& linked, const CallbacksHandler& callbacksHandler) : callbacksHandler(callbacksHandler) , linked_(linked) @@ -826,6 +866,17 @@ AVModelPimpl::AVModelPimpl(AVModel& linked, const CallbacksHandler& callbacksHan &AVModelPimpl::onDecodingStopped, Qt::DirectConnection); + // Media player connection + connect(&callbacksHandler, + &CallbacksHandler::fileOpened, + this, + [this](const QString& path, MapStringString info) { + Q_UNUSED(path); + bool hasAudio = info["audio_stream"].toInt() >= 0; + bool hasVideo = info["video_stream"].toInt() >= 0; + Q_EMIT linked_.fileOpened(hasAudio, hasVideo); + }); + auto startedPreview = false; auto restartRenderers = [&](const QStringList& callList) { for (const auto& callId : callList) { diff --git a/src/libclient/callbackshandler.cpp b/src/libclient/callbackshandler.cpp index 254b361fa..b594ebddb 100644 --- a/src/libclient/callbackshandler.cpp +++ b/src/libclient/callbackshandler.cpp @@ -284,6 +284,11 @@ CallbacksHandler::CallbacksHandler(const Lrc& parent) this, &CallbacksHandler::deviceEvent, Qt::QueuedConnection); + connect(&VideoManager::instance(), + &VideoManagerInterface::fileOpened, + this, + &CallbacksHandler::fileOpened, + Qt::DirectConnection); connect(&ConfigurationManager::instance(), &ConfigurationManagerInterface::audioDeviceEvent, diff --git a/src/libclient/callbackshandler.h b/src/libclient/callbackshandler.h index 4d62fdca0..ea7033a47 100644 --- a/src/libclient/callbackshandler.h +++ b/src/libclient/callbackshandler.h @@ -295,6 +295,11 @@ Q_SIGNALS: */ void deviceEvent(); + /** + * Emitted when a media player is opened + */ + void fileOpened(const QString& path, const MapStringString& info); + /** * Emitted when an audio level is plugged or unplugged */ @@ -365,7 +370,6 @@ Q_SIGNALS: const QString& conversationId, const MapStringString& preferences); void recordingStateChanged(const QString& callId, bool state); - /** * Emitted when a conversation receives a new position */ diff --git a/src/libclient/qtwrapper/instancemanager.cpp b/src/libclient/qtwrapper/instancemanager.cpp index bb18c0b09..e53649c09 100644 --- a/src/libclient/qtwrapper/instancemanager.cpp +++ b/src/libclient/qtwrapper/instancemanager.cpp @@ -41,6 +41,7 @@ InstanceManagerInterface::InstanceManagerInterface(bool muteDaemon) #ifdef ENABLE_VIDEO using libjami::VideoSignal; + using libjami::MediaPlayerSignal; #endif #ifndef MUTE_LIBJAMI diff --git a/src/libclient/qtwrapper/videomanager_wrap.cpp b/src/libclient/qtwrapper/videomanager_wrap.cpp index 70bd98f36..214d23716 100644 --- a/src/libclient/qtwrapper/videomanager_wrap.cpp +++ b/src/libclient/qtwrapper/videomanager_wrap.cpp @@ -23,6 +23,7 @@ VideoManagerInterface::VideoManagerInterface() #ifdef ENABLE_VIDEO using libjami::exportable_callback; using libjami::VideoSignal; + using libjami::MediaPlayerSignal; videoHandlers = {exportable_callback<VideoSignal::DeviceEvent>([this]() { Q_EMIT deviceEvent(); }), exportable_callback<VideoSignal::DecodingStarted>([this](const std::string& id, @@ -41,6 +42,11 @@ VideoManagerInterface::VideoManagerInterface() Q_EMIT decodingStopped(QString(id.c_str()), QString(shmPath.c_str()), isMixer); + }), + exportable_callback<MediaPlayerSignal::FileOpened>( + [this](const std::string& path, const std::map<std::string, std::string>& info) { + Q_EMIT fileOpened(QString(path.c_str()), + convertMap(info)); })}; #endif } diff --git a/src/libclient/qtwrapper/videomanager_wrap.h b/src/libclient/qtwrapper/videomanager_wrap.h index 62e6662ed..cb4a52874 100644 --- a/src/libclient/qtwrapper/videomanager_wrap.h +++ b/src/libclient/qtwrapper/videomanager_wrap.h @@ -194,11 +194,52 @@ public Q_SLOTS: // METHODS return convertMap(libjami::getRenderer(id.toStdString())); } + QString createMediaPlayer(const QString& path) + { + return QString::fromStdString(libjami::createMediaPlayer(path.toStdString())); + } + + bool closeMediaPlayer(const QString& id) + { + return libjami::closeMediaPlayer(id.toStdString()); + } + + bool pausePlayer(const QString& id, bool pause) + { + return libjami::pausePlayer(id.toStdString(), pause); + } + + bool mutePlayerAudio(const QString& id, bool mute) + { + return libjami::mutePlayerAudio(id.toStdString(), mute); + } + + bool playerSeekToTime(const QString& id, int time) + { + return libjami::playerSeekToTime(id.toStdString(), time); + } + + qint64 getPlayerPosition(const QString& id) + { + return libjami::getPlayerPosition(id.toStdString()); + } + + qint64 getPlayerDuration(const QString& id) + { + return libjami::getPlayerDuration(id.toStdString()); + } + + void setAutoRestart(const QString& id, bool restart) + { + libjami::setAutoRestart(id.toStdString(), restart); + } + Q_SIGNALS: // SIGNALS void deviceEvent(); void decodingStarted( const QString& id, const QString& shmPath, int width, int height, bool isMixer); void decodingStopped(const QString& id, const QString& shmPath, bool isMixer); + void fileOpened(const QString& path, const MapStringString& info); }; namespace org { -- GitLab