diff --git a/src/api/avmodel.h b/src/api/avmodel.h index 65cf1023e2f23b14b7ec863c0aecd78b4141dfb2..87d957e2f10fd8cdc86da1e026b957b76a85c191 100644 --- a/src/api/avmodel.h +++ b/src/api/avmodel.h @@ -251,7 +251,7 @@ public: */ const video::Renderer& getRenderer(const QString& id) const; /** - * Render a file to the call id specified + * @deprecated Render a file to the call id specified * @param uri the path of the file * @param callId * @note callId can be omitted to switch the input of the local recorder @@ -266,7 +266,7 @@ public: */ void switchInputTo(const QString& id, const QString& callId = {}); /** - * Render the current display to the call id specified + * @deprecated Render the current display to the call id specified * @param idx of the display * @param x top left of the area * @param y top up of the area @@ -276,6 +276,15 @@ public: * @note callId can be omitted to switch the input of the local recorder */ void setDisplay(int idx, int x, int y, int w, int h, const QString& callId = {}); + /** + * Get the current display resource string + * @param idx of the display + * @param x top left of the area + * @param y top up of the area + * @param w width of the area + * @param h height of the area + */ + QString getDisplay(int idx, int x, int y, int w, int h); /** * Get informations on the rendered device * @param call_id linked call to the renderer diff --git a/src/api/newcallmodel.h b/src/api/newcallmodel.h index ca8e5479a85a3e95b83789591ea5625c081965e0..47df435a52012ade73ca9508e2d6908f42a15cc9 100644 --- a/src/api/newcallmodel.h +++ b/src/api/newcallmodel.h @@ -67,6 +67,7 @@ public: const account::Info& owner; enum class Media { NONE, AUDIO, VIDEO }; + enum class MediaRequestType { FILESHARING, SCREENSHARING, CAMERA }; NewCallModel(const account::Info& owner, const CallbacksHandler& callbacksHandler, @@ -85,8 +86,15 @@ public: * Request a media change in a ongoing call. * @param callId * @param mediaLabel label of media to be changed - */ - void requestMediaChange(const QString& callId, const QString& mediaLabel); + * @param source + * @param type + * @param mute + */ + void requestMediaChange(const QString& callId, + const QString& mediaLabel, + const QString& source, + MediaRequestType type, + bool mute); /** * Get the call from its call id diff --git a/src/avmodel.cpp b/src/avmodel.cpp index 43cb55bdcbe8cc6efb98b6faf7ce38a5815d3e4e..c261a2e1de6fefc6e2c2483e079f6fdace4bc203 100644 --- a/src/avmodel.cpp +++ b/src/avmodel.cpp @@ -555,9 +555,20 @@ AVModel::setInputFile(const QString& uri, const QString& callId) void AVModel::setDisplay(int idx, int x, int y, int w, int h, const QString& callId) +{ + auto resource = getDisplay(idx, x, y, w, h); + if (callId.isEmpty()) { + VideoManager::instance().switchInput(resource); + } else { + CallManager::instance().switchInput(callId, resource); + } +} + +QString +AVModel::getDisplay(int idx, int x, int y, int w, int h) { QString sep = DRing::Media::VideoProtocolPrefix::SEPARATOR; - auto resource = QString("%1%2:%3+%4,%5 %6x%7") + return QString("%1%2:%3+%4,%5 %6x%7") .arg(DRing::Media::VideoProtocolPrefix::DISPLAY) .arg(sep) .arg(idx) @@ -565,11 +576,6 @@ AVModel::setDisplay(int idx, int x, int y, int w, int h, const QString& callId) .arg(y) .arg(w) .arg(h); - if (callId.isEmpty()) { - VideoManager::instance().switchInput(resource); - } else { - CallManager::instance().switchInput(callId, resource); - } } void diff --git a/src/newcallmodel.cpp b/src/newcallmodel.cpp index ad91b6c1f08c3f7959c38bad9313d57bc46602bc..0d26ae6fa71cead8fffaf93d29673f5354dfff21 100644 --- a/src/newcallmodel.cpp +++ b/src/newcallmodel.cpp @@ -42,6 +42,7 @@ // Qt #include <QObject> #include <QString> +#include <QUrl> // std #include <chrono> @@ -357,7 +358,7 @@ NewCallModel::createCall(const QString& uri, bool isAudioOnly, VectorMapStringSt } void -NewCallModel::requestMediaChange(const QString& callId, const QString& mediaLabel) +NewCallModel::requestMediaChange(const QString& callId, const QString& mediaLabel, const QString& uri, MediaRequestType type, bool mute) { // Main audio: audio_0 // Main video: video_0 @@ -366,57 +367,102 @@ NewCallModel::requestMediaChange(const QString& callId, const QString& mediaLabe if (!callInfo) return; - if (callInfo->type == call::Type::CONFERENCE) { - if (mediaLabel.contains("audio_0")) { - CallManager::instance().muteLocalMedia(callId, - DRing::Media::Details::MEDIA_TYPE_AUDIO, - !callInfo->audioMuted); - callInfo->audioMuted = !callInfo->audioMuted; - } else if (mediaLabel.contains("video_0")) { - CallManager::instance().muteLocalMedia(callId, - DRing::Media::Details::MEDIA_TYPE_VIDEO, - !callInfo->videoMuted); - callInfo->videoMuted = !callInfo->videoMuted; + QString sep = DRing::Media::VideoProtocolPrefix::SEPARATOR; + QString resource = ""; + int found = 0; + QString srctype = MediaAttributeValue::SRC_TYPE_CAPTURE_DEVICE; + + switch (type) { + case MediaRequestType::FILESHARING: { + // File sharing + resource = !uri.isEmpty() ? QString("%1%2%3") + .arg(DRing::Media::VideoProtocolPrefix::FILE) + .arg(sep) + .arg(QUrl(uri).toLocalFile()) + : DRing::Media::VideoProtocolPrefix::NONE; + if (callInfo->type == call::Type::CONFERENCE) { + CallManager::instance().switchInput(callId, resource); + return; } - if (callInfo->status == call::Status::IN_PROGRESS) - emit callInfosChanged(owner.id, callId); + if (!resource.isEmpty()) + srctype = MediaAttributeValue::SRC_TYPE_FILE; + + break; + } + case MediaRequestType::SCREENSHARING: { + // Screen/window sharing + resource = uri; + if (callInfo->type == call::Type::CONFERENCE) { + CallManager::instance().switchInput(callId, resource); + return; + } + srctype = MediaAttributeValue::SRC_TYPE_DISPLAY; + break; + } + case MediaRequestType::CAMERA: { + // Camera device + resource = !uri.isEmpty() ? QString("%1%2%3") + .arg(DRing::Media::VideoProtocolPrefix::CAMERA) + .arg(sep) + .arg(uri) + : DRing::Media::VideoProtocolPrefix::NONE; + + if (callInfo->type == call::Type::CONFERENCE) { + if (mediaLabel.contains("audio_0")) { + CallManager::instance().muteLocalMedia(callId, + DRing::Media::Details::MEDIA_TYPE_AUDIO, + !callInfo->audioMuted && mute); + } else if (mediaLabel.contains("video_0")) { + CallManager::instance().muteLocalMedia(callId, + DRing::Media::Details::MEDIA_TYPE_VIDEO, + !callInfo->videoMuted && mute); + } + return; + } + + srctype = MediaAttributeValue::SRC_TYPE_CAPTURE_DEVICE; + break; + } + default: return; } auto proposedList = callInfo->mediaList; - - int found = 0; for (auto& item : proposedList) { if (item[MediaAttributeKey::LABEL] == mediaLabel) { + mute = resource.isEmpty() ? item[MediaAttributeKey::MUTED] == "false" : mute; item[MediaAttributeKey::ENABLED] = "true"; - item[MediaAttributeKey::MUTED] = item[MediaAttributeKey::MUTED] == "true" ? "false" - : "true"; + item[MediaAttributeKey::MUTED] = mute ? "true" : "false"; + item[MediaAttributeKey::SOURCE_TYPE] = srctype; + item[MediaAttributeKey::SOURCE] = resource.isEmpty() ? item[MediaAttributeKey::SOURCE] : resource; + break; } found++; } + if (found == proposedList.size() && mediaLabel == "video_0") { + mute &= !resource.isEmpty(); MapStringString mediaAttribute = {{MediaAttributeKey::MEDIA_TYPE, MediaAttributeValue::VIDEO}, {MediaAttributeKey::ENABLED, "true"}, - {MediaAttributeKey::MUTED, "false"}, - {MediaAttributeKey::SOURCE, ""}, - {MediaAttributeKey::LABEL, "video_0"}}; + {MediaAttributeKey::MUTED, + mute ? "true" : "false"}, + {MediaAttributeKey::SOURCE_TYPE, srctype}, + {MediaAttributeKey::SOURCE, resource}, + {MediaAttributeKey::LABEL, mediaLabel}}; proposedList.push_back(mediaAttribute); - // We should prepare it here for adding file and screen sharing - // for now it supports only adding main video to an audio only call } CallManager::instance().requestMediaChange(callId, proposedList); // If media existed and its mute state was changed here, then we should // update the mediaList because we will not receive signal // mediaNegotiationStatus if (found < callInfo->mediaList.size()) { - callInfo->mediaList[found][MediaAttributeKey::MUTED] - = callInfo->mediaList[found][MediaAttributeKey::MUTED] == "true" ? "false" : "true"; + callInfo->mediaList = proposedList; if (mediaLabel.contains("audio_0")) { - callInfo->audioMuted = !callInfo->audioMuted; + callInfo->audioMuted = mute; } else if (mediaLabel.contains("video_0")) { - callInfo->videoMuted = !callInfo->videoMuted; + callInfo->videoMuted = mute; } if (callInfo->status == call::Status::IN_PROGRESS) emit callInfosChanged(owner.id, callId); @@ -516,7 +562,7 @@ NewCallModel::toggleMedia(const QString& callId, const NewCallModel::Media media if (!hasCall(callId)) return; auto mediaLabel = media == NewCallModel::Media::VIDEO ? "video_0" : "audio_0"; - requestMediaChange(callId, mediaLabel); + requestMediaChange(callId, mediaLabel, "", MediaRequestType::CAMERA, true); } void