diff --git a/src/app/avadapter.cpp b/src/app/avadapter.cpp index c2c6a90217a7588a36c819e966a747aaf9d9a833..53bbf71e79f9a84eee924f686b6ade700310df86 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 8f76d1deb5b823b7abb41eb0b9cbbe83be268826..d6296ea5bbda3307ac16ef0f1c8ebf7425cc46e2 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 aa477673f6cde3b6ebedb21dfb47478949fffb09..f6ac8c47eaab0f77b059ecbbac3f0c1bb1cb848a 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 254b361fa84bf68deac96fea1f935880c86e465b..b594ebddb677707c7427321895cd24d0cb165540 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 4d62fdca079c2f6d0a65e377f22380c8d3443ce6..ea7033a4787cf4637940e64d3a076412bb22013e 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 bb18c0b09ea197431ac0ffb9392e3a7628f90d6b..e53649c09c64815563087e57594e8ca5fc4fa7ed 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 70bd98f369c50132a5864bcc7c1de20e9743351f..214d23716068e2d3a6224165a2b25c200b1dcb79 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 62e6662ed5237810cb7c28f7716e908c9b4ca340..cb4a5287422b85543194462f16261d683cb21c2a 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 {