Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[flutter_webrtc] Update libwebrtc to m114 version #625

Merged
merged 15 commits into from
Nov 22, 2023
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion packages/flutter_webrtc/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
## NEXT
## 0.1.3

* Increase the minimum Flutter version to 3.3.
* Update libwebrtc to m114 version.
* Update flutter_webrtc to 0.9.46.
* Update and format flutter_webrtc_demo.
* Support the empty candidate for 'addIceCandidate' api.

## 0.1.2

Expand Down
4 changes: 2 additions & 2 deletions packages/flutter_webrtc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ For other Tizen devices :

```yaml
dependencies:
flutter_webrtc: ^0.9.28
flutter_webrtc_tizen: ^0.1.2
flutter_webrtc: ^0.9.46
flutter_webrtc_tizen: ^0.1.3
```

## Functionality
Expand Down
14 changes: 5 additions & 9 deletions packages/flutter_webrtc/example/flutter_webrtc_demo/README.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,21 @@
# flutter-webrtc-demo

[![slack](https://img.shields.io/badge/join-us%20on%20slack-gray.svg?longCache=true&logo=slack&colorB=brightgreen)](https://join.slack.com/t/flutterwebrtc/shared_invite/zt-q83o7y1s-FExGLWEvtkPKM8ku_F8cEQ)

Flutter WebRTC plugin Demo

Online Demo: <https://demo.cloudwebrtc.com:8086/>
Online Demo: https://flutter-webrtc.github.io/flutter-webrtc-demo/

## Usage

- `cd flutter_webrtc_demo`
- `flutter-tizen pub get`
- `flutter-tizen run`

## Note

- If you want to test `P2P Call Sample`, please use the [webrtc-flutter-server](https://github.com/cloudwebrtc/flutter-webrtc-server), and enter your server address into the example app.

## screenshots

### iOS

# iOS
<img width="180" height="320" src="https://raw.githubusercontent.com/cloudwebrtc/flutter-webrtc-demo/master/screenshots/flutter-webrtc-ios-example.png"/> <img width="180" height="320" src="https://raw.githubusercontent.com/cloudwebrtc/flutter-webrtc-demo/master/screenshots/ios-01.jpeg"/> <img width="180" height="320" src="https://raw.githubusercontent.com/cloudwebrtc/flutter-webrtc-demo/master/screenshots/ios-02.jpeg"/>

### Android

# Android
<img width="180" height="320" src="https://raw.githubusercontent.com/cloudwebrtc/flutter-webrtc-demo/master/screenshots/flutter-webrtc-android-example.png"/> <img width="180" height="320" src="https://raw.githubusercontent.com/cloudwebrtc/flutter-webrtc-demo/master/screenshots/android-01.png"/> <img width="180" height="320" src="https://raw.githubusercontent.com/cloudwebrtc/flutter-webrtc-demo/master/screenshots/android-02.png"/>
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,3 @@ analyzer:
# allow self-reference to deprecated members (we do this because otherwise we have
# to annotate every member in every test, assert, etc, when we deprecate something)
deprecated_member_use_from_same_package: ignore
# Ignore analyzer hints for updating pubspecs when using Future or
# Stream and not importing dart:async
# Please see https://github.com/flutter/flutter/pull/24528 for details.
sdk_version_async_exported_from_core: ignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class _MyAppState extends State<MyApp> {
_initItems();
}

ListBody _buildRow(context, item) {
Widget _buildRow(context, item) {
return ListBody(children: <Widget>[
ListTile(
title: Text(item.title),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ class _CallSampleState extends State<CallSample> {
final RTCVideoRenderer _remoteRenderer = RTCVideoRenderer();
bool _inCalling = false;
Session? _session;

bool _waitAccept = false;

@override
Expand Down Expand Up @@ -92,7 +91,7 @@ class _CallSampleState extends State<CallSample> {
break;
case CallState.CallStateInvite:
_waitAccept = true;
await _showInvateDialog();
await _showInviteDialog();
break;
case CallState.CallStateConnected:
if (_waitAccept) {
Expand Down Expand Up @@ -156,7 +155,7 @@ class _CallSampleState extends State<CallSample> {
);
}

Future<bool?> _showInvateDialog() {
Future<bool?> _showInviteDialog() {
return showDialog<bool?>(
context: context,
builder: (context) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class _DataChannelSampleState extends State<DataChannelSample> {
RTCDataChannel? _dataChannel;
Session? _session;
Timer? _timer;
var _text = '';
String _text = '';
bool _waitAccept = false;

@override
Expand Down Expand Up @@ -69,7 +69,7 @@ class _DataChannelSampleState extends State<DataChannelSample> {
);
}

Future<bool?> _showInvateDialog() {
Future<bool?> _showInviteDialog() {
return showDialog<bool?>(
context: context,
builder: (context) {
Expand All @@ -93,6 +93,7 @@ class _DataChannelSampleState extends State<DataChannelSample> {
void _connect(BuildContext context) async {
_signaling ??= Signaling(widget.host, context);
await _signaling!.connect();

_signaling?.onDataChannelMessage = (_, dc, RTCDataChannelMessage data) {
setState(() {
if (data.isBinary) {
Expand Down Expand Up @@ -140,7 +141,7 @@ class _DataChannelSampleState extends State<DataChannelSample> {
break;
case CallState.CallStateInvite:
_waitAccept = true;
await _showInvateDialog();
await _showInviteDialog();
break;
case CallState.CallStateConnected:
if (_waitAccept) {
Expand Down Expand Up @@ -203,7 +204,7 @@ class _DataChannelSampleState extends State<DataChannelSample> {
_signaling?.bye(_session!.sid);
}

ListBody _buildRow(context, peer) {
Widget _buildRow(context, peer) {
var self = peer['id'] == _selfId;
return ListBody(children: <Widget>[
ListTile(
Expand Down Expand Up @@ -242,7 +243,7 @@ class _DataChannelSampleState extends State<DataChannelSample> {
body: _inCalling
? Center(
child: Container(
child: Text('Recevied => $_text'),
child: Text('Received => $_text'),
),
)
: ListView.builder(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,35 +106,35 @@ class Signaling {
void switchCamera() {
if (_localStream != null) {
if (_videoSource != VideoSource.Camera) {
for (var sender in _senders) {
_senders.forEach((sender) {
if (sender.track!.kind == 'video') {
sender.replaceTrack(_localStream!.getVideoTracks()[0]);
sender.replaceTrack(_localStream!.getVideoTracks().first);
}
}
});
_videoSource = VideoSource.Camera;
onLocalStream?.call(_localStream!);
} else {
Helper.switchCamera(_localStream!.getVideoTracks()[0]);
Helper.switchCamera(_localStream!.getVideoTracks().first);
}
}
}

void switchToScreenSharing(MediaStream stream) {
if (_localStream != null && _videoSource != VideoSource.Screen) {
for (var sender in _senders) {
_senders.forEach((sender) {
if (sender.track!.kind == 'video') {
sender.replaceTrack(stream.getVideoTracks()[0]);
sender.replaceTrack(stream.getVideoTracks().first);
}
}
});
onLocalStream?.call(stream);
_videoSource = VideoSource.Screen;
}
}

void muteMic() {
if (_localStream != null) {
var enabled = _localStream!.getAudioTracks()[0].enabled;
_localStream!.getAudioTracks()[0].enabled = !enabled;
var enabled = _localStream!.getAudioTracks().first.enabled;
_localStream!.getAudioTracks().first.enabled = !enabled;
}
}

Expand All @@ -159,9 +159,9 @@ class Signaling {
'session_id': sessionId,
'from': _selfId,
});
var sess = _sessions[sessionId];
if (sess != null) {
_closeSession(sess);
var session = _sessions[sessionId];
if (session != null) {
_closeSession(session);
}
}

Expand All @@ -181,16 +181,13 @@ class Signaling {
bye(session.sid);
}

void onMessage(message) async {
Map<String, dynamic> mapData = message;
var data = mapData['data'];

switch (mapData['type']) {
void onMessage(Map<String, dynamic> message) async {
switch (message['type']) {
case 'peers':
{
List<dynamic> peers = data;
List<dynamic> peers = message['data'] ?? [];
if (onPeersUpdate != null) {
var event = <String, dynamic>{};
var event = {};
event['self'] = _selfId;
event['peers'] = peers;
onPeersUpdate?.call(event);
Expand All @@ -199,10 +196,11 @@ class Signaling {
break;
case 'offer':
{
var peerId = data['from'];
var description = data['description'];
var media = data['media'];
var sessionId = data['session_id'];
Map<String, dynamic> data = message['data'] ?? {};
String peerId = data['from'] ?? '';
Map<String, dynamic> description = data['description'] ?? {};
String media = data['media'] ?? '';
String sessionId = data['session_id'] ?? '';
var session = _sessions[sessionId];
var newSession = await _createSession(session,
peerId: peerId,
Expand All @@ -215,7 +213,6 @@ class Signaling {
// await _createAnswer(newSession, media);

if (newSession.remoteCandidates.isNotEmpty) {
// ignore: avoid_function_literals_in_foreach_calls
newSession.remoteCandidates.forEach((candidate) async {
await newSession.pc?.addCandidate(candidate);
});
Expand All @@ -227,8 +224,9 @@ class Signaling {
break;
case 'answer':
{
var description = data['description'];
var sessionId = data['session_id'];
Map<String, dynamic> data = message['data'] ?? {};
Map<String, dynamic> description = data['description'] ?? {};
String sessionId = data['session_id'] ?? '';
var session = _sessions[sessionId];
await session?.pc?.setRemoteDescription(
RTCSessionDescription(description['sdp'], description['type']));
Expand All @@ -237,9 +235,10 @@ class Signaling {
break;
case 'candidate':
{
var peerId = data['from'];
var candidateMap = data['candidate'];
var sessionId = data['session_id'];
Map<String, dynamic> data = message['data'] ?? {};
String peerId = data['from'] ?? '';
Map<String, dynamic> candidateMap = data['candidate'] ?? {};
String sessionId = data['session_id'] ?? '';
var session = _sessions[sessionId];
var candidate = RTCIceCandidate(candidateMap['candidate'],
candidateMap['sdpMid'], candidateMap['sdpMLineIndex']);
Expand All @@ -258,13 +257,16 @@ class Signaling {
break;
case 'leave':
{
var peerId = data as String;
_closeSessionByPeerId(peerId);
String? peerId = message['data'];
if (peerId != null) {
_closeSessionByPeerId(peerId);
}
}
break;
case 'bye':
{
var sessionId = data['session_id'];
Map<String, dynamic> data = message['data'] ?? {};
String sessionId = data['session_id'] ?? '';
print('bye: $sessionId');
var session = _sessions.remove(sessionId);
if (session != null) {
Expand Down Expand Up @@ -299,10 +301,11 @@ class Signaling {
"uris": ["turn:127.0.0.1:19302?transport=udp"]
}
*/
List<String> uris = _turnCredential!['uris'] ?? [];
_iceServers = {
'iceServers': [
{
'urls': _turnCredential!['uris'][0],
'urls': uris.first,
'username': _turnCredential!['username'],
'credential': _turnCredential!['password']
},
Expand Down Expand Up @@ -409,7 +412,7 @@ class Signaling {
// Unified-Plan
pc.onTrack = (event) {
if (event.track.kind == 'video') {
onAddRemoteStream?.call(newSession, event.streams[0]);
onAddRemoteStream?.call(newSession, event.streams.first);
}
};
_localStream!.getTracks().forEach((track) async {
Expand Down Expand Up @@ -533,7 +536,7 @@ class Signaling {
RTCSessionDescription _fixSdp(RTCSessionDescription s) {
var sdp = s.sdp;
s.sdp =
sdp!.replaceAll('profile-level-id=640c1f', 'profile-level-id=42e032');
sdp?.replaceAll('profile-level-id=640c1f', 'profile-level-id=42e032');
return s;
}

Expand Down Expand Up @@ -568,25 +571,23 @@ class Signaling {
await _localStream!.dispose();
_localStream = null;
}
_sessions.forEach((key, sess) async {
await sess.pc?.close();
await sess.dc?.close();
_sessions.forEach((key, session) async {
await session.pc?.close();
await session.dc?.close();
});
_sessions.clear();
}

void _closeSessionByPeerId(String peerId) {
// ignore: prefer_typing_uninitialized_variables
var session;
_sessions.removeWhere((String key, Session sess) {
_sessions.removeWhere((String key, Session session) {
var ids = key.split('-');
session = sess;
return peerId == ids[0] || peerId == ids[1];
var found = peerId == ids[0] || peerId == ids[1];
if (found) {
_closeSession(session);
onCallStateChange?.call(session, CallState.CallStateBye);
}
return found;
});
if (session != null) {
_closeSession(session);
onCallStateChange?.call(session, CallState.CallStateBye);
}
}

Future<void> _closeSession(Session session) async {
Expand Down
Loading