8000 feat: add getCapabilities/setCodecPreferences methods. (#1251) · binvb/flutter-webrtc@d5a0145 · GitHub
[go: up one dir, main page]

Skip to content

Commit d5a0145

Browse files
authored
feat: add getCapabilities/setCodecPreferences methods. (flutter-webrtc#1251)
* feat: (WIP) add getCapabilities/setCodecPreferences methods. * chore: Implementation for darwin. * update. * chore: Implementation for Android. * update webrtc-sdk for android. * update libwebrtc dependency for darwin. * chore: Implementation for Windows/Linux. * update so for linux.
1 parent 043de47 commit d5a0145

25 files changed

+572
-121
lines changed

android/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ android {
4949
}
5050

5151
dependencies {
52-
implementation 'com.github.webrtc-sdk:android:104.5112.05'
52+
implementation 'com.github.webrtc-sdk:android:104.5112.06'
5353
implementation 'com.github.davidliu:audioswitch:c498d866c57f1d88056d5e7e7a78d622e3b0c046'
5454
implementation 'androidx.annotation:annotation:1.1.0'
5555
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"

android/src/main/java/com/cloudwebrtc/webrtc/MethodCallHandlerImpl.java

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
import org.webrtc.PeerConnectionFactory;
5959
import org.webrtc.PeerConnectionFactory.InitializationOptions;
6060
import org.webrtc.PeerConnectionFactory.Options;
61+
import org.webrtc.RtpCapabilities;
6162
import org.webrtc.RtpSender;
6263
import org.webrtc.SdpObserver;
6364
import org.webrtc.SessionDescription;
@@ -701,12 +702,75 @@ public void onMethodCall(MethodCall call, @NonNull Result notSafeResult) {
701702
}
702703
break;
703704
}
705+
case "getRtpSenderCapabilities": {
706+
String kind = call.argument("kind");
707+
MediaStreamTrack.MediaType mediaType = MediaStreamTrack.MediaType.MEDIA_TYPE_AUDIO;
708+
if (kind.equals("video")) {
709+
mediaType = MediaStreamTrack.MediaType.MEDIA_TYPE_VIDEO;
710+
}
711+
RtpCapabilities capabilities = mFactory.getRtpSenderCapabilities(mediaType);
712+
result.success(capabilitiestoMap(capabilities).toMap());
713+
break;
714+
}
715+
case "getRtpReceiverCapabilities": {
716+
String kind = call.argument("kind");
717+
MediaStreamTrack.MediaType mediaType = MediaStreamTrack.MediaType.MEDIA_TYPE_AUDIO;
718+
if (kind.equals("video")) {
719+
mediaType = MediaStreamTrack.MediaType.MEDIA_TYPE_VIDEO;
720+
}
721+
RtpCapabilities capabilities = mFactory.getRtpReceiverCapabilities(mediaType);
722+
result.success(capabilitiestoMap(capabilities).toMap());
723+
break;
724+
}
725+
case "setCodecPreferences":
726+
String peerConnectionId = call.argument("peerConnectionId");
727+
List<Map<String, Object>> codecs = call.argument("codecs");
728+
String transceiverId = call.argument("transceiverId");
729+
rtpTransceiverSetCodecPreferences(peerConnectionId, transceiverId, codecs, result);
730+
result.success(null);
731+
break;
704732
default:
705733
result.notImplemented();
706734
break;
707735
}
708736
}
709737

