Я пытаюсь воспроизвести локальный медиафайл с помощью LibVLCSharp и наложить поверх него звук метронома. Вот упрощенная версия кода, который я использовал:
private LibVLC libVlc;
private MediaPlayer mediaPlayer;
async Task Open()
{
libVlc = new LibVLC();
Core.Initialize();
Media media = new(libVlc, new Uri(MEDIA_FILE_PATH));
await media.Parse();
mediaPlayer = new MediaPlayer(media);
}
async Task Play()
{
PeriodicTimer metronomeTimer = new(METRONOME_TIMER_INTERVAL);
mediaPlayer.Play();
for (int i = 0; i < 10; i++)
{
PlayMetronomeSound();
await metronomeTimer.WaitForNextTickAsync();
}
}
Этот код работает нормально, но между звуком метронома и звуком, воспроизводимым LibVLC, существует небольшая задержка. Если я подпишусь на событие mediaPlayer.Playing
, я увижу, что это событие запускается примерно через 150 мс после вызова mediaPlayer.Play()
. Я полагаю, это буферизует медиа в это время?
Если это так, есть ли способ предварительно буферизовать носитель в методе Open()
, чтобы избежать задержки в Play()
?
Единственный обходной путь, который мне удалось найти, — это вызвать mediaPlayer.Play()
в методе Open()
, затем mediaPlayer.Pause()
в обработчике событий mediaPlayer.Playing
, а затем перейти к началу с помощью mediaPlayer.SeekTo(TimeSpan.Zero)
. В этом случае второй вызов mediaPlayer.Play()
немедленно запускает воспроизведение, и проблем с синхронизацией больше нет, но мне это кажется хаком.
Учитывая, что ни Windows, ни C#/.Net даже близко не поддерживают работу в реальном времени, я бы сделал шаг назад и рассмотрел возможность использования чего-то вроде FFMPEG для фактического смешивания щелчка со звуковым слоем видео в разные временные метки. Это должно дать вам а) повторяемые результаты и б) гораздо большую точность.
@JeremyLakeman, к сожалению, не имеет отношения к этому. Этот вопрос касается MediaPlayer UWP, а не LibVLCSharp.
@Fildor, отсутствие поддержки режима реального времени - это нормально, меня устраивает точность до 50 мс, если ошибки синхронизации не накапливаются с течением времени. Я провел небольшое тестирование и обнаружил, что PeriodicTimer
относительно точен (разница менее 1 мс за несколько минут). Точность воспроизведения LibVLCSharp также ниже 20 мс, как только я начну синхронизировать воспроизведение. Микширование звука метронома в медиа определенно сработает, но, к сожалению, мне также нужно обновлять элементы пользовательского интерфейса с одинаковыми интервалами, поэтому мне нужно синхронизировать их с воспроизведением мультимедиа.
Вы можете попробовать следующую пользовательскую опцию libvlc --start-paused
(в конструкторе libvlc) или :start-paused
в качестве аргумента Media.AddOption
. Это может привести к желаемому результату.
Кроме того, почему бы не вызвать PlayMetronomeSound
, когда сработает событие Playing
?
media.AddOption(":start-paused")
сработало, спасибо! Вызов PlayMetronomeSound
, когда срабатывает событие Playing
— вы имеете в виду блокировку метода async Task Play()
и отправку сигнала от обработчика события mediaPlayer.Playing
для разблокировки Play
? Да, я планировал это сделать, если бы не было более простых/простых вариантов.
Связанный? stackoverflow.com/questions/51276649/…