8000 [WIP] Update. · Condelab/flutter-webrtc@7112405 · GitHub
[go: up one dir, main page]

Skip to content

Commit 7112405

Browse files
committed
[WIP] Update.
1 parent aa78cbc commit 7112405

14 files changed

+331
-149
lines changed

lib/get_user_media.dart

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ import 'media_stream.dart';
44
import 'utils.dart';
55

66
class navigator {
7+
/// Get a MediaStream from video capture.
8+
/// Use |mediaConstraints| to limit video size,
9+
/// frame rate, and video devices
710
static Future<MediaStream> getUserMedia(
811
Map<String, dynamic> mediaConstraints) async {
912
MethodChannel channel = WebRTC.methodChannel();
@@ -18,11 +21,9 @@ class navigator {
1821
}
1922
}
2023

21-
/* Implement screen sharing,
22-
* use MediaProjection for Android and use ReplayKit for iOS
23-
* TODO: implement for native layer.
24-
* */
25-
static Future<MediaStream> getDisplayMedia(
24+
/// Get a MediaStream from screen sharing.
25+
/// Currently supports Android/iOS.
26+
static Future<MediaStream> getDisplayMedia(
2627
Map<String, dynamic> mediaConstraints) async {
2728
MethodChannel channel = WebRTC.methodChannel();
2829
try {
@@ -36,6 +37,8 @@ static Future<MediaStream> getDisplayMedia(
3637
}
3738
}
3839

40+
/// Enumerate the currently available video capture devices,
41+
/// returns a list of video devices and the sourceId.
3942
static Future<List<dynamic>> getSources() async {
4043
MethodChannel channel = WebRTC.methodChannel();
4144
try {

lib/media_recorder.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import 'dart:async';
22
import 'dart:math';
33

4+
import 'package:flutter/services.dart';
45
import 'package:flutter_webrtc/media_stream_track.dart';
56
import 'package:flutter_webrtc/utils.dart';
67

78
class MediaRecorder {
9+
MethodChannel _methodChannel = WebRTC.methodChannel();
810
static final _random = Random();
911
final _recorderId = _random.nextInt(0x7FFFFFFF);
1012

@@ -16,15 +18,15 @@ class MediaRecorder {
1618
if (audioChannel == null && videoTrack == null)
1719
throw Exception("Neither audio nor video track were provided");
1820

19-
await WebRTC.methodChannel().invokeMethod('startRecordToFile', {
21+
await _methodChannel.invokeMethod('startRecordToFile', {
2022
'path': path,
2123
'audioChannel': audioChannel?.index,
2224
'videoTrackId': videoTrack?.id,
2325
'recorderId': _recorderId
2426
});
2527
}
2628

27-
Future<void> stop() async => await WebRTC.methodChannel()
29+
Future<void> stop() async => await _methodChannel
2830
.invokeMethod('stopRecordToFile', {'recorderId': _recorderId});
2931
}
3032

lib/media_stream.dart

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ import 'media_stream_track.dart';
44
import 'utils.dart';
55

66
class MediaStream {
7-
MethodChannel _channel = WebRTC.methodChannel();
7+
/// private:
8+
MethodChannel _methodChannel = WebRTC.methodChannel();
89
String _streamId;
910
List<MediaStreamTrack> _audioTracks = new List<MediaStreamTrack>();
1011
List<MediaStreamTrack> _videoTracks = new List<MediaStreamTrack>();
1112

13+
/// public:
1214
factory MediaStream.fromMap(Map<String, dynamic> map) {
1315
MediaStream stream = new MediaStream(map['streamId']);
1416
stream._setMediaTracks(map['audioTracks'], map['videoTracks']);
@@ -17,16 +19,16 @@ class MediaStream {
1719

1820
MediaStream(this._streamId);
1921

22+
String get id => _streamId;
23+
2024
Future<void> getMediaTracks() async {
21-
_channel = WebRTC.methodChannel();
22-
final Map<dynamic, dynamic> response = await _channel.invokeMethod(
25+
final Map<dynamic, dynamic> response = await _methodChannel.invokeMethod(
2326
'mediaStreamGetTracks',
2427
<String, dynamic>{'streamId': _streamId},
2528
);
2629
_setMediaTracks(response['audioTracks'], response['videoTracks']);
2730
}
2831

29-
String get id => _streamId;
3032
Future<void> addTrack(MediaStreamTrack track,
3133
{bool addToNaitve = true}) async {
3234
if (track.kind == 'audio')
@@ -35,7 +37,7 @@ class MediaStream {
3537
_videoTracks.add(track);
3638

3739
if (addToNaitve)
38-
await _channel.invokeMethod('mediaStreamAddTrack',
40+
await _methodChannel.invokeMethod('mediaStreamAddTrack',
3941
<String, dynamic>{'streamId': _streamId, 'trackId': track.id});
4042
}
4143

@@ -47,7 +49,7 @@ class MediaStream {
4749
_videoTracks.removeWhere((it) => it.id == track.id);
4850

4951
if (removeFromNaitve)
50-
await _channel.invokeMethod('mediaStreamRemoveTrack',
52+
await _methodChannel.invokeMethod('mediaStreamRemoveTrack',
5153
<String, dynamic>{'streamId': _streamId, 'trackId': track.id});
5254
}
5355

@@ -60,12 +62,13 @@ class MediaStream {
6062
}
6163

6264
Future<Null> dispose() async {
63-
await _channel.invokeMethod(
65+
await _methodChannel.invokeMethod(
6466
'streamDispose',
6567
<String, dynamic>{'streamId': _streamId},
6668
);
6769
}
6870

71+
/// private: method.
6972
void _setMediaTracks(List<dynamic> audioTracks, List<dynamic> videoTracks) {
7073
List<MediaStreamTrack> newAudioTracks = new List();
7174
audioTracks.forEach((trackInfo) {

lib/media_stream_track.dart

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,67 +4,74 @@ import 'package:flutter/services.dart';
44
import 'utils.dart';
55

66
class MediaStreamTrack {
7-
MethodChannel _channel = WebRTC.methodChannel();
7+
/// private:
8+
MethodChannel _methodChannel = WebRTC.methodChannel();
89
String _trackId;
910
String _label;
1011
String _kind;
1112
bool _enabled;
1213

14+
/// public:
1315
factory MediaStreamTrack.fromMap(Map<String, dynamic> map) {
1416
return new MediaStreamTrack(
1517
map['trackId'], map['label'], map['kind'], map['enabled']);
1618
}
1719

1820
MediaStreamTrack(this._trackId, this._label, this._kind, this._enabled);
1921

22+
/// Mute/unmute the track.
2023
set enabled(bool enabled) {
21-
_channel.invokeMethod('mediaStreamTrackSetEnable',
24+
_methodChannel.invokeMethod('mediaStreamTrackSetEnable',
2225
<String, dynamic>{'trackId': _trackId, 'enabled': enabled});
2326
_enabled = enabled;
2427
}
2528

2629
bool get enabled => _enabled;
30+
2731
String get label => _label;
32+
2833
String get kind => _kind;
29-
String get id => _trackId;
3034

31-
///Future contains isFrontCamera
32-
///Throws error if switching camera failed
33-
Future<bool> switchCamera() => _channel.invokeMethod(
34-
'mediaStreamTrackSwitchCamera',
35-
<String, dynamic>{'trackId': _trackId},
36-
);
35+
String get id => _trackId;
3736

38-
void setVolume(double volume) async {
39-
await _channel.invokeMethod(
37+
Future<void> setVolume(double volume) async {
38+
await _methodChannel.invokeMethod(
4039
'setVolume',
4140
<String, dynamic>{'trackId': _trackId, 'volume': volume},
4241
);
4342
}
4443

45-
void setMicrophoneMute(bool mute) async {
46-
print('MediaStreamTrack:setMicrophoneMute $mute');
47-
await _channel.invokeMethod(
44+
/// AudioTrack methods.
45+
/// Mute/unmute the microphone.
46+
Future<void> setMicrophoneMute(bool mute) async {
47+
await _methodChannel.invokeMethod(
4848
'setMicrophoneMute',
4949
<String, dynamic>{'trackId': _trackId, 'mute': mute},
5050
);
5151
}
5252

53-
void enableSpeakerphone(bool enable) async {
54-
print('MediaStreamTrack:enableSpeakerphone $enable');
55-
await _channel.invokeMethod(
53+
Future<void> enableSpeakerphone(bool enable) async {
54+
await _methodChannel.invokeMethod(
5655
'enableSpeakerphone',
5756
<String, dynamic>{'trackId': _trackId, 'enable': enable},
5857
);
5958
}
6059

61-
captureFrame(String filePath) => _channel.invokeMethod(
60+
/// VideoTrack methods
61+
/// Future contains isFrontCamera
62+
/// Throws error if switching camera failed.
63+
Future<bool> switchCamera() => _methodChannel.invokeMethod(
64+
'mediaStreamTrackSwitchCamera',
65+
<String, dynamic>{'trackId': _trackId},
66+
);
67+
68+
Future<void> captureFrame(String filePath) => _methodChannel.invokeMethod(
6269
'captureFrame',
6370
<String, dynamic>{'trackId': _trackId, 'path': filePath},
6471
);
6572

6673
Future<void> dispose() async {
67-
await _channel.invokeMethod(
74+
await _methodChannel.invokeMethod(
6875
'trackDispose',
6976
<String, dynamic>{'trackId': _trackId},
7077
);

lib/rtc_data_channel.dart

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ import 'dart:typed_data';
33
import 'package:flutter/services.dart';
44
import 'utils.dart';
55

6-
enum MessageType { text, binary }
7-
86
/// Initialization parameters for [RTCDataChannel].
97
class RTCDataChannelInit {
108
bool ordered = true;
@@ -25,6 +23,8 @@ class RTCDataChannelInit {
2523
}
2624
}
2725

26+
enum MessageType { text, binary }
27+
2828
/// A class that represents a datachannel message.
2929
/// Can either contain binary data as a [Uint8List] or
3030
/// text data as a [String].
@@ -74,18 +74,36 @@ typedef void RTCDataChannelOnMessageCallback(RTCDataChannelMessage message);
7474
/// A class that represents a WebRTC datachannel.
7575
/// Can send and receive text and binary messages.
7676
class RTCDataChannel {
77+
/// private:
78+
MethodChannel _methodChannel = WebRTC.methodChannel();
79+
int _dataChannelId;
7780
String _peerConnectionId;
7881
String _label;
79-
int _dataChannelId;
8082
RTCDataChannelState _state;
81-
MethodChannel _channel = WebRTC.methodChannel();
8283
StreamSubscription<dynamic> _eventSubscription;
83-
84+
final _stateChangeController =
85+
StreamController<RTCDataChannelState>.broadcast(sync: true);
86+
final _messageController =
87+
StreamController<RTCDataChannelMessage>.broadcast(sync: true);
8488
final _typeStringToMessageType = <String, MessageType>{
8589
'text': MessageType.text,
8690
'binary': MessageType.binary
8791
};
8892

93+
/// public:
94+
95+
RTCDataChannel(this._peerConnectionId, this._label, this._dataChannelId) {
96+
stateChangeStream = _stateChangeController.stream;
97+
messageStream = _messageController.stream;
98+
_eventSubscription = _eventChannelFor(_dataChannelId)
99+
.receiveBroadcastStream()
100+
.listen(eventListener, onError: errorListener);
101+
}
102+
103+
104+
/// Get label.
105+
String get lable => _label;
106+
89107
/// Get current state.
90108
RTCDataChannelState get state => _state;
91109

@@ -100,11 +118,6 @@ class RTCDataChannel {
100118
/// binary data as a [Uint8List] or text data as a [String].
101119
RTCDataChannelOnMessageCallback onMessage;
102120

103-
final _stateChangeController =
104-
StreamController<RTCDataChannelState>.broadcast(sync: true);
105-
final _messageController =
106-
StreamController<RTCDataChannelMessage>.broadcast(sync: true);
107-
108121
/// Stream of state change events. Emits the new state on change.
109122
/// Closes when the [RTCDataChannel] is closed.
110123
Stream<RTCDataChannelState> stateChangeStream;
@@ -113,14 +126,6 @@ class RTCDataChannel {
113126
/// Closes when the [RTCDataChannel] is closed.
114127
Stream<RTCDataChannelMessage> messageStream;
115128

116-
RTCDataChannel(this._peerConnectionId, this._label, this._dataChannelId) {
117-
stateChangeStream = _stateChangeController.stream;
118-
messageStream = _messageController.stream;
119-
_eventSubscription = _eventChannelFor(_dataChannelId)
120-
.receiveBroadcastStream()
121-
.listen(eventListener, onError: errorListener);
122-
}
123-
124129
/// RTCDataChannel event listener.
125130
void eventListener(dynamic event) {
126131
final Map<dynamic, dynamic> map = event;
@@ -164,7 +169,7 @@ class RTCDataChannel {
164169
/// To send a binary message, pass a binary [RTCDataChannelMessage]
165170
/// constructed with [RTCDataChannelMessage.fromBinary]
166171
Future<void> send(RTCDataChannelMessage message) async {
167-
await _channel.invokeMethod('dataChannelSend', <String, dynamic>{
172+
await _methodChannel.invokeMethod('dataChannelSend', <String, dynamic>{
168173
'peerConnectionId': _peerConnectionId,
169174
'dataChannelId': _dataChannelId,
170175
'type': message.isBinary ? "binary" : "text",
@@ -176,7 +181,7 @@ class RTCDataChannel {
176181
await _stateChangeController.close();
177182
await _messageController.close();
178183
await _eventSubscription?.cancel();
179-
await _channel.invokeMethod('dataChannelClose', <String, dynamic>{
184+
await _methodChannel.invokeMethod('dataChannelClose', <String, dynamic>{
180185
'peerConnectionId': _peerConnectionId,
181186
'dataChannelId': _dataChannelId
182187
});

lib/rtc_dtmf_sender.dart

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,68 @@
1+
import 'dart:async';
2+
import 'package:flutter/services.dart';
3+
4+
import 'utils.dart';
5+
16
class RTCDTMFSender {
7+
/// private:
28
String _id;
9+
MethodChannel _methodChannel = WebRTC.methodChannel();
310

11+
/// public::
412
RTCDTMFSender(this._id);
13+
14+
Future<bool> canInsertDtmf() async {
15+
try {
16+
final Map<dynamic, dynamic> response = await _methodChannel.invokeMethod(
17+
'dtmfSenderCanInsertDtmf', <String, dynamic>{'dtmfSenderId': _id});
18+
return response['result'];
19+
} on PlatformException catch (e) {
20+
throw 'Unable to RTCDTMFSender::canInsertDtmf: ${e.message}';
21+
}
22+
}
23+
24+
Future<bool> insertDtmf(String tones, int duration, int interToneGap) async {
25+
try {
26+
final Map<dynamic, dynamic> response = await _methodChannel
27+
.invokeMethod('dtmfSenderCanInsertDtmf', <String, dynamic>{
28+
'dtmfSenderId': _id,
29+
'tones': tones,
30+
'duration': duration,
31+
'interToneGap': interToneGap
32+
});
33+
return response['result'];
34+
} on PlatformException catch (e) {
35+
throw 'Unable to RTCDTMFSender::insertDtmf: ${e.message}';
36+
}
37+
}
38+
39+
Future<String> tones() async {
40+
try {
41+
final Map<dynamic, dynamic> response = await _methodChannel.invokeMethod(
42+
'dtmfSenderGetTones', <String, dynamic>{'dtmfSenderId': _id});
43+
return response['result'];
44+
} on PlatformException catch (e) {
45+
throw 'Unable to RTCDTMFSender::tones: ${e.message}';
46+
}
47+
}
48+
49+
Future<int> duration() async {
50+
try {
51+
final Map<dynamic, dynamic> response = await _methodChannel.invokeMethod(
52+
'dtmfSenderGetDuration', <String, dynamic>{'dtmfSenderId': _id});
53+
return response['result'];
54+
} on PlatformException catch (e) {
55+
throw 'Unable to RTCDTMFSender::duration: ${e.message}';
56+
}
57+
}
58+
59+
Future<int> interToneGap() async {
60+
try {
61+
final Map<dynamic, dynamic> response = await _methodChannel.invokeMethod(
62+
'dtmfSenderGetInterToneGap', <String, dynamic>{'dtmfSenderId': _id});
63+
return response['result'];
64+
} on PlatformException catch (e) {
65+
throw 'Unable to RTCDTMFSender::interToneGap: ${e.message}';
66+
}
67+
}
568
}

0 commit comments

Comments
 (0)
0