C# 使用NAudio播放FFMPEG音频会产生大量噪声
我有一个视频,我正试图用FFMPEG框架播放,NAudio播放音频帧。视频播放得很好,但是当我使用BufferedWaveProvider播放音频,而底层音频听起来正确时,它有大量的静态/噪声。在附录代码中要注意的是,当事件从托管C++类中发射时,C类接收事件,然后获取最新的相关AVFrAMS数据。这对视频来说是完美的,但就像我说的,当我试着播放音频时,我有一大堆噪音。现在我已经硬编码了NAudio波形格式设置,但是它们应该与视频的音频相匹配C# 使用NAudio播放FFMPEG音频会产生大量噪声,c#,c++,audio,ffmpeg,naudio,C#,C++,Audio,Ffmpeg,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等工具将波形与正确的波形进行比较。这种差异可能会让你找到原因我只是好奇,我到底应该找什么?一个是正确的音频,另一个是带有大量噪声的正确音频。是否存在指向某个问题或另一个问题的特定线索?波形中的间隙表示缓冲区过大且未填满,不连续性表示缓冲区过小或某些缓冲区被丢弃。你可能会有一个有符号/无符号的不匹配,这会使波形的下半部分失真。如果你有问题,你可以随时发布一个屏幕截图。谢谢,我会在可能的时候更新。我暂时继续,但会在接下来的几天内回来。