10000 Null safety (#516) · Appleprabh/flutter-webrtc@8d37879 · GitHub
[go: up one dir, main page]

Skip to content

Commit 8d37879

Browse files
Null safety (flutter-webrtc#516)
* BREAKING CHANGES - MediaStream.getTrackById can throw an eeception if the track if not found * BREAKING CHANGES - Remove unused RTC_Configuration classes * null safety migration * FIX - stop from RTC_RTP_TRANSCEIVER was never set REFACTOR - Null safety * Refactor - Null safety * Migrate Exemple to null safety * package null-fafety * FIX - Type conversion for null safety Example (loopback) - Add callback method to the right semantics * Add CHANGELOG for 0.6.0-null-safety.0. * update. Co-authored-by: Louis-Michel Mathurin <mathurin.lm@we-r.app>
1 parent de60bd9 commit 8d37879

Some content is hidden

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

58 files changed

+645
-553
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
# Changelog
22

33
--------------------------------------------
4+
[0.6.0-nullsafety.0] - 2021.03.22
5+
6+
* [Dart] null-safety (@wer-mathurin Thanks for the hard work).
7+
48
[0.5.8] - 2021.01.26
59

610
* [Web] Support selecting audio output.

example/lib/main.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ class MyApp extends StatefulWidget {
5151
}
5252

5353
class _MyAppState extends State<MyApp> {
54-
List<RouteItem> items;
54+
late List<RouteItem> items;
5555

5656
@override
5757
void initState() {

example/lib/src/data_channel_sample.dart

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@ class DataChannelSample extends StatefulWidget {
1212
}
1313

1414
class _DataChannelSampleState extends State<DataChannelSample> {
15-
RTCPeerConnection _peerConnection;
15+
RTCPeerConnection? _peerConnection;
1616
bool _inCalling = false;
1717

18-
RTCDataChannelInit _dataChannelDict;
19-
RTCDataChannel _dataChannel;
18+
RTCDataChannelInit? _dataChannelDict;
19+
RTCDataChannel? _dataChannel;
2020

21-
String _sdp;
21+
String _sdp = '';
2222

2323
@override
2424
void initState() {
@@ -38,11 +38,11 @@ class _DataChannelSampleState extends State<DataChannelSample> {
3838
}
3939

4040
void _onCandidate(RTCIceCandidate candidate) {
41-
print('onCandidate: ' + candidate.candidate);
42-
_peerConnection.addCandidate(candidate);
41+
print('onCandidate: ${candidate.candidate}');
42+
_peerConnection?.addCandidate(candidate);
4343
setState(() {
4444
_sdp += '\n';
45-
_sdp += candidate.candidate;
45+
_sdp += candidate.candidate ?? '';
4646
});
4747
}
4848

@@ -101,29 +101,29 @@ class _DataChannelSampleState extends State<DataChannelSample> {
101101
_peerConnection =
102102
await createPeerConnection(configuration, loopbackConstraints);
103103

104-
_peerConnection.onSignalingState = _onSignalingState;
105-
_peerConnection.onIceGatheringState = _onIceGatheringState;
106-
_peerConnection.onIceConnectionState = _onIceConnectionState;
107-
_peerConnection.onIceCandidate = _onCandidate;
108-
_peerConnection.onRenegotiationNeeded = _onRenegotiationNeeded;
104+
_peerConnection!.onSignalingState = _onSignalingState;
105+
_peerConnection!.onIceGatheringState = _onIceGatheringState;
106+
_peerConnection!.onIceConnectionState = _onIceConnectionState;
107+
_peerConnection!.onIceCandidate = _onCandidate;
108+
_peerConnection!.onRenegotiationNeeded = _onRenegotiationNeeded;
109109

110110
_dataChannelDict = RTCDataChannelInit();
111-
_dataChannelDict.id = 1;
112-
_dataChannelDict.ordered = true;
113-
_dataChannelDict.maxRetransmitTime = -1;
114-
_dataChannelDict.maxRetransmits = -1;
115-
_dataChannelDict.protocol = 'sctp';
116-
_dataChannelDict.negotiated = false;
117-
118-
_dataChannel = await _peerConnection.createDataChannel(
119-
'dataChannel', _dataChannelDict);
120-
_peerConnection.onDataChannel = _onDataChannel;
121-
122-
var description = await _peerConnection.createOffer(offerSdpConstraints);
111+
_dataChannelDict!.id = 1;
112+
_dataChannelDict!.ordered = true;
113+
_dataChannelDict!.maxRetransmitTime = -1;
114+
_dataChannelDict!.maxRetransmits = -1;
115+
_dataChannelDict!.protocol = 'sctp';
116+
_dataChannelDict!.negotiated = false;
117+
118+
_dataChannel = await _peerConnection!
119+
.createDataChannel('dataChannel', _dataChannelDict!);
120+
_peerConnection!.onDataChannel = _onDataChannel;
121+
122+
var description = await _peerConnection!.createOffer(offerSdpConstraints);
123123
print(description.sdp);
124-
await _peerConnection.setLocalDescription(description);
124+
await _peerConnection!.setLocalDescription(description);
125125

126-
_sdp = description.sdp;
126+
_sdp = description.sdp ?? '';
127127
//change for loopback.
128128
//description.type = 'answer';
129129
//_peerConnection.setRemoteDescription(description);
@@ -139,8 +139,8 @@ class _DataChannelSampleState extends State<DataChannelSample> {
139139

140140
void _hangUp() async {
141141
try {
142-
await _dataChannel.close();
143-
await _peerConnection.close();
142+
await _dataChannel?.close();
143+
await _peerConnection?.close();
144144
_peerConnection = null;
145145
} catch (e) {
146146
print(e.toString());

example/lib/src/get_display_media_sample.dart

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ class GetDisplayMediaSample extends StatefulWidget {
1515
}
1616

1717
class _GetDisplayMediaSampleState extends State<GetDisplayMediaSample> {
18-
MediaStream _localStream;
18+
MediaStream? _localStream;
1919
final _localRenderer = RTCVideoRenderer();
2020
bool _inCalling = false;
21-
Timer _timer;
21+
Timer? _timer;
2222
var _counter = 0;
2323

2424
@override
@@ -33,7 +33,7 @@ class _GetDisplayMediaSampleState extends State<GetDisplayMediaSample> {
3333
if (_inCalling) {
3434
_stop();
3535
}
36-
if (_timer != null) _timer.cancel();
36+
_timer?.cancel();
3737
_localRenderer.dispose();
3838
}
3939

@@ -74,10 +74,8 @@ class _GetDisplayMediaSampleState extends State<GetDisplayMediaSample> {
7474

7575
Future<void> _stop() async {
7676
try {
77-
if (_localStream != null) {
78-
await _localStream.dispose();
79-
_localStream = null;
80-
}
77+
await _localStream?.dispose();
78+
_localStream = null;
8179
_localRenderer.srcObject = null;
8280
} catch (e) {
8381
print(e.toString());
@@ -89,7 +87,7 @@ class _GetDisplayMediaSampleState extends State<GetDisplayMediaSample> {
8987
setState(() {
9088
_inCalling = false;
9189
});
92-
_timer.cancel();
90+
_timer?.cancel();
9391
}
9492

9593
@override

example/lib/src/get_user_media_sample.dart

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@ class GetUserMediaSample extends StatefulWidget {
1616
}
1717

1818
class _GetUserMediaSampleState extends State<GetUserMediaSample> {
19-
MediaStream _localStream;
19+
MediaStream? _localStream;
2020
final _localRenderer = RTCVideoRenderer();
2121
bool _inCalling = false;
2222
bool _isTorchOn = false;
23-
MediaRecorder _mediaRecorder;
23+
MediaRecorder? _mediaRecorder;
2424
bool get _isRec => _mediaRecorder != null;
2525

26-
List<MediaDeviceInfo> _mediaDevicesList;
26+
List<MediaDeviceInfo>? _mediaDevicesList;
2727

2828
@override
2929
void initState() {
@@ -61,7 +61,7 @@ class _GetUserMediaSampleState extends State<GetUserMediaSample> {
6161
};
6262

6363
try {
64-
var stream = await navigator.getUserMedia(mediaConstraints);
64+
var stream = await navigator.mediaDevices.getUserMedia(mediaConstraints);
6565
_mediaDevicesList = await navigator.mediaDevices.enumerateDevices();
6666
_localStream = stream;
6767
_localRenderer.srcObject = _localStream;
@@ -77,31 +77,35 @@ class _GetUserMediaSampleState extends State<GetUserMediaSample> {
7777

7878
void _hangUp() async {
7979
try {
80-
await _localStream.dispose();
80+
await _localStream?.dispose();
8181
_localRenderer.srcObject = null;
82+
setState(() {
83+
_inCalling = false;
84+
});
8285
} catch (e) {
8386
print(e.toString());
8487
}
85-
setState(() {
86-
_inCalling = false;
87-
});
8888
}
8989

9090
void _startRecording() async {
91+
if (_localStream == null) throw Exception('Stream is not initialized');
9192
if (Platform.isIOS) {
9293
print('Recording is not available on iOS');
9394
return;
9495
}
9596
// TODO(rostopira): request write storage permission
9697
final storagePath = await getExternalStorageDirectory();
98+
if (storagePath == null) throw Exception('Can\'t find storagePath');
99+
97100
final filePath = storagePath.path + '/webrtc_sample/test.mp4';
98101
_mediaRecorder = MediaRecorder();
99102
setState(() {});
100-
await _localStream.getMediaTracks();
101-
final videoTrack = _localStream
103+
104+
await _localStream!.getMediaTracks();
105+
final videoTrack = _localStream!
102106
.getVideoTracks()
103107
.firstWhere((track) => track.kind == 'video');
104-
await _mediaRecorder.start(
108+
await _mediaRecorder!.start(
105109
filePath,
106110
videoTrack: videoTrack,
107111
);
@@ -115,7 +119,9 @@ class _GetUserMediaSampleState extends State<GetUserMediaSample> {
115119
}
116120

117121
void _toggleTorch() async {
118-
final videoTrack = _localStream
122+
if (_localStream == null) throw Exception('Stream is not initialized');
123+
124+
final videoTrack = _localStream!
119125
.getVideoTracks()
120126
.firstWhere((track) => track.kind == 'video');
121127
final has = await videoTrack.hasTorch();
@@ -130,23 +136,29 @@ class _GetUserMediaSampleState extends State<GetUserMediaSample> {
130136
}
131137

132138
void _toggleCamera() async {
133-
final videoTrack = _localStream
139+
if (_localStream == null) throw Exception('Stream is not initialized');
140+
141+
final videoTrack = _localStream!
134142
.getVideoTracks()
135143
.firstWhere((track) => track.kind == 'video');
136144
await videoTrack.switchCamera();
137145
}
138146

139147
void _captureFrame() async {
< B93C /td>148+
if (_localStream == null) throw Exception('Stream is not initialized');
149+
140150
String filePath;
141151
if (Platform.isAndroid) {
142152
final storagePath = await getExternalStorageDirectory();
153+
if (storagePath == null) throw Exception('Can\'t find storagePath');
154+
143155
filePath = storagePath.path + '/webrtc_sample/test.jpg';
144156
} else {
145157
final storagePath = await getApplicationDocumentsDirectory();
146158
filePath = storagePath.path + '/test${DateTime.now()}.jpg';
147159
}
148160

149-
final videoTrack = _localStream
161+
final videoTrack = _localStream!
150162
.getVideoTracks()
151163
.firstWhere((track) => track.kind == 'video');
152164
await videoTrack.captureFrame(filePath);
@@ -178,16 +190,17 @@ class _GetUserMediaSampleState extends State<GetUserMediaSample> {
178190
PopupMenuButton<String>(
179191
onSelected: _selectAudioOutput,
180192
itemBuilder: (BuildContext context) {
181-
return _mediaDevicesList
182-
.where((device) => device.kind == 'audiooutput')
183-
.map((device) {
184-
if (device.kind == 'audiooutput') {
193+
if (_mediaDevicesList != null) {
194+
return _mediaDevicesList!
195+
.where((device) => device.kind == 'audiooutput')
196+
.map((device) {
185197
return PopupMenuItem<String>(
186198
value: device.deviceId,
187199
child: Text(device.label),
188200
);
189-
}
190-
}).toList();
201+
}).toList();
202+
}
203+
return [];
191204
},
192205
),
193206
]

example/lib/src/get_user_media_sample_web.dart

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@ class GetUserMediaSample extends StatefulWidget {
1616
}
1717

1818
class _GetUserMediaSampleState extends State<GetUserMediaSample> {
19-
MediaStream _localStream;
19+
MediaStream? _localStream;
2020
final _localRenderer = RTCVideoRenderer();
2121
bool _inCalling = false;
22-
MediaRecorder _mediaRecorder;
22+
MediaRecorder? _mediaRecorder;
2323

24-
List<MediaDeviceInfo> _cameras;
24+
List<MediaDeviceInfo>? _cameras;
2525
bool get _isRec => _mediaRecorder != null;
26-
List<dynamic> cameras;
26+
List<dynamic>? cameras;
2727

2828
@override
2929
void initState() {
@@ -81,10 +81,8 @@ class _GetUserMediaSampleState extends State<GetUserMediaSample> {
8181

8282
Future<void> _stop() async {
8383
try {
84-
if (_localStream != null) {
85-
await _localStream.dispose();
86-
_localStream = null;
87-
}
84+
await _localStream?.dispose();
85+
_localStream = null;
8886
_localRenderer.srcObject = null;
8987
} catch (e) {
9088
print(e.toString());
@@ -99,9 +97,10 @@ class _GetUserMediaSampleState extends State<GetUserMediaSample> {
9997
}
10098

10199
void _startRecording() async {
100+
if (_localStream == null) throw Exception('Can\'t record without a stream');
102101
_mediaRecorder = MediaRecorder();
103102
setState(() {});
104-
_mediaRecorder.startWeb(_localStream);
103+
_mediaRecorder?.startWeb(_localStream!);
105104
}
106105

107106
void _stopRecording() async {
@@ -114,7 +113,8 @@ class _GetUserMediaSampleState extends State<GetUserMediaSample> {
114113
}
115114

116115
void _captureFrame() async {
117-
final videoTrack = _localStream
116+
if (_localStream == null) throw Exception('Can\'t record without a stream');
117+
final videoTrack = _localStream!
118118
.getVideoTracks()
119119
.firstWhere((track) => track.kind == 'video');
120120
final frame = await videoTrack.captureFrame();
@@ -149,12 +149,16 @@ class _GetUserMediaSampleState extends State<GetUserMediaSample> {
149149
PopupMenuButton<String>(
150150
onSelected: _switchCamera,
151151
itemBuilder: (BuildContext context) {
152-
return _cameras.map((device) {
153-
return PopupMenuItem<String>(
154-
value: device.deviceId,
155-
child: Text(device.label),
156-
);
157-
}).toList();
152+
if (_cameras != null) {
153+
return _cameras!.map((device) {
154+
return PopupMenuItem<String>(
155+
value: device.deviceId,
156+
child: Text(device.label),
157+
);
158+
}).toList();
159+
} else {
160+
return [];
161+
}
158162
},
159163
),
160164
// IconButton(
@@ -186,8 +190,10 @@ class _GetUserMediaSampleState extends State<GetUserMediaSample> {
186190
}
187191

188192
void _switchCamera(String deviceId) async {
193+
if (_localStream == null) return;
194+
189195
await Helper.switchCamera(
190-
_localStream.getVideoTracks()[0], deviceId, _localStream);
196+
_localStream!.getVideoTracks()[0], deviceId, _localStream);
191197
setState(() {});
192198
}
193199
}

0 commit comments

Comments
 (0)
0