/// <summary>
        /// Create an audio track from a local audio capture device (microphone).
        /// This does not add the track to any peer connection. Instead, the track must be added manually to
        /// an audio transceiver to be attached to a peer connection and transmitted to a remote peer.
        /// </summary>
        /// <param name="settings">Settings to initialize the local audio track.</param>
        /// <returns>Asynchronous task completed once the device is capturing and the track is created.</returns>
        /// <remarks>
        /// On UWP this requires the "microphone" capability.
        /// See <see href="https://docs.microsoft.com/en-us/windows/uwp/packaging/app-capability-declarations"/>
        /// for more details.
        /// </remarks>
        public static Task <LocalAudioTrack> CreateFromDeviceAsync(LocalAudioTrackSettings settings = null)
        {
            return(Task.Run(() =>
            {
                // On UWP this cannot be called from the main UI thread, so always call it from
                // a background worker thread.

                string trackName = settings?.trackName;
                if (string.IsNullOrEmpty(trackName))
                {
                    trackName = Guid.NewGuid().ToString();
                }

                // Create interop wrappers
                var track = new LocalAudioTrack(trackName);

                // Parse settings
                var config = new PeerConnectionInterop.LocalAudioTrackInteropInitConfig(track, settings);

                // Create native implementation objects
                uint res = LocalAudioTrackInterop.LocalAudioTrack_CreateFromDevice(config, trackName,
                                                                                   out LocalAudioTrackHandle trackHandle);
                Utils.ThrowOnErrorCode(res);
                track.SetHandle(trackHandle);
                return track;
            }));
        }
        /// <inheritdoc/>
        public void Dispose()
        {
            if (_nativeHandle.IsClosed)
            {
                return;
            }

            // Remove the track from the peer connection, if any
            if (Transceiver != null)
            {
                Debug.Assert(PeerConnection != null);
                Debug.Assert(Transceiver.LocalTrack == this);
                Transceiver.LocalAudioTrack = null;
            }
            Debug.Assert(PeerConnection == null);
            Debug.Assert(Transceiver == null);

            // Unregister interop callbacks
            if (_selfHandle != IntPtr.Zero)
            {
                LocalAudioTrackInterop.LocalAudioTrack_RegisterFrameCallback(_nativeHandle, null, IntPtr.Zero);
                Utils.ReleaseWrapperRef(_selfHandle);
                _selfHandle          = IntPtr.Zero;
                _interopCallbackArgs = null;
            }

            // Destroy the native object. This may be delayed if a P/Invoke callback is underway,
            // but will be handled at some point anyway, even if the managed instance is gone.
            _nativeHandle.Dispose();
        }
Example #3
0
 private void RegisterInteropCallbacks()
 {
     _interopCallbackArgs = new LocalAudioTrackInterop.InteropCallbackArgs()
     {
         Track         = this,
         FrameCallback = LocalAudioTrackInterop.FrameCallback,
     };
     _selfHandle = Utils.MakeWrapperRef(this);
     LocalAudioTrackInterop.LocalAudioTrack_RegisterFrameCallback(
         _nativeHandle, _interopCallbackArgs.FrameCallback, _selfHandle);
 }