mirror of
https://github.com/kunkundi/crossdesk.git
synced 2025-10-26 20:25:34 +08:00
[feat] support multiple streams in sdp
This commit is contained in:
@@ -89,7 +89,9 @@ int IceAgent::CreateIceAgent(nice_cb_state_changed_t on_state_changed,
|
||||
LOG_ERROR("Failed to add stream");
|
||||
}
|
||||
|
||||
nice_agent_set_stream_name(agent_, stream_id_, "video");
|
||||
if (has_video_stream_) {
|
||||
nice_agent_set_stream_name(agent_, stream_id_, "video");
|
||||
}
|
||||
|
||||
if (enable_turn_) {
|
||||
nice_agent_set_relay_info(agent_, stream_id_, n_components_,
|
||||
@@ -147,11 +149,6 @@ int IceAgent::DestroyIceAgent() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *IceAgent::GetLocalStreamSdp() {
|
||||
local_sdp_ = nice_agent_generate_local_stream_sdp(agent_, stream_id_, true);
|
||||
return local_sdp_.c_str();
|
||||
}
|
||||
|
||||
const char *IceAgent::GenerateLocalSdp() {
|
||||
if (!nice_inited_) {
|
||||
LOG_ERROR("Nice agent has not been initialized");
|
||||
@@ -168,12 +165,60 @@ const char *IceAgent::GenerateLocalSdp() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
local_sdp_ = nice_agent_generate_local_sdp(agent_);
|
||||
video_stream_sdp_ = nice_agent_generate_local_sdp(agent_);
|
||||
audio_stream_sdp_ = video_stream_sdp_;
|
||||
data_stream_sdp_ = video_stream_sdp_;
|
||||
local_sdp_ = video_stream_sdp_;
|
||||
|
||||
if (has_audio_stream_) {
|
||||
std::string to_replace = "video";
|
||||
std::string replacement = "audio";
|
||||
size_t pos = 0;
|
||||
while ((pos = audio_stream_sdp_.find(to_replace, pos)) !=
|
||||
std::string::npos) {
|
||||
audio_stream_sdp_.replace(pos, to_replace.length(), replacement);
|
||||
pos += replacement.length();
|
||||
}
|
||||
local_sdp_ += audio_stream_sdp_;
|
||||
}
|
||||
|
||||
if (has_data_stream_) {
|
||||
std::string to_replace = "video";
|
||||
std::string replacement = "data";
|
||||
size_t pos = 0;
|
||||
while ((pos = data_stream_sdp_.find(to_replace, pos)) !=
|
||||
std::string::npos) {
|
||||
data_stream_sdp_.replace(pos, to_replace.length(), replacement);
|
||||
pos += replacement.length();
|
||||
}
|
||||
local_sdp_ += data_stream_sdp_;
|
||||
}
|
||||
|
||||
LOG_INFO("Generate local sdp:[\n{}]", local_sdp_.c_str());
|
||||
|
||||
return local_sdp_.c_str();
|
||||
}
|
||||
|
||||
const char *IceAgent::GetLocalStreamSdp(uint32_t stream_id) {
|
||||
if (!nice_inited_) {
|
||||
LOG_ERROR("Nice agent has not been initialized");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (nullptr == agent_) {
|
||||
LOG_ERROR("Nice agent is nullptr");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (destroyed_) {
|
||||
LOG_ERROR("Nice agent is destroyed");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
local_sdp_ = nice_agent_generate_local_stream_sdp(agent_, stream_id, true);
|
||||
return local_sdp_.c_str();
|
||||
}
|
||||
|
||||
int IceAgent::SetRemoteSdp(const char *remote_sdp) {
|
||||
if (!nice_inited_) {
|
||||
LOG_ERROR("Nice agent has not been initialized");
|
||||
|
||||
@@ -43,10 +43,10 @@ class IceAgent {
|
||||
|
||||
int DestroyIceAgent();
|
||||
|
||||
const char* GetLocalStreamSdp();
|
||||
|
||||
const char* GenerateLocalSdp();
|
||||
|
||||
const char* GetLocalStreamSdp(uint32_t stream_id);
|
||||
|
||||
int SetRemoteSdp(const char* remote_sdp);
|
||||
|
||||
int GatherCandidates();
|
||||
@@ -70,6 +70,17 @@ class IceAgent {
|
||||
std::string turn_username_ = "";
|
||||
std::string turn_password_ = "";
|
||||
|
||||
bool has_video_stream_ = true;
|
||||
uint32_t n_video_streams_ = 1;
|
||||
std::string video_stream_sdp_;
|
||||
bool has_audio_stream_ = true;
|
||||
uint32_t n_audio_streams_ = 1;
|
||||
std::string audio_stream_sdp_;
|
||||
bool has_data_stream_ = true;
|
||||
uint32_t n_data_streams_ = 1;
|
||||
std::string data_stream_sdp_;
|
||||
|
||||
public:
|
||||
std::thread nice_thread_;
|
||||
std::atomic<NiceAgent*> agent_{nullptr};
|
||||
std::atomic<GMainLoop*> gloop_{nullptr};
|
||||
|
||||
@@ -380,35 +380,30 @@ int IceTransmission::GatherCandidates() {
|
||||
}
|
||||
|
||||
int IceTransmission::SetRemoteSdp(const std::string &remote_sdp) {
|
||||
ice_agent_->SetRemoteSdp(remote_sdp.c_str());
|
||||
// LOG_INFO("[{}] set remote sdp", user_id_);
|
||||
|
||||
// GetAceptedVideoPayloadType(remote_sdp);
|
||||
// GetAceptedAudioPayloadType(remote_sdp);
|
||||
|
||||
remote_ice_username_ = GetIceUsername(remote_sdp);
|
||||
std::string media_stream_sdp = GetLocalCapabilitiesToSdp(remote_sdp);
|
||||
LOG_ERROR("media_stream_sdp: [{}] [{}]", media_stream_sdp, remote_sdp);
|
||||
|
||||
ice_agent_->SetRemoteSdp(media_stream_sdp.c_str());
|
||||
// LOG_INFO("[{}] set remote sdp", user_id_);
|
||||
|
||||
remote_ice_username_ = GetIceUsername(media_stream_sdp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int IceTransmission::SendOffer() {
|
||||
local_sdp_ = use_trickle_ice_ ? ice_agent_->GetLocalStreamSdp()
|
||||
: ice_agent_->GenerateLocalSdp();
|
||||
local_sdp_ = ice_agent_->GenerateLocalSdp();
|
||||
|
||||
std::string toReplace = "ICE/SDP";
|
||||
std::string replacement = "UDP/TLS/RTP/SAVPF 111 114 115 116 123 124 125";
|
||||
|
||||
size_t pos = 0;
|
||||
while ((pos = local_sdp_.find(toReplace, pos)) != std::string::npos) {
|
||||
local_sdp_.replace(pos, toReplace.length(), replacement);
|
||||
pos += replacement.length();
|
||||
}
|
||||
AppendLocalCapabilitiesToSdp(local_sdp_);
|
||||
|
||||
json message = {{"type", "offer"},
|
||||
{"transmission_id", transmission_id_},
|
||||
{"user_id", user_id_},
|
||||
{"remote_user_id", remote_user_id_},
|
||||
{"sdp", local_sdp_.c_str()}};
|
||||
LOG_INFO("Send offer with sdp:\n[\n{}]", local_sdp_.c_str());
|
||||
// LOG_INFO("Send offer with sdp:\n[\n{}]", local_sdp_.c_str());
|
||||
if (ice_ws_transport_) {
|
||||
ice_ws_transport_->Send(message.dump());
|
||||
LOG_INFO("[{}->{}] send offer", user_id_, remote_user_id_);
|
||||
@@ -417,14 +412,13 @@ int IceTransmission::SendOffer() {
|
||||
}
|
||||
|
||||
int IceTransmission::SendAnswer() {
|
||||
local_sdp_ = use_trickle_ice_ ? ice_agent_->GetLocalStreamSdp()
|
||||
: ice_agent_->GenerateLocalSdp();
|
||||
local_sdp_ = ice_agent_->GenerateLocalSdp();
|
||||
json message = {{"type", "answer"},
|
||||
{"transmission_id", transmission_id_},
|
||||
{"user_id", user_id_},
|
||||
{"remote_user_id", remote_user_id_},
|
||||
{"sdp", local_sdp_.c_str()}};
|
||||
LOG_INFO("Send answer with sdp:\n[\n{}]", local_sdp_.c_str());
|
||||
// LOG_INFO("Send answer with sdp:\n[\n{}]", local_sdp_.c_str());
|
||||
if (ice_ws_transport_) {
|
||||
ice_ws_transport_->Send(message.dump());
|
||||
LOG_INFO("[{}->{}] send answer", user_id_, remote_user_id_);
|
||||
@@ -433,18 +427,78 @@ int IceTransmission::SendAnswer() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// int IceTransmission::AppendLocalCapabilitiesToSdp() {
|
||||
// std::string toReplace = "ICE/SDP";
|
||||
// std::string replacement = "UDP/TLS/RTP/SAVPF 111 114 115 116 123 124 125";
|
||||
int IceTransmission::AppendLocalCapabilitiesToSdp(std::string &remote_sdp) {
|
||||
std::string to_replace = "ICE/SDP";
|
||||
std::string video_capabilities = "UDP/TLS/RTP/SAVPF 96 97 98 99";
|
||||
std::string audio_capabilities = "UDP/TLS/RTP/SAVPF 111";
|
||||
std::string data_capabilities = "UDP/TLS/RTP/SAVPF 127";
|
||||
|
||||
// size_t pos = 0;
|
||||
// while ((pos = local_sdp_.find(toReplace, pos)) != std::string::npos) {
|
||||
// local_sdp_.replace(pos, toReplace.length(), replacement);
|
||||
// pos += replacement.length();
|
||||
// }
|
||||
std::size_t video_start = remote_sdp.find("m=video");
|
||||
std::size_t video_end = remote_sdp.find("\n", video_start);
|
||||
std::size_t audio_start = remote_sdp.find("m=audio");
|
||||
std::size_t audio_end = remote_sdp.find("\n", audio_start);
|
||||
std::size_t data_start = remote_sdp.find("m=data");
|
||||
std::size_t data_end = remote_sdp.find("\n", data_start);
|
||||
|
||||
// return 0;
|
||||
// }
|
||||
size_t pos = 0;
|
||||
if (video_start != std::string::npos && video_end != std::string::npos) {
|
||||
if ((pos = local_sdp_.find(to_replace, video_start)) != std::string::npos) {
|
||||
local_sdp_.replace(pos, to_replace.length(), video_capabilities);
|
||||
pos += video_capabilities.length();
|
||||
}
|
||||
}
|
||||
|
||||
if (audio_start != std::string::npos && audio_end != std::string::npos) {
|
||||
if ((pos = local_sdp_.find(to_replace, audio_start)) != std::string::npos) {
|
||||
local_sdp_.replace(pos, to_replace.length(), audio_capabilities);
|
||||
pos += audio_capabilities.length();
|
||||
}
|
||||
}
|
||||
|
||||
if (data_start != std::string::npos && data_end != std::string::npos) {
|
||||
if ((pos = local_sdp_.find(to_replace, data_start)) != std::string::npos) {
|
||||
local_sdp_.replace(pos, to_replace.length(), data_capabilities);
|
||||
pos += data_capabilities.length();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string IceTransmission::GetLocalCapabilitiesToSdp(
|
||||
const std::string &remote_sdp) {
|
||||
std::string media_stream_sdp;
|
||||
std::size_t video_start = remote_sdp.find("m=video");
|
||||
std::size_t video_end = remote_sdp.find("m=audio");
|
||||
std::size_t audio_start = video_end;
|
||||
std::size_t audio_end = remote_sdp.find("m=data");
|
||||
std::size_t data_start = audio_end;
|
||||
std::size_t data_end = remote_sdp.find("a=candidate");
|
||||
std::size_t candidate_start = data_end;
|
||||
|
||||
if ((video_start != std::string::npos && video_end != std::string::npos) ||
|
||||
(audio_start != std::string::npos && audio_end != std::string::npos) ||
|
||||
(data_start != std::string::npos && data_end != std::string::npos)) {
|
||||
if (video_start != std::string::npos && video_end != std::string::npos) {
|
||||
media_stream_sdp =
|
||||
remote_sdp.substr(video_start, video_end - video_start);
|
||||
} else if (audio_start != std::string::npos &&
|
||||
audio_end != std::string::npos) {
|
||||
media_stream_sdp =
|
||||
remote_sdp.substr(audio_start, audio_end - audio_start);
|
||||
} else {
|
||||
media_stream_sdp = remote_sdp.substr(data_start, data_end - data_start);
|
||||
}
|
||||
|
||||
if (candidate_start != std::string::npos) {
|
||||
media_stream_sdp += remote_sdp.substr(candidate_start);
|
||||
}
|
||||
} else {
|
||||
return remote_sdp;
|
||||
}
|
||||
|
||||
return media_stream_sdp;
|
||||
}
|
||||
|
||||
RtpPacket::PAYLOAD_TYPE IceTransmission::GetAceptedVideoPayloadType(
|
||||
const std::string &remote_sdp) {
|
||||
|
||||
@@ -104,6 +104,9 @@ class IceTransmission {
|
||||
int SendAnswer();
|
||||
|
||||
private:
|
||||
int AppendLocalCapabilitiesToSdp(std::string &remote_sdp);
|
||||
std::string GetLocalCapabilitiesToSdp(const std::string &remote_sdp);
|
||||
|
||||
RtpPacket::PAYLOAD_TYPE GetAceptedVideoPayloadType(
|
||||
const std::string &remote_sdp);
|
||||
RtpPacket::PAYLOAD_TYPE GetAceptedAudioPayloadType(
|
||||
|
||||
Reference in New Issue
Block a user