738+
private ConstraintsMap capabilitiestoMap(RtpCapabilities capabilities) {
739+
ConstraintsMap capabilitiesMap = new ConstraintsMap();
740+
ConstraintsArray codecArr = new ConstraintsArray();
741+
for(RtpCapabilities.CodecCapability codec : capabilities.codecs){
742+
ConstraintsMap codecMap = new ConstraintsMap();
743+
codecMap.putString("mimeType", codec.mimeType);
744+
codecMap.putInt("clockRate", codec.clockRate);
745+
if(codec.numChannels != null)
746+
codecMap.putInt("channels", codec.numChannels);
747+
List<String> sdpFmtpLineArr = new ArrayList<>();
748+
for(Map.Entry<String, String> entry : codec.parameters.entrySet()) {
749+
if(entry.getKey().length() > 0) {
750+
sdpFmtpLineArr.add(entry.getKey() + "=" + entry.getValue());
751+
} else {
752+
sdpFmtpLineArr.add(entry.getValue());
753+
}
754+
}
755+
if(sdpFmtpLineArr.size() > 0)
756+
codecMap.putString("sdpFmtpLine", String.join(";", sdpFmtpLineArr));
757+
codecArr.pushMap(codecMap);
758+
}
759+
ConstraintsArray headerExtensionsArr = new ConstraintsArray();
760+
for(RtpCapabilities.HeaderExtensionCapability headerExtension : capabilities.headerExtensions){
761+
ConstraintsMap headerExtensionMap = new ConstraintsMap();
762+
headerExtensionMap.putString("uri", headerExtension.getUri());
763+
headerExtensionMap.putInt("id", headerExtension.getPreferredId());
764+
headerExtensionMap.putBoolean("encrypted", headerExtension.getPreferredEncrypted());
765+
headerExtensionsArr.pushMap(headerExtensionMap);
766+
}
767+
capabilitiesMap.putArray("codecs", codecArr.toArrayList());
768+
capabilitiesMap.putArray("headerExtensions", headerExtensionsArr.toArrayList());
769+
ConstraintsArray fecMechanismsArr = new ConstraintsArray();
770+
capabilitiesMap.putArray("fecMechanisms", fecMechanismsArr.toArrayList());
771+
return capabilitiesMap;
772+
}
773+
710774
private PeerConnection getPeerConnection(String id) {
711775
PeerConnectionObserver pco = mPeerConnectionObservers.get(id);
712776
return (pco == null) ? null : pco.getPeerConnection();
@@ -1734,6 +1798,15 @@ public void rtpTransceiverSetDirection(String peerConnectionId, String direction
17341798
}
17351799
}
17361800

