public async Task AddAudioTrackFromDeviceAsync(string trackName) { const string DefaultAudioDeviceName = "Default audio device"; await RequestMediaAccessAsync(StreamingCaptureMode.Audio); // FIXME - this leaks 'source', never disposed (and is the track itself disposed??) var initConfig = new LocalAudioDeviceInitConfig(); var source = await AudioTrackSource.CreateFromDeviceAsync(initConfig); var settings = new LocalAudioTrackInitConfig { trackName = trackName }; var track = LocalAudioTrack.CreateFromSource(source, settings); SessionModel.Current.AudioTracks.Add(new AudioTrackViewModel { Source = source, Track = track, TrackImpl = track, IsRemote = false, DeviceName = DefaultAudioDeviceName }); SessionModel.Current.LocalTracks.Add(new TrackViewModel(Symbol.Volume) { DisplayName = DefaultAudioDeviceName }); }
// This method might be run outside the app thread and should not access the Unity API. private static async Task <WebRTC.AudioTrackSource> CreateSourceAsync(LocalAudioDeviceInitConfig deviceConfig) { var createTask = DeviceAudioTrackSource.CreateAsync(deviceConfig); // Continue the task outside the Unity app context, in order to avoid deadlock // if OnDisable waits on this task. return(await createTask.ConfigureAwait(continueOnCapturedContext : false)); }
public static async Task AddAudioTrackFromDeviceAsync(string trackName) { const string DefaultAudioDeviceName = "Default audio device"; await Utils.RequestMediaAccessAsync(StreamingCaptureMode.Audio); // FIXME - this leaks 'source', never disposed (and is the track itself disposed??) var initConfig = new LocalAudioDeviceInitConfig(); var source = await DeviceAudioTrackSource.CreateAsync(initConfig); var settings = new LocalAudioTrackInitConfig { trackName = trackName }; var track = LocalAudioTrack.CreateFromSource(source, settings); SessionModel.Current.AddAudioTrack(track, DefaultAudioDeviceName); }
private async Task <WebRTC.AudioTrackSource> InitAsync(CancellationToken token) { // Cache public properties on the Unity app thread. var deviceConfig = new LocalAudioDeviceInitConfig { AutoGainControl = _autoGainControl, }; // Continue the task outside the Unity app context, in order to avoid deadlock // if OnDisable waits on this task. bool accessGranted = await RequestAccessAsync(token).ConfigureAwait(continueOnCapturedContext: false); if (!accessGranted) { return(null); } return(await CreateSourceAsync(deviceConfig).ConfigureAwait(continueOnCapturedContext: false)); }
protected async void OnEnable() { if (Source != null) { return; } #if UNITY_WSA && !UNITY_EDITOR // Request access to audio capture. The OS may show some popup dialog to the // user to request permission. This will succeed only if the user approves it. try { if (UnityEngine.WSA.Application.RunningOnUIThread()) { await RequestAccessAsync(); } else { UnityEngine.WSA.Application.InvokeOnUIThread(() => RequestAccessAsync(), waitUntilDone: true); } } catch (Exception ex) { // Log an error and prevent activation Debug.LogError($"Audio access failure: {ex.Message}."); this.enabled = false; return; } #endif var initConfig = new LocalAudioDeviceInitConfig { AutoGainControl = _autoGainControl, }; Source = await WebRTC.AudioTrackSource.CreateFromDeviceAsync(initConfig); if (Source == null) { throw new Exception("Failed ot create microphone audio source."); } IsStreaming = true; AudioSourceStarted.Invoke(this); }
protected async void OnEnable() { if (Source != null) { return; } #if PLATFORM_ANDROID // Ensure Android binding is initialized before accessing the native implementation Android.Initialize(); // Check for permission to access the camera if (!Permission.HasUserAuthorizedPermission(Permission.Microphone)) { if (!_androidRecordAudioRequestPending) { // Monitor the OnApplicationFocus(true) event during the next 5 minutes, // and check for permission again each time (see below why). _androidRecordAudioRequestPending = true; _androidRecordAudioRequestRetryUntilTime = Time.time + 300; // Display dialog requesting user permission. This will return immediately, // and unfortunately there's no good way to tell when this completes. As a rule // of thumb, application should lose focus, so check when focus resumes should // be sufficient without having to poll every frame. Permission.RequestUserPermission(Permission.Microphone); } return; } #endif #if UNITY_WSA && !UNITY_EDITOR // Request access to audio capture. The OS may show some popup dialog to the // user to request permission. This will succeed only if the user approves it. try { if (UnityEngine.WSA.Application.RunningOnUIThread()) { await RequestAccessAsync(); } else { UnityEngine.WSA.Application.InvokeOnUIThread(() => RequestAccessAsync(), waitUntilDone: true); } } catch (Exception ex) { // Log an error and prevent activation Debug.LogError($"Audio access failure: {ex.Message}."); this.enabled = false; return; } #endif var initConfig = new LocalAudioDeviceInitConfig { AutoGainControl = _autoGainControl, }; try { Source = await DeviceAudioTrackSource.CreateAsync(initConfig); if (Source == null) { throw new Exception("DeviceAudioTrackSource.CreateAsync() returned a NULL source."); } } catch (Exception ex) { Debug.LogError($"Failed to create device track source for {nameof(MicrophoneSource)} component '{name}'."); Debug.LogException(ex, this); return; } IsStreaming = true; AudioSourceStarted.Invoke(this); }
/// <summary> /// Constructor for creating a local audio device initialization settings marshaling struct. /// </summary> /// <param name="settings">The settings to initialize the newly created marshaling struct.</param> /// <seealso cref="DeviceAudioTrackSource.CreateAsync(LocalAudioDeviceInitConfig)"/> public LocalAudioDeviceMarshalInitConfig(LocalAudioDeviceInitConfig settings) { AutoGainControl = (mrsOptBool)settings?.AutoGainControl; }