C# で圧縮サウンド ファイルをポータブルな方法で再生するにはどうすればよいですか?
質問
C# / .Net で圧縮サウンド ファイルを再生する、特許の制限を受けないポータブルな方法はありますか?番組内で発生するさまざまなイベントで短い「ジングル」音を再生したい。
System.Media.SoundPlayer は WAV のみを処理できますが、通常、ダウンロード可能なアプリケーションに埋め込むには大きすぎます。MP3 は特許で保護されているため、完全に管理されたデコーダ/プレーヤーがあったとしても、自由に再配布することはできません。利用可能な最良の形式は OGG Vorbis と思われますが、C# Vorbis ライブラリを動作させるには運がありませんでした (私はなんとか生の PCM を抽出できました) クスヴォルビス しかし、その後の遊び方がわかりません)。
プロジェクトは少なくとも Windows と Linux 上で実行する必要があるため、アプリケーションと一緒にバイナリを配布したくありませんし、P/Invoke に依存したくありません。GPL とライセンス互換性がある限り、.Net アセンブリをバンドルしても問題ありません。
[この質問は、 mono-dev に関するメーリング リストのディスカッション 1年前のメーリングリスト]
解決
私は最終的にこのトピックを再検討し、次の助けを借りました。 BrokenGlass による WAVE ヘッダーの書き込み, 、csvorbis を更新しました。を追加しました OggDecodeStream に渡すことができるのは System.Media.SoundPlayer
任意の (互換性のある) Ogg Vorbis ストリームを再生するだけです。使用例:
using (var file = new FileStream(oggFilename, FileMode.Open, FileAccess.Read))
{
var player = new SoundPlayer(new OggDecodeStream(file));
player.PlaySync();
}
この場合の「互換性がある」とは、「試してみたらうまくいった」という意味です。デコーダは完全に管理されており、Microsoft .Net 上で正常に動作します。現時点では、Mono のデコーダに回帰があるようです。 SoundPlayer
それが歪みの原因となります。
古い:
System.Diagnostics.Process.Start("fullPath.mp3");
驚いていますが、 ダイナが挙げた方法 実際に機能します。しかし、私はプログラムで発生するさまざまなイベントで短い「ジングル」サウンドをプレイすることを考えていました。「ping!」をする必要があるたびにユーザーのメディアプレーヤーを起動したくありません。音。
コード プロジェクト リンクについては、残念ながらこれは単なる P/Invoke ラッパーです。
他のヒント
プロジェクトは少なくともWindowsとLinuxで実行されるはずであるため、私のアプリケーションでバイナリを配布したり、P/Invokeに依存したりすることも望みません。GPLとライセンス互換性がある限り、.NETアセンブリをバンドリングするのは大丈夫です。
残念ながら、バイナリの配布を回避したり、P/Invoke を回避したりすることは不可能でしょう。いずれにせよ、.net クラス ライブラリはその下で P/Invoke を使用します。マネージ コードは何かを行うために、ある時点でアンマネージ オペレーティング システム API と通信する必要があります。
OGG ファイルを PCM に変換することはマネージ コードで可能であるはずですが、.net にはオーディオのネイティブ サポートがないため、実際には 3 つのオプションがあります。
外部プログラムを呼び出してサウンドを再生します (前述のとおり)
P/C モジュールを呼び出してサウンドを再生します
P/OS API を呼び出してサウンドを再生します。
(4.) このコードを Windows 上でのみ実行している場合は、おそらく DirectShow を使用するだけで済みます。
P/Invoke はクロスプラットフォームで使用できますhttp://www.mono-project.com/Interop_with_Native_Libraries#Library_Names
PCM データを取得したら (OGG C Lib またはマネージ コードを使用して、次のようなもの) http://www.robburke.net/mle/mp3sharp/ もちろん MP3 にはライセンスの問題があります)、それを再生する方法が必要になります。残念ながら、.net はサウンド カードを直接評価したり、ストリーミング オーディオを再生する方法を提供しません。起動時に ogg ファイルを PCM に変換し、System.Media.SoundPlayer を使用して、生成された wav ファイルを再生できます。Microsoft が提案している現在の方法では、P/Invoke を使用して OS のサウンド再生 API にアクセスします。 http://msdn.microsoft.com/en-us/library/ms229685.aspx
PCM サウンドを再生するためのクロスプラットフォーム API は OpenAL であり、www.taoframework.com で OpenAL の C# バインディングを使用して (PCM) サウンドを再生できるはずですが、残念ながら、多くの DLL および .so ファイルをアプリケーションが配布時に機能するようにするために必要ですが、これは、前に説明したように避けられません。
「System.Diagnostics」にあるものを呼び出してサウンドを再生するというのは、私にはかなり悪い考えのように思えます。この関数の目的は次のとおりです。
//
// Summary:
// Starts a process resource by specifying the name of a document or application
// file and associates the resource with a new System.Diagnostics.Process component.
//
// Parameters:
// fileName:
// The name of a document or application file to run in the process.
//
// Returns:
// A new System.Diagnostics.Process component that is associated with the process
// resource, or null, if no process resource is started (for example, if an
// existing process is reused).
//
// Exceptions:
// System.ComponentModel.Win32Exception:
// There was an error in opening the associated file.
//
// System.ObjectDisposedException:
// The process object has already been disposed.
//
// System.IO.FileNotFoundException:
// The PATH environment variable has a string containing quotes.
すべてのオーディオ API の母である fmod を見てみる必要があると思います。
自由に夢を見てください http://www.fmod.org/index.php/download#FMODExProgrammersAPI
XNA Audio API は .net/c# アプリケーションで適切に動作し、このアプリケーションでも美しく動作します。イベントベースのトリガーと複数のサウンドの同時再生。まさにあなたが望むものです。あ、圧縮もね。
まあ、それは特定の国の特許関連法によって異なりますが、私の知る限り、特許に違反せずに MP3 デコーダを作成する方法はありません。あなたの問題に対する最良のクロスプラットフォームのオープンソース ソリューションは次のとおりだと思います。 Gストリーマー. 。これには C# バインディングがあり、急速に進化しています。ただし、Windows 上で GStreamer を使用して構築するのは簡単な作業ではありません。 ここ は良い出発点です。 バンシー プロジェクトではこのアプローチを使用していますが、Windows ではまだ実際には使用できません (ただし、ほぼ動作する夜間ビルドがいくつかあります)。 FMOD も良い代替手段です。残念ながら、これはオープンソースではなく、その API は何らかの形で C スタイルになっていることがわかりました。
オープンソースである純粋な C# vorbis デコーダーが利用可能です。
これが今も関係があるかどうかはわかりません。最も簡単な解決策は使用することです Nオーディオ, これは、C# で書かれたマネージド オープン ソース オーディオ API です。もう 1 つ試してみたいのは、ffmpeg を利用して、次のプロセスを作成することです。 ffplay.exe (正しいバイナリは共有ビルドの下にあります)。
プレイ処理に他のものを使用せずにこれを行う方法はありません。
System.Diagnostic を使用すると外部ソフトウェアが起動しますが、それを望んでいるとは思えませんよね。プログラム内で Y が発生したときに X サウンド ファイルをバックグラウンドで再生したいだけですよね?
興味深い質問のように見えるので投票しました。:D