1801+
public void rtpTransceiverSetCodecPreferences(String peerConnectionId, String transceiverId, List<Map<String, Object>> codecs, Result result) {
1802+
PeerConnectionObserver pco = mPeerConnectionObservers.get(peerConnectionId);
1803+
if (pco == null || pco.getPeerConnection() == null) {
1804+
resultError("setCodecPreferences", "peerConnection is null", result);
1805+
} else {
1806+
pco.rtpTransceiverSetCodecPreferences(transceiverId, codecs, result);
1807+
}
1808+
}
1809+
17371810
public void rtpTransceiverGetDirection(String peerConnectionId, String transceiverId, Result result) {
17381811
PeerConnectionObserver pco = mPeerConnectionObservers.get(peerConnectionId);
17391812
if (pco == null || pco.getPeerConnection() == null) {

android/src/main/java/com/cloudwebrtc/webrtc/PeerConnectionObserver.java

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import java.math.BigInteger;
1515
import java.nio.ByteBuffer;
1616
import java.util.ArrayList;
17+
import java.util.Arrays;
1718
import java.util.HashMap;
1819
import java.util.Iterator;
1920
import java.util.Map;
@@ -30,6 +31,7 @@
3031
import org.webrtc.RTCStats;
3132
import org.webrtc.RTCStatsCollectorCallback;
3233
import org.webrtc.RTCStatsReport;
34+
import org.webrtc.RtpCapabilities;
3335
import org.webrtc.RtpParameters;
3436
import org.webrtc.RtpReceiver;
3537
import org.webrtc.RtpSender;
@@ -1001,6 +1003,44 @@ public void rtpTransceiverSetDirection(String direction, String transceiverId, R
10011003
result.success(null);
10021004
}
10031005

1006+
public void rtpTransceiverSetCodecPreferences(String transceiverId, List<Map<String, Object>> codecs, Result result) {
1007+
RtpTransceiver transceiver = getRtpTransceiverById(transceiverId);
1008+
if (transceiver == null) {
1009+
resultError("rtpTransceiverSetCodecPreferences", "transceiver is null", result);
1010+
return;
1011+
}
1012+
List<RtpCapabilities.CodecCapability> preferedCodecs = new ArrayList<>();
1013+
for(Map<String, Object> codec : codecs) {
1014+
RtpCapabilities.CodecCapability codecCapability = new RtpCapabilities.CodecCapability();
1015+
String mimeType = (String) codec.get("mimeType");
1016+
List<String> mimeTypeParts = Arrays.asList(mimeType.split("/"));
1017+
codecCapability.name = mimeTypeParts.get(1);
1018+
codecCapability.kind = stringToMediaType(mimeTypeParts.get(0));
1019+
codecCapability.mimeType = mimeType;
1020+
codecCapability.clockRate = (int) codec.get("clockRate");
1021+
if(codec.get("numChannels") != null)
1022+
codecCapability.numChannels = (int) codec.get("numChannels");
1023+
if(codec.get("sdpFmtpLine") != null) {
1024+
String sdpFmtpLine = (String) codec.get("sdpFmtpLine");
1025+
codecCapability.parameters = new HashMap<>();
1026+
List<String> parameters = Arrays.asList(sdpFmtpLine.split(";"));
1027+
for(String parameter : parameters) {
1028+
if(parameter.contains("=")) {
1029+
List<String> parameterParts = Arrays.asList(parameter.split("="));
1030+
codecCapability.parameters.put(parameterParts.get(0), parameterParts.get(1));
1031+
} else {
1032+
codecCapability.parameters.put("", parameter);
1033+
}
1034+
}
1035+
} else {
1036+
codecCapability.parameters = new HashMap<>();
1037+
}
1038+
preferedCodecs.add(codecCapability);
1039+
}
1040+
transceiver.setCodecPreferences(preferedCodecs);
1041+
result.success(null);
1042+
}
1043+
10041044
public void rtpTransceiverGetDirection(String transceiverId, Result result) {
10051045
RtpTransceiver transceiver = getRtpTransceiverById(transceiverId);
10061046
if (transceiver == null) {

common/cpp/include/flutter_peerconnection.h

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ class FlutterPeerConnection {
8181
std::unique_ptr<MethodResultProxy> result);
8282

8383
void GetRemoteDescription(RTCPeerConnection* pc,
84-
std::unique_ptr<MethodResultProxy> resulte);
84+
std::unique_ptr<MethodResultProxy> result);
8585

8686
scoped_refptr<RTCRtpTransceiverInit> mapToRtpTransceiverInit(
8787
const EncodableMap& transceiverInit);
@@ -96,27 +96,27 @@ class FlutterPeerConnection {
9696
const std::string& trackId,
9797
const std::string& mediaType,
9898
const EncodableMap& transceiverInit,
99-
std::unique_ptr<MethodResultProxy> resulte);
99+
std::unique_ptr<MethodResultProxy> result);
100100

101101
void GetTransceivers(RTCPeerConnection* pc,
102-
std::unique_ptr<MethodResultProxy> resulte);
102+
std::unique_ptr<MethodResultProxy> result);
103103

104104
void GetReceivers(RTCPeerConnection* pc,
105-
std::unique_ptr<MethodResultProxy> resulte);
105+
std::unique_ptr<MethodResultProxy> result);
106106

107107
void RtpSenderDispose(RTCPeerConnection* pc,
108108
std::string rtpSenderId,
109-
std::unique_ptr<MethodResultProxy> resulte);
109+
std::unique_ptr<MethodResultProxy> result);
110110

111111
void RtpSenderSetTrack(RTCPeerConnection* pc,
112112
RTCMediaTrack* track,
113113
std::string rtpSenderId,
114-
std::unique_ptr<MethodResultProxy> resulte);
114+
std::unique_ptr<MethodResultProxy> result);
115115

116116
void RtpSenderReplaceTrack(RTCPeerConnection* pc,
117117
RTCMediaTrack* track,
118118
std::string rtpSenderId,
119-
std::unique_ptr<MethodResultProxy> resulte);
119+
std::unique_ptr<MethodResultProxy> result);
120120

121121
scoped_refptr<RTCRtpParameters> updateRtpParameters(
122122
EncodableMap newParameters,
@@ -125,35 +125,40 @@ class FlutterPeerConnection {
125125
void RtpSenderSetParameters(RTCPeerConnection* pc,
126126
std::string rtpSenderId,
127127
const EncodableMap& parameters,
128-
std::unique_ptr<MethodResultProxy> resulte);
128+
std::unique_ptr<MethodResultProxy> result);
129129

130130
void RtpTransceiverStop(RTCPeerConnection* pc,
131131
std::string rtpTransceiverId,
132-
std::unique_ptr<MethodResultProxy> resulte);
132+
std::unique_ptr<MethodResultProxy> result);
133133

