2012-03-28 245 views
4

我试图在用户点击特定按钮时播放短暂的声音。但问题是我总是收到对象引用未设置为实例对象。意味着空!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”在我的根解决方案文件夹中,它被标记为内容。另一种方法是MonoTouch.AVFoundation.AVAudioPlayer

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

但是同样的错误。我搜索了它,我发现很多人都有这个问题。我们需要知道它是否是一个错误。

+0

注意:上面的前3行是在iOS7(初始化,类别,SetActive)不推荐使用...没有它们的伟大工程。 – Ender2050 2014-04-26 15:11:00

回答

4

你的代码看起来是正确的(我比较代码here,它可以播放音频)。

问题可能是音频文件不包含在应用程序包中。您可以轻松地使用此代码检查:

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

太棒了!你是对的。我试过你的方法,我发现这个文件不存在。所以我再次检查了这个文件,现在我发现它没有被标记为内容。我改变它,但它不会工作。我删除了obj文件夹,问题终于解决了。谢谢。 – Peyman 2012-03-28 15:34:35

+0

仍然不适合我。声音文件存在。我设定了一个brakpoint。我的'sound.PlaySystemSound()'行被击中,'sound'是SystemSound的有效实例。我的设备音量一直处于上升状态。我的声音不起作用。期。我开始非常讨厌Xamarin。即使在最愚蠢的简单情况下,iOS也不会做它所说的事情。 – 2016-02-01 23:38:55

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具有对回调lambda的实时引用(它必须,在完成播放时实际执行回调)。在参考文件消失之前,播放器本身仍处于活动对象图中。在调用player.Dispose()之后,玩家有资格使用GC,但不能在该点之前。 – 2016-07-07 17:30:15

1

在大多数情况下,这将是File不存在。如果你和我一样,并且你确定文件存在。请确保以下几点:

  1. 的文件的路径应该是relative到类(即:Sounds\beep.wav)(绝对路径并没有为我在模拟器上工作)
  2. 确保您在定义SoundSystemclass level。这是因为MT有一个积极的Garbage Collector,并且可以在你开始玩之前处置你的SoundSystem。看到这question