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

Posted

技术标签:

【中文标题】使用 MediaPlayer 类从内存播放 WAV 文件【英文标题】:Play WAV File from Memory using MediaPlayer Class 【发布时间】:2018-03-06 01:52:14 【问题描述】:

我在按下某个键时播放.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();


我也在使用这个全局键盘挂钩,它可能会导致延迟。

https://gist.github.com/Ciantic/471698

【问题讨论】:

player.Open(uri) 不这样做吗?也许在你开始监听按键之前打开文件? @Tronald 我会试试的。 如果您想更好地控制播放并获得更好的性能,您可能需要查看 NAudio。 【参考方案1】:

如果您的要求是明确地从MemoryStream 播放,那么据我所知,您不能使用MediaPlayer。如果适合你,你可以使用SoundPlayer

    soundPlayer = new System.Media.SoundPlayer(memoryStream);
    soundPlayer.Play();

或者

    soundPlayer.Stream.Seek(0, SeekOrigin.Begin);
    soundPlayer.Stream.Write(buffer, 0, buffer.Length);
    soundPlayer.Play();

更新

MediaPlayer 有延迟,它的设计目的不是以这种方式播放短音。

这完全未经测试,但是,您可以在 Task.Run 线程池或后台线程中尝试 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();
            );

或其他方法 Play multiple sounds using SoundPlayer

// 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);

最后

如果以上仍然不合适,你可能会更好地查看DirectSound 甚至可能是nAudio,或者在这方面更强大的东西

【讨论】:

我无法使用 SoundPlayer,因为它不能同时播放 2 个声音。但我不必使用 MemoryStream,只要它可以从内存中播放即可。我只是想找到一种方法来减少延迟,我认为是硬盘驱动器速度造成的。 Task.Run() 不会同时播放 2。 DllImport PlayWorker(), IsBeingPlayed 未找到。 @MattMcManis 正在播放只是一个复制和粘贴错误,不需要 eb 那里

以上是关于使用 MediaPlayer 类从内存播放 WAV 文件的主要内容,如果未能解决你的问题,请参考以下文章

delphi怎么用mediaplayer播放资源?

Android使用AudioTrack播放WAV音频文件

Android MediaPlayer 不播放

求助:关于C#中使用axwindowsmediaplayer 播放wav文件的问题

求助:C#中使用axwindowsmediaplayer 播放wav文件的问题

使用MediaPlayer播放音频文件