1

編集: この奇妙な動作を最も簡単に再現するには、2 番目の更新に進みます。

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 プロジェクトを使用しましたが、フォームと Application.Run 行を削除しました。(私のコードはすべてメイン内にありました)

これが機能するには、メッセージ ループが必要であることがわかります (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) { }
    }

別のオプションは、メインを次のように維持することです。

    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