Skip to content

Commit

Permalink
Merge pull request #3 from GetStream/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
sierpinskid authored Nov 6, 2023
2 parents 92fa0d6 + 97d4ea0 commit f27eb39
Show file tree
Hide file tree
Showing 23 changed files with 995 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
using StreamVideo.Libs.Auth;
using StreamVideo.Libs.Serialization;
using StreamVideo.Libs.Utils;
using Unity.WebRTC;
using UnityEngine;

namespace StreamVideo.ExampleProject
Expand Down Expand Up @@ -47,13 +46,8 @@ protected void Start()
_client.CallEnded += OnCallEnded;

ConnectToStreamAsync(credentials).LogIfFailed();

//StreamTodo: handle by SDK
StartCoroutine(WebRTC.Update());
}

protected void Update() => _client?.Update();

protected async void OnDestroy()
{
_uiManager.JoinClicked -= OnJoinClicked;
Expand Down Expand Up @@ -128,8 +122,6 @@ private async void OnJoinClicked(bool create)
Debug.Log($"Join clicked, create: {create}, callId: {callId}");

var streamCall = await _client.JoinCallAsync(StreamCallType.Default, callId, create, ring: true, notify: false);


}
catch (Exception e)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public async Task GrantPermission()
await streamCall.GrantPermissionsAsync(new[] { OwnCapability.SendAudio }, participant);
}

public async Task GrantRequestedPermissions()
public Task GrantRequestedPermissions()
{
//StreamTodo: implement streamCall.PermissionRequests
/*
Expand All @@ -61,6 +61,7 @@ public async Task GrantRequestedPermissions()
}
*
*/
return Task.CompletedTask;
}

public async Task BlockUser()
Expand Down Expand Up @@ -122,17 +123,14 @@ public async Task MuteUsers()
// Mute user in a call using their instance of IStreamVideoCallParticipant and choose which of their tracks you want to mute: audio, video, or screenShare
await streamCall.MuteUsersAsync(new[] { participant }, audio: true, video: true, screenShare: true);
}

public async Task MuteAllUsers()
{
var callType = StreamCallType.Default; // Call type affects default permissions
var callId = "my-call-id";

var streamCall = await _client.JoinCallAsync(callType, callId, create: true, ring: false, notify: false);

IStreamVideoUser user = null;
IStreamVideoCallParticipant participant = null;

// Mute all user in a call and choose which of their tracks you want to mute: audio, video, or screenShare
await streamCall.MuteAllUsersAsync(audio: true, video: true, screenShare: true);
}
Expand Down
5 changes: 2 additions & 3 deletions Packages/StreamVideo/Runtime/Core/IStreamVideoClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@
using StreamVideo.Core.QueryBuilders.Filters;
using StreamVideo.Core.StatefulModels;
using StreamVideo.Libs.Auth;
using StreamVideo.Libs.VideoClientInstanceRunner;
using UnityEngine;

