C# 使用MediaPlayer类从内存播放WAV文件

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(); } 我

我在按键时播放.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();
}
我也在使用这个全局键盘挂钩,它可能会导致延迟


如果您的要求是从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);
}