C# 使用NAudio播放FFMPEG音频会产生大量噪声

C# 使用NAudio播放FFMPEG音频会产生大量噪声,c#,c++,audio,ffmpeg,naudio,C#,C++,Audio,Ffmpeg,Naudio,我有一个视频,我正试图用FFMPEG框架播放,NAudio播放音频帧。视频播放得很好,但是当我使用BufferedWaveProvider播放音频,而底层音频听起来正确时,它有大量的静态/噪声。在附录代码中要注意的是,当事件从托管C++类中发射时,C类接收事件,然后获取最新的相关AVFrAMS数据。这对视频来说是完美的,但就像我说的,当我试着播放音频时,我有一大堆噪音。现在我已经硬编码了NAudio波形格式设置,但是它们应该与视频的音频相匹配 //////////////////////

我有一个视频,我正试图用FFMPEG框架播放,NAudio播放音频帧。视频播放得很好,但是当我使用BufferedWaveProvider播放音频,而底层音频听起来正确时,它有大量的静态/噪声。在附录代码中要注意的是,当事件从托管C++类中发射时,C类接收事件,然后获取最新的相关AVFrAMS数据。这对视频来说是完美的,但就像我说的,当我试着播放音频时,我有一大堆噪音。现在我已经硬编码了NAudio波形格式设置,但是它们应该与视频的音频相匹配

    ///////////////////////// C# /////////////////////////////

    // Gets the size of the data from the audio AVFrame (audioFrame->linesize[0])
    int size = _Decoder.GetAVAudioFrameSize();

    if (!once)
    {
        managedArray = new byte[size];
        once = true;
    }

    // Gets the data array from the audio AVFrame
    IntPtr data = _Decoder.GetAVAudioFrameData();

    Marshal.Copy(data, managedArray, 0, size);

    if (_waveProvider == null)
    {
        _waveProvider = new BufferedWaveProvider(new WaveFormat(44100, 16, 2));
        _waveOut.NumberOfBuffers = 2;
        _waveOut.DesiredLatency = 300;
        _waveOut.Init(_waveProvider);
        _waveOut.Play();
    }

    _waveProvider.AddSamples(managedArray, 0, size);


    //////////////////////// Managed C++ /////////////////////////
    while (_shouldRead)
    {
        // if we're not initialized, sleep
        if (!_initialized || !_FFMpegObject->AVFormatContextReady())
        {
            Thread::Sleep(READ_INIT_WAIT_TIME);
        }
        else if (_sequentialFailedReadCount > MAX_SEQUENTIAL_READ_FAILS)
        {
            // we've failed a lot and probably lost the stream, try to reconnect.
            _sequentialFailedReadCount = 0;
            _initialized = false;
            StartInitThread();
            Thread::Sleep(READ_INIT_WAIT_TIME << 1);
        }
        else // otherwise, try reading one AV packet 
        {
            if (_FFMpegObject->AVReadFrame())
            {
                if (_FFMpegObject->GetAVPacketStreamIndex() == _videoStreamIndex)
                {
                    _sequentialFailedReadCount = 0;

                    // decode the video packet
                    _frameLock->WaitOne();
                    frameFinished = _FFMpegObject->AVCodecDecodeVideo2();
                    _frameLock->ReleaseMutex();

                    if (frameFinished)
                    {
                        _framesDecoded++;

                        if (!_isPaused) // If paused and AFAP playback, just don't call the callback
                        {
                            FrameFinished(this, EventArgs::Empty);

                            Thread::Sleep((int)(1000 / (GetFrameRate() * _speed)));
                        }
                    }
                }
                else if (_FFMpegObject->GetAVPacketStreamIndex() == _audioStreamIndex)
                {
                    // decode the audio packet.
                    _frameLock->WaitOne();
                    audioFrameFinished = _FFMpegObject->AVCodecDecodeAudio4();
                    _frameLock->ReleaseMutex();

                    if (audioFrameFinished)
                    {
                        if (!_isPaused) // If paused and AFAP playback, just don't call the callback
                        {
                            // Fire the event - leaving it up to video to do the sleeps -- not sure if that will work or not
                            AudioFrameFinished(this, EventArgs::Empty);
                        }
                    }
                }

                _FFMpegObject->AVFreeFramePacket();

            }
            else // failed to read an AV packet
            {
                _sequentialFailedReadCount++;
                _failedReadCount++;
                Thread::Sleep(READ_FAILED_WAIT_TIME);
            }
        }
    }
