From 75f14b52b3bf0bdc780f00ae953158d7cca945e9 Mon Sep 17 00:00:00 2001 From: Artem Yelizarov Date: Wed, 15 May 2024 11:52:46 +0300 Subject: [PATCH 1/5] Pass user-agent header to the SDK --- .../xcshareddata/IDEWorkspaceChecks.plist | 8 -- .../xcschemes/PlaybackSDK-Package.xcscheme | 66 ---------------- .../xcschemes/PlaybackSDK.xcscheme | 5 +- .../xcschemes/PlaybackSDKTests.xcscheme | 75 ------------------- Package.resolved | 8 +- Package.swift | 9 +-- .../PlayBack API/PlayBackAPI.swift | 2 +- .../PlayBack API/PlayBackAPIService.swift | 12 ++- Sources/PlaybackSDK/PlayBackSDKManager.swift | 15 +++- .../PlayerInformationAPI.swift | 2 +- .../PlayerInformationAPIService.swift | 7 +- .../BitMovinPlugin/BitmovinPlayerPlugin.swift | 2 +- 12 files changed, 40 insertions(+), 171 deletions(-) delete mode 100644 .swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist delete mode 100644 .swiftpm/xcode/xcshareddata/xcschemes/PlaybackSDK-Package.xcscheme delete mode 100644 .swiftpm/xcode/xcshareddata/xcschemes/PlaybackSDKTests.xcscheme diff --git a/.swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/.swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d9810..0000000 --- a/.swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/.swiftpm/xcode/xcshareddata/xcschemes/PlaybackSDK-Package.xcscheme b/.swiftpm/xcode/xcshareddata/xcschemes/PlaybackSDK-Package.xcscheme deleted file mode 100644 index c7ef817..0000000 --- a/.swiftpm/xcode/xcshareddata/xcschemes/PlaybackSDK-Package.xcscheme +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/.swiftpm/xcode/xcshareddata/xcschemes/PlaybackSDK.xcscheme b/.swiftpm/xcode/xcshareddata/xcschemes/PlaybackSDK.xcscheme index c35394f..1138452 100644 --- a/.swiftpm/xcode/xcshareddata/xcschemes/PlaybackSDK.xcscheme +++ b/.swiftpm/xcode/xcshareddata/xcschemes/PlaybackSDK.xcscheme @@ -1,10 +1,11 @@ + buildImplicitDependencies = "YES" + buildArchitectures = "Automatic"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Package.resolved b/Package.resolved index dde829e..c9509bf 100644 --- a/Package.resolved +++ b/Package.resolved @@ -6,17 +6,17 @@ "repositoryURL": "https://github.com/bitmovin/bitmovin-analytics-collector-ios.git", "state": { "branch": null, - "revision": "3feebb1db5f6bc2d3ad0b7241f3baea523e9ab9e", - "version": "3.6.0" + "revision": "3431fdbfb3098c0826b332ec52c869a30f20b947", + "version": "3.6.2" } }, { "package": "BitmovinPlayer", "repositoryURL": "https://github.com/bitmovin/player-ios.git", "state": { - "branch": null, + "branch": "3.56.1", "revision": "31ed8a5fb931bd600c5e1ca6d19c17d77762b56b", - "version": "3.56.1" + "version": null } }, { diff --git a/Package.swift b/Package.swift index 9e23336..5d89e1a 100644 --- a/Package.swift +++ b/Package.swift @@ -20,10 +20,9 @@ let package = Package( // Declare dependencies // BitmovinPlayer - .package(name: "BitmovinPlayer", - url: "https://github.com/bitmovin/player-ios.git", - .exact("3.56.1")), - + .package(url: "https://github.com/bitmovin/player-ios.git", + revision: "3.56.1"), + // other dependencies .package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0") @@ -34,7 +33,7 @@ let package = Package( .target( name: "PlaybackSDK", dependencies: [ - .product(name: "BitmovinPlayer", package: "BitmovinPlayer"), + .product(name: "BitmovinPlayer", package: "player-ios"), ] ), .testTarget( diff --git a/Sources/PlaybackSDK/PlayBack API/PlayBackAPI.swift b/Sources/PlaybackSDK/PlayBack API/PlayBackAPI.swift index 1ee290a..bedec15 100644 --- a/Sources/PlaybackSDK/PlayBack API/PlayBackAPI.swift +++ b/Sources/PlaybackSDK/PlayBack API/PlayBackAPI.swift @@ -21,7 +21,7 @@ internal protocol PlayBackAPI { - andAuthorizationToken: Optional authorization token, can be nil for free videos. - Returns: A publisher emitting the response model or an error. */ - func getVideoDetails(forEntryId entryId: String, andAuthorizationToken: String?) -> AnyPublisher + func getVideoDetails(forEntryId entryId: String, andAuthorizationToken: String?, userAgent: String?) -> AnyPublisher } #endif diff --git a/Sources/PlaybackSDK/PlayBack API/PlayBackAPIService.swift b/Sources/PlaybackSDK/PlayBack API/PlayBackAPIService.swift index d237d45..43bc68e 100644 --- a/Sources/PlaybackSDK/PlayBack API/PlayBackAPIService.swift +++ b/Sources/PlaybackSDK/PlayBack API/PlayBackAPIService.swift @@ -33,7 +33,11 @@ internal class PlayBackAPIService: PlayBackAPI { - andAuthorizationToken: Optional authorization token, can be nil for free videos. - Returns: A publisher emitting the response model or an error. */ - func getVideoDetails(forEntryId entryId: String, andAuthorizationToken: String?) -> AnyPublisher { + func getVideoDetails( + forEntryId entryId: String, + andAuthorizationToken: String?, + userAgent: String? + ) -> AnyPublisher { guard let url = URL(string: "\(PlayBackSDKManager.shared.baseURL)/entry/\(entryId)") else { return Fail(error: PlayBackAPIError.invalidPlaybackDataURL).eraseToAnyPublisher() } @@ -45,7 +49,11 @@ internal class PlayBackAPIService: PlayBackAPI { if let authorizationTokenExist = andAuthorizationToken, !authorizationTokenExist.isEmpty { request.addValue("Bearer \(authorizationTokenExist)", forHTTPHeaderField: "Authorization") } - + + if let userAgent, !userAgent.isEmpty { + request.addValue(userAgent, forHTTPHeaderField: "User-Agent") + } + request.addValue(apiKey, forHTTPHeaderField: "x-api-key") return URLSession.shared.dataTaskPublisher(for: request) diff --git a/Sources/PlaybackSDK/PlayBackSDKManager.swift b/Sources/PlaybackSDK/PlayBackSDKManager.swift index af481d4..c105adb 100644 --- a/Sources/PlaybackSDK/PlayBackSDKManager.swift +++ b/Sources/PlaybackSDK/PlayBackSDKManager.swift @@ -44,8 +44,9 @@ public class PlayBackSDKManager { // MARK: Private properties private var playerInfoAPI: PlayerInformationAPI? private var playBackAPI: PlayBackAPI? + private var userAgentHeader: String? private var cancellables = Set() - + // MARK: Internal properties /// Bitmovin license key. internal var bitmovinLicense: String? @@ -63,9 +64,10 @@ public class PlayBackSDKManager { /// - Parameters: /// - apiKey: The API key for initializing the SDK. /// - baseURL: The base URL for API endpoints. Defaults to `nil`. + /// - userAgent: Custom `User-Agent` header to use with playback requests. Can be used if there was a custom header set to start session request. Defaults to `nil` /// - completion: A closure to be called after initialization. /// It receives a result indicating success or failure. - public func initialize(apiKey: String, baseURL: String? = nil, completion: @escaping (Result) -> Void) { + public func initialize(apiKey: String, baseURL: String? = nil, userAgent: String? = nil, completion: @escaping (Result) -> Void) { guard !apiKey.isEmpty else { completion(.failure(SDKError.initializationError)) return @@ -76,6 +78,7 @@ public class PlayBackSDKManager { } amgAPIKey = apiKey + userAgentHeader = userAgent playerInfoAPI = PlayerInformationAPIService(apiKey: apiKey) let playBackAPIService = PlayBackAPIService(apiKey: apiKey) self.playBackAPI = playBackAPIService @@ -113,7 +116,7 @@ public class PlayBackSDKManager { return } - playerInfoAPIExist.getPlayerInformation() + playerInfoAPIExist.getPlayerInformation(userAgent: userAgentHeader) .sink(receiveCompletion: { result in switch result { case .failure(let error): @@ -154,7 +157,11 @@ public class PlayBackSDKManager { } // Call the /entry endpoint for the given entry ID - playBackAPIExist.getVideoDetails(forEntryId: entryId, andAuthorizationToken: andAuthorizationToken) + playBackAPIExist.getVideoDetails( + forEntryId: entryId, + andAuthorizationToken: andAuthorizationToken, + userAgent: userAgentHeader + ) .sink(receiveCompletion: { result in switch result { case .failure(let error): diff --git a/Sources/PlaybackSDK/Playback Configuration API/PlayerInformationAPI.swift b/Sources/PlaybackSDK/Playback Configuration API/PlayerInformationAPI.swift index 130893f..9716ed7 100644 --- a/Sources/PlaybackSDK/Playback Configuration API/PlayerInformationAPI.swift +++ b/Sources/PlaybackSDK/Playback Configuration API/PlayerInformationAPI.swift @@ -9,6 +9,6 @@ import Foundation import Combine internal protocol PlayerInformationAPI { - func getPlayerInformation() -> AnyPublisher + func getPlayerInformation(userAgent: String?) -> AnyPublisher } #endif diff --git a/Sources/PlaybackSDK/Playback Configuration API/PlayerInformationAPIService.swift b/Sources/PlaybackSDK/Playback Configuration API/PlayerInformationAPIService.swift index eb0397c..73ce44b 100644 --- a/Sources/PlaybackSDK/Playback Configuration API/PlayerInformationAPIService.swift +++ b/Sources/PlaybackSDK/Playback Configuration API/PlayerInformationAPIService.swift @@ -16,7 +16,7 @@ internal class PlayerInformationAPIService: PlayerInformationAPI { self.apiKey = apiKey } - func getPlayerInformation() -> AnyPublisher { + func getPlayerInformation(userAgent: String?) -> AnyPublisher { guard let url = URL(string: "\(PlayBackSDKManager.shared.baseURL)/player") else { return Fail(error: PlayBackAPIError.invalidPlayerInformationURL).eraseToAnyPublisher() } @@ -24,7 +24,10 @@ internal class PlayerInformationAPIService: PlayerInformationAPI { var request = URLRequest(url: url) request.addValue("application/json", forHTTPHeaderField: "Accept") request.addValue(apiKey, forHTTPHeaderField: "x-api-key") - + if let userAgent { + request.addValue(userAgent, forHTTPHeaderField: "User-Agent") + } + return URLSession.shared.dataTaskPublisher(for: request) .map { $0.data } .decode(type: PlayerInformationResponseModel.self, decoder: JSONDecoder()) diff --git a/Sources/PlaybackSDK/Player Plugin/BitMovinPlugin/BitmovinPlayerPlugin.swift b/Sources/PlaybackSDK/Player Plugin/BitMovinPlugin/BitmovinPlayerPlugin.swift index 502850d..248a31d 100644 --- a/Sources/PlaybackSDK/Player Plugin/BitMovinPlugin/BitmovinPlayerPlugin.swift +++ b/Sources/PlaybackSDK/Player Plugin/BitMovinPlugin/BitmovinPlayerPlugin.swift @@ -9,7 +9,7 @@ import BitmovinPlayer import SwiftUI public class BitmovinPlayerPlugin: VideoPlayerPlugin { - + private let playerConfig: PlayerConfig private var player: BitMovinPlayerView? From 02f68ccc94d23a786767403f22ebba153cb45927 Mon Sep 17 00:00:00 2001 From: Artem Yelizarov Date: Wed, 15 May 2024 11:48:47 +0300 Subject: [PATCH 2/5] Revert deletion of package schemes --- .../xcshareddata/IDEWorkspaceChecks.plist | 8 ++ .../xcschemes/PlaybackSDK-Package.xcscheme | 66 ++++++++++++++++ .../xcschemes/PlaybackSDKTests.xcscheme | 75 +++++++++++++++++++ 3 files changed, 149 insertions(+) create mode 100644 .swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 .swiftpm/xcode/xcshareddata/xcschemes/PlaybackSDK-Package.xcscheme create mode 100644 .swiftpm/xcode/xcshareddata/xcschemes/PlaybackSDKTests.xcscheme diff --git a/.swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/.swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/.swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/.swiftpm/xcode/xcshareddata/xcschemes/PlaybackSDK-Package.xcscheme b/.swiftpm/xcode/xcshareddata/xcschemes/PlaybackSDK-Package.xcscheme new file mode 100644 index 0000000..c7ef817 --- /dev/null +++ b/.swiftpm/xcode/xcshareddata/xcschemes/PlaybackSDK-Package.xcscheme @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.swiftpm/xcode/xcshareddata/xcschemes/PlaybackSDKTests.xcscheme b/.swiftpm/xcode/xcshareddata/xcschemes/PlaybackSDKTests.xcscheme new file mode 100644 index 0000000..c06f2f3 --- /dev/null +++ b/.swiftpm/xcode/xcshareddata/xcschemes/PlaybackSDKTests.xcscheme @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 948eab2c9d2393cf82d047e7ac8805e58e70916c Mon Sep 17 00:00:00 2001 From: Artem Yelizarov Date: Wed, 15 May 2024 13:44:11 +0300 Subject: [PATCH 3/5] Update version in the bitmovin plugin --- .../Player Plugin/BitMovinPlugin/BitmovinPlayerPlugin.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/PlaybackSDK/Player Plugin/BitMovinPlugin/BitmovinPlayerPlugin.swift b/Sources/PlaybackSDK/Player Plugin/BitMovinPlugin/BitmovinPlayerPlugin.swift index 248a31d..c87909d 100644 --- a/Sources/PlaybackSDK/Player Plugin/BitMovinPlugin/BitmovinPlayerPlugin.swift +++ b/Sources/PlaybackSDK/Player Plugin/BitMovinPlugin/BitmovinPlayerPlugin.swift @@ -25,7 +25,7 @@ public class BitmovinPlayerPlugin: VideoPlayerPlugin { playerConfig.key = PlayBackSDKManager.shared.bitmovinLicense self.playerConfig = playerConfig self.name = "BitmovinPlayerPlugin" - self.version = "1.0" + self.version = "1.0.1" } func getPlayer() -> Player? { From 2036529b8a58b68cfbc9c4ba81765d246798aa19 Mon Sep 17 00:00:00 2001 From: Artem Yelizarov Date: Thu, 16 May 2024 13:35:17 +0300 Subject: [PATCH 4/5] Add usage section about initialization, loading and user-agent header --- README.md | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/README.md b/README.md index 558b682..49c35df 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,59 @@ Swift import PlaybackSDK ``` +# PlaybackSDKManager + +The `PlaybackSDKManager` is a singleton object designed to manage the functionalities of the playback SDK. It provides methods for initialization, loading player UI, and loading HLS streams. + +# Initialization + +To initialize the playback SDK, use the `initialize` method of the `PlaybackSDKManager` singleton object. This method requires an API key for authentication. Optionally, you can specify a base URL for the playback API. + +Example: + +```swift + // Initialize SDK with the settings + PlaybackSDKManager.shared.initialize(apiKey: "", baseURL: "") { result -> + // Register default layer plugin + + switch result { + case .success(let license): + val customPlugin = BitmovinVideoPlayerPlugin() + VideoPlayerPluginManager.shared.registerPlugin(customPlugin) + case .failure(let error): + // Handle error + } + } +``` + + +# Loading Player UI + +To load the player UI in your application, use the `loadPlayer` method of the `PlaybackSDKManager` singleton object. This method is a Composable function that you can use to load and render the player UI. + +Example: + +```swift +PlayBackSDKManager.shared.loadPlayer(entryID: entryId, authorizationToken: authorizationToken) { error in + // Handle player UI error  +}  +``` + +# Playing Access-Controlled Content +To play premium or freemium on-demand and live videos, an `authorizationToken` has to be passed into the player. +Before loading the player, a call to CloudPay to start session must be made with the same token. +```swift +"\(baseURL)/sso/start?token=\(authorizationToken)" +``` +In case a custom `user-agent` header is set for the request when creating a token, it should be passed to the player as well. + +Example: + +```swift +PlayBackSDKManager.shared.initialize(apiKey: apiKey, baseURL: baseURL, userAgent: customUserAgent) { result in  + // Handle player UI error  +}  +``` **Resources:** From 2511c8a93448b99b80170073ae86abfe879f6740 Mon Sep 17 00:00:00 2001 From: Artem Yelizarov Date: Fri, 17 May 2024 13:48:59 +0300 Subject: [PATCH 5/5] Revert to an old way of connecting the exact player version dependency --- Package.resolved | 8 ++++---- Package.swift | 9 ++++++--- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/Package.resolved b/Package.resolved index c9509bf..dde829e 100644 --- a/Package.resolved +++ b/Package.resolved @@ -6,17 +6,17 @@ "repositoryURL": "https://github.com/bitmovin/bitmovin-analytics-collector-ios.git", "state": { "branch": null, - "revision": "3431fdbfb3098c0826b332ec52c869a30f20b947", - "version": "3.6.2" + "revision": "3feebb1db5f6bc2d3ad0b7241f3baea523e9ab9e", + "version": "3.6.0" } }, { "package": "BitmovinPlayer", "repositoryURL": "https://github.com/bitmovin/player-ios.git", "state": { - "branch": "3.56.1", + "branch": null, "revision": "31ed8a5fb931bd600c5e1ca6d19c17d77762b56b", - "version": null + "version": "3.56.1" } }, { diff --git a/Package.swift b/Package.swift index 5d89e1a..ff20d1d 100644 --- a/Package.swift +++ b/Package.swift @@ -20,8 +20,11 @@ let package = Package( // Declare dependencies // BitmovinPlayer - .package(url: "https://github.com/bitmovin/player-ios.git", - revision: "3.56.1"), + .package( + name: "BitmovinPlayer", + url: "https://github.com/bitmovin/player-ios.git", + .exact("3.56.1") + ), // other dependencies .package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0") @@ -33,7 +36,7 @@ let package = Package( .target( name: "PlaybackSDK", dependencies: [ - .product(name: "BitmovinPlayer", package: "player-ios"), + .product(name: "BitmovinPlayer", package: "BitmovinPlayer"), ] ), .testTarget(