8000 update. · next-coder/flutter-webrtc@49751f6 · GitHub
[go: up one dir, main page]

Skip to content

Commit 49751f6

Browse files
committed
update.
1 parent 12d86c6 commit 49751f6

18 files changed

+536
-154
lines changed

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

Lines changed: 171 additions & 62 deletions
Large diffs are not rendered by default.

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

Lines changed: 205 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import java.nio.ByteBuffer;
55
import java.util.HashMap;
66
import java.util.Iterator;
7+
import java.util.List;
78
import java.util.Map;
89

910
import android.util.Base64;
@@ -17,11 +18,15 @@
1718

1819
import org.webrtc.AudioTrack;
1920
import org.webrtc.DataChannel;
21+
import org.webrtc.DtmfSender;
2022
import org.webrtc.IceCandidate;
2123
import org.webrtc.MediaStream;
2224
import org.webrtc.MediaStreamTrack;
2325
import org.webrtc.PeerConnection;
26+
import org.webrtc.RtpParameters;
2427
import org.webrtc.RtpReceiver;
28+
import org.webrtc.RtpSender;
29+
import org.webrtc.RtpTransceiver;
2530
import org.webrtc.StatsObserver;
2631
import org.webrtc.StatsReport;
2732
import org.webrtc.VideoTrack;
@@ -38,6 +43,9 @@ class PeerConnectionObserver implements PeerConnection.Observer, EventChannel.St
3843
private PeerConnection peerConnection;
3944
final Map<String, MediaStream> remoteStreams;
4045
final Map<String, MediaStreamTrack> remoteTracks;
46+
final Map<String, RtpTransceiver> transceivers;
47+
final Map<String, RtpSender> senders;
48+
final Map<String, RtpReceiver> receivers;
4149
private final FlutterWebRTCPlugin plugin;
4250

4351
EventChannel eventChannel;
@@ -48,7 +56,9 @@ class PeerConnectionObserver implements PeerConnection.Observer, EventChannel.St
4856
this.id = id;
4957
this.remoteStreams = new HashMap<String, MediaStream>();
5058
this.remoteTracks = new HashMap<String, MediaStreamTrack>();
51-
59+
this.transceivers = new HashMap<String, RtpTransceiver>();
60+
this.senders = new HashMap<String, RtpSender>();
61+
this.receivers = new HashMap<String, RtpReceiver>();
5262

