2012-03-28 29 views
4

ユーザーが特定のボタンをタップすると、短いサウンドを再生しようとしています。しかし、問題は、私は常にオブジェクト参照がインスタンスオブジェクトに設定されていないということです。 Nullを意味する!MonoTouch:サウンドを再生する

まず、MonoTouch.AudioToolBox.SystemSoundを試しました。

MonoTouch.AudioToolbox.AudioSession.Initialize(); 
MonoTouch.AudioToolbox.AudioSession.Category = MonoTouch.AudioToolbox.AudioSessionCategory.MediaPlayback; 
MonoTouch.AudioToolbox.AudioSession.SetActive(true); 

var t = MonoTouch.AudioToolbox.SystemSound.FromFile("click.mp3"); 
t.PlaySystemSound(); 

"click.mp3"はルートソリューションフォルダにあり、コンテンツとしてフラグが立てられます。 もう1つのアプローチはMonoTouch.AVFoundation.AVAudioPlayerです。

var url = NSUrl.FromFilename("click.mp3"); 
AVAudioPlayer player = AVAudioPlayer.FromUrl(url); 
player.FinishedPlaying += (sender, e) => { player.Dispose(); }; 
player.Play(); 

でも同じエラーです。私はそれをgoogledと私は多くの人々がこの問題を抱えていることがわかります。バグかどうかを知る必要があります。

+0

注:上記の上位3行は、iOS7(初期化、カテゴリ、SetActive)では非推奨です...それらなしで素晴らしい作品です。 – Ender2050

答えて

4

コードが正しいように見えます(オーディオを再生できるコードhereと比較しています)。

問題は、オーディオファイルが何とかアプリケーションバンドルに含まれていないことです。あなたは簡単にこのコードでそれを確認することができます。

if (!System.IO.File.Exists ("click.mp3")) 
    Console.WriteLine ("bundling error"); 
+0

恐ろしい!あなたが正しいです。あなたのアプローチを試みましたが、このファイルが存在しないことがわかりました。だから、ファイルをもう一度チェックして、今度はそれがコンテンツとしてフラグが立てられていないことがわかります。私はそれを変更するが、それは動作しません。私はobjフォルダを削除し、問題は最終的に解決しました。ありがとうございました。 – Peyman

+0

まだ動作しません。サウンドファイルが存在します。私はブレーキポイントを設定した。私の 'sound.PlaySystemSound()'行はヒットし、 'sound'はSystemSoundの有効なインスタンスです。私のデバイスのボリュームが一番上になります。私の音は再生されません。期間。私は本当にXamarinが嫌いです。最も愚かなシンプルなシナリオでも、それが言っていることをまったくやっていないという理由だけで、 –

7

SystemSoundMP3の使用について、この質問を参照して答える:Playing a Sound With Monotouch

AVAudioPlayerするために、以下のパターンが危険であることに注意してください:

AVAudioPlayer player = AVAudioPlayer.FromUrl(url); 
player.FinishedPlaying += (sender, e) => { player.Dispose(); }; 
player.Play(); 
Playは非同期ですので、

です。つまり、管理されたplayerインスタンスは、FinishedPlayingが発生する前に範囲外になる可能性があります。このが範囲外のである場合、GCはすでにインスタンスを収集している可能性があります。

この問題を解決するには、playerローカル変数をタイプフィールドに昇格させます。これにより、サウンド再生中にGCがインスタンスを収集しないようにします。

+0

プレイバックはコールバックが行われる前に処理されません。 OSは、コールバックラムダへのライブ参照を持っています(実際にコールバックが終了すると、コールバックを実行する必要があります)。その参照がなくなるまで、プレーヤー自体はライブオブジェクトグラフに残ります。 player.Dispose()を呼び出した後、playerはGCの対象となりますが、その時点より前の時点では対象となりません。 –

1

ほとんどの場合、Fileは存在しません。あなたが私のようで、ファイルが存在することを確認した場合。次のことを確認します。

  1. ファイルのパスがあなたのクラスにrelative(すなわち:Sounds\beep.wav)でなければなりません(絶対パスは、シミュレータ上で私のために動作しませんでした)
  2. あなたがSoundSystemを定義していることを確認してくださいclass level。これは、MTには驚異的なバージョンのGarbage Collectorがあり、再生を開始する前にSoundSystemを処分できるためです。これを参照してくださいquestion
関連する問題