
一份代码跑遍iOS和macOSSoundManager如何统一AVAudioPlayer与NSSound【免费下载链接】SoundManagerSimple sound and music player class for playing audio on Mac and iPhone项目地址: https://gitcode.com/gh_mirrors/so/SoundManagerSoundManager 是一款轻量的 Objective-C 声音播放类同一份源码即可运行在 iOS 和 macOS 上自动统一 AVAudioPlayer 与 NSSound 两种音频后端提供音效与背景音乐统一控制、淡入淡出、循环播放等完整能力是 Mac 与 iPhone 开发者实现多平台音频功能的最简方案。为什么 iOS 和 macOS 的音频代码很难通用很多开发者在做一码双端项目时都会被音频模块卡住iOS 端依赖 AVFoundation 框架的AVAudioPlayer还要处理AVAudioSession音频会话、后台播放等逻辑老版本 macOS10.6 Snow Leopard 及更早只能用 Cocoa 框架的NSSoundAPI 完全不同两者的循环播放、播放完成回调、声道控制等接口细节也各不相同。如果直接写原生代码往往需要维护两套逻辑甚至用#if写满整个音频管理器。SoundManager 的思路是把平台差异收敛到最薄的适配层里对外只暴露一套 API。SoundManager 如何统一两套音频 APISoundManager 核心只有两个文件SoundManager/SoundManager.h与SoundManager/SoundManager.m约 600 行代码却完整解决了上述所有差异。第 1 步头文件里的平台裁决打开SoundManager/SoundManager.h开头几行条件编译就是整个库的精髓#if TARGET_OS_IPHONE #define SM_USE_AV_AUDIO_PLAYER 1 // iPhone/iPad一律用 AVAudioPlayer #else // macOS 部署目标 ≥ 10.7Lion也改用 AVAudioPlayer // 只有更老的 macOS 才回落到 NSSound #endif #if SM_USE_AV_AUDIO_PLAYER #define SM_SOUND AVAudioPlayer #else #define SM_SOUND NSSound #endifSM_SOUND宏让后续所有代码都面向一个抽象播放器类型编写平台选择只在这一处发生运行平台部署目标实际使用的底层类iOS任意AVAudioPlayermacOS≥ 10.7LionAVAudioPlayermacOS 10.7NSSound第 2 步Sound 类抹平 API 差异Sound类是 SoundManager 对单个音频文件的封装内部持有一个SM_SOUND实例它悄悄处理了多处细节差异播放完成回调AVAudioPlayer 的委托方法是audioPlayerDidFinishPlaying:successfully:NSSound 是sound:didFinishPlaying:Sound 类把两者统一触发同一个SoundDidFinishPlayingNotification通知循环播放AVAudioPlayer 用numberOfLoops -1表示无限循环NSSound 用布尔属性loopsSound.looping属性则把两者归一为一个 YES/NO立体声平移pan老版 macOS 的 NSSound 不支持声道平移Sound 类自动退化为空实现代码不会崩溃预加载预热prepareToPlay在 iOS 上调用prepareToPlay预解码在老 macOS 上则用静音播放再立即停止的技巧触发音频子系统初始化消除首次播放的卡顿。第 3 步iPhone 后台音乐的特殊处理allowsBackgroundMusic属性只在 iOS 上有意义设为 YES 时SoundManager 会把AVAudioSession类别切换为AVAudioSessionCategoryAmbient让你的音乐和用户正在听的 iPod 音乐共存不打架在 macOS 上该属性则是安全空操作。上图仓库内置 iPhone 示例工程Examples/iPhone Example/的启动屏图片快速上手两行代码统一播放音效和音乐一键集成步骤获取源码如需 clone 仓库地址为 https://gitcode.com/gh_mirrors/so/SoundManager把SoundManager/SoundManager.h和SoundManager/SoundManager.m拖入 Xcode 工程iOS 工程或部署目标 ≥ 10.7 的 Mac 工程需添加AVFoundation框架注意自 1.4 版本起要求 ARC自动引用计数非 ARC 工程需给SoundManager.m加上-fobjc-arc编译标志也可以通过 SoundManager.podspec.json 提供的 Pod 规格文件用 CocoaPods 安装支持 iOS 4.3 / OS X 10.6。最简使用示例仓库中的 iPhone 示例Examples/iPhone Example/SoundManagerExample/SoundManagerExampleViewController.m展示了标准用法核心只有几行// 启动时预热消除首次播放延迟 [[SoundManager sharedManager] prepareToPlay]; // 循环播放背景音乐自动交叉淡入淡出 [[SoundManager sharedManager] playMusic:track1 looping:YES]; // 播放音效 [[SoundManager sharedManager] playSound:sound1 looping:NO]; // 停止音乐默认淡出 [[SoundManager sharedManager] stopMusic];macOS 示例Examples/Mac Example/SoundManagerExample/SoundManagerExampleAppDelegate.m的业务代码与 iPhone 版几乎逐行一致——这正是一份代码跑遍两个平台的最佳证明。功能清单淡入淡出、循环与音量均衡SoundManager 内置的音频能力对休闲应用和游戏已经相当够用淡入淡出fadeIn:、fadeOut:、fadeTo:duration:内部用 60fps 的 NSTimer 平滑过渡音乐切换时自动交叉淡入淡出crossfade循环播放音效和音乐都支持looping:参数音量体系baseVolume可在创建时对不同文件做响度均衡volume在其基础上统一调节避免某些音效特别炸耳的麻烦声道平移pan属性取值 -1.0 到 1.0实现声音的空间定位老版 macOS 自动降级⏱播放进度duration/currentTime属性可读可写把currentTime设为 0 即可倒带完成回调既可用completionHandler块回调也可监听SoundDidFinishPlayingNotification通知多对象监听互不干扰智能预热prepareToPlay自动扫描包内的 caf / m4a / mp4 / mp3 / wav / aif 文件并预加载其一。音频格式推荐用 afconvert 生成 .caf 文件iOS 对音频格式比较挑剔官方 README 建议背景音效统一使用.caf格式用系统自带的afconvert命令行工具即可生成# 背景音乐立体声 AAC /usr/bin/afconvert -f caff -d aac 输入文件 输出文件.caf # 短音效立体声 IMA4 /usr/bin/afconvert -f caff -d ima4 输入文件 输出文件.caf示例工程中就附带了sound1.caf、sound2.caf音效和track1.caf、track2.caf音乐四个文件位于Examples/Sounds/可直接参考。适合谁用总结SoundManager 采用宽松的zlib 许可证见 LICENCE.md当前版本 1.4.2适合以下场景需要同一份音频代码同时跑在 iPhone 和 Mac上的项目只需要播放/暂停/淡入淡出等基础能力不需要复杂音频引擎如实时混音、效果器链的休闲应用希望代码足够小、可完全读懂并自由修改的团队。如果未来需要 3D 音频或复杂混音AVAudioEngine 是更好的选择但对于把声音放出来这件事SoundManager 用不到 600 行代码给出了一个干净、优雅且真正跨平台的答案。【免费下载链接】SoundManagerSimple sound and music player class for playing audio on Mac and iPhone项目地址: https://gitcode.com/gh_mirrors/so/SoundManager创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考