5363
this.eventChannel =
5464
new EventChannel(
@@ -81,6 +91,9 @@ void close() {
8191
remoteStreams.clear();
8292
remoteTracks.clear();
8393
dataChannels.clear();
94+
transceivers.clear();
95+
senders.clear();;
96+
receivers.clear();;
8497
}
8598
void dispose(){
8699
this.close();
@@ -201,7 +214,7 @@ public void onComplete(StatsReport[] reports) {
201214

202215
@Override
203216
public void onIceCandidate(final IceCandidate candidate) {
204-
Log.d(TAG, "onIceCandidate");
217+
Log.d(TAG, "onIceCandidate => " + candidate.toString());
205218
ConstraintsMap params = new ConstraintsMap();
206219
params.putString("event", "onCandidate");
207220
ConstraintsMap candidateParams = new ConstraintsMap();
@@ -474,4 +487,194 @@ private String signalingStateString(PeerConnection.SignalingState signalingState
474487
}
475488
return null;
476489
}
490+
491+
@Nullable
492+
private String transceiverDirectionString(RtpTransceiver.RtpTransceiverDirection direction) {
493+
switch (direction) {
494+
case SEND_RECV:
495+
return "sendrecv";
496+
case SEND_ONLY:
497+
return "sendonly";
498+
case RECV_ONLY:
499+
return "recvonly";
500+
case INACTIVE:
501+
return "inactive";
502+
}
503+
return null;
504+
}
505+
506+
private RtpTransceiver.RtpTransceiverDirection typStringToTransceiverDirection(String direction) {
507+
switch (direction) {
508+
case "sendrecv":
509+
return RtpTransceiver.RtpTransceiverDirection.SEND_RECV;
510+
case "sendonly":
511+
return RtpTransceiver.RtpTransceiverDirection.SEND_ONLY;
512+
case "recvonly":
513+
return RtpTransceiver.RtpTransceiverDirection.RECV_ONLY;
514+
case "inactive":
515+
return RtpTransceiver.RtpTransceiverDirection.INACTIVE;
516+
}
517+
return RtpTransceiver.RtpTransceiverDirection.INACTIVE;
518+
}
519+
520+
private Map<String, Object> rtpParametersToMap(RtpParameters rtpParameters){
521+
ConstraintsMap info = new ConstraintsMap();
522+
info.putString("transactionId", rtpParameters.transactionId);
523+
524+
ConstraintsMap rtcp = new ConstraintsMap();
525+
rtcp.putString("cname", rtpParameters.getRtcp().getCname());
526+
rtcp.putBoolean("reducedSize", rtpParameters.getRtcp().getReducedSize());
527+
info.putMap("rtcp", rtcp.toMap());
528+
529+
ConstraintsArray headerExtensions = new ConstraintsArray();
530+
for(RtpParameters.HeaderExtension extension : rtpParameters.getHeaderExtensions()){
531+
ConstraintsMap map = new ConstraintsMap();
532+
map.putString("uri",extension.getUri());
533+
map.putInt("id", extension.getId());
534+
map.putBoolean("encrypted", extension.getEncrypted());
535+
headerExtensions.pushMap(map);
536+
}
537+
info.putArray("headerExtensions", headerExtensions.toArrayList());
538+
539+
ConstraintsArray encodings = new ConstraintsArray();
540+
for(RtpParameters.Encoding encoding : rtpParameters.encodings){
541+
ConstraintsMap map = new ConstraintsMap();
542+
map.putBoolean("active",encoding.active);
543+
map.putInt("maxBitrateBps", encoding.maxBitrateBps);
544+
map.putInt("minBitrateBps", encoding.minBitrateBps);
545+
map.putInt("maxFramerate", encoding.maxFramerate);
546+
map.putInt("numTemporalLayers", encoding.numTemporalLayers);
547+
map.putDouble("scaleResolutionDownBy", encoding.scaleResolutionDownBy);
548+
map.putLong("ssrc", encoding.ssrc);
549+
encodings.pushMap(map);
550+
}
551+
info.putArray("encodings", encodings.toArrayList());
552+
553+
ConstraintsArray codecs = new ConstraintsArray();
554+
for(RtpParameters.Codec codec : rtpParameters.codecs){
555+
ConstraintsMap map = new ConstraintsMap();
556+
map.putString("name",codec.name);
557+
map.putInt("payloadType", codec.payloadType);
558+
map.putInt("clockRate", codec.clockRate);
559+
map.putInt("numChannels", codec.numChannels);
560+
map.putMap("numTemporalLayers", new HashMap<String, Object>(codec.parameters));
561+
//map.putString("kind", codec.kind);
562+
codecs.pushMap(map);
563+
}
564+
565+
info.putArray("codecs", codecs.toArrayList());
566+
return info.toMap();
567+
}
568+
569+
@Nullable
570+
private Map<String, Object> mediaTrackToMap(MediaStreamTrack track){
571+
ConstraintsMap info = new ConstraintsMap();
572+
if(track != null){
573+
info.putString("trackId", track.id());
574+
info.putString("label",track.id());
575+
info.putString("kind",track.kind());
576+
info.putBoolean("enabled", track.enabled());
577+
}
578+
return info.toMap();
579+
}
580+
581+
private Map<String, Object> dtmfSenderToMap(DtmfSender dtmfSender, String id){
582+
ConstraintsMap info = new ConstraintsMap();
583+
info.putString("dtmfSenderId",id);
584+
info.putInt("interToneGap", dtmfSender.interToneGap());
585+
info.putInt("duration",dtmfSender.duration());
586+
return info.toMap();
587+
}
588+
589+
private Map<String, Object> rtpSenderToMap(RtpSender sender){
590+
ConstraintsMap info = new ConstraintsMap();
591+
info.putString("senderId", sender.id());
592+
info.putBoolean("ownsTrack", true);
593+
info.putMap("dtmfSender", dtmfSenderToMap(sender.dtmf(), sender.id()));
594+
info.putMap("rtpParameters", rtpParametersToMap(sender.getParameters()));
595+
info.putMap("track", mediaTrackToMap(sender.track()));
596+
return info.toMap();
597+
}
598+
599+
private Map<String, Object> rtpReceiverToMap(RtpReceiver receiver){
600+
ConstraintsMap info = new ConstraintsMap();
601+
info.putString("receiverId", receiver.id());
602+
info.putMap("track", mediaTrackToMap(receiver.track()));
603+
return info.toMap();
604+
}
605+
606+
Map<String, Object> transceiverToMap(RtpTransceiver transceiver){
607+
ConstraintsMap info = new ConstraintsMap();
608+
info.putString("transceiverId", transceiver.getMid());
609+
info.putString("mid", transceiver.getMid());
610+
info.putString("direction", transceiverDirectionString(transceiver.getDirection()));
611+
info.putMap("sender", rtpSenderToMap(transceiver.getSender()));
612+
info.putMap("receiver", rtpReceiverToMap(transceiver.getReceiver()));
613+
return info.toMap();
614+
}
615+
616+
@Override
617+
public void onTrack(RtpTransceiver transceiver) {
618+
ConstraintsMap params = new ConstraintsMap();
619+
params.putString("event", "onTrack");
620+
params.putMap("transceiver", transceiverToMap(transceiver));
621+
sendEvent(params);
622+
}
623+
624+
public void createSender(String kind, String streamId, Result result){
625+
RtpSender sender = peerConnection.createSender(kind, streamId);
626+
senders.put(sender.id(),sender);
627+
result.success(rtpSenderToMap(sender));
628+
}
629+
630+
public void addTrack(MediaStreamTrack track, List<String> streamIds, Result result){
631+
RtpSender sender = peerConnection.addTrack(track, streamIds);
632+
senders.put(sender.id(),sender);
633+
result.success(rtpSenderToMap(sender));
634+
}
635+
636+
public void removeTrack(String senderId, Result result){
637+
RtpSender sender = senders.get(senderId);
638+
if(sender == null){
639+
result.error("removeTrack", "removeTrack() sender is null", null);
640+
return;
641+
}
642+
boolean res = peerConnection.removeTrack(sender);
643+
ConstraintsMap params = new ConstraintsMap();
644+
params.putBoolean("result", res);
645+
result.success(params);
646+
}
647+
648+
public void addTransceiver(MediaStreamTrack track, Map<String, Object> transceiverInit, Result result) {
649+
RtpTransceiver transceiver;
650+
if(transceiverInit != null){
651+
List<String> streamIds = (List)transceiverInit.get("streamIds");
652+
String direction = (String)transceiverInit.get("direction");
653+
RtpTransceiver.RtpTransceiverInit init = new RtpTransceiver.RtpTransceiverInit(typStringToTransceiverDirection(direction) ,streamIds);
654+
transceiver = peerConnection.addTransceiver(track, init);
655+
} else {
656+
transceiver = peerConnection.addTransceiver(track);
657+
}
658+
transceivers.put(transceiver.getMid(), transceiver);
659+
result.success(transceiverToMap(transceiver));
660+
}
661+
662+
public void addTransceiverOfType(String mediaType, Map<String, Object> transceiverInit, Result result) {
663+
MediaStreamTrack.MediaType type = MediaStreamTrack.MediaType.MEDIA_TYPE_AUDIO;
664+
if(mediaType == "audio")
665+
type = MediaStreamTrack.MediaType.MEDIA_TYPE_AUDIO;
666+
else if(mediaType == "video")
667+
type = MediaStreamTrack.MediaType.MEDIA_TYPE_VIDEO;
668+
RtpTransceiver transceiver;
669+
if(transceiverInit != null){
670+
List<String> streamIds = (List)transceiverInit.get("streamIds");
671+
String direction = (String)transceiverInit.get("direction");
672+
RtpTransceiver.RtpTransceiverInit init = new RtpTransceiver.RtpTransceiverInit(typStringToTransceiverDirection(direction) ,streamIds);
673+
transceiver = peerConnection.addTransceiver(type, init);
674+
} else {
675+
transceiver = peerConnection.addTransceiver(type);
676+
}
677+
transceivers.put(transceiver.getMid(), transceiver);
678+
result.success(transceiverToMap(transceiver));
679+
}
477680
}

android/src/main/java/com/cloudwebrtc/webrtc/utils/ConstraintsMap.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,10 @@ public void putInt(String key, int value) {
8585
mMap.put(key, value);
8686
}
8787

88+
public void putLong(String key, long value) {
89+
mMap.put(key, value);
90+
}
91+
8892
public void putString(String key, String value) {
8993
mMap.put(key, value);
9094
}

lib/get_user_media.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class navigator {
2323

2424
/// Get a MediaStream from screen sharing.
2525
/// Currently supports Android/iOS.
26+
/// TODO: Implement the desktop version.
2627
static Future<MediaStream> getDisplayMedia(
2728
Map<String, dynamic> mediaConstraints) async {
2829
MethodChannel channel = WebRTC.methodChannel();

lib/media_recorder.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ class MediaRecorder {
1010
static final _random = Random();
1111
final _recorderId = _random.nextInt(0x7FFFFFFF);
1212

13+
MediaRecorder();
14+
1315
Future<void> start(String path,
1416
{MediaStreamTrack videoTrack, RecorderAudioChannel audioChannel
1517
//TODO: add codec/quality options

lib/media_stream.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class MediaStream {
1111
List<MediaStreamTrack> _videoTracks = new List<MediaStreamTrack>();
1212

1313
/// public:
14-
factory MediaStream.fromMap(Map<String, dynamic> map) {
14+
factory MediaStream.fromMap(Map<dynamic, dynamic> map) {
1515
MediaStream stream = new MediaStream(map['streamId']);
1616
stream._setMediaTracks(map['audioTracks'], map['videoTracks']);
1717
return stream;

lib/media_stream_track.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class MediaStreamTrack {
1212
bool _enabled;
1313

1414
/// public:
15-
factory MediaStreamTrack.fromMap(Map<String, dynamic> map) {
15+
factory MediaStreamTrack.fromMap(Map<dynamic, dynamic> map) {
1616
return new MediaStreamTrack(
1717
map['trackId'], map['label'], map['kind'], map['enabled']);
1818
}
@@ -41,6 +41,8 @@ class MediaStreamTrack {
4141
);
4242
}
4343

44+
/// TODO: Split the following method into a RTCAudioTrack and RTCVideoTrack.
45+
///
4446
/// AudioTrack methods.
4547
/// Mute/unmute the microphone.
4648
Future<void> setMicrophoneMute(bool mute) async {

lib/rtc_dtmf_sender.dart

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,16 @@ import 'utils.dart';
66
class RTCDTMFSender {
77
/// private:
88
String _id;
9+
int _interToneGap;
10+
int _duration;
911
MethodChannel _methodChannel = WebRTC.methodChannel();
1012

11-
/// public::
12-
RTCDTMFSender(this._id);
13+
/// public:
14+
factory RTCDTMFSender.fromMap(Map<String, dynamic> map){
15+
return new RTCDTMFSender(map['dtmfSenderId'], map['interToneGap'], map['duration']);
16+
}
17+
18+
RTCDTMFSender(this._id, this._interToneGap, this._duration);
1319

1420
Future<bool> canInsertDtmf() async {
1521
try {
@@ -50,7 +56,8 @@ class RTCDTMFSender {
5056
try {
5157
final Map<dynamic, dynamic> response = await _methodChannel.invokeMethod(
5258
'dtmfSenderGetDuration', <String, dynamic>{'dtmfSenderId': _id});
53-
return response['result'];
59+
_duration = response['result'];
60+
return _duration;
5461
} on PlatformException catch (e) {
5562
throw 'Unable to RTCDTMFSender::duration: ${e.message}';
5663
}
@@ -60,7 +67,8 @@ class RTCDTMFSender {
6067
try {
6168
final Map<dynamic, dynamic> response = await _methodChannel.invokeMethod(
6269
'dtmfSenderGetInterToneGap', <String, dynamic>{'dtmfSenderId': _id});
63-
return response['result'];
70+
_interToneGap = response['result'];
71+
return _interToneGap;
6472
} on PlatformException catch (e) {
6573
throw 'Unable to RTCDTMFSender::interToneGap: ${e.message}';
6674
}

lib/rtc_ice_candidate.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ class RTCIceCandidate {
33
String sdpMid;
44
int sdpMlineIndex;
55

6-
factory RTCIceCandidate.fromMap(Map<String, dynamic> map) {
6+
factory RTCIceCandidate.fromMap(Map<dynamic, dynamic> map) {
77
return new RTCIceCandidate(
88
map['candidate'], map['sdpMid'], map['sdpMLineIndex']);
99
}

0 commit comments

Comments
 (0)
0