///////////C/////////////////////////////
//获取音频AVFrame中数据的大小(audioFrame->linesize[0])
int size=_Decoder.GetAVAudioFrameSize();
如果(!一次)
{
managedArray=新字节[大小];
一次=真;
}
//从音频帧获取数据数组
IntPtr data=_Decoder.GetAVAudioFrameData();
封送处理副本(数据,managedArray,0,大小);
if(_waveProvider==null)
{
_waveProvider=新的BufferedWaveProvider(新的波形格式(44100,16,2));
_waveOut.NumberOfBuffers=2;
_waveOut.DesiredLatency=300;
_Init(_waveProvider);
_waveOut.Play();
}
_AddSamples(managedArray,0,大小);
////////////////////////管理C++,////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////管理。
而(你应该读)
{
//如果我们没有初始化,请睡眠
如果(!_已初始化| |!_FFMpegObject->AVFormatContextReady())
{
线程::睡眠(读取初始等待时间);
}
否则如果(_sequentialFailedReadCount>MAX_SEQUENTIAL_READ_失败)
{
//我们失败了很多,可能丢失了数据流,请尝试重新连接。
_sequentialFailedReadCount=0;
_初始化=假;
StartInitThread();
线程::睡眠(READ_INIT_WAIT_TIME AVReadFrame())
{
如果(\u FFMpegObject->GetAVPacketStreamIndex()==\u videoStreamIndex)
{
_sequentialFailedReadCount=0;
//解码视频包
_frameLock->WaitOne();
frameFinished=\u FFMpegObject->avcodedecodevideo2();
_frameLock->ReleaseMutex();
如果(框架完成)
{
_framesDecoded++;
if(!\u isPaused)//如果暂停并播放AFAP,就不要调用回调
{
FrameFinished(此,EventArgs::Empty);
线程::Sleep((int)(1000/(GetFrameRate()*u speed));
}
}
}
否则如果(\u FFMpegObject->GetAVPacketStreamIndex()==\u audioStreamIndex)
{
//解码音频包。
_frameLock->WaitOne();
audioFrameFinished=\u FFMpegObject->avcodedecodeAudio4();
_frameLock->ReleaseMutex();
如果(音频帧已完成)
{
if(!\u isPaused)//如果暂停并播放AFAP,就不要调用回调
{
//启动事件-让视频来进行睡眠-不确定这是否有效
AudioFrameFinished(此,EventArgs::Empty);
}
}
}
_FFMpegObject->avfreeframepack();
}
else//无法读取AV数据包
{
_sequentialFailedReadCount++;
_failedReadCount++;
线程::睡眠(读取失败\u等待时间);
}
}
}

调试此类问题的一个好方法是记录音频输出,并使用audacity等工具将波形与正确的波形进行比较。这种差异可能会让你找到原因我只是好奇,我到底应该找什么?一个是正确的音频,另一个是带有大量噪声的正确音频。是否存在指向某个问题或另一个问题的特定线索?波形中的间隙表示缓冲区过大且未填满,不连续性表示缓冲区过小或某些缓冲区被丢弃。你可能会有一个有符号/无符号的不匹配,这会使波形的下半部分失真。如果你有问题,你可以随时发布一个屏幕截图。谢谢,我会在可能的时候更新。我暂时继续,但会在接下来的几天内回来。