diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 3ff9b1575..727cf2cd2 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -2332,6 +2332,9 @@ groupCallStream channel_id:int32 scale:int32 time_offset:int53 = GroupCallStream //@description Represents a list of group call streams @streams A list of group call streams groupCallStreams streams:vector = GroupCallStreams; +//@description Represents an RTMP url @url The URL @stream_key Stream key +rtmpUrl url:string stream_key:string = RtmpUrl; + //@description Describes a recently speaking participant in a group call @participant_id Group call participant identifier @is_speaking True, is the user has spoken recently groupCallRecentSpeaker participant_id:MessageSender is_speaking:Bool = GroupCallRecentSpeaker; @@ -5278,9 +5281,15 @@ setVideoChatDefaultParticipant chat_id:int53 default_participant_id:MessageSende //@chat_id Chat identifier, in which the video chat will be created //@title Group call title; if empty, chat title will be used //@start_date Point in time (Unix timestamp) when the group call is supposed to be started by an administrator; 0 to start the video chat immediately. The date must be at least 10 seconds and at most 8 days in the future -//@is_rtmp_stream True, if the chat will be an RTMP stream instead of an ordinary video chat +//@is_rtmp_stream True, if the chat will be an RTMP stream instead of an ordinary video chat; requires creator privileges createVideoChat chat_id:int53 title:string start_date:int32 is_rtmp_stream:Bool = GroupCallId; +//@description Returns RTMP URL for streaming to the chat; requires creator privileges @chat_id Chat identifier +getVideoChatRtmpUrl chat_id:int53 = RtmpUrl; + +//@description Replaces the current RTMP URL for streaming to the chat; requires creator privileges @chat_id Chat identifier +replaceVideoChatRtmpUrl chat_id:int53 = RtmpUrl; + //@description Returns information about a group call @group_call_id Group call identifier getGroupCall group_call_id:int32 = GroupCall; diff --git a/td/telegram/GroupCallManager.cpp b/td/telegram/GroupCallManager.cpp index 84e41722a..09b76f6c1 100644 --- a/td/telegram/GroupCallManager.cpp +++ b/td/telegram/GroupCallManager.cpp @@ -245,6 +245,41 @@ class CreateGroupCallQuery final : public Td::ResultHandler { } }; +class GetGroupCallRtmpStreamUrlGroupCallQuery final : public Td::ResultHandler { + Promise> promise_; + DialogId dialog_id_; + + public: + explicit GetGroupCallRtmpStreamUrlGroupCallQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(DialogId dialog_id, bool revoke) { + dialog_id_ = dialog_id; + + auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); + CHECK(input_peer != nullptr); + + send_query( + G()->net_query_creator().create(telegram_api::phone_getGroupCallStreamRtmpUrl(std::move(input_peer), revoke))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + promise_.set_value(td_api::make_object(ptr->url_, ptr->key_)); + } + + void on_error(Status status) final { + td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "GetGroupCallRtmpStreamUrlGroupCallQuery"); + promise_.set_error(std::move(status)); + } +}; + class GetGroupCallQuery final : public Td::ResultHandler { Promise> promise_; @@ -1308,6 +1343,23 @@ void GroupCallManager::create_voice_chat(DialogId dialog_id, string title, int32 ->send(dialog_id, title, start_date, is_rtmp_stream); } +void GroupCallManager::get_voice_chat_rtmp_stream_url(DialogId dialog_id, bool revoke, + Promise> &&promise) { + if (!dialog_id.is_valid()) { + return promise.set_error(Status::Error(400, "Invalid chat identifier specified")); + } + if (!td_->messages_manager_->have_dialog_force(dialog_id, "get_voice_chat_rtmp_stream_url")) { + return promise.set_error(Status::Error(400, "Chat not found")); + } + if (!td_->messages_manager_->have_input_peer(dialog_id, AccessRights::Read)) { + return promise.set_error(Status::Error(400, "Can't access chat")); + } + + TRY_STATUS_PROMISE(promise, can_manage_group_calls(dialog_id)); + + td_->create_handler(std::move(promise))->send(dialog_id, revoke); +} + void GroupCallManager::on_voice_chat_created(DialogId dialog_id, InputGroupCallId input_group_call_id, Promise &&promise) { TRY_STATUS_PROMISE(promise, G()->close_status()); diff --git a/td/telegram/GroupCallManager.h b/td/telegram/GroupCallManager.h index 72b88fd88..fb4908038 100644 --- a/td/telegram/GroupCallManager.h +++ b/td/telegram/GroupCallManager.h @@ -52,6 +52,9 @@ class GroupCallManager final : public Actor { void create_voice_chat(DialogId dialog_id, string title, int32 start_date, bool is_rtmp_stream, Promise &&promise); + void get_voice_chat_rtmp_stream_url(DialogId dialog_id, bool revoke, + Promise> &&promise); + void get_group_call(GroupCallId group_call_id, Promise> &&promise); void on_update_group_call_rights(InputGroupCallId input_group_call_id); diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index f911def51..1190ebc1d 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -5745,6 +5745,18 @@ void Td::on_request(uint64 id, td_api::createVideoChat &request) { request.is_rtmp_stream_, std::move(query_promise)); } +void Td::on_request(uint64 id, const td_api::getVideoChatRtmpUrl &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + group_call_manager_->get_voice_chat_rtmp_stream_url(DialogId(request.chat_id_), false, std::move(promise)); +} + +void Td::on_request(uint64 id, const td_api::replaceVideoChatRtmpUrl &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + group_call_manager_->get_voice_chat_rtmp_stream_url(DialogId(request.chat_id_), true, std::move(promise)); +} + void Td::on_request(uint64 id, const td_api::getGroupCall &request) { CHECK_IS_USER(); CREATE_REQUEST_PROMISE(); diff --git a/td/telegram/Td.h b/td/telegram/Td.h index 3aae6c132..a60c9bc6d 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -744,6 +744,10 @@ class Td final : public Actor { void on_request(uint64 id, td_api::createVideoChat &request); + void on_request(uint64 id, const td_api::getVideoChatRtmpUrl &request); + + void on_request(uint64 id, const td_api::replaceVideoChatRtmpUrl &request); + void on_request(uint64 id, const td_api::getGroupCall &request); void on_request(uint64 id, const td_api::startScheduledGroupCall &request); diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index c43304b46..3b7325e88 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -3023,6 +3023,14 @@ class CliClient final : public Actor { bool is_rtmp_stream; get_args(args, chat_id, title, start_date, is_rtmp_stream); send_request(td_api::make_object(chat_id, title, start_date, is_rtmp_stream)); + } else if (op == "gvcru") { + ChatId chat_id; + get_args(args, chat_id); + send_request(td_api::make_object(chat_id)); + } else if (op == "rvcru") { + ChatId chat_id; + get_args(args, chat_id); + send_request(td_api::make_object(chat_id)); } else if (op == "ggc") { send_request(td_api::make_object(as_group_call_id(args))); } else if (op == "ggcs") {