134134
void RtpTransceiverGetCurrentDirection(
135135
RTCPeerConnection* pc,
136136
std::string rtpTransceiverId,
137-
std::unique_ptr<MethodResultProxy> resulte);
137+
std::unique_ptr<MethodResultProxy> result);
138138

139139
void SetConfiguration(RTCPeerConnection* pc,
140140
const EncodableMap& configuration,
141-
std::unique_ptr<MethodResultProxy> resulte);
141+
std::unique_ptr<MethodResultProxy> result);
142142

143143
void CaptureFrame(RTCVideoTrack* track,
144144
std::string path,
145-
std::unique_ptr<MethodResultProxy> resulte);
145+
std::unique_ptr<MethodResultProxy> result);
146146

147147
scoped_refptr<RTCRtpTransceiver> getRtpTransceiverById(RTCPeerConnection* pc,
148148
std::string id);
149149

150150
void RtpTransceiverSetDirection(RTCPeerConnection* pc,
151151
std::string rtpTransceiverId,
152152
std::string direction,
153-
std::unique_ptr<MethodResultProxy> resulte);
153+
std::unique_ptr<MethodResultProxy> result);
154+
155+
void RtpTransceiverSetCodecPreferences(RTCPeerConnection* pc,
156+
std::string rtpTransceiverId,
157+
const EncodableList codecs,
158+
std::unique_ptr<MethodResultProxy> result);
154159

155160
void GetSenders(RTCPeerConnection* pc,
156-
std::unique_ptr<MethodResultProxy> resulte);
161+
std::unique_ptr<MethodResultProxy> result);
157162

158163
void AddIceCandidate(RTCIceCandidate* candidate,
159164
RTCPeerConnection* pc,

common/cpp/src/flutter_peerconnection.cc

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ EncodableMap rtpParametersToMap(
7474
map[EncodableValue("minBitrate")] =
7575
EncodableValue(encoding->min_bitrate_bps());
7676
map[EncodableValue("maxFramerate")] =
77-
EncodableValue(encoding->max_framerate());
77+
EncodableValue((int)encoding->max_framerate());
7878
map[EncodableValue("scaleResolutionDownBy")] =
7979
EncodableValue(encoding->scale_resolution_down_by());
8080
map[EncodableValue("ssrc")] = EncodableValue((long)encoding->ssrc());
@@ -727,6 +727,36 @@ void FlutterPeerConnection::RtpTransceiverSetDirection(
727727
}
728728
}
729729

730+
void FlutterPeerConnection::RtpTransceiverSetCodecPreferences(
731+
RTCPeerConnection* pc,
732+
std::string rtpTransceiverId,
733+
const EncodableList codecs,
734+
std::unique_ptr<MethodResultProxy> result) {
735+
std::shared_ptr<MethodResultProxy> result_ptr(result.release());
736+
auto transceiver = getRtpTransceiverById(pc, rtpTransceiverId);
737+
if (nullptr == transceiver.get()) {
738+
result_ptr->Error("RtpTransceiverSetCodecPreferences", " transceiver is null ");
739+
return;
740+
}
741+
std::vector<scoped_refptr<RTCRtpCodecCapability>> codecList;
742+
for(auto codec : codecs) {
743+
auto codecMap = GetValue<EncodableMap>(codec);
744+
auto codecMimeType = findString(codecMap, "mimeType");
745+
auto codecClockRate = findInt(codecMap, "clockRate");
746+
auto codecNumChannels = findInt(codecMap, "channels");
747+
auto codecSdpFmtpLine = findString(codecMap, "sdpFmtpLine");
748+
auto codecCapability = RTCRtpCodecCapability::Create();
749+
if(codecSdpFmtpLine != std::string())
750+
codecCapability->set_sdp_fmtp_line(codecSdpFmtpLine);
751+
codecCapability->set_clock_rate(codecClockRate);
752+
if (codecNumChannels != -1)
753+
codecCapability->set_channels(codecNumChannels);
754+
codecCapability->set_mime_type(codecMimeType);
755+
codecList.push_back(codecCapability);
756+
}
757+
transceiver->SetCodecPreferences(codecList);
758+
}
759+
730760
void FlutterPeerConnection::GetSenders(
731761
RTCPeerConnection* pc,
732762
std::unique_ptr<MethodResultProxy> result) {

0 commit comments

Comments
 (0)
0