diff --git a/AudioExample/AudioExample.xcodeproj/xcshareddata/xcschemes/AudioExample.xcscheme b/AudioExample/AudioExample.xcodeproj/xcshareddata/xcschemes/AudioExample.xcscheme
index 8726906..bc22a65 100644
--- a/AudioExample/AudioExample.xcodeproj/xcshareddata/xcschemes/AudioExample.xcscheme
+++ b/AudioExample/AudioExample.xcodeproj/xcshareddata/xcschemes/AudioExample.xcscheme
@@ -75,6 +75,11 @@
value = ""
isEnabled = "YES">
+
+
0 {
self.expectedContentLength = .length(value: contentLength)
}
+ streamState.outputStream?.open()
}
internal func didReceive(data: Data, response: HTTPURLResponse?) {
underlyingQueue.async { [weak self] in
guard let self = self else { return }
self.outputStreamWriter.storeReceived(data: data)
- if let outputStream = self.streamState.outputStream, outputStream.hasSpaceAvailable {
- let writtenBytes = self.outputStreamWriter.writeData(on: outputStream, bufferSize: self.bufferSize)
- self.checkEndOfFile(stream: outputStream, writtenBytes: writtenBytes)
+ if let outputStream = self.streamState.outputStream, outputStream.streamStatus == .open {
+ if outputStream.hasSpaceAvailable {
+ let writtenBytes = self.outputStreamWriter.writeData(on: outputStream, bufferSize: self.bufferSize)
+ self.checkEndOfFile(stream: outputStream, writtenBytes: writtenBytes)
+ }
}
}
$streamState.read { state in
diff --git a/AudioStreaming/Core/Network/NetworkSessionDelegate.swift b/AudioStreaming/Core/Network/NetworkSessionDelegate.swift
index a78f717..55a4ff8 100644
--- a/AudioStreaming/Core/Network/NetworkSessionDelegate.swift
+++ b/AudioStreaming/Core/Network/NetworkSessionDelegate.swift
@@ -41,9 +41,9 @@ internal final class NetworkSessionDelegate: NSObject, URLSessionDataDelegate {
}
//extension NetworkSessionDelegate: URLSessionTaskDelegate {
-//
+//
// func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
// completionHandler(.performDefaultHandling, nil)
// }
-//
+//
//}
diff --git a/AudioStreaming/Core/Network/NetworkingClient.swift b/AudioStreaming/Core/Network/NetworkingClient.swift
index 68f4d53..2bb59ea 100644
--- a/AudioStreaming/Core/Network/NetworkingClient.swift
+++ b/AudioStreaming/Core/Network/NetworkingClient.swift
@@ -18,7 +18,9 @@ extension URLSessionConfiguration {
static var networkingConfiguration: URLSessionConfiguration {
let configuration = URLSessionConfiguration.default
configuration.networkServiceType = .avStreaming
+ configuration.requestCachePolicy = .reloadIgnoringCacheData
configuration.urlCache = nil
+ configuration.httpCookieStorage = nil
return configuration
}
}
diff --git a/AudioStreaming/Core/Network/OutputStreamWriter.swift b/AudioStreaming/Core/Network/OutputStreamWriter.swift
index 98fa61a..dd84eca 100644
--- a/AudioStreaming/Core/Network/OutputStreamWriter.swift
+++ b/AudioStreaming/Core/Network/OutputStreamWriter.swift
@@ -7,8 +7,10 @@
final class OutputStreamWriter {
/// The accumulated data received from the URLSession
private var dataReceived = Data()
- /// Keeps a track of the written bytes in the output stream
- private var bytesWritten: Int = 0
+ /// Keeps track of the total written bytes in the output stream
+ private var totalBytesWritten: Int = 0
+ /// Keeps tracks of the index that bytes were written in the output stream
+ private var byteIndex: Int = 0
/// Write the data on the `OutputStream`
///
@@ -20,12 +22,12 @@ final class OutputStreamWriter {
guard !dataReceived.isEmpty else { return 0 }
var bytes = dataReceived.getBytes { $0 }
/// offset the buffer by the number of written bytes
- bytes += bytesWritten
+ bytes += byteIndex
let dataCount = dataReceived.count
// get the count of bytes to be written, restrict to maximum of `bufferSize`
- let count = (dataCount - bytesWritten >= bufferSize)
+ let count = (dataCount - byteIndex >= bufferSize)
? bufferSize
- : dataCount - bytesWritten
+ : dataCount - byteIndex
guard count > 0 else {
return 0
}
@@ -34,10 +36,20 @@ final class OutputStreamWriter {
defer { buffer.deallocate() }
memcpy(buffer, bytes, count)
- bytesWritten += stream.write(buffer, maxLength: count)
- return bytesWritten
+ let written = stream.write(buffer, maxLength: count)
+ byteIndex += written
+ if written > 0 && dataReceived.count > written {
+ dataReceived.removeFirst(written)
+ byteIndex -= written
+ }
+
+ totalBytesWritten += written
+ return totalBytesWritten
}
+ /// Stores the given data
+ ///
+ /// - parameter data: A `Data` object as received from a network request.
func storeReceived(data: Data) {
self.dataReceived.append(data)
}
diff --git a/AudioStreaming/Streaming/AudioSource/AudioEntry.swift b/AudioStreaming/Streaming/AudioSource/AudioEntry.swift
index 538ebc8..22cd8f5 100644
--- a/AudioStreaming/Streaming/AudioSource/AudioEntry.swift
+++ b/AudioStreaming/Streaming/AudioSource/AudioEntry.swift
@@ -41,11 +41,11 @@ public class AudioEntry {
var packetCount: Double = 0
var packetDuration: Double {
- return Double(audioStreamFormat.basicStreamDescription.mFramesPerPacket) / Double(sampleRate)
+ return Double(audioStreamFormat.mFramesPerPacket) / Double(sampleRate)
}
/// The sample rate from the `audioStreamFormat`
var sampleRate: Float {
- Float(audioStreamFormat.basicStreamDescription.mSampleRate)
+ Float(audioStreamFormat.mSampleRate)
}
var framesState: EntryFramesState
@@ -54,7 +54,7 @@ public class AudioEntry {
var audioDataOffset: UInt64 = 0
var audioDataByteCount: UInt64?
- var audioStreamFormat = AVAudioFormat()
+ var audioStreamFormat = AudioStreamBasicDescription()
private var avaragePacketByteSize: Double {
let packets = processedPacketsState
@@ -78,19 +78,20 @@ public class AudioEntry {
}
func calculatedBitrate() -> Double {
+ lock.lock(); defer { lock.unlock() }
let packets = processedPacketsState
if packetDuration > 0 {
if packets.count > estimationMinPacketsPreferred ||
- (audioStreamFormat.basicStreamDescription.mBytesPerFrame == 0 && packets.count > estimationMinPackets) {
+ (audioStreamFormat.mBytesPerFrame == 0 && packets.count > estimationMinPackets) {
return avaragePacketByteSize / packetDuration * 8
}
}
- return (Double(audioStreamFormat.basicStreamDescription.mBytesPerFrame) * audioStreamFormat.basicStreamDescription.mSampleRate) * 8
+ return (Double(audioStreamFormat.mBytesPerFrame) * audioStreamFormat.mSampleRate) * 8
}
func progressInFrames() -> Float {
lock.lock(); defer { lock.unlock() }
- return (seekTime + Float(audioStreamFormat.basicStreamDescription.mSampleRate)) + Float(framesState.played)
+ return (seekTime + Float(audioStreamFormat.mSampleRate)) + Float(framesState.played)
}
func duration() -> Double {
diff --git a/AudioStreaming/Streaming/AudioSource/RemoteAudioSource.swift b/AudioStreaming/Streaming/AudioSource/RemoteAudioSource.swift
index 949d167..dc84f10 100644
--- a/AudioStreaming/Streaming/AudioSource/RemoteAudioSource.swift
+++ b/AudioStreaming/Streaming/AudioSource/RemoteAudioSource.swift
@@ -208,6 +208,7 @@ public class RemoteAudioSource: NSObject, AudioStreamSource {
private func buildUrlRequest(with url: URL, seekIfNeeded seekOffset: Int) -> URLRequest {
var urlRequest = URLRequest(url: self.url)
urlRequest.networkServiceType = .avStreaming
+ urlRequest.cachePolicy = .reloadIgnoringLocalCacheData
for header in self.additionalRequestHeaders {
urlRequest.addValue(header.value, forHTTPHeaderField: header.key)