You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Playground与SKScene中检测AVAudioPlayer播放结束并连续播放MP3

在Playground + SKScene中实现AVAudioPlayer连续播放

当然有办法啦!虽然Playground和SKScene环境有点特殊,但利用AVAudioPlayer的委托方法完全能实现连续播放,我给你捋清楚具体怎么操作:

核心思路

我们需要借助AVAudioPlayerDelegate的audioPlayerDidFinishPlaying(_:successfully:)方法来监听单段音频播放完成,然后自动触发下一段的播放。同时要注意Playground的异步执行特性,避免Playground提前终止。

具体步骤及代码示例

  1. 准备工作:遵循委托协议并维护播放状态
    让你的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?
    }
    
  2. 配置Playground的异步执行
    在Playground的入口处,一定要设置needsIndefiniteExecution = true,否则Playground会在音频开始播放前就结束运行:

    PlaygroundPage.current.needsIndefiniteExecution = true
    
  3. 实现播放初始化和委托方法
    添加一个方法来初始化并播放当前索引的音频,然后在委托方法里触发下一段播放:

    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()
            }
        }
    }
    
  4. 启动场景并开始播放
    最后创建场景实例并启动播放:

    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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:25:39