Compare commits

...

2 Commits

Author SHA1 Message Date
tanhakabir 7d65841f1c fix recursive polling logic 2021-04-16 10:04:33 -07:00
tanhakabir 17e0ee5dd8 Update example app to include a radio stream link (#89)
* update links

* update example app to show podcast, soundbite, and radio
2021-04-06 21:16:13 -07:00
4 changed files with 24 additions and 12 deletions
@@ -72,8 +72,8 @@
<rect key="frame" x="16" y="60" width="343" height="32"/>
<segments>
<segment title="Soundbite"/>
<segment title="Acquired"/>
<segment title="Y Combinator"/>
<segment title="Podcast"/>
<segment title="Radio"/>
</segments>
<connections>
<action selector="audioSelected:" destination="vXZ-lx-hvc" eventType="valueChanged" id="oYE-yq-348"/>
+7 -7
View File
@@ -13,18 +13,18 @@ struct AudioInfo: Hashable {
var urls: [URL] = [URL(string: "https://www.fesliyanstudios.com/musicfiles/2019-04-23_-_Trusted_Advertising_-_www.fesliyanstudios.com/15SecVersion2019-04-23_-_Trusted_Advertising_-_www.fesliyanstudios.com.mp3")!,
URL(string: "https://chtbl.com/track/18338/traffic.libsyn.com/secure/acquired/acquired_-_armrev_2.mp3?dest-id=376122")!,
URL(string: "https://backtracks.fm/ycombinator/pr/0f685f72-29b1-11e9-9bcf-0ece7a7d2472/111---jake-klamka-and-kevin-hale---y-combinator.mp3?s=1&amp;sd=1&amp;u=1549423185")!]
URL(string: "https://ice6.somafm.com/groovesalad-256-mp3")!]
var url: URL {
switch index {
case 0:
return URL(string: "https://www.fesliyanstudios.com/musicfiles/2019-04-23_-_Trusted_Advertising_-_www.fesliyanstudios.com/15SecVersion2019-04-23_-_Trusted_Advertising_-_www.fesliyanstudios.com.mp3")!
return urls[0]
case 1:
return URL(string: "https://chtbl.com/track/18338/traffic.libsyn.com/secure/acquired/acquired_-_armrev_2.mp3?dest-id=376122")!
return urls[1]
case 2:
return URL(string: "https://backtracks.fm/ycombinator/pr/0f685f72-29b1-11e9-9bcf-0ece7a7d2472/111---jake-klamka-and-kevin-hale---y-combinator.mp3?s=1&amp;sd=1&amp;u=1549423185")!
return urls[2]
default:
return URL(string: "https://www.fesliyanstudios.com/musicfiles/2019-04-23_-_Trusted_Advertising_-_www.fesliyanstudios.com/15SecVersion2019-04-23_-_Trusted_Advertising_-_www.fesliyanstudios.com.mp3")!
return urls[0]
}
}
@@ -33,9 +33,9 @@ struct AudioInfo: Hashable {
case 0:
return "Soundbite"
case 1:
return "Acquired"
return "Podcast"
case 2:
return "Y Combinator"
return "Radio"
default:
return "Soundbite"
}
+1
View File
@@ -173,6 +173,7 @@ class AudioEngine: AudioEngineProtocol {
Timer.scheduledTimer(withTimeInterval: timeInterval, repeats: false) { [weak self] (timer: Timer) in
guard let self = self else { return }
guard self.playingStatus != .ended else {
// Log.test("END TIMER")
self.delegate = nil
return
}
+14 -3
View File
@@ -71,6 +71,7 @@ class AudioStreamEngine: AudioEngine {
private var numberOfBuffersScheduledInTotal = 0 {
didSet {
// Log.test(numberOfBuffersScheduledInTotal)
Log.debug("number of buffers scheduled in total: \(numberOfBuffersScheduledInTotal)")
if numberOfBuffersScheduledInTotal == 0 {
pause()
@@ -86,6 +87,7 @@ class AudioStreamEngine: AudioEngine {
private var numberOfBuffersScheduledFromPoll = 0 {
didSet {
if numberOfBuffersScheduledFromPoll > MAX_POLL_BUFFER_COUNT {
// Log.test("🛑 🛑 STOP POLLING")
shouldPollForNextBuffer = false
}
@@ -149,7 +151,7 @@ class AudioStreamEngine: AudioEngine {
guard let self = self else { return }
guard self.playingStatus != .ended else { return }
self.pollForNextBufferRecursive()
self.pollForNextBuffer()
self.updateNetworkBufferRange()
self.updateNeedle()
self.updateIsPlaying()
@@ -162,9 +164,16 @@ class AudioStreamEngine: AudioEngine {
//Called when
//1. First time audio is finally parsed
//2. When we run to the end of the network buffer and we're waiting again
private func pollForNextBufferRecursive() {
private func pollForNextBuffer() {
guard shouldPollForNextBuffer else { return }
// Log.test("POLL INIT")
pollForNextBufferRecursive()
}
private func pollForNextBufferRecursive() {
// Log.test("POLL")
do {
var nextScheduledBuffer: AVAudioPCMBuffer! = try converter.pullBuffer()
numberOfBuffersScheduledFromPoll += 1
@@ -174,15 +183,17 @@ class AudioStreamEngine: AudioEngine {
queue.async { [weak self] in
if #available(iOS 11.0, *) {
// to make sure the pcm buffers are properly free'd from memory we need to nil them after the player has used them
self?.playerNode.scheduleBuffer(nextScheduledBuffer, completionCallbackType: .dataRendered, completionHandler: { (_) in
self?.playerNode.scheduleBuffer(nextScheduledBuffer, completionCallbackType: .dataConsumed, completionHandler: { (_) in
nextScheduledBuffer = nil
self?.numberOfBuffersScheduledInTotal -= 1
// Log.test("POLL DATA RENDERED")
self?.pollForNextBufferRecursive()
})
} else {
self?.playerNode.scheduleBuffer(nextScheduledBuffer) {
nextScheduledBuffer = nil
self?.numberOfBuffersScheduledInTotal -= 1
// Log.test("POLL OLD")
self?.pollForNextBufferRecursive()
}
}