Skip to content

Instantly share code, notes, and snippets.

@standinga
Created January 23, 2019 01:29
Show Gist options
  • Save standinga/f79232adb15e1f867ad1637f47c61003 to your computer and use it in GitHub Desktop.
Save standinga/f79232adb15e1f867ad1637f47c61003 to your computer and use it in GitHub Desktop.
multiple AVAudioPlayerNode observing lastRenderTime
//
// AudioPlayer.swift
// AudioPlayerNodes
//
// Created by michal on 23/01/2019.
// Copyright © 2019 michal. All rights reserved.
//
import AVFoundation
class AudioPlayer {
var audioFile:AVAudioFile
var engine:AVAudioEngine
var playerNodes = [AVAudioPlayerNode]()
var mixer: AVAudioMixerNode
var timer: Timer!
init (_ url: URL) {
audioFile = try! AVAudioFile(forReading: url)
engine = AVAudioEngine()
mixer = AVAudioMixerNode()
engine.attach(mixer)
engine.connect(mixer, to: engine.outputNode, format: nil)
createNodes()
}
private func createNodes() {
for _ in 0...3 {
let node = AVAudioPlayerNode()
playerNodes += [node]
}
}
func start() {
for node in playerNodes {
engine.attach(node)
engine.connect(node, to: mixer, format: nil)
node.scheduleFile(audioFile, at: nil, completionHandler: nil)
try! engine.start()
}
self.timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) {[unowned self] timer in
for node in self.playerNodes {
guard let nodeTime = node.lastRenderTime,
let playerTime = node.playerTime(forNodeTime: nodeTime) else {
continue
}
let secs = Double(playerTime.sampleTime) / playerTime.sampleRate
print(secs)
}
}
DispatchQueue.global().async { [unowned self] in
for node in self.playerNodes {
sleep(1)
node.play()
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment