Мне очень сложно выяснить, как получить несколько источников звука в один поток без значительных задержек. Я следовал за документацией 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 и (потенциально) resampler добавит значительных накладных расходов, но я хотел бы знать, что лучше всего подходит для синхронизации видео и аудио.
Редактировать: Мой вход 44100 Гц, поэтому используется MediaFoundationResampler. После небольшого тестирования это причина большей части задержки, но у меня есть несколько входов с разными форматами.
Итак, как синхронизировать аудио и видео? Или как уменьшить время MediaFoundationResampler для повторной выборки? Какая здесь самая лучшая практика? Я мог бы использовать несколько выходов, но вместо этого было рекомендовано использовать микшер.