前几天看到用户投诉,还以为是ios系统bug,结果今天偶然自己测到了,开了静音模式,所有ios做过的creator项目都没声音了
但是看抖音跟其他游戏都是能放的
我昨天也遇到微信小游戏再IOS上没有声音了,cocos-v3.8.7,怎么开关静音都没用,关键别的小游戏有,还在查原因。
不知道跟微信基础库有没有关,我游戏以前IOS是有声音的,微信那边之前也有人碰到过了但是官方一直没复现给出解决方案。
这是一个非常经典的问题。产生这个现象的原因是 iOS 的音频会话( AVAudioSession )默认策略通常是 “Ambient” (环境音),这种模式下,App 的声音会受静音键(Mute Switch)控制。
要像其他游戏一样无视静音键播放声音,你需要将音频会话类别设置为 “Playback” 。这需要修改构建后的 iOS 原生代码。
以下是具体的解决步骤,适用于 Cocos Creator 2.x 和 3.x 版本:
核心解决方案:修改原生 iOS 代码
你需要修改构建出的 iOS 工程中的 AppController.mm 文件。
1. 找到文件
构建项目(Build)后,进入你的项目目录:
-
路径通常为:
build/jsb-link/frameworks/runtime-src/proj.ios_mac/ios/AppController.mm -
Cocos Creator 3.x (如果使用了 native 目录):
native/engine/ios/AppController.mm - 或者直接在 Xcode 中打开工程,在左侧目录树中找到
AppController.mm。
2. 引入头文件
在文件最顶部,确保引入了 AVFoundation :
Objective-C#import <AVFoundation/AVFoundation.h>
3. 修改 didFinishLaunchingWithOptions 方法
找到 didFinishLaunchingWithOptions 函数,在函数的 最开始 (或者在初始化 window 之前)加入以下代码:
`Objective-C- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// --- 开始添加的代码 ---
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
NSError *error = nil;
// 设置类别为 Playback。这种模式会忽略静音键,并且默认不会与后台音乐混合(会打断其他音乐)
[audioSession setCategory:AVAudioSessionCategoryPlayback error:&error];
// 激活 AudioSession
[audioSession setActive:YES error:&error];
// --- 结束添加的代码 ---
// ... 原有的代码 ...
return YES;
}`
进阶调整:关于与其他音乐混音
上面的 AVAudioSessionCategoryPlayback 有一个特性: 它会打断其他 App 的音乐(例如玩家正在听 Apple Music 或 Spotify) 。
如果你希望 无视静音键 ,同时 允许玩家后台听歌 (即你的游戏音效和玩家的背景音乐共存),你需要修改 setCategory 的参数:
Objective-C// 允许混音 (MixWithOthers) 且 无视静音键 (Playback) [audioSession setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error:&error];
注意: 开启混音模式后,你需要确保你的游戏在暂停或切后台时正确管理音频的暂停,否则声音可能会一直播放。
为什么其他引擎没问题?
Unity 或 Unreal 等引擎在导出 iOS 工程时,默认会将 Audio Session 设置为 Playback 模式,因为这是游戏的通行标准。Cocos Creator 默认保留了 iOS 系统的标准行为(即尊重静音键),把控制权留给了开发者去修改。
总结
-
静音键生效 是因为默认使用了
AVAudioSessionCategoryAmbient。 -
解决方法 是在
AppController.mm中将其改为AVAudioSessionCategoryPlayback。 -
修改时机 :每次重新构建(Build)iOS 工程时,如果选择了“覆盖(Overwrite)”原生工程,代码可能会被还原。建议将修改后的
AppController.mm放入自定义构建模板(Build Template)中,或者在构建后手动检查。
我可以帮你解释如何创建构建模板(Build Template),以防止下次构建时这段代码被覆盖吗?
ai回答,先记录一下
big 胆,王哲说了,不许用ai回答。还好王总不在