如何混合多个输入并保持同步?
How to mix multiple inputs and keep synchronization?
我很难弄清楚如何在没有明显延迟的情况下将多个音频源整合到一个流中。我尽可能地遵循了 NAudio 的文档,并编写了以下内容;
public void Start()
{
_format = new WaveFormat(48000, 16, 2);
_mixingSampleProvider = new MixingSampleProvider(WaveFormat.CreateIeeeFloatWaveFormat(48000, 2));
_compressorStream = new SimpleCompressorStream(new MixingWaveStream(_mixingSampleProvider.ToWaveProvider()));
_compressorStream.Enabled = true;
foreach (var p in _activeRenderers)
{
p.Start(_compressorStream);
}
}
public void RegisterProvider(IAudioProvider provider)
{
var audioWaveProvider = new AudioWaveProvider(provider, _format);
_providers.Add(audioWaveProvider);
_mixingSampleProvider.AddMixerInput(audioWaveProvider.WaveProvider);
}
MixingWaveStream
是从 IWaveProvider 到 WaveStream 的转换。 p.Start()
此时简单地初始化一个 WasapiOut 并调用 Play()
。现在只有一个(我意识到当前的设置不适用于多个输出)。
还有我的 AudioWaveProvider;
public AudioWaveProvider(IAudioProvider provider, WaveFormat format)
{
// Resample if necessary
if (provider.BitDepth != format.BitsPerSample || provider.Channels != format.Channels || provider.SampleRate != format.SampleRate)
{
_waveProviderToSendSamples = new BufferedWaveProvider(new WaveFormat(provider.SampleRate, provider.BitDepth, provider.Channels));
WaveProvider = new MediaFoundationResampler(_waveProviderToSendSamples, format);
}
else
{
WaveProvider = new BufferedWaveProvider(format);
_waveProviderToSendSamples = (BufferedWaveProvider)WaveProvider;
}
AudioProvider = provider;
provider.ProvideSamples += Provider_ProvideSamples;
}
private void Provider_ProvideSamples(IAudioProvider provider, AudioSamples samples)
{
_waveProviderToSendSamples.AddSamples(samples.Samples, 0, (int)samples.Samples.Length);
}
我的音频提供者(在本例中只是一个 libvlc 播放的视频)通过一个事件提供样本。
一切正常但是有明显的延迟(查看我正在输出的视频帧时大约 100 毫秒)。我意识到添加混音器、BufferedWaveProvider 和(可能)重采样器会增加大量开销,但我想知道保持视频和音频同步的最佳做法是什么。
编辑:我的输入是 44100Hz,因此使用了 MediaFoundationResampler。经过一些测试,这是大部分延迟的原因,但我有多个不同格式的输入。
那么,如何使音频和视频保持同步?或者如何减少 MediaFoundationResampler 重新采样所需的时间?这里的最佳做法是什么?我可以使用多个输出,但建议改用混音器。
是的,MediaFoundationTransform
有一个 hard-coded 一秒钟音频的读取大小,因为这样可以很容易地计算出源缓冲区和目标缓冲区的大小应该是多少。在试验了最佳大小后,我一直打算在将来使它可配置,但由于我只在可以提前阅读的情况下使用它,所以我从来没有考虑过它。
如果您可以创建自己的 NAudio 自定义版本,那么您可以尝试使用较小的 sourceBuffer 大小。
我很难弄清楚如何在没有明显延迟的情况下将多个音频源整合到一个流中。我尽可能地遵循了 NAudio 的文档,并编写了以下内容;
public void Start()
{
_format = new WaveFormat(48000, 16, 2);
_mixingSampleProvider = new MixingSampleProvider(WaveFormat.CreateIeeeFloatWaveFormat(48000, 2));
_compressorStream = new SimpleCompressorStream(new MixingWaveStream(_mixingSampleProvider.ToWaveProvider()));
_compressorStream.Enabled = true;
foreach (var p in _activeRenderers)
{
p.Start(_compressorStream);
}
}
public void RegisterProvider(IAudioProvider provider)
{
var audioWaveProvider = new AudioWaveProvider(provider, _format);
_providers.Add(audioWaveProvider);
_mixingSampleProvider.AddMixerInput(audioWaveProvider.WaveProvider);
}
MixingWaveStream
是从 IWaveProvider 到 WaveStream 的转换。 p.Start()
此时简单地初始化一个 WasapiOut 并调用 Play()
。现在只有一个(我意识到当前的设置不适用于多个输出)。
还有我的 AudioWaveProvider;
public AudioWaveProvider(IAudioProvider provider, WaveFormat format)
{
// Resample if necessary
if (provider.BitDepth != format.BitsPerSample || provider.Channels != format.Channels || provider.SampleRate != format.SampleRate)
{
_waveProviderToSendSamples = new BufferedWaveProvider(new WaveFormat(provider.SampleRate, provider.BitDepth, provider.Channels));
WaveProvider = new MediaFoundationResampler(_waveProviderToSendSamples, format);
}
else
{
WaveProvider = new BufferedWaveProvider(format);
_waveProviderToSendSamples = (BufferedWaveProvider)WaveProvider;
}
AudioProvider = provider;
provider.ProvideSamples += Provider_ProvideSamples;
}
private void Provider_ProvideSamples(IAudioProvider provider, AudioSamples samples)
{
_waveProviderToSendSamples.AddSamples(samples.Samples, 0, (int)samples.Samples.Length);
}
我的音频提供者(在本例中只是一个 libvlc 播放的视频)通过一个事件提供样本。
一切正常但是有明显的延迟(查看我正在输出的视频帧时大约 100 毫秒)。我意识到添加混音器、BufferedWaveProvider 和(可能)重采样器会增加大量开销,但我想知道保持视频和音频同步的最佳做法是什么。
编辑:我的输入是 44100Hz,因此使用了 MediaFoundationResampler。经过一些测试,这是大部分延迟的原因,但我有多个不同格式的输入。
那么,如何使音频和视频保持同步?或者如何减少 MediaFoundationResampler 重新采样所需的时间?这里的最佳做法是什么?我可以使用多个输出,但建议改用混音器。
是的,MediaFoundationTransform
有一个 hard-coded 一秒钟音频的读取大小,因为这样可以很容易地计算出源缓冲区和目标缓冲区的大小应该是多少。在试验了最佳大小后,我一直打算在将来使它可配置,但由于我只在可以提前阅读的情况下使用它,所以我从来没有考虑过它。
如果您可以创建自己的 NAudio 自定义版本,那么您可以尝试使用较小的 sourceBuffer 大小。