MonoTouch:播放声音

Posted

技术标签:

【中文标题】MonoTouch:播放声音【英文标题】:MonoTouch: Playing sound 【发布时间】:2012-03-28 09:49:19 【问题描述】:

当用户点击特定按钮时,我正在尝试播放短声。但问题是我总是收到未设置为实例对象的对象引用。表示空!

我首先尝试了 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();

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

【问题讨论】:

注意:上面的前 3 行在 iOS7 中已被弃用(Initialize、Category、SetActive)......没有它们也很好。 【参考方案1】:

关于使用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 在播放声音时不会收集实例。

【讨论】:

在回调发生之前播放器不会被释放。操作系统有一个对回调 lambda 的实时引用(它必须在完成播放时实际执行回调)。在该引用消失之前,玩家本身仍在活动对象图中。在调用 player.Dispose() 之后,玩家有资格获得 GC,但在那之前没有。【参考方案2】:

您的代码看起来是正确的(我对比了可以播放音频的代码here)。

可能的问题是音频文件未以某种方式包含在应用程序包中。您可以使用以下代码轻松检查它:

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

【讨论】:

太棒了!你说的对。我试过你的方法,我发现这个文件不存在。所以我再次检查了文件,现在我看到它没有被标记为内容。我改变它,但它不会工作。我删除了obj文件夹,问题终于解决了。谢谢。 仍然对我不起作用。声音文件存在。我设置了一个刹车点。我的sound.PlaySystemSound() 行被击中,sound 是 SystemSound 的有效实例。我的设备音量一直调高。我的声音没有播放。时期。我开始非常讨厌 Xamarin.iOS,因为它几乎从不做它所说的事情,即使在最愚蠢的简单场景中也是如此。【参考方案3】:

在大多数情况下,File 不存在。如果您像我一样,并且确保该文件存在。确保以下几点:

    文件的路径应该是relative 到您的班级(即:Sounds\beep.wav)(绝对路径在模拟器上对我不起作用) 确保在class level 中定义SoundSystem。这是因为 MT 有一个非常激进的Garbage Collector,甚至可以在你的SoundSystem 开始播放之前就处理掉它。看到这个question

【讨论】:

以上是关于MonoTouch:播放声音的主要内容,如果未能解决你的问题,请参考以下文章

使用 Monotouch 播放默认 iOS 系统声音

使用 AudioQueue 和 Monotouch 静态声音录制

montouch 检测声音何时播放完毕

Monotouch 停止播放音频剪辑

C# 播放声音的方法?

没有播放声音