在Playground与SKScene中检测AVAudioPlayer播放结束并连续播放MP3
在Playground + SKScene中实现AVAudioPlayer连续播放
当然有办法啦!虽然Playground和SKScene环境有点特殊,但利用AVAudioPlayer的委托方法完全能实现连续播放,我给你捋清楚具体怎么操作:
核心思路
我们需要借助AVAudioPlayerDelegate的audioPlayerDidFinishPlaying(_:successfully:)方法来监听单段音频播放完成,然后自动触发下一段的播放。同时要注意Playground的异步执行特性,避免Playground提前终止。
具体步骤及代码示例
准备工作:遵循委托协议并维护播放状态
让你的SKScene子类遵循AVAudioPlayerDelegate,同时定义音频文件路径数组、当前播放索引和当前的AVAudioPlayer实例:import SpriteKit import AVFoundation import PlaygroundSupport class AudioPlayScene: SKScene, AVAudioPlayerDelegate { // 存储音频文件的路径数组(假设你的mp3都在Playground的资源里) let audioPaths = ["audio1.mp3", "audio2.mp3", "audio3.mp3"] var currentAudioIndex = 0 var currentPlayer: AVAudioPlayer? }配置Playground的异步执行
在Playground的入口处,一定要设置needsIndefiniteExecution = true,否则Playground会在音频开始播放前就结束运行:PlaygroundPage.current.needsIndefiniteExecution = true实现播放初始化和委托方法
添加一个方法来初始化并播放当前索引的音频,然后在委托方法里触发下一段播放:extension AudioPlayScene { func startPlaying() { guard currentAudioIndex < audioPaths.count else { // 所有音频播放完成,可做收尾处理 PlaygroundPage.current.finishExecution() return } let audioName = audioPaths[currentAudioIndex] guard let url = Bundle.main.url(forResource: audioName, withExtension: nil) else { print("找不到音频文件:\(audioName)") currentAudioIndex += 1 startPlaying() return } do { currentPlayer = try AVAudioPlayer(contentsOf: url) currentPlayer?.delegate = self currentPlayer?.play() print("正在播放:\(audioName)") } catch { print("初始化播放器失败:\(error.localizedDescription)") currentAudioIndex += 1 startPlaying() } } // 委托方法:监听音频播放完成 func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) { if flag { print("播放完成:\(audioPaths[currentAudioIndex])") currentAudioIndex += 1 startPlaying() // 播放下一段 } else { print("播放失败,跳过当前音频") currentAudioIndex += 1 startPlaying() } } }启动场景并开始播放
最后创建场景实例并启动播放:let scene = AudioPlayScene(size: CGSize(width: 400, height: 300)) scene.startPlaying() PlaygroundPage.current.liveView = scene
注意事项
- 确保你的mp3文件已经添加到Playground的资源文件夹中,并且文件名和数组里的一致。
- 如果在SKScene的生命周期方法(比如
didMove(to:))里启动播放,记得也要设置PlaygroundPage.current.needsIndefiniteExecution = true。 - 播放完成后如果不需要Playground继续运行,可以调用
PlaygroundPage.current.finishExecution()来终止。
内容的提问来源于stack exchange,提问作者mikro098
相关产品推荐
相关产品推荐

