WinFormsでサウンドを鳴らす最短ルートと実践レシピ

TL;DR(用途別の選び方)

用途対応形式おすすめAPI理由/注意
通知音・簡易効果音(WAV)WAVSystem.Media.SoundPlayer標準・依存少・最短。Playは未ロード時に自動ロードされる。   
MP3など多形式を簡単にMP3/他WPFのMediaPlayer(WinFormsから参照)追加参照でシンプルに多形式対応。先頭から再生したい時はPosition=TimeSpan.Zero。 
連続再生・ループ・UIにプレイヤーを出したいMP3/他AxWindowsMediaPlayer(COM)ループ等が手軽。COM参照が必要。 
音量制御・ミキシング等の高度機能多形式NAudio柔軟・拡張性大。NuGetで導入。 

最短で動かす(WAV):SoundPlayer

using System;
using System.Media;
using System.Windows.Forms;

public partial class Form1 : Form
{
    Button btn;
    public Form1()
    {
        btn = new Button { Text = "Play WAV" };
        btn.Click += (_, __) =>
        {
            using var player = new SoundPlayer(@"fanfare.wav");
            // 最短なら Load 省略でも OK(Play が未ロード時にロードを行う)
            player.Play();
        };
        Controls.Add(btn);
    }
}
  • SoundPlayer.Play() は、まだロードされていなければ内部でロードして再生します。 
  • 一部環境(Windows 11 のセキュリティ設定)で using + Load + Play の組み合わせで不安定になる事例があるため、Loadを省略してPlayだけにすると回避できたという知見があります(観察事例)。
    • なお、これは環境依存の挙動です。まずは上記の最短コードで問題ないか確認してください。

参考:SoundPlayer クラス(Microsoft Learn)。 


MP3 をシンプルに鳴らす:WPF の MediaPlayer を併用

WinForms プロジェクトに PresentationCore / PresentationFramework / WindowsBase を参照追加して使います。

using System;
using System.Windows.Forms;
using System.Windows.Media; // WPF

public partial class Form1 : Form
{
    Button btn;
    MediaPlayer _player;

    public Form1()
    {
        btn = new Button { Text = "Play MP3" };
        btn.Click += (_, __) =>
        {
            // 先頭から再生したい場合は毎回位置をリセット
            _player.Position = TimeSpan.Zero;
            _player.Play();
        };
        Controls.Add(btn);

        // 事前に開いておくとクリック遅延が減る
        _player = new MediaPlayer();
        _player.Open(new Uri(@"sound.mp3", UriKind.Relative));
    }
}
  • 多形式(MP3 など)に対応。
  • 「都度Openせず毎回先頭から鳴らす」には、上記のように一度Openしておき、クリック時にPosition=TimeSpan.Zeroが手軽。 参考:MediaPlayer クラス(Microsoft Learn)。 

注意:一部環境でフォームの見た目が微妙に変わる等の副作用を避けたい場合、次の AxWindowsMediaPlayer も選択肢です。 


ループやUI組み込みを手軽に:AxWindowsMediaPlayer(COM)

  1. ツールボックスに「Windows Media Player」を追加(COM コンポーネント)
  2. いったんフォームにドラッグ&ドロップして参照(AxWMPLib / WMPLib)を追加
  3. コードから生成して使う(UIに表示しなくても可)
using System;
using System.Windows.Forms;
using AxWMPLib;

public partial class Form1 : Form
{
    Button btn;
    AxWindowsMediaPlayer _wmp;

    public Form1()
    {
        btn = new Button { Text = "Loop Play" };
        btn.Click += (_, __) =>
        {
            _wmp.URL = "sound.mp3";
            _wmp.settings.setMode("loop", true);
            _wmp.Ctlcontrols.play();
        };
        Controls.Add(btn);

        _wmp = new AxWindowsMediaPlayer();
        _wmp.CreateControl(); // 重要:コントロール初期化
    }
}

「1回だけ再生(ループしない)」なら、setMode(“loop", false) にするか、その行自体を削除すればOKです。前回ループONにしていた場合は設定が残るので、明示的にOFFしておくのが安全です。

btn.Click += (_, __) =>
{
    _wmp.URL = "sound.mp3";
    _wmp.settings.setMode("loop", false); // ← ループOFF
    _wmp.Ctlcontrols.play();
};

ボタンを分けたいなら、例えばこう:

var btnOnce = new Button { Text = "Play Once", Left = 100 };
btnOnce.Click += (_, __) =>
{
    _wmp.settings.setMode("loop", false);
    _wmp.URL = "sound.mp3";
    _wmp.Ctlcontrols.play();
};
Controls.Add(btnOnce);

(補足)過去にtrueにしているとそのままループし続けるので、「ループしない」動作を保証したいときは毎回 false をセットしてください。

  • ループ再生などの操作が容易。 

高度機能(音量・ミキシング等):NAudio

NuGet で NAudio を追加して利用します。

using System;
using System.Windows.Forms;
using NAudio.Wave;

public partial class Form1 : Form
{
    Button btn;
    WaveOutEvent _out = new();
    AudioFileReader? _reader;

    public Form1()
    {
        btn = new Button { Text = "Play via NAudio" };
        btn.Click += (_, __) =>
        {
            _reader?.Dispose();
            _reader = new AudioFileReader("sound.mp3"); // WAV/MP3 等OK
            _out.Init(_reader);
            _out.Play();
        };
        Controls.Add(btn);
    }
}
  • 多形式・音量制御・ミキシングなどが柔軟。ライブラリの更新も活発。 

よくある落とし穴と対処

  • ファイルパスが通らない
    • 開発中は fanfare.wav などをプロジェクトに追加し、「出力ディレクトリにコピー」=「常にコピー/新しい場合はコピー」にしておくと相対パスで扱いやすい。
  • 毎回のクリックで先頭から鳴らしたい
    • MediaPlayer.Position = TimeSpan.Zero、AxWindowsMediaPlayer.settings.setMode(“loop", true)(ループ時)などを利用。 
  • SoundPlayer で Load 周りが不安定
    • まずは Play() のみで試す。環境依存の事象がある(観察知見)。 
  • UIが固まる
    • SoundPlayer.PlaySync() は同期再生でブロックします。通常は Play() を用いる。(API仕様は Microsoft Learn を参照) 

参考

  • 元記事(構成・知見の出典):「WinFormsアプリケーションでのサウンド再生方法」(最終更新 2024-08-29)。 
  • SoundPlayer(Microsoft Learn)。Play が未ロード時にロードすること等の仕様。 
  • MediaPlayer(Microsoft Learn)。WPF メディア再生。 
  • NAudio(GitHub)。 

変更点サマリ(再構成方針)

  • 「最短で鳴らす」→「目的別の選び方」→「具体レシピ」→「落とし穴」の一本線導線に整理。
  • MP3の最短手段として WPF MediaPlayer の「事前Open+Positionリセット」パターンを明確化。 
  • SoundPlayer.Load 省略に関する環境依存の注意を観察知見として分離記述。 

訪問数 3 回, 今日の訪問数 1回