AVAudioEngine 在模拟器上播放音频 - 但不在实体 Apple Watch 上播放

AVAudioEngine playing audio on simulator - but not on physical Apple Watch

提问人:Womble Tristes 提问时间:10/18/2023 更新时间:10/18/2023 访问量:13

问:

给定一个类,该类根据给定的 BPM 值重复播放名为“WoodClaves.aif”的文件。

import Foundation
import SwiftUI
import AVFoundation

class MetronomTimerModel: ObservableObject {

    var bpm: Double = 120  // Default BPM
    @Published var beatCounterIndex = 0
    
    var metronomeTimer: Timer?
    
    var audioPlayerNode:AVAudioPlayerNode
    var audioFile:AVAudioFile
    var audioEngine:AVAudioEngine

    init() {
        audioFile = try! AVAudioFile(forReading: Bundle.main.url(forResource: "WoodClaves", withExtension: "aif")!)
         
         audioPlayerNode = AVAudioPlayerNode()
         
         audioEngine = AVAudioEngine()
         audioEngine.attach(self.audioPlayerNode)
         
         audioEngine.connect(audioPlayerNode, to: audioEngine.mainMixerNode, format: audioFile.processingFormat)
        
        do {
            try AVAudioSession.sharedInstance().setCategory(.playback)
        } catch let error {
            print(error.localizedDescription)
        }
        
        

         try! audioEngine.start()
    }

    func startMetronome() {
        
        self.bpm = Double(UserDefaults.standard.integer(forKey: "bpm"))

           let interval = 60.0 / bpm

           metronomeTimer = Timer.scheduledTimer(withTimeInterval: interval, repeats: true) { timer in
               if self.beatCounterIndex == 0 {
                   self.playTick(bpm: Int(self.bpm))
               } else {
                   //...
               }
               // Increment the beatCounter and reset it after each 4 measure
               self.beatCounterIndex = (self.beatCounterIndex + 1) % 4
           }

        // Run the timer on the main run loop
                if let metronomeTimer = metronomeTimer {
                    RunLoop.main.add(metronomeTimer, forMode: .common)
                }
       }
    
    // Function to stop the metronome, invalidates timer and resets beat counter
        func stopMetronome() {
            //...
        }
    
    
    func playTick(bpm: Int) {
        do {
            
            let buffer = generateBuffer(forBpm: bpm)

            self.audioPlayerNode.play()

            self.audioPlayerNode.scheduleBuffer(buffer, at: nil, options: .loops, completionHandler: nil)
            
        } catch let error {
            print(error.localizedDescription)
        }
    }
    
    func stopTicking() {
        audioPlayerNode.stop()
    }
    
    func generateBuffer(forBpm bpm: Int) -> AVAudioPCMBuffer {
        audioFile.framePosition = 0
        let periodLength = AVAudioFrameCount(audioFile.processingFormat.sampleRate * 60 / Double(bpm))
        let buffer = AVAudioPCMBuffer(pcmFormat: audioFile.processingFormat, frameCapacity: periodLength)
        try! audioFile.read(into: buffer!)
        buffer?.frameLength = periodLength
        return buffer!
    }

}

只要我在模拟器中运行它,它就可以正常工作。但是,当我在物理设备上运行它时,没有音频输出,也没有任何错误。

静音模式已关闭。

以这种方式购买,如果我使用 AVAudioPlayer,也会出现同样的问题。

怎么了?

Swift 苹果手表 watchOS AVAudioEngine

评论


答: 暂无答案