我有这个相同的问题。我相信每个人都会。这是我如何解决它。
基本上,我在音频播放完成前1秒向流中执行回调的标记添加了一个标记。然后该回调触发一个叫700ms的定时器,该方法在完成之前停止音频(大约300ms)。我没有这个计时器就试过了,它不一致。看起来好像如果你设置一个标记在结束之前发射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);
}
});
}
感谢您的回答布拉德,这是一个领先的 - 你可以给我一些提示你是什么意思,通过重新调整小提琴手中不同的WAV文件?这与将声音嵌入SL应用程序并使用MediaElement播放它有何不同? – Rodney 2010-11-12 04:05:59
好吧,我想出了你的意思 - 通过在Fiddler中保存Response主体,你可以获得8khz的wav文件,正如你所指出的那样,文件末尾没有crack啪声。我已经深入了解代码并在原始文章中添加了一些内容(我认为这是WaveMediaStreamSource,然后我仍然不知道如何修复它!) – Rodney 2010-11-12 11:14:36
有趣。不幸的是,我从来没有为Silverlight编码,所以我没有任何进一步帮助的方法。再次,我会研究音频停止时会发生什么。如果采样速率在播放过程中突然发生变化,那么可能存在问题。 – Brad 2010-11-12 14:25:12