namespace Photon.Voice.Unity { using Voice; using UnityEngine; /// /// This component is useful to handle audio device and config changes. /// [RequireComponent(typeof(Recorder))] [AddComponentMenu("Photon Voice/Audio Changes Handler")] [DisallowMultipleComponent] public class AudioChangesHandler : VoiceComponent { private IAudioInChangeNotifier photonMicChangeNotifier; private Recorder recorder; /// /// Try to react to device change notification when Recorder is started. /// [Tooltip("React to device change notification when Recorder is started.")] public bool HandleDeviceChange = true; /// /// iOS: Try to react to device change notification when Recorder is started. /// [Tooltip("iOS: React to device change notification when Recorder is started.")] public bool HandleDeviceChangeIOS; /// /// Android: Try to react to device change notification when Recorder is started. /// [Tooltip("Android: React to device change notification when Recorder is started.")] public bool HandleDeviceChangeAndroid; protected override void Awake() { base.Awake(); this.recorder = this.GetComponent(); this.Logger.Log(LogLevel.Info, "Subscribing to system (audio) changes."); this.photonMicChangeNotifier = Platform.CreateAudioInChangeNotifier(this.PhotonMicrophoneChangeDetected, this.Logger); if (this.photonMicChangeNotifier.IsSupported) // OSX, iOS, Switch { if (this.photonMicChangeNotifier.Error == null) { this.Logger.Log(LogLevel.Info, "Subscribed to audio in change notifications via Photon plugin."); } else { this.Logger.Log(LogLevel.Error, "Error creating instance of photonMicChangeNotifier: {0}", this.photonMicChangeNotifier.Error); } } else { this.Logger.Log(LogLevel.Info, "Skipped subscribing to audio change notifications via Photon's AudioInChangeNotifier as not supported on current platform: {0}", Application.platform); // TODO: according to documentation, OnAudioConfigurationChanged fires on output device change, so in theory it will not work if only a microphone is added or removed. AudioSettings.OnAudioConfigurationChanged += this.OnAudioConfigChanged; this.Logger.Log(LogLevel.Info, "Subscribed to audio configuration changes via Unity OnAudioConfigurationChanged callback."); } } private void OnDestroy() { if (this.photonMicChangeNotifier != null) { this.photonMicChangeNotifier.Dispose(); this.photonMicChangeNotifier = null; this.Logger.Log(LogLevel.Info, "Unsubscribed from audio in change notifications via Photon plugin."); } AudioSettings.OnAudioConfigurationChanged -= this.OnAudioConfigChanged; this.Logger.Log(LogLevel.Info, "Unsubscribed from audio in change notifications via Unity OnAudioConfigurationChanged callback."); } private void PhotonMicrophoneChangeDetected() { this.Logger.Log(LogLevel.Info, "Microphones change detected by Photon native plugin."); this.OnDeviceChange(); } private void OnDeviceChange() { bool handle = false; switch (Application.platform) { case RuntimePlatform.IPhonePlayer: #if UNITY_VISIONOS case RuntimePlatform.VisionOS: #endif handle = this.HandleDeviceChangeIOS; break; case RuntimePlatform.Android: handle = this.HandleDeviceChangeAndroid; break; default: handle = this.HandleDeviceChange; break; } if (handle) { this.recorder.MicrophoneDeviceChangeDetected(); this.Logger.Log(LogLevel.Info, "Device change detected and the recording will be restarted."); } else { this.Logger.Log(LogLevel.Info, "Device change detected but its handling is disabled."); } } private void OnAudioConfigChanged(bool deviceWasChanged) { this.Logger.Log(LogLevel.Info, "OnAudioConfigurationChanged: {0}", deviceWasChanged ? "Device was changed." : "AudioSettings.Reset was called."); this.OnDeviceChange(); } } }