У меня была такая же проблема. Я уверен, что все делают. Вот как я это решил.
По сути, я добавил маркер в поток, который выполнял обратный вызов за 1 секунду до завершения воспроизведения звука. Затем этот обратный вызов запускает таймер, который вызывается через 700 мс, и этот метод останавливает звук (около 300 мс) до его завершения. Я попробовал это без этого таймера, и это было противоречиво. Кажется, если вы установите маркер на 300 мс до конца, он не всегда будет срабатывать. Лучше получить его за секунду до этого, а затем запустить собственный таймер, чтобы отключить его, когда вы будете готовы.
Вот соответствующие фрагменты кода. Надеюсь, что это может помочь кому-то еще. Есть множество других хитростей для написания нормально работающего аудиоплеера, но этот код должен решить, по крайней мере, вашу проблему с щелчками.
public void Page_Loaded(object sender, EventArgs args)
{
mediaElement.MediaOpened += new RoutedEventHandler(mediaElement_MediaOpened);
mediaElement.MarkerReached += new TimelineMarkerRoutedEventHandler(mediaElement_MarkerReached);
}
Timer t;
void mediaElement_MarkerReached(object sender, TimelineMarkerRoutedEventArgs e)
{
// almost completed playing the file so lets stop before the annoying click is heard
t = new Timer(handleStopTimerDone, "", 700, 0);
}
public void handleStopTimerDone(object state)
{
// stop the audio playing
Stop();
}
private void mediaElement_MediaOpened(object sender, RoutedEventArgs e)
{
TimeSpan duration = mediaElement.NaturalDuration.TimeSpan;
TimelineMarker newMarker = new TimelineMarker();
newMarker.Time = new TimeSpan(duration.Ticks - 10000000);
while (mediaElement.Markers.Count > 0)
{
mediaElement.Markers.RemoveAt(0);
}
mediaElement.Markers.Add(newMarker);
}
public void Stop()
{
this.Dispatcher.BeginInvoke(delegate()
{
mediaElement.AutoPlay = false;
mediaElement.Stop();
mediaElement.Position = TimeSpan.FromSeconds(0);
if (memData != null)
{
WaveMediaStreamSource wavMss = new WaveMediaStreamSource(memData);
mediaElement.SetSource(wavMss);
}
});
}