C# 使用MediaPlayer类从内存播放WAV文件
我在按键时播放.wav声音文件。但是在播放声音之前有一个延迟 如何将文件复制到内存并从MemoryStream而不是硬盘播放C# 使用MediaPlayer类从内存播放WAV文件,c#,wpf,C#,Wpf,我在按键时播放.wav声音文件。但是在播放声音之前有一个延迟 如何将文件复制到内存并从MemoryStream而不是硬盘播放 if (e.Key == Key.Enter) { MediaPlayer player = new MediaPlayer(); Uri uri = new Uri("Sounds\\enter.wav", UriKind.RelativeOrAbsolute); player.Open(uri); player.Play(); } 我
if (e.Key == Key.Enter) {
MediaPlayer player = new MediaPlayer();
Uri uri = new Uri("Sounds\\enter.wav", UriKind.RelativeOrAbsolute);
player.Open(uri);
player.Play();
}
我也在使用这个全局键盘挂钩,它可能会导致延迟
如果您的要求是从MemoryStream显式播放,那么据我所知,您不能使用MediaPlayer。如果它适合你,你可以使用 或 使现代化 MediaPlayer有一个延迟,它的设计不是以这种方式播放短声音 这是完全未经测试的,但是,您可以在任务中尝试SoundPlayer。运行线程池或后台线程。这样可以获得缓冲性能增益
byte[] buffer;
Task.Run(() =>
{
soundPlayer = new SoundPlayer()
soundPlayer.Stream.Seek(0, SeekOrigin.Begin);
soundPlayer.Stream.Write(buffer, 0, buffer.Length);
soundPlayer.Play();
// or
soundPlayer = new System.Media.SoundPlayer(memoryStream);
soundPlayer.Play();
});
还是另一种方法
最后
如果上述内容仍然不适用,您可能会更擅长使用DirectSound,甚至nAudio,或者在这方面有更强大功能的东西,而不是player。Openuri就是这样做的吗?也许在你开始听按键之前打开文件?@Tronald我会试试。如果你想要更多的播放控制和更好的性能,你可以看看NAudio。我不能使用SoundPlayer,因为它不能一次播放两个声音。但我不必使用MemoryStream,只要它可以根据记忆播放就行。我只是想找到一种减少延迟的方法,我认为是硬盘速度造成的。Task.Run不能同时播放2。DllImport PlayWorker,未找到正在播放。@正在播放的MattMcManis只是一个复制粘贴错误,不需要在那里播放
soundPlayer.Stream.Seek(0, SeekOrigin.Begin);
soundPlayer.Stream.Write(buffer, 0, buffer.Length);
soundPlayer.Play();
byte[] buffer;
Task.Run(() =>
{
soundPlayer = new SoundPlayer()
soundPlayer.Stream.Seek(0, SeekOrigin.Begin);
soundPlayer.Stream.Write(buffer, 0, buffer.Length);
soundPlayer.Play();
// or
soundPlayer = new System.Media.SoundPlayer(memoryStream);
soundPlayer.Play();
});
// Sound api functions
[DllImport("winmm.dll")]
static extern Int32 mciSendString(string command, StringBuilder buffer, int bufferSize, IntPtr hwndCallback)
...
private void PlayWorker()
{
StringBuilder sb = new StringBuilder();
mciSendString("open \"" + FileName + "\" alias " + this.TrackName, sb, 0, IntPtr.Zero);
mciSendString("play " + this.TrackName, sb, 0, IntPtr.Zero);
}