/// <summary> /// Internal handler to actually initialize the /// </summary> private Task InitializePluginAsync(CancellationToken token) { Debug.Log("Initializing WebRTC plugin..."); _nativePeer.Servers = IceServers.Select(i => i.ToString()).ToList(); _nativePeer.UserName = IceUsername; _nativePeer.Credentials = IceCredential; return(_nativePeer.InitializeAsync(token).ContinueWith((initTask) => { token.ThrowIfCancellationRequested(); if (initTask.Exception != null) { _mainThreadWorkQueue.Enqueue(() => { var errorMessage = new StringBuilder(); errorMessage.Append("WebRTC plugin initializing failed. See full log for exception details.\n"); Exception ex = initTask.Exception; while (ex is AggregateException ae) { errorMessage.Append($"AggregationException: {ae.Message}\n"); ex = ae.InnerException; } errorMessage.Append($"Exception: {ex.Message}"); OnError.Invoke(errorMessage.ToString()); }); throw initTask.Exception; } _mainThreadWorkQueue.Enqueue(OnPostInitialize); }, token)); }
/// <summary> /// Initialize the underlying WebRTC peer connection. /// </summary> /// <remarks> /// This method is asynchronous and completes its task when the initializing completed. /// On successful completion, it also trigger the <see cref="OnInitialized"/> event. /// Note however that this completion is free-threaded and complete immediately when the /// underlying peer connection is initialized, whereas any <see cref="OnInitialized"/> /// event handler is invoked when control returns to the main Unity app thread. The former /// is faster, but does not allow accessing the underlying peer connection because it /// returns before <see cref="OnPostInitialize"/> executed. Therefore it is generally /// recommended to listen to the <see cref="OnInitialized"/> event, and ignore the returned /// <see xref="System.Threading.Tasks.Task"/> object. /// </remarks> private async Task <WebRTC.PeerConnection> InitializePluginAsync(CancellationToken token) { // Ensure Android binding is initialized before accessing the native implementation Android.Initialize(); #if UNITY_WSA && !UNITY_EDITOR if (Library.UsedAudioDeviceModule == AudioDeviceModule.LegacyModule) { // Preventing access to audio crashes the ADM1 at startup and the entire application. bool permissionGranted = await UwpUtils.RequestAccessAsync(StreamingCaptureMode.Audio); if (!permissionGranted) { return(null); } } #endif // Create the peer connection managed wrapper and its native implementation var nativePeer = new WebRTC.PeerConnection(); nativePeer.AudioTrackAdded += (RemoteAudioTrack track) => { // Tracks will be output by AudioReceivers, so avoid outputting them twice. track.OutputToDevice(false); }; Debug.Log("Initializing WebRTC Peer Connection..."); var config = new PeerConnectionConfiguration(); foreach (var server in IceServers) { config.IceServers.Add(new IceServer { Urls = { server.ToString() }, TurnUserName = IceUsername, TurnPassword = IceCredential }); } try { await nativePeer.InitializeAsync(config, token); return(nativePeer); } catch (OperationCanceledException canceled) { throw canceled; } catch (Exception ex) { nativePeer.Dispose(); token.ThrowIfCancellationRequested(); EnsureIsMainAppThread(); var errorMessage = new StringBuilder(); errorMessage.Append("WebRTC plugin initializing failed. See full log for exception details.\n"); errorMessage.Append($"Exception: {ex.Message}"); OnError.Invoke(errorMessage.ToString()); throw ex; } }
/// <summary> /// Internal handler to actually initialize the /// </summary> private Task InitializePluginAsync(CancellationToken token) { Debug.Log("Initializing WebRTC plugin..."); var config = new PeerConnectionConfiguration(); foreach (var server in IceServers) { config.IceServers.Add(new IceServer { Urls = { server.ToString() }, TurnUserName = IceUsername, TurnPassword = IceCredential }); } return(_nativePeer.InitializeAsync(config, token).ContinueWith((initTask) => { token.ThrowIfCancellationRequested(); if (initTask.Exception != null) { _mainThreadWorkQueue.Enqueue(() => { var errorMessage = new StringBuilder(); errorMessage.Append("WebRTC plugin initializing failed. See full log for exception details.\n"); Exception ex = initTask.Exception; while (ex is AggregateException ae) { errorMessage.Append($"AggregationException: {ae.Message}\n"); ex = ae.InnerException; } errorMessage.Append($"Exception: {ex.Message} {ex.ToString()}"); OnError.Invoke(errorMessage.ToString()); }); throw initTask.Exception; } _mainThreadWorkQueue.Enqueue(OnPostInitialize); }, token)); }