mirror of
https://github.com/HaishinKit/HaishinKit.swift.git
synced 2026-05-07 20:12:28 +00:00
52 lines
1.7 KiB
Swift
52 lines
1.7 KiB
Swift
@preconcurrency import AVFoundation
|
|
|
|
/// An object that provides the interface to control audio playback.
|
|
public final actor AudioPlayer {
|
|
private var connected: [AudioPlayerNode: Bool] = [:]
|
|
private var audioEngine: AVAudioEngine?
|
|
private var playerNodes: [AudioPlayerNode: AVAudioPlayerNode] = [:]
|
|
|
|
/// Create an audio player object.
|
|
public init(audioEngine: AVAudioEngine) {
|
|
self.audioEngine = audioEngine
|
|
}
|
|
|
|
func isConnected(_ playerNode: AudioPlayerNode) -> Bool {
|
|
return connected[playerNode] == true
|
|
}
|
|
|
|
func connect(_ playerNode: AudioPlayerNode, format: AVAudioFormat?) {
|
|
guard let audioEngine, let avPlayerNode = playerNodes[playerNode] else {
|
|
return
|
|
}
|
|
if let format {
|
|
audioEngine.connect(avPlayerNode, to: audioEngine.outputNode, format: format)
|
|
if !audioEngine.isRunning {
|
|
try? audioEngine.start()
|
|
}
|
|
connected[playerNode] = true
|
|
} else {
|
|
if audioEngine.isRunning {
|
|
audioEngine.stop()
|
|
}
|
|
audioEngine.disconnectNodeOutput(avPlayerNode)
|
|
connected[playerNode] = nil
|
|
}
|
|
}
|
|
|
|
func detach(_ playerNode: AudioPlayerNode) {
|
|
if let playerNode = playerNodes[playerNode] {
|
|
audioEngine?.detach(playerNode)
|
|
}
|
|
playerNodes[playerNode] = nil
|
|
}
|
|
|
|
func makePlayerNode() -> AudioPlayerNode {
|
|
let avAudioPlayerNode = AVAudioPlayerNode()
|
|
audioEngine?.attach(avAudioPlayerNode)
|
|
let playerNode = AudioPlayerNode(player: self, playerNode: avAudioPlayerNode)
|
|
playerNodes[playerNode] = avAudioPlayerNode
|
|
return playerNode
|
|
}
|
|
}
|