如何检测其他应用是否正在播放音乐?

2022-09-01 16:12:20

我正在制作一个游戏,并且我想检测在我的游戏运行时是否有其他人已经在播放音乐(或开始播放音乐)。如果是这样的话,我会淡出游戏中的音乐,继续播放音效。我正在使用 Unity 和 FMOD 进行音频播放。

据我所知,Android提供了两种不同的方法来做到这一点:AudioManager.isMusicActiveAudioManager.OnAudioFocusChangeListener

AudioManager.isMusicActive不适用于我的特定情况,因为 Unity/FMOD 寄存器本身的方式似乎会使这种情况始终返回 true

AudioManager.OnAudioFocusChangeListener让我检测另一个应用程序是否请求音频焦点,但无法检测我是否可以安全地再次请求它。

我不知道Unity / FMOD如何设置音频会话,但默认设置是播放声音,而不管在后台播放的任何其他内容。所以,如果我只知道是否有其他东西在玩,这将很容易!

有没有办法判断除了我自己的应用程序之外,是否有其他东西正在播放音乐?

注意:当我说音乐时,它也可能是有声读物,播客或最接近的等效物。

似乎有可能寻找任何正在进行的媒体播放通知,但这需要升级权限,这似乎对如此小的功能的要求太大了。

以下是一些解决方案的候选方案:

  • AudioFocusRequest.setAcceptsDelayedFocusGain 这可以在请求音频焦点时指定,但只是意味着我现在不需要焦点,以后也很好。但是,如果还有其他任何东西正在播放未“锁定”的音频,我将窃取音频焦点,停止该音频焦点,并在此过程中不向我提供进一步的信息。

  • AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK最初看起来很有希望,但是由于这取决于其他应用程序请求音频焦点以将自身指定为瞬态(即通知声音或类似声音),并且对我检测更长形式的外部音频播放没有任何好处。

  • BroadcastReceiver/MediaNotifications,这是Spotify的实现,但据我所知,这需要在我的应用程序中为我想要确认的每个玩家提供特定的支持,以及启用广播的用户。可能有效,但看起来很脆。


答案 1

要首先回答您的大胆问题,您可以尝试使用标志。排他性意味着没有其他可以播放的东西,因此应该返回AUDIOFOCUS_REQUEST_FAILED或AUDIOFOCUS_REQUEST_GRANTED这应该给你一个代理答案,以解决你的问题“除了我自己的应用程序播放音乐之外的东西”。requestAudioFocusAUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE

您是对的,听众并不是要告诉您是否可以安全地请求访问,但是他们可以告诉您何时可以安全地开始播放。只需在应用最初加载或置于前台时(假设它尚未播放音乐)发出请求即可。如果您被授予,请玩,如果没有,则不要玩。如果您没有立即访问,请不要担心,因为您可以有一个监听器,等待稍后授予您的访问权限(即在地图结束时几秒钟后发出方向,或者几分钟后当其他长期音频源停止时)。

据我所知,这是对生命周期的更长时间的看法。

应用启动后(或无论何时处于前台状态),请请求AUDIOFOCUS_GAIN。如果没有播放任何内容,您将获得音频焦点,并且可以开始播放。如果正在播放某些内容,则可能无法立即获得音频焦点,因此不应开始播放。如果您没有开始播放,请确保在FocusChangeListener中收听“AUDIOFOCUS_GAIN”。收到此消息意味着您可以开始玩了!

不要担心“锁定”他人。只要你在请求AUDIOFOCUS_GAIN时提出了合理的请求(这是合理的,因为你计划将音频用于你的游戏,并且你计划使用它超过 15 秒),那么从另一个应用接管音频是有意义的,因为你的应用正在前台,应该接管主音频。但是,在您的OnAudioFocusChangeListener中,您应该是一个好公民,并监听如果用户切换回OTHER应用程序或如果其他东西暂时弹出,您可能会发生的LOSS事件,您需要相应地暂停/静音或降低音量/躲避自己。

通过这种方式,你可以编码你的应用是否位于前端和中心,或者它是否被告知要安静和安静多长时间。这使您不必担心谁/什么/为什么/有多少其他应用程序退出,以及对音频执行某些操作,而是专注于简单地协调和响应音频管理器的指令,直到您不再关心(即.app退出等)。

我发现这两个链接对于理解基础知识以及应用程序应该如何相互尊重非常有用。

最后一个链接是世博会AV管理器。这并不是要将 Expo 作为解决方案,只是我觉得 Expo AV 代码运行良好,它是一个经过深思熟虑的示例,说明了在导航音频管理时可能遇到的条件组合,以及哪些代码/成员变量可能有助于跟踪所有这些条件。该文件中还有很多“Expo-ey”框架,这些事情可能会分散注意力和被忽略,但如果你只是看看,我认为那里有一些很好的灵感。acquireAudioFocusonAudioFocusChange

对于一些代码和一个很好的概述

了解生命周期背后的理念和基本原理,以及如何成为优秀的音频公民

来源:世博会视听经理

另外,作为最后一点,不要忘记做一个好公民,当你不需要它时放弃专注。即背景/前景,如果您的用户在游戏中关闭音乐等。


答案 2

推荐