Skip to content

Commit

Permalink
Merge branch 'main' into gh-pages
Browse files Browse the repository at this point in the history
  • Loading branch information
KharchenkoAlex committed May 27, 2024
2 parents 1192e8e + 4e3f386 commit 254eb22
Show file tree
Hide file tree
Showing 9 changed files with 92 additions and 18 deletions.
5 changes: 3 additions & 2 deletions .swiftpm/xcode/xcshareddata/xcschemes/PlaybackSDK.xcscheme
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1520"
LastUpgradeVersion = "1540"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
buildImplicitDependencies = "YES"
buildArchitectures = "Automatic">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
Expand Down
10 changes: 6 additions & 4 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@ let package = Package(
// Declare dependencies

// BitmovinPlayer
.package(name: "BitmovinPlayer",
url: "https://github.com/bitmovin/player-ios.git",
.exact("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")

Expand Down
53 changes: 53 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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: "<API_KEY>", baseURL: "<BASE_URL>") { 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:**
Expand Down
2 changes: 1 addition & 1 deletion Sources/PlaybackSDK/PlayBack API/PlayBackAPI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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<PlaybackResponseModel, Error>
func getVideoDetails(forEntryId entryId: String, andAuthorizationToken: String?, userAgent: String?) -> AnyPublisher<PlaybackResponseModel, Error>
}

#endif
12 changes: 10 additions & 2 deletions Sources/PlaybackSDK/PlayBack API/PlayBackAPIService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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<PlaybackResponseModel, Error> {
func getVideoDetails(
forEntryId entryId: String,
andAuthorizationToken: String?,
userAgent: String?
) -> AnyPublisher<PlaybackResponseModel, Error> {
guard let url = URL(string: "\(PlayBackSDKManager.shared.baseURL)/entry/\(entryId)") else {
return Fail(error: PlayBackAPIError.invalidPlaybackDataURL).eraseToAnyPublisher()
}
Expand All @@ -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)
Expand Down
15 changes: 11 additions & 4 deletions Sources/PlaybackSDK/PlayBackSDKManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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<AnyCancellable>()

// MARK: Internal properties
/// Bitmovin license key.
internal var bitmovinLicense: String?
Expand All @@ -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<String, Error>) -> Void) {
public func initialize(apiKey: String, baseURL: String? = nil, userAgent: String? = nil, completion: @escaping (Result<String, Error>) -> Void) {
guard !apiKey.isEmpty else {
completion(.failure(SDKError.initializationError))
return
Expand All @@ -76,6 +78,7 @@ public class PlayBackSDKManager {
}

amgAPIKey = apiKey
userAgentHeader = userAgent
playerInfoAPI = PlayerInformationAPIService(apiKey: apiKey)
let playBackAPIService = PlayBackAPIService(apiKey: apiKey)
self.playBackAPI = playBackAPIService
Expand Down Expand Up @@ -113,7 +116,7 @@ public class PlayBackSDKManager {
return
}

playerInfoAPIExist.getPlayerInformation()
playerInfoAPIExist.getPlayerInformation(userAgent: userAgentHeader)
.sink(receiveCompletion: { result in
switch result {
case .failure(let error):
Expand Down Expand Up @@ -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):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ import Foundation
import Combine

internal protocol PlayerInformationAPI {
func getPlayerInformation() -> AnyPublisher<PlayerInformationResponseModel, Error>
func getPlayerInformation(userAgent: String?) -> AnyPublisher<PlayerInformationResponseModel, Error>
}
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,18 @@ internal class PlayerInformationAPIService: PlayerInformationAPI {
self.apiKey = apiKey
}

func getPlayerInformation() -> AnyPublisher<PlayerInformationResponseModel, Error> {
func getPlayerInformation(userAgent: String?) -> AnyPublisher<PlayerInformationResponseModel, Error> {
guard let url = URL(string: "\(PlayBackSDKManager.shared.baseURL)/player") else {
return Fail(error: PlayBackAPIError.invalidPlayerInformationURL).eraseToAnyPublisher()
}

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())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import BitmovinPlayer
import SwiftUI

public class BitmovinPlayerPlugin: VideoPlayerPlugin {

private let playerConfig: PlayerConfig
private var player: BitMovinPlayerView?

Expand All @@ -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? {
Expand Down

0 comments on commit 254eb22

Please sign in to comment.