Skip to content

Instantly share code, notes, and snippets.

@standinga
Created April 16, 2019 23:10
Show Gist options
  • Save standinga/b9287a1c6f4ecc1f952e9d14b36aecaf to your computer and use it in GitHub Desktop.
Save standinga/b9287a1c6f4ecc1f952e9d14b36aecaf to your computer and use it in GitHub Desktop.
Playground AVPlayer playing remote mp3 with with sounds played on top of that file
import AVFoundation
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
class AudioPlayer {
var topAudioFiles: [AVAudioFile] = []
var engine:AVAudioEngine
var topAudioAudioNodes = [AVAudioPlayerNode]()
var mixer: AVAudioMixerNode
var timer: Timer!
var urls: [URL] = []
var player: AVPlayer!
var times = [NSValue]()
var delays = [UInt64]()
init (_ url: URL, urls: [URL] = []) {
self.urls = urls
topAudioFiles = urls.map { try! AVAudioFile(forReading: $0) }
player = AVPlayer(url: url)
engine = AVAudioEngine()
mixer = AVAudioMixerNode()
engine.attach(mixer)
engine.connect(mixer, to: engine.outputNode, format: nil)
initTimeOffsets()
initTopAudioNodes()
try! engine.start()
}
// play beeps every 1 bar @ 124 bpm (1936ms offset)
func initTimeOffsets() {
for i in 1...50 {
let t = Double(1936 * i) / 1000.0
times += [NSValue(time: CMTime(seconds: t, preferredTimescale: 600))]
}
for i in 1...100 {
delays += [UInt64(i * 1936 / 1000 * 44100)]
}
}
func initTopAudioNodes() {
for _ in topAudioFiles {
topAudioAudioNodes += [AVAudioPlayerNode()]
}
for node in topAudioAudioNodes {
engine.attach(node)
engine.connect(node, to: mixer, format: nil)
}
}
func playWithAudioPlayerAndNodes() {
player.play()
var i = 1
player.addBoundaryTimeObserver(forTimes: times, queue: nil) {
let index = i % self.topAudioAudioNodes.count
let node = self.topAudioAudioNodes[index]
node.scheduleFile(self.topAudioFiles[index], at: nil, completionHandler: nil)
node.play()
i += 1
}
}
}
let bundle = Bundle.main
let beepLow = bundle.url(forResource: "beeplow", withExtension: "wav")!
let beepMid = bundle.url(forResource: "beepmid", withExtension: "wav")!
let backgroundAudio = URL(string: "https://www.xxxx.com/xxxx/mp3/xxxx-xxxx-1.mp3")!
let audioPlayer = AudioPlayer(backgroundAudio, urls: [beepLow, beepMid])
audioPlayer.playWithAudioPlayerAndNodes()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment