Member 13383318 Ответов: 2

Получил кадр с частотой дискретизации 16000, в MP3 с частотой дискретизации 44100. Mp3filereader не поддерживает изменения частоты дискретизации


Привет, Марк
Я встречаюсь с проблемой для NAudio, когда я использовал приведенные ниже коды для MP3file,
Stream stream = Новый Поток памяти (байт);
var mp3Reader = новый Mp3FileReader(поток);
Mp3FileReader выдает исключение:
Got a frame at sample rate 16000, in an MP3 with sample rate 44100. Mp3FileReader does not support sample rate changes

Не могли бы вы сказать мне, где я делаю что-то не так? спасибо.

С наилучшими пожеланиями!

Джефф Цзян

Что я уже пробовал:

использование (wavestream reader = new Mp3FileReader(inputStream))
using (var temp = new LameMP3FileWriter(tempStream, reader.WaveFormat, LAMEPreset.СТАНДАРТ))
{
читатель.CopyTo(tempStream);
}

var mp3Reader = новый Mp3FileReader(tempStream);
Последний код показывает это сообщение об ошибке:
Got a frame at sample rate 16000, in an MP3 with sample rate 44100. Mp3FileReader does not support sample rate changes

Я видел эту статью"Как конвертировать между (большинством) аудиоформатами в .NET", но не нашел решения этой проблемы.
Я нахожу странную проблему:

var testStream = новый Mp3FileReader(inputStream);

var outStream = новый Mp3FileReader(testStream);

последний код покажет эту ошибку. почему?

Member 13383318

Кроме того, я вставил все свои коды для этой ошибки, надеюсь, ваши предложения.
Мое требование таково: "измените канал Как 1, битрейт как 32 Кбит / с и разделите промежуток времени mp3-файла на 2 минуты"

public Stream AudioStream(Stream inputStream, int channel, int bitRate, int spliteLength)
        {
            Stream fs = new MemoryStream();
            Stream outputStream = new MemoryStream();           
            try
            {
                int rates = bitRate / 1024;
                int averageBytesPerSecond = bitRate / 8;
                Stream tempStream = new MemoryStream();

                using (var waveStream = new Mp3FileReader(inputStream))
                using (WaveFileWriter waveFileWriter = new WaveFileWriter(tempStream, WaveFormat.CreateCustomFormat(waveStream.WaveFormat.Encoding, waveStream.WaveFormat.SampleRate, channel, averageBytesPerSecond, waveStream.WaveFormat.BlockAlign, waveStream.WaveFormat.BitsPerSample)))
                //using (WaveFileWriter waveFileWriter = new WaveFileWriter(tempStream, waveStream.Mp3WaveFormat))
// I use above the code , show the same error
                {
                    byte[] bytes = new byte[waveStream.Length];
                    waveStream.Read(bytes, 0, (int)waveStream.Length);
                    waveFileWriter.Write(bytes, 0, bytes.Length);
                    waveFileWriter.Flush();
                    fs = BytesToStream(bytes);
                }
                fs.Position = 0;

                using (var mp3 = new Mp3FileReader(fs))
                //Got a frame at sample rate 16000, in an MP3 with sample rate 44100. Mp3FileReader does not support sample rate changes.
                {
                    Mp3Frame frame;
                    while ((frame = mp3.ReadNextFrame()) != null)
                    {
                        if ((int)mp3.CurrentTime.TotalSeconds <= spliteLength)
                        {
                            outputStream.Write(frame.RawData, 0, frame.RawData.Length);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                string msg = e.Message;

            }
            return outputStream;
        }

Member 13383318

Мой адрес электронной почты :zefeng_jiang2000@163.com
дайте мне знать, если у вас есть какие-либо комментарии по этому вопросу. спасибо

Member 13383318

Я проверяю исходный код " Mp3FileReader. cs"
Я нашел проблему:
Вызовите функцию " ValidateFrameFormat(frame);"
когда проверялись все mp3frames один за другим, первый кадр и второй кадр были в порядке , но когда проверялся третий кадр, битрейт менялся на 16000, возвращалась эта ошибка. Я не понимал этого вопроса.


  private void CreateTableOfContents()        {            try            {                // Just a guess at how many entries we'll need so the internal array need not resize very much                // 400 bytes per frame is probably a good enough approximation.                tableOfContents = new List<Mp3Index>((int)(mp3DataLength / 400));                Mp3Frame frame;                do                {                    var index = new Mp3Index();                    index.FilePosition = mp3Stream.Position;                    index.SamplePosition = totalSamples;                    frame = ReadNextFrame(false);                    if (frame != null)                    {                        ValidateFrameFormat(frame);                         totalSamples += frame.SampleCount;                        index.SampleCount = frame.SampleCount;                        index.ByteCount = (int)(mp3Stream.Position - index.FilePosition);                        tableOfContents.Add(index);                    }                } while (frame != null);            }            catch (EndOfStreamException)            {                // not necessarily a problem            }        }

2 Ответов

Рейтинг:
0

0x01AA

Я сделал несколько коротких тестов с вашим образцом проекта, и дело в том, что NAudio не поддерживает VBR Причина этого, скорее всего, заключается в том, что VBR обычно нелегко обрабатывать позиции.

В зависимости от вашей цели вы можете, например, искать другую аудиотеку или, если вы хотите продолжить работу с NAudio и хотите реализовать только конвертер MP3 в WAV, вы можете загрузить некоторые исходные файлы NAudio и изменить некоторые классы в соответствии с вашими потребностями.

Что же об этом имею ввиду:
скачать [^]https://github.com/naudio/NAudio/blob/master/NAudio/Wave/WaveStreams/Mp3FileReader.cs и возьмите его за основу для реализации вашего собственного MyMp3FileReader.cs с классом MyMp3FileReader.

public class MyMp3FileReader : WaveStream

а тут модифицируют особенно
private void ValidateFrameFormat(Mp3Frame frame)

Кроме того вам нужно скорее всего также реализовать свой собственный IMp3FrameDecompressor и AcmStream.

Во всяком случае, все это означает, что вам нужно что-то глубоко погрузиться в MP3 и ACM (Audio Compression Manager). Это действительно хорошее поле, и оно того стоит.

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


Member 13383318

Спасибо за помощь. :)

Member 13383318

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

Рейтинг:
0

0x01AA

Вы должны разместить свой вопрос в нижней части статьи: Как конвертировать между (большинством) аудиоформатами в .NET[^]
Это как Марк получит информацию и, возможно, ответит.

Кстати: вы говорите о VBR?


Member 13383318

Да, это VBR.

0x01AA

Я пытаюсь найти проблему, я уже давно не использую MP3-плеер сам, но помню, что особенно сосредоточился на VBR.

0x01AA

Я проверил свой исходный код c ++
MPEGLAYER3WAVEFORMAT mSrcFmt; / / mmreg. h
mSrcFmt.wID = MPEGLAYER3_ID_MPEG; / / MPEGLAYER3_ID_CONSTANTFRAMESIZE;
mSrcFmt. fdwFlags = MPEGLAYER3_FLAG_PADDING_OFF; / / MPEGLAYER3_FLAG_PADDING_ISO;
mSrcFmt.nBlockSize = 1152;
mSrcFmt.nFramesPerBlock = 1;
mSrcFmt.nCodecDelay = 0;
mSrcFmt.с wfx.wFormatTag = WAVE_FORMAT_MPEGLAYER3;
mSrcFmt.wfx. nChannels = static_cast & lt;word> (каналы);
mSrcFmt.wfx. nSamplesPerSec = static_cast< dword> (SamplesPerSec);
mSrcFmt.wfx. wBitsPerSample = 0;
mSrcFmt.wfx.nBlockAlign = 1152; //(mSrcFmt.wfx.nChannels * mSrcFmt.wfx. wBitsPerSample) / 8;
mSrcFmt.wfx. nAvgBytesPerSec = 192000/8; / / mSrcFmt.wfx. nSamplesPerSec * mSrcFmt.wfx. nBlockAlign;
mSrcFmt.с wfx.cbSize = 12; //оператор sizeof(mSrcFmt) - оператор sizeof(mSrcFmt.с wfx);

по сравнению с фрагментом кода статьи, смотрите особенно "this.fdwFlags" и попробуйте установить его в "not padding":

открытый класс Mp3WaveFormat : WaveFormat
{

общественные Mp3WaveFormat(инт частота дискретизации, каналы инт, инт блока, инт битрейт)
{
this. extraSize = Mp3WaveFormatExtraBytes;
this.id = Mp3WaveFormatId.В формате MPEG;
// * * * * Сравните это с моим фрагментом кода c++, я думаю *****
этот.flags = Mp3WaveFormatFlags.PaddingIso;
...
}


Additinal: для первых тестов с VBR я также предлагаю работать с постоянными значениями, например BlockAlign и т. д. как вы видите это в фрагменте кода c++.

Надеюсь, это поможет.

Member 13383318

Я установил постоянные значения для BlockAlign,BitsPerSample, SampleRate и т. д.
но это не работа.

0x01AA

Если у вас есть возможность предоставить мне ссылку для скачивания вашего исходного кода (проекта), я могу попробовать.

Member 13383318

вы можете нажать ниже url-адреса, чтобы загрузить мой исходный код. Используйте VS2015, чтобы открыть проект, спасибо.

https://pan.baidu.com/s/1qYiEqle

0x01AA

Он отвечает: ", ,的的的在在。", который показывает мне в Google Translate что-то вроде " ссылка истекла"

0x01AA

Второе испытание это работает у меня оно есть :)

Member 13383318

заранее спасибо. :)