namespace StreamVideo.Core
{
public interface IStreamVideoClient : IDisposable
public interface IStreamVideoClient : IStreamVideoClientEventsListener, IDisposable
{
/// <summary>
/// Called when client is connected. Returns local user object of type <see cref="IStreamVideoUser"/>
Expand All @@ -27,8 +28,6 @@ public interface IStreamVideoClient : IDisposable
/// <param name="credentials">Credentials required to connect user: api_key, user_id, and user_token</param>
Task<IStreamVideoUser> ConnectUserAsync(AuthCredentials credentials);

void Update();

Task DisconnectAsync();

Task<IStreamCall> JoinCallAsync(StreamCallType callType, string callId, bool create, bool ring,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,9 @@ protected override async Task OnConnectAsync(CancellationToken cancellationToken
//StreamTodo: Add cancel token support to WS
await WebsocketClient.ConnectAsync(uri);

Logs.Info("WS connected! Let's send the connect message");
#if STREAM_DEBUG_ENABLED
Logs.Info("Coordinator connected! Let's send the connect message");
#endif

//StreamTodo: handle TokenProvider
var authMessage = new WSAuthMessageRequestInternalDTO()
Expand All @@ -88,6 +90,10 @@ protected override async Task OnConnectAsync(CancellationToken cancellationToken

var serializedAuthMsg = Serializer.Serialize(authMessage);

#if STREAM_DEBUG_ENABLED
Logs.Info($"Coordinator auth message: {serializedAuthMsg}");
#endif

WebsocketClient.Send(serializedAuthMsg);

await _connectUserTaskSource.Task;
Expand Down
43 changes: 39 additions & 4 deletions Packages/StreamVideo/Runtime/Core/StreamVideoClient.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
Expand All @@ -20,7 +21,9 @@
using StreamVideo.Libs.NetworkMonitors;
using StreamVideo.Libs.Serialization;
using StreamVideo.Libs.Time;
using StreamVideo.Libs.VideoClientInstanceRunner;
using StreamVideo.Libs.Websockets;
using Unity.WebRTC;
using UnityEngine;
using Cache = StreamVideo.Core.State.Caches.Cache;

Expand Down Expand Up @@ -57,9 +60,14 @@ var sfuWebSocket
var serializer = factory.CreateSerializer();
var timeService = factory.CreateTimeService();
var networkMonitor = factory.CreateNetworkMonitor();
var gameObjectRunner = factory.CreateClientRunner();

return new StreamVideoClient(coordinatorWebSocket, sfuWebSocket, httpClient,
var client = new StreamVideoClient(coordinatorWebSocket, sfuWebSocket, httpClient,
serializer, timeService, networkMonitor, applicationInfo, logs, config);

gameObjectRunner?.RunClientInstance(client);

return client;
}

/// <summary>
Expand Down Expand Up @@ -172,6 +180,7 @@ public void Dispose()
{
UnsubscribeFrom(InternalLowLevelClient);
InternalLowLevelClient?.Dispose();
Destroyed?.Invoke();
}

public async Task<IStreamVideoUser> ConnectUserAsync(AuthCredentials credentials)
Expand All @@ -181,9 +190,10 @@ public async Task<IStreamVideoUser> ConnectUserAsync(AuthCredentials credentials
return LocalUser;
}

//StreamTodo: hide this and have it called by hidden runner
public void Update() => InternalLowLevelClient.Update();

public IEnumerator WebRTCUpdateCoroutine() => WebRTC.Update();

public Task DisconnectAsync() => InternalLowLevelClient.DisconnectAsync();

public void SetAudioInputSource(AudioSource audioSource)
Expand Down Expand Up @@ -228,6 +238,31 @@ public async Task<QueryCallsResult> QueryCallsAsync(IEnumerable<IFieldFilterRule

return new QueryCallsResult(calls, response.Prev, response.Next);
}

#region IStreamVideoClientEventsListener

event Action IStreamVideoClientEventsListener.Destroyed
{
add => this.Destroyed += value;
remove => this.Destroyed -= value;
}

void IStreamVideoClientEventsListener.Destroy()
{
//StreamTodo: we should probably check: if waiting for connection -> cancel, if connected -> disconnect, etc
DisconnectAsync().ContinueWith(t =>
{
if (t.IsFaulted)
{
_logs.Exception(t.Exception);
return;
}
Dispose();
});
}

#endregion

internal StreamVideoLowLevelClient InternalLowLevelClient { get; private set; }

Expand Down Expand Up @@ -312,15 +347,15 @@ internal Task RemoveMembersAsync(IStreamCall call, List<string> removeUsers)
RemoveMembers = removeUsers,
});

private event Action Destroyed;

private readonly ILogs _logs;
private readonly ITimeService _timeService;
private readonly ICache _cache;

private StreamVideoClient(IWebsocketClient coordinatorWebSocket, IWebsocketClient sfuWebSocket,
IHttpClient httpClient, ISerializer serializer, ITimeService timeService, INetworkMonitor networkMonitor,
IApplicationInfo applicationInfo, ILogs logs, IStreamClientConfig config)
{
_timeService = timeService ?? throw new ArgumentNullException(nameof(timeService));
_logs = logs ?? throw new ArgumentNullException(nameof(logs));

InternalLowLevelClient = new StreamVideoLowLevelClient(coordinatorWebSocket, sfuWebSocket, httpClient,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public interface IStreamDependenciesFactory

ITokenProvider CreateTokenProvider(TokenProvider.TokenUriHandler urlFactory);

IStreamVideoClientRunner CreateChatClientRunner();
IStreamVideoClientRunner CreateClientRunner();

INetworkMonitor CreateNetworkMonitor();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ public virtual IHttpClient CreateHttpClient()

public virtual ITokenProvider CreateTokenProvider(TokenProvider.TokenUriHandler urlFactory) => new TokenProvider(CreateHttpClient(), urlFactory);

public virtual IStreamVideoClientRunner CreateChatClientRunner()
public virtual IStreamVideoClientRunner CreateClientRunner()
{
var go = new GameObject
{
name = "Stream Chat Client Runner",
name = "Stream Client Runner",
#if !STREAM_DEBUG_ENABLED
hideFlags = HideFlags.DontSaveInEditor | HideFlags.HideAndDontSave
#endif
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections;

namespace StreamVideo.Libs.VideoClientInstanceRunner
{
Expand All @@ -9,9 +10,9 @@ namespace StreamVideo.Libs.VideoClientInstanceRunner
public interface IStreamVideoClientEventsListener
{
/// <summary>
/// Event fired when the client is disposed
/// Event fired when the client is destroyed
/// </summary>
event Action Disposed;
event Action Destroyed;

/// <summary>
/// Call when application is being destroyed.
Expand All @@ -24,5 +25,10 @@ public interface IStreamVideoClientEventsListener
/// E.g. for Unity call when MonoBehaviour.Update is called by the engine or call from coroutine.
/// </summary>
void Update();

/// <summary>
/// This method exposes the WebRTC.Update(). In Unity, call it once with StartCoroutine(instance.WebRTCUpdateCoroutine());
/// </summary>
IEnumerator WebRTCUpdateCoroutine();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ public interface IStreamVideoClientRunner
/// <summary>
/// Pass environment callbacks to the <see cref="IStreamVideoClientEventsListener"/> and react to its events
/// </summary>
void RunChatInstance(IStreamVideoClientEventsListener streamVideoInstance);
void RunClientInstance(IStreamVideoClientEventsListener streamVideoInstance);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,36 @@ namespace StreamVideo.Libs.VideoClientInstanceRunner
public sealed class StreamMonoBehaviourWrapper
{
/// <summary>
/// This is a MonoBehaviour wrapper that will pass Unity Engine callbacks to the Stream Chat Client
/// This is a MonoBehaviour wrapper that will pass Unity Engine callbacks to the Stream Video Client
/// </summary>
public sealed class UnityStreamVideoClientRunner : MonoBehaviour, IStreamVideoClientRunner
{
public void RunChatInstance(IStreamVideoClientEventsListener streamVideoInstance)
public void RunClientInstance(IStreamVideoClientEventsListener streamVideoInstance)
{
if (!Application.isPlaying)
{
Debug.LogWarning($"Application is not playing. The MonoBehaviour {nameof(UnityStreamVideoClientRunner)} wrapper will not execute." +
$" You need to call Stream Chat Client's {nameof(IStreamVideoClientEventsListener.Update)} and {nameof(IStreamVideoClientEventsListener.Destroy)} by yourself");
$" You need to call Stream Video Client's {nameof(IStreamVideoClientEventsListener.Update)} and {nameof(IStreamVideoClientEventsListener.Destroy)} by yourself");
DestroyImmediate(gameObject);
return;
}

_streamVideoInstance = streamVideoInstance ?? throw new ArgumentNullException(nameof(streamVideoInstance));
_streamVideoInstance.Disposed += OnStreamVideoInstanceDisposed;
StartCoroutine(UpdateCoroutine());
_streamVideoInstance.Destroyed += OnStreamVideoInstanceDestroyed;
_updateCoroutine = StartCoroutine(UpdateCoroutine());

#if STREAM_DEBUG_ENABLED
Debug.Log($"Run Stream Video Client - coroutines started");
#endif

//StreamTodo: should not be needed in the future thanks to this PR: https://github.com/Unity-Technologies/com.unity.webrtc/pull/977
_webRtcUpdateCoroutine = StartCoroutine(streamVideoInstance.WebRTCUpdateCoroutine());
}

private IStreamVideoClientEventsListener _streamVideoInstance;

private Coroutine _updateCoroutine;
private Coroutine _webRtcUpdateCoroutine;

// Called by Unity
private void Awake()
{
Expand All @@ -45,7 +54,7 @@ private void OnDestroy()
return;
}

_streamVideoInstance.Disposed -= OnStreamVideoInstanceDisposed;
_streamVideoInstance.Destroyed -= OnStreamVideoInstanceDestroyed;
StopCoroutine(UpdateCoroutine());
_streamVideoInstance.Destroy();
_streamVideoInstance = null;
Expand All @@ -60,19 +69,21 @@ private IEnumerator UpdateCoroutine()
}
}

private void OnStreamVideoInstanceDisposed()
private void OnStreamVideoInstanceDestroyed()
{
if (_streamVideoInstance == null)
{
return;
}

_streamVideoInstance.Disposed -= OnStreamVideoInstanceDisposed;
_streamVideoInstance.Destroyed -= OnStreamVideoInstanceDestroyed;
_streamVideoInstance = null;
StopCoroutine(UpdateCoroutine());

StopCoroutine(_updateCoroutine);
StopCoroutine(_webRtcUpdateCoroutine);

#if STREAM_DEBUG_ENABLED
Debug.Log($"Stream Chat Client Disposed - destroy {nameof(UnityStreamVideoClientRunner)} instance");
Debug.Log($"Stream Video Client Disposed - destroy {nameof(UnityStreamVideoClientRunner)} instance");
#endif
Destroy(gameObject);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,6 @@ private async Task<byte[]> TryReceiveSingleMessageAsync()
case WebSocketMessageType.Text:
case WebSocketMessageType.Binary:
return ms.ToArray();
break;
case WebSocketMessageType.Close:
// Handled above
break;
Expand Down
Loading

0 comments on commit f27eb39

Please sign in to comment.