NAudio icon indicating copy to clipboard operation
NAudio copied to clipboard

WasapiLoopbackCapture Http Live Stream

Open 4hera opened this issue 1 year ago • 3 comments

Hi, I want to capture the audio going to my computer's default audio output with WasapiLoopbackCapture and broadcast it over http. Just like a radio broadcast. I tried the following parts but I was not successful. Where am I making a mistake? AudioStreamService.cs

    public class AudioStreamService
    {
        private readonly WasapiLoopbackCapture _loopbackCapture;
        private readonly MemoryStream _memoryStream;
        private readonly MMDeviceEnumerator MMDE;
        private readonly MMDevice masterDevice;
        private readonly WaveFormat waveFormat;
        public AudioStreamService()
        {
            MMDE = new MMDeviceEnumerator();
            masterDevice = MMDE.GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia);
            _loopbackCapture = new WasapiLoopbackCapture(masterDevice);
            _loopbackCapture.DataAvailable += LoopbackCapture_DataAvailable;
            _memoryStream = new MemoryStream();
        }

        private void LoopbackCapture_DataAvailable(object sender, WaveInEventArgs e)
        {
            _memoryStream.Write(e.Buffer, 0, e.BytesRecorded);
        }

        public void StartAudioCapture()
        {
            if (_loopbackCapture.CaptureState == NAudio.CoreAudioApi.CaptureState.Stopped ||
                _loopbackCapture.CaptureState == NAudio.CoreAudioApi.CaptureState.Stopping)
            {
                _loopbackCapture.StartRecording();
            }
        }

        public void StopAudioCapture()
        {
            _loopbackCapture.StopRecording();
        }

        public byte[] GetAudioData()
        {
            var audioData = _memoryStream.ToArray();
            _memoryStream.SetLength(0);
            return audioData;
        }
        public string GetState()
        {
            return _loopbackCapture.CaptureState.ToString();
        }
    }

Startup.cs

          app.UseRouting();

          app.UseEndpoints(endpoints =>
          {
              endpoints.MapControllers();
              endpoints.MapGet("/stream", async context =>
              {
                  var audioStreamService = context.RequestServices.GetService<AudioStreamService>();

                  context.Response.Headers.Add("Content-Type", "audio/mpeg");

                  while (audioStreamService.GetState() == "Capturing")
                  {
                      var audioData = audioStreamService.GetAudioData();

                      if (audioData.Length > 0)
                      {
                          await context.Response.Body.WriteAsync(audioData, 0, audioData.Length);
                          await context.Response.Body.FlushAsync();
                      }
                  }
              });
          });

4hera avatar Apr 02 '24 12:04 4hera

You're saying that the content-type is audio/mpeg, but WASAPI is capturing uncompressed IEEE floating point audio. You'd want something else encoding it to MP4 on the fly to support this kind of setup, which is unfortunately not easy to achieve with NAudio, as the MediaFoundationEncoder works best with whole files

markheath avatar Apr 11 '24 16:04 markheath

Thanks for your answer. I am developing websocket based soft kvm software. I transfer the image to the browser. Additionally, I wanted to transfer the sound. Is there a source or code block you can recommend for the encoding process you mentioned?

4hera avatar Apr 17 '24 21:04 4hera