Кодировать MemoryStream напрямую в MP3 с помощью NAudio - PullRequest
0 голосов
/ 10 октября 2019

Я пытаюсь использовать один из приведенных ниже методов пакета NAudio nuget:

MediaFoundationEncoder.EncodeToMp3(new RawSourceWaveStream(_audioStream, _audioWriter.WaveFormat), "Test.mp3", 320000);

using (var reader = new WaveFileReader(_audioStream))
{
    MediaFoundationEncoder.EncodeToMp3(reader, "Test.mp3", 320000);
}

Это должно кодировать поток WAV напрямую в mp3. Ну, это так, но результат состоит только из шума.

Когда я сохраняю тот же MemoryStream (WaveFileWriter) с

File.WriteAllBytes("Test.wav", _audioStream.ToArray());
MediaFoundationEncoder.EncodeToMp3(new WaveFileReader("Test.wav"), "Test.mp3", 320000);

, созданный файл wav в порядке, и я могу использовать этот файл wav для кодирования его в mp3. Но я хочу сначала избежать сохранения файла wav.

Есть ли способ кодировать поток напрямую в mp3, не получая при этом шума? Я понятия не имею, почему один метод работает, а другой нет. Гугл мне тоже не помог. Так что, возможно, у вас, ребята, есть идея.

Спасибо за ваши усилия.

Дополнительная информация:
.NET Core 3.0 Windows Application
NAudio Nuget Package (Версия: 1.9.0)

Полный класс:

using NAudio.MediaFoundation;
using NAudio.Wave;
using System;
using System.IO;

namespace Recorder.NAudio
{
    public class Recorder
    {
        private WasapiLoopbackCapture _audioCapture;
        private WaveFileWriter _audioWriter;
        private MemoryStream _audioStream;

        public bool IsRecording { get; private set; }

        public Recorder()
        {
            MediaFoundationApi.Startup();
        }

        public void Init()
        {
            _audioCapture = new WasapiLoopbackCapture();

            _audioStream = new MemoryStream(1024);
            _audioWriter = new WaveFileWriter(_audioStream, new WaveFormat(44100, 24, 2));

            _audioCapture.DataAvailable += DataReceived;
            _audioCapture.RecordingStopped += RecordingStopped;
        }

        private void RecordingStopped(object sender, StoppedEventArgs e)
        {
            _audioCapture.DataAvailable -= DataReceived;
            _audioCapture.RecordingStopped -= RecordingStopped;

            _audioCapture.Dispose();
            _audioCapture = null;
            _audioWriter.Flush();
            _audioStream.Flush();

            _audioStream.Position = 0;

            //This works the mp3 file is fine, but I want to avoid the workaround of first saving a wav file to my hard drive
            File.WriteAllBytes("Test.wav", _audioStream.ToArray());
            MediaFoundationEncoder.EncodeToMp3(new WaveFileReader("Test.wav"), "Test.mp3", 320000);

            //Try 1: This doesn't work the mp3 file consists only of noise
            MediaFoundationEncoder.EncodeToMp3(new RawSourceWaveStream(_audioStream, _audioWriter.WaveFormat), "Test.mp3", 320000);

            //Try 2: This doesn't work the mp3 file consists only of noise
            using (var reader = new WaveFileReader(_audioStream))
            {
                MediaFoundationEncoder.EncodeToMp3(reader, "Test.mp3", 320000);
            }

            _audioWriter.Close();
            _audioWriter.Dispose();
            _audioWriter = null;
            _audioStream.Close();
            _audioStream.Dispose();
            _audioStream = null;

            GC.Collect();
        }

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

        public void Start()
        {
            Init();

            _audioCapture.StartRecording();
            IsRecording = true;
        }

        public void Stop()
        {
            _audioCapture.StopRecording();
            IsRecording = false;
        }
    }
}

1 Ответ

0 голосов
/ 11 октября 2019

Я нашел решение. Когда я изменяю конструктор WaveFileWriter на это:

_audioWriter = new WaveFileWriter(_audioStream, _audioCapture.WaveFormat);

, а затем меняю настройки звука моего устройства в диалоговом окне настроек звука Windows на:
2 канала, 24 бита, 44100 Гц вместо 2 каналов, 24 бит, 96000 Гц он работает по какой-то причине ...

...