Merge branch 'td/initWithStreamForGroupCall' into 'main'

fix: allow passing a WrappedMediaStream to GroupCall.enter() to use as the local user media stream

See merge request famedly/company/frontend/famedlysdk!1275
This commit is contained in:
td 2023-04-25 09:22:04 +00:00
commit 970551d8cb
1 changed files with 38 additions and 28 deletions

View File

@ -348,44 +348,55 @@ class GroupCall {
/// Initializes the local user media stream. /// Initializes the local user media stream.
/// The media stream must be prepared before the group call enters. /// The media stream must be prepared before the group call enters.
Future<WrappedMediaStream> initLocalStream() async { /// if you allow the user to configure their camera and such ahead of time,
/// you can pass that `stream` on to this function.
/// This allows you to configure the camera before joining the call without
/// having to reopen the stream and possibly losing settings.
Future<WrappedMediaStream> initLocalStream(
{WrappedMediaStream? stream}) async {
if (state != GroupCallState.LocalCallFeedUninitialized) { if (state != GroupCallState.LocalCallFeedUninitialized) {
throw Exception('Cannot initialize local call feed in the $state state.'); throw Exception('Cannot initialize local call feed in the $state state.');
} }
setState(GroupCallState.InitializingLocalCallFeed); setState(GroupCallState.InitializingLocalCallFeed);
MediaStream stream; WrappedMediaStream localWrappedMediaStream;
try { if (stream == null) {
stream = await _getUserMedia( MediaStream stream;
type == GroupCallType.Video ? CallType.kVideo : CallType.kVoice);
} catch (error) { try {
setState(GroupCallState.LocalCallFeedUninitialized); stream = await _getUserMedia(
rethrow; type == GroupCallType.Video ? CallType.kVideo : CallType.kVoice);
} catch (error) {
setState(GroupCallState.LocalCallFeedUninitialized);
rethrow;
}
final userId = client.userID;
localWrappedMediaStream = WrappedMediaStream(
renderer: voip.delegate.createRenderer(),
stream: stream,
userId: userId!,
room: room,
client: client,
purpose: SDPStreamMetadataPurpose.Usermedia,
audioMuted: stream.getAudioTracks().isEmpty,
videoMuted: stream.getVideoTracks().isEmpty,
isWeb: voip.delegate.isWeb,
isGroupCall: true,
);
} else {
localWrappedMediaStream = stream;
} }
final userId = client.userID; localUserMediaStream = localWrappedMediaStream;
final newStream = WrappedMediaStream(
renderer: voip.delegate.createRenderer(),
stream: stream,
userId: userId!,
room: room,
client: client,
purpose: SDPStreamMetadataPurpose.Usermedia,
audioMuted: stream.getAudioTracks().isEmpty,
videoMuted: stream.getVideoTracks().isEmpty,
isWeb: voip.delegate.isWeb,
isGroupCall: true,
);
localUserMediaStream = newStream;
await localUserMediaStream!.initialize(); await localUserMediaStream!.initialize();
await addUserMediaStream(newStream); await addUserMediaStream(localWrappedMediaStream);
setState(GroupCallState.LocalCallFeedInitialized); setState(GroupCallState.LocalCallFeedInitialized);
return newStream; return localWrappedMediaStream;
} }
Future<void> updateAudioDevice() async { Future<void> updateAudioDevice() async {
@ -406,16 +417,15 @@ class GroupCall {
} }
/// enter the group call. /// enter the group call.
Future<void> enter() async { Future<void> enter({WrappedMediaStream? stream}) async {
if (!(state == GroupCallState.LocalCallFeedUninitialized || if (!(state == GroupCallState.LocalCallFeedUninitialized ||
state == GroupCallState.LocalCallFeedInitialized)) { state == GroupCallState.LocalCallFeedInitialized)) {
throw Exception('Cannot enter call in the $state state'); throw Exception('Cannot enter call in the $state state');
} }
if (state == GroupCallState.LocalCallFeedUninitialized) { if (state == GroupCallState.LocalCallFeedUninitialized) {
await initLocalStream(); await initLocalStream(stream: stream);
} }
await _addParticipant( await _addParticipant(
(await room.requestUser(client.userID!, ignoreErrors: true))!); (await room.requestUser(client.userID!, ignoreErrors: true))!);