1

编辑:转到第二次更新,以最简单地重现这种奇怪的行为。

我正在尝试使用 WindowsMediaPlayer 库播放和停止声音。

我在互联网上搜索了几十个页面,都说基本播放需要相同的代码。

但它对我无济于事。

        WMPLib.WindowsMediaPlayer wplayer = new WMPLib.WindowsMediaPlayer();

        wplayer.URL = path; // relative path, absolute path, mp3 file, wav file.. I've tried everything
        wplayer.controls.play();

我只是无法让它播放任何声音。

此外,如果我检查 currentMedia 属性,它会正确识别我的文件,

但它声称其持续时间为 0:00。

为什么会这样?

更新:

我发现我的问题的答案是Application.Run()

我使用了一个 WinForms 项目,但删除了 Form 和 Application.Run 行。(我所有的代码都在 Main 中)

事实证明,必须有一个消息循环才能工作(顺便说一下,这对SoundPlayer班级来说是不正确的)

另外(可能出于同样的原因),在调试模式下,当从一行转到下一行时,我什么也听不见,直到 GUI 线程被释放。

我仍然很好奇为什么会这样?

为什么 WMP 需要消息循环?为什么 SoundPlayer 没有?

还是我错过了理解?

更新 2:

如何重现?

新项目 -> Winforms -> 删除 Form1 -> 转到 program.cs

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        TryPlay(); // Do nothing.
        while (true) { }
    }

    static void TryPlay()
    {
        string path = @"001_The Beatles - Help.wav";
        WMPLib.WindowsMediaPlayer wplayer = new WMPLib.WindowsMediaPlayer();
        wplayer.MediaError += wplayer_MediaError;

        wplayer.URL = path;

        wplayer.controls.play();
    }

    static void wplayer_MediaError(object pMediaObject)
    {
        MessageBox.Show("ERROR");
    }
}

但是如果我们改变主:

    static void Main()
    {
        //TryPlay();
        new Thread(() => TryPlay()).Start(); // WORKS(!)
        while (true) { }
    }

另一种选择是保持 Main 像这样:

    static void Main()
    {
        TryPlay();
        while (true) { }
    }

但更改 TryPlay 方法:

    static void TryPlay()
    {
        string path = @"001_The Beatles - Help.wav";
        WMPLib.WindowsMediaPlayer wplayer = new WMPLib.WindowsMediaPlayer();
        wplayer.MediaError += wplayer_MediaError;

        wplayer.URL = path;

        wplayer.controls.play();
        Application.Run(); // <------  WORKS. (why?)
    }
4

0 回答 0