1
0
mirror of https://gitlab.com/comunic/comunicmobile synced 2024-11-26 06:49:22 +00:00

Add audio only calls support

This commit is contained in:
Pierre HUBERT 2020-04-23 13:12:40 +02:00
parent a74600ce4b
commit 707577f9ac
2 changed files with 26 additions and 3 deletions

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_webrtc/media_stream.dart';
/// Single call member information /// Single call member information
/// ///
@ -9,10 +10,14 @@ enum MemberStatus { JOINED, READY }
class CallMember { class CallMember {
final int userID; final int userID;
MemberStatus status; MemberStatus status;
MediaStream stream;
CallMember({ CallMember({
@required this.userID, @required this.userID,
this.status = MemberStatus.JOINED, this.status = MemberStatus.JOINED,
}) : assert(userID != null), }) : assert(userID != null),
assert(status != null); assert(status != null);
bool get hasVideoStream =>
stream != null && stream.getVideoTracks().length > 0;
} }

View File

@ -324,7 +324,12 @@ class _CallScreenState extends SafeState<CallScreen> {
// Register callbacks // Register callbacks
peerConnection.onIceCandidate = peerConnection.onIceCandidate =
(c) => CallsHelper.sendIceCandidate(convID, memberID, c); (c) => CallsHelper.sendIceCandidate(convID, memberID, c);
peerConnection.onAddStream = (s) => _renderers[memberID].srcObject = s; peerConnection.onAddStream = (s) {
setState(() {
_membersList.getUser(memberID).stream = s;
_renderers[memberID].srcObject = s;
});
};
// Request an offer to establish a peer connection // Request an offer to establish a peer connection
await CallsHelper.requestOffer(convID, memberID); await CallsHelper.requestOffer(convID, memberID);
@ -373,7 +378,8 @@ class _CallScreenState extends SafeState<CallScreen> {
/// Call this when a user has interrupted streaming /// Call this when a user has interrupted streaming
Future<void> _removeRemotePeerConnection(int memberID) async { Future<void> _removeRemotePeerConnection(int memberID) async {
_membersList.getUser(memberID).status = MemberStatus.JOINED; final member = _membersList.getUser(memberID);
member.status = MemberStatus.JOINED;
setState(() {}); setState(() {});
if (_peersConnections.containsKey(memberID)) { if (_peersConnections.containsKey(memberID)) {
@ -385,6 +391,11 @@ class _CallScreenState extends SafeState<CallScreen> {
await _renderers[memberID].dispose(); await _renderers[memberID].dispose();
_renderers.remove(memberID); _renderers.remove(memberID);
} }
if (member.stream != null) {
member.stream.dispose();
member.stream = null;
}
} }
/// Call this when a member has completely left the call /// Call this when a member has completely left the call
@ -491,7 +502,8 @@ class _CallScreenState extends SafeState<CallScreen> {
// Remove peers videos // Remove peers videos
Column( Column(
children: _membersList.readyPeers children: _membersList.readyPeers
.where((f) => _renderers.containsKey(f.userID)) .where(
(f) => f.hasVideoStream && _renderers.containsKey(f.userID))
.map((f) => _buildMemberVideo(f.userID)) .map((f) => _buildMemberVideo(f.userID))
.toList(), .toList(),
), ),
@ -528,6 +540,7 @@ class _CallScreenState extends SafeState<CallScreen> {
children: <Widget>[ children: <Widget>[
// Show / hide user video button // Show / hide user video button
_FooterButton( _FooterButton(
visible: _canMakeVideoCall,
icon: Icon(_isLocalStreamVisible icon: Icon(_isLocalStreamVisible
? Icons.visibility ? Icons.visibility
: Icons.visibility_off), : Icons.visibility_off),
@ -549,6 +562,7 @@ class _CallScreenState extends SafeState<CallScreen> {
// Toggle video button // Toggle video button
_FooterButton( _FooterButton(
visible: _canMakeVideoCall,
icon: Icon(isStreamingVideo && !isVideoMuted icon: Icon(isStreamingVideo && !isVideoMuted
? Icons.videocam ? Icons.videocam
: Icons.videocam_off), : Icons.videocam_off),
@ -583,17 +597,21 @@ class _CallScreenState extends SafeState<CallScreen> {
class _FooterButton extends StatelessWidget { class _FooterButton extends StatelessWidget {
final Function() onPressed; final Function() onPressed;
final Widget icon; final Widget icon;
final bool visible;
const _FooterButton({ const _FooterButton({
Key key, Key key,
@required this.icon, @required this.icon,
@required this.onPressed, @required this.onPressed,
this.visible = true,
}) : assert(onPressed != null), }) : assert(onPressed != null),
assert(icon != null), assert(icon != null),
assert(visible != null),
super(key: key); super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (!visible) return Container();
return Expanded( return Expanded(
child: IconButton( child: IconButton(
icon: icon, icon: icon,