8000 WIP - api standardization across implementation (#364) · next-coder/flutter-webrtc@b80623c · GitHub
[go: up one dir, main page]

Skip to content
8000

Commit b80623c

Browse files
authored
WIP - api standardization across implementation (flutter-webrtc#364)
* Initial attemp * Implement proposed structure * Prevent breaking change for MediaDevices Rename MediaDevices to Navigator * Align with w3c js API * export video_renderer * Re-organise classes to not expose Renderer Implementation * Expose enabled setter for mediaStreamTrack * Fix import * fix import * Add missing methods * Remove invalid import * Prevent breaking change for RTCVideoRenderer() * code clean * make sure we use the factory method * Fix VideoRenderer casting * Add more precide message to depracated * Keep factory impl in is own class Delegate in RTCVideoRenderer * Example for exposing class with delegate * remove expose interface when base class is provided * Merge change from master to resolve conflict * API Expose signalingState API Expose iceGatheringState API Expose iceConnectionState * Chage to relative path * Rename Interface * Change interface name * change interface name
1 parent c6423b2 commit b80623c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+1372
-915
lines changed

example/lib/src/get_display_media_sample.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ class _GetDisplayMediaSampleState extends State<GetDisplayMediaSample> {
5252
final mediaConstraints = <String, dynamic>{'audio': false, 'video': true};
5353

5454
try {
55-
var stream = await MediaDevices.getDisplayMedia(mediaConstraints);
55+
var stream = await navigator.getDisplayMedia(mediaConstraints);
5656
_localStream = stream;
5757
_localRenderer.srcObject = _localStream;
5858
} catch (e) {

example/lib/src/get_user_media_sample.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class _GetUserMediaSampleState extends State<GetUserMediaSample> {
5959
};
6060

6161
try {
62-
var stream = await MediaDevices.getUserMedia(mediaConstraints);
62+
var stream = await navigator.getUserMedia(mediaConstraints);
6363
_localStream = stream;
6464
_localRenderer.srcObject = _localStream;
6565
} catch (e) {

example/lib/src/get_user_media_sample_web.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class _GetUserMediaSampleState extends State<GetUserMediaSample> {
2727
void initState() {
2828
super.initState();
2929
initRenderers();
30-
MediaDevices.getSources().then((md) {
30+
navigator.getSources().then((md) {
3131
setState(() {
3232
cameras = md.where((d) => d['kind'] == 'videoinput').toList();
3333
});
@@ -62,7 +62,7 @@ class _GetUserMediaSampleState extends State<GetUserMediaSample> {
6262
};
6363

6464
try {
65-
var stream = await MediaDevices.getUserMedia(mediaConstraints);
65+
var stream = await navigator.getUserMedia(mediaConstraints);
6666
_localStream = stream;
6767
_localRenderer.srcObject = _localStream;
6868
} catch (e) {

example/lib/src/loopback_sample.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ class _MyAppState extends State<LoopBackSample> {
128128
if (_peerConnection != null) return;
129129

130130
try {
131-
_localStream = await MediaDevices.getUserMedia(mediaConstraints);
131+
_localStream = await navigator.getUserMedia(mediaConstraints);
132132
_localRenderer.srcObject = _localStream;
133133
_peerConnection =
134134
await createPeerConnection(configuration, loopbackConstraints);

lib/flutter_webrtc.dart

Lines changed: 16 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,19 @@
11
library flutter_webrtc;
22

3-
export 'src/enums.dart';
4-
export 'src/get_user_media.dart'
5-
if (dart.library.html) 'src/web/get_user_media.dart';
6-
export 'src/media_recorder.dart'
7-
if (dart.library.html) 'src/web/media_recorder.dart';
8-
export 'src/media_stream.dart'
9-
if (dart.library.html) 'src/web/media_stream.dart';
10-
export 'src/media_stream_track.dart'
11-
if (dart.library.html) 'src/web/media_stream_track.dart';
12-
export 'src/rtc_data_channel.dart'
13-
if (dart.library.html) 'src/web/rtc_data_channel.dart';
14-
export 'src/rtc_dtmf_sender.dart'
15-
if (dart.library.html) 'src/web/rtc_dtmf_sender.dart';
16-
export 'src/rtc_ice_candidate.dart'
17-
if (dart.library.html) 'src/web/rtc_ice_candidate.dart';
18-
export 'src/rtc_peerconnection.dart'
19-
if (dart.library.html) 'src/web/rtc_peerconnection.dart';
20-
export 'src/rtc_peerconnection_factory.dart'
3+
export 'src/interface/enums.dart';
4+
export 'src/interface/media_stream.dart';
5+
export 'src/interface/media_stream_track.dart';
6+
export 'src/interface/rtc_data_channel.dart';
7+
export 'src/interface/rtc_dtmf_sender.dart';
8+
export 'src/interface/rtc_ice_candidate.dart';
9+
export 'src/interface/rtc_peerconnection.dart';
10+
export 'src/interface/rtc_session_description.dart';
11+
export 'src/interface/rtc_stats_report.dart';
12+
export 'src/media_devices.dart';
13+
export 'src/media_recorder.dart';
14+
export 'src/native/rtc_peerconnection_factory.dart'
2115
if (dart.library.html) 'src/web/rtc_peerconnection_factory.dart';
22-
export 'src/rtc_session_description.dart'
23-
if (dart.library.html) 'src/web/rtc_session_description.dart';
24-
export 'src/rtc_stats_report.dart';
25-
export 'src/rtc_video_view.dart'
26-
if (dart.library.html) 'src/web/rtc_video_view.dart';
27-
export 'src/utils.dart' if (dart.library.html) 'src/web/utils.dart';
16+
export 'src/native/rtc_video_view_impl.dart'
17+
if (dart.library.html) 'src/web/rtc_video_view_impl.dart';
18+
export 'src/native/utils.dart' if (dart.library.html) 'src/web/utils.dart';
19+
export 'src/rtc_video_renderer.dart';
File renamed without changes.

lib/src/interface/factory.dart

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import 'media_recorder.dart';
2+
import 'media_stream.dart';
3+
import 'navigator.dart';
4+
import 'rtc_peerconnection.dart';
5+
import 'rtc_video_renderer.dart';
6+
7+
abstract class RTCFactory {
8+
Future<RTCPeerConnection> createPeerConnection(
9+
Map<String, dynamic> configuration,
10+
[Map<String, dynamic> constraints]);
11+
12+
Future<MediaStream> createLocalMediaStream(String label);
13+
14+
Navigator get navigator;
15+
16+
MediaRecorder mediaRecorder();
17+
18+
VideoRenderer videoRenderer();
19+
}

lib/src/interface/media_recorder.dart

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import 'enums.dart';
2+
import 'media_stream.dart';
3+
import 'media_stream_track.dart';
4+
5+
abstract class MediaRecorder {
6+
/// For Android use audioChannel param
7+
/// For iOS use audioTrack
8+
Future<void> start(
9+
String path, {
10+
MediaStreamTrack videoTrack,
11+
RecorderAudioChannel audioChannel,
12+
});
13+
14+
/// Only for Flutter Web
15+
void startWeb(
16+
MediaStream stream, {
17+
Function(dynamic blob, bool isLastOne) onDataChunk,
18+
String mimeType,
19+
});
20+
21+
Future<dynamic> stop();
22+
}

lib/src/interface/media_stream.dart

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import 'media_stream_track.dart';
2+
3+
abstract class MediaStream {
4+
MediaStream(this._id, this._ownerTag);
5+
final String _id;
6+
final String _ownerTag;
7+
8+
String get id => _id;
9+
10+
String get ownerTag => _ownerTag;
11+
12+
Future<void> getMediaTracks();
13+
14+
Future<void> addTrack(MediaStreamTrack track, {bool addToNative = true});
15+
16+
Future<void> removeTrack(MediaStreamTrack track,
17+
{bool removeFromNative = true});
18+
19+
List<MediaStreamTrack> getAudioTracks();
20+
21+
List<MediaStreamTrack> getVideoTracks();
22+
23+
Future<void> dispose() async {
24+
return Future.value();
25+
}
26+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
abstract class MediaStreamTrack {
2+
MediaStreamTrack();
3+
4+
bool get enabled;
5+
set enabled(bool b);
6+
7+
String get label;
8+
9+
String get kind;
10+
11+
String get id;
12+
13+
///Future contains isFrontCamera
14+
///Throws error if switching camera failed
15+
Future<bool> switchCamera();
16+
17+
Future<void> adaptRes(int width, int height);
18+
19+
void setVolume(double volume);
20+
21+
void setMicrophoneMute(bool mute);
22+
23+
void enableSpeakerphone(bool enable);
24+
25+
Future<dynamic> captureFrame([String filePath]);
26+
27+
Future<bool> hasTorch();
28+
Future<void> setTorch(bool torch);
29+
30+
Future<void> dispose() {
31+
return Future.value();
32+
}
33+
}

lib/src/interface/mediadevices.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import 'media_stream.dart';
2+
3+
abstract class MediaDevices {
4+
Future<MediaStream> getUserMedia(Map<String, dynamic> mediaConstraints);
5+
Future<MediaStream> getDisplayMedia(Map<String, dynamic> mediaConstraints);
6+
Future< 10000 List<dynamic>> getSources();
7+
}

lib/src/interface/navigator.dart

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import 'media_stream.dart';
2+
import 'mediadevices.dart';
3+
4+
abstract class Navigator {
5+
Future<MediaStream> getUserMedia(Map<String, dynamic> mediaConstraints);
6+
Future<MediaStream> getDisplayMedia(Map<String, dynamic> mediaConstraints);
7+
Future<List<dynamic>> getSources();
8+
MediaDevices get mediaDevices;
9+
}
Lines changed: 13 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
import 'dart:async';
2-
import 'dart:html' as html;
3-
import 'dart:js_util' as jsutil;
42
import 'dart:typed_data';
53

6-
import '../enums.dart';
4+
import 'enums.dart';
75

86
class RTCDataChannelInit {
97
bool ordered = true;
@@ -22,7 +20,7 @@ class RTCDataChannelInit {
2220
if (maxRetransmits > 0) 'maxRetransmits': maxRetransmits,
2321
'protocol': protocol,
2422
'negotiated': negotiated,
25-
if (id != 0) 'id': id
23+
'id': id
2624
};
2725
}
2826
}
@@ -63,48 +61,18 @@ class RTCDataChannelMessage {
6361
}
6462

6563
typedef RTCDataChannelStateCallback = void Function(RTCDataChannelState state);
64+
6665
typedef RTCDataChannelOnMessageCallback = void Function(
6766
RTCDataChannelMessage data);
6867

69-
class RTCDataChannel {
70-
RTCDataChannel(this._jsDc) {
71-
stateChangeStream = _stateChangeController.stream;
72-
messageStream = _messageController.stream;
73-
_jsDc.onClose.listen((_) {
74-
_state = RTCDataChannelState.RTCDataChannelClosed;
75-
_stateChangeController.add(_state);
76-
if (onDataChannelState != null) {
77-
onDataChannelState(_state);
78-
}
79-
});
80-
_jsDc.onOpen.listen((_) {
81-
_state = RTCDataChannelState.RTCDataChannelOpen;
82-
_stateChangeController.add(_state);
83-
if (onDataChannelState != null) {
84-
onDataChannelState(_state);
85-
}
86-
});
87-
_jsDc.onMessage.listen((event) async {
88-
var msg = await _parse(event.data);
89-
_messageController.add(msg);
90-
if (onMessage != null) {
91-
onMessage(msg);
92-
}
93-
});
94-
}
68+
abstract class RTCDataChannel {
69+
RTCDataChannel();
9570

96-
final html.RtcDataChannel _jsDc;
9771
RTCDataChannelStateCallback onDataChannelState;
9872
RTCDataChannelOnMessageCallback onMessage;
99-
RTCDataChannelState _state = RTCDataChannelState.RTCDataChannelConnecting;
10073

10174
/// Get current state.
102-
RTCDataChannelState get state => _state;
103-
104-
final _stateChangeController =
105-
StreamController<RTCDataChannelState>.broadcast(sync: true);
106-
final _messageController =
107-
StreamController<RTCDataChannelMessage>.broadcast(sync: true);
75+
RTCDataChannelState get state;
10876

10977
/// Stream of state change events. Emits the new state on change.
11078
/// Closes when the [RTCDataChannel] is closed.
@@ -114,32 +82,12 @@ class RTCDataChannel {
11482
/// Closes when the [RTCDataChannel] is closed.
11583
Stream<RTCDataChannelMessage> messageStream;
11684

117-
Future<RTCDataChannelMessage> _parse(dynamic data) async {
118-
if (data is String) return RTCDataChannelMessage(data);
119-
dynamic arrayBuffer;
120-
if (data is html.Blob) {
121-
// This should never happen actually
122-
arrayBuffer = await jsutil
123-
.promiseToFuture(jsutil.callMethod(data, 'arrayBuffer', []));
124-
} else {
125-
arrayBuffer = data;
126-
}
127-
return RTCDataChannelMessage.fromBinary(arrayBuffer.asUint8List());
128-
}
85+
/// Send a message to this datachannel.
86+
/// To send a text message, use the default constructor to instantiate a text [RTCDataChannelMessage]
87+
/// for the [message] parameter.
88+
/// To send a binary message, pass a binary [RTCDataChannelMessage]
89+
/// constructed with [RTCDataChannelMessage.fromBinary]
90+
Future<void> send(RTCDataChannelMessage message);
12991

130-
Future<void> send(RTCDataChannelMessage message) {
131-
if (!message.isBinary) {
132-
_jsDc.send(message.text);
133-
} else {
134-
// This may just work
135-
_jsDc.sendByteBuffer(message.binary.buffer);
136-
// If not, convert to ArrayBuffer/Blob
137-
}
138-
return Future.value();
139-
}
140-
141-
Future<void> close() {
142-
_jsDc.close();
143-
return Future.value();
144-
}
92+
Future<void> close();
14593
}

lib/src/web/rtc_dtmf_sender.dart renamed to lib/src/interface/rtc_dtmf_sender.dart

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,4 @@
1-
import 'dart:html' as html;
2-
3-
class RTCDTMFSender {
4-
RTCDTMFSender(this._jsDtmfSender);
5-
final html.RtcDtmfSender _jsDtmfSender;
6-
1+
abstract class RTCDTMFSender {
72
/// tones:A String containing the DTMF codes to be transmitted to the recipient.
83
/// Specifying an empty string as the tones parameter clears the tone
94
/// buffer, aborting any currently queued tones. A "," character inserts
@@ -15,11 +10,10 @@ class RTCDTMFSender {
1510
/// if you specify a lower value, 30 ms will be used instead);
1611
/// the default is 70 ms.
1712
Future<void> insertDTMF(String tones,
18-
{int duration = 100, int interToneGap = 70}) async {
19-
return _jsDtmfSender.insertDtmf(tones, duration, interToneGap);
20-
}
13+
{int duration = 100, int interToneGap = 70});
2114

2215
/// Compatible with old methods
16+
@Deprecated('Use method insertDTMF instead')
2317
Future<void> sendDtmf(String tones,
2418
{int duration = 100, int interToneGap = 70}) =>
2519
insertDTMF(tones, duration: duration, interToneGap: interToneGap);

0 commit comments

Comments
 (0)
0