diff --git a/Sources/MuxPlayerSwift/FairPlay/ErrorDispatcher.swift b/Sources/MuxPlayerSwift/FairPlay/ErrorDispatcher.swift new file mode 100644 index 0000000..78d1024 --- /dev/null +++ b/Sources/MuxPlayerSwift/FairPlay/ErrorDispatcher.swift @@ -0,0 +1,14 @@ +// +// ErrorDispatcher.swift +// +// + +import Foundation + +protocol ErrorDispatcher { + func dispatchError( + errorCode: String, + errorMessage: String, + playerObjectIdentifier: ObjectIdentifier + ) +} diff --git a/Sources/MuxPlayerSwift/FairPlay/FairPlaySessionManager.swift b/Sources/MuxPlayerSwift/FairPlay/FairPlaySessionManager.swift index ee7c1d7..942d340 100644 --- a/Sources/MuxPlayerSwift/FairPlay/FairPlaySessionManager.swift +++ b/Sources/MuxPlayerSwift/FairPlay/FairPlaySessionManager.swift @@ -90,7 +90,8 @@ class DefaultFairPlayStreamingSessionManager< var playbackOptionsByPlaybackID: [String: PlaybackOptions] = [:] let contentKeySession: ContentKeySession - + let errorDispatcher: (any ErrorDispatcher) + #if DEBUG var logger: Logger = Logger( OSLog( @@ -276,6 +277,12 @@ class DefaultFairPlayStreamingSessionManager< requestCompletion(Result.failure( FairPlaySessionError.because(cause: error) )) +// // TODO: Confirm error code +// self.errorDispatcher.dispatchError( +// errorCode: "5001", +// errorMessage: error.localizedDescription, +// playerObjectIdentifier: <#T##ObjectIdentifier#> +// ) return } @@ -349,10 +356,12 @@ class DefaultFairPlayStreamingSessionManager< init( contentKeySession: ContentKeySession, - urlSession: URLSession + urlSession: URLSession, + errorDispatcher: any ErrorDispatcher ) { self.contentKeySession = contentKeySession self.urlSession = urlSession + self.errorDispatcher = errorDispatcher } } diff --git a/Sources/MuxPlayerSwift/GlobalLifecycle/PlayerSDK.swift b/Sources/MuxPlayerSwift/GlobalLifecycle/PlayerSDK.swift index a893e67..871dfeb 100644 --- a/Sources/MuxPlayerSwift/GlobalLifecycle/PlayerSDK.swift +++ b/Sources/MuxPlayerSwift/GlobalLifecycle/PlayerSDK.swift @@ -28,32 +28,39 @@ class PlayerSDK { let fairPlaySessionManager: FairPlayStreamingSessionManager convenience init() { + let monitor = Monitor() + #if targetEnvironment(simulator) self.init( fairPlayStreamingSessionManager: DefaultFairPlayStreamingSessionManager( contentKeySession: AVContentKeySession(keySystem: .clearKey), - urlSession: .shared - ) + urlSession: .shared, + errorDispatcher: monitor + ), + monitor: monitor ) #else let sessionManager = DefaultFairPlayStreamingSessionManager( contentKeySession: AVContentKeySession(keySystem: .fairPlayStreaming), - urlSession: .shared + urlSession: .shared, + errorDispatcher: monitor ) sessionManager.sessionDelegate = ContentKeySessionDelegate( sessionManager: sessionManager ) self.init( - fairPlayStreamingSessionManager: sessionManager + fairPlayStreamingSessionManager: sessionManager, + monitor: monitor ) #endif } init( - fairPlayStreamingSessionManager: FairPlayStreamingSessionManager + fairPlayStreamingSessionManager: FairPlayStreamingSessionManager, + monitor: Monitor ) { - self.monitor = Monitor() self.fairPlaySessionManager = fairPlayStreamingSessionManager + self.monitor = monitor #if DEBUG self.abrLogger = Logger( diff --git a/Sources/MuxPlayerSwift/Monitoring/Monitor.swift b/Sources/MuxPlayerSwift/Monitoring/Monitor.swift index 3671371..1f3a987 100644 --- a/Sources/MuxPlayerSwift/Monitoring/Monitor.swift +++ b/Sources/MuxPlayerSwift/Monitoring/Monitor.swift @@ -9,7 +9,7 @@ import Foundation import MuxCore import MUXSDKStats -class Monitor { +class Monitor: ErrorDispatcher { struct MonitoredPlayer { var name: String @@ -207,4 +207,24 @@ class Monitor { bindings.removeValue(forKey: objectIdentifier) } + + // MARK: - Error Dispatch + + func dispatchError( + errorCode: String, + errorMessage: String, + playerObjectIdentifier: ObjectIdentifier + ) { + guard let monitoredPlayer = self.bindings[playerObjectIdentifier] else { + return + } + + let playerName = monitoredPlayer.name + + MUXSDKStats.dispatchError( + errorCode, + withMessage: errorMessage, + forPlayer: playerName + ) + } } diff --git a/Tests/MuxPlayerSwift/FairPlay/FairPlaySessionManagerTests.swift b/Tests/MuxPlayerSwift/FairPlay/FairPlaySessionManagerTests.swift index 482be2d..503e284 100644 --- a/Tests/MuxPlayerSwift/FairPlay/FairPlaySessionManagerTests.swift +++ b/Tests/MuxPlayerSwift/FairPlay/FairPlaySessionManagerTests.swift @@ -29,7 +29,8 @@ class FairPlaySessionManagerTests : XCTestCase { let defaultFairPlaySessionManager = DefaultFairPlayStreamingSessionManager( // .clearKey is used because .fairPlay requires a physical device contentKeySession: session, - urlSession: mockURLSession + urlSession: mockURLSession, + errorDispatcher: Monitor() ) self.sessionManager = defaultFairPlaySessionManager defaultFairPlaySessionManager.sessionDelegate = ContentKeySessionDelegate( @@ -576,7 +577,8 @@ class FairPlaySessionManagerTests : XCTestCase { ) let defaultFairPlaySessionManager = DefaultFairPlayStreamingSessionManager( contentKeySession: session, - urlSession: mockURLSession + urlSession: mockURLSession, + errorDispatcher: Monitor() ) self.sessionManager = defaultFairPlaySessionManager let sessionDelegate = ContentKeySessionDelegate( @@ -616,7 +618,8 @@ class FairPlaySessionManagerTests : XCTestCase { PlayerSDK.shared = PlayerSDK( - fairPlayStreamingSessionManager: defaultFairPlaySessionManager + fairPlayStreamingSessionManager: defaultFairPlaySessionManager, + monitor: Monitor() ) let _ = AVPlayerItem( diff --git a/Tests/MuxPlayerSwift/MonitorTests.swift b/Tests/MuxPlayerSwift/MonitorTests.swift index be61e43..b9b554d 100644 --- a/Tests/MuxPlayerSwift/MonitorTests.swift +++ b/Tests/MuxPlayerSwift/MonitorTests.swift @@ -31,6 +31,12 @@ class TestMonitor: Monitor { options: MonitoringOptions, usingDRM: Bool = false ) { + super.setupMonitoring( + playerViewController: playerViewController, + options: options, + usingDRM: usingDRM + ) + monitoringRegistrations.append( (options, usingDRM) ) @@ -41,6 +47,12 @@ class TestMonitor: Monitor { options: MonitoringOptions, usingDRM: Bool = false ) { + super.setupMonitoring( + playerLayer: playerLayer, + options: options, + usingDRM: usingDRM + ) + monitoringRegistrations.append( (options, usingDRM) ) @@ -137,6 +149,13 @@ class MonitorTests: XCTestCase { ) ) + let playerBinding = try XCTUnwrap( + testMonitor.bindings[ObjectIdentifier(playerViewController)] + ) + XCTAssertNotNil( + playerBinding + ) + let registration = try XCTUnwrap( testMonitor.monitoringRegistrations.first ) @@ -158,6 +177,13 @@ class MonitorTests: XCTestCase { ) ) + let playerBinding = try XCTUnwrap( + testMonitor.bindings[ObjectIdentifier(playerLayer)] + ) + XCTAssertNotNil( + playerBinding + ) + let registration = try XCTUnwrap( testMonitor.monitoringRegistrations.first ) @@ -184,6 +210,13 @@ class MonitorTests: XCTestCase { ) ) + let playerBinding = try XCTUnwrap( + testMonitor.bindings[ObjectIdentifier(preexistingPlayerLayer)] + ) + XCTAssertNotNil( + playerBinding + ) + let registration = try XCTUnwrap( testMonitor.monitoringRegistrations.first )