Skip to content

Commit

Permalink
CORE-5100 Playlist documentation
Browse files Browse the repository at this point in the history
- Playlist documentation on README file
- Added example of loadPlaylist on Tutorial
- Example of playlist controls and events on Tutorial
- Preview Swift DocC command added to test tutorial locally
  • Loading branch information
StefanoStream committed Nov 21, 2024
1 parent a30b267 commit 7280775
Show file tree
Hide file tree
Showing 8 changed files with 148 additions and 0 deletions.
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,26 @@ PlaybackSDKManager.shared.loadPlayer(entryID: entryId, authorizationToken: autho
```

# Loading a Playlist

To load a sequential list of videos into the player UI, use the `loadPlaylist` method of the `PlaybackSDKManager` singleton object. This method is a Composable function that you can use to load and render the player UI.
`entryIDs`: an array of Strings containing the unique identifiers of all the videos in the playlist.
`entryIDToPlay`: specifies the unique video identifier that will be played first in the playlist. Optional parameter

Example:

```swift
PlaybackSDKManager.shared.loadPlayer(entryIDs: listEntryId, entryIDToPlay: "0_xxxxxxxx", authorizationToken: authorizationToken) { errors in
// Handle player UI playlist errors
```

## Control playlist
xxx

## Playlist events
xxx

# Playing Access-Controlled Content
To play on-demand and live videos that require authorization, at some point before loading the player your app must call CloudPay to start session, passing the authorization token:
```swift
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import SwiftUI
import PlaybackSDK

struct PlayerTestPlaylistControlsAndEventsView: View {

@StateObject private var pluginManager = VideoPlayerPluginManager.shared
private let entryIDs = ["ENTRY_ID1", "ENTRY_ID_2", "ENTRY_ID_3"]
private let entryIDToPlay = "ENTRY_ID_2" // Optional parameter
private let entryIdToSeek = "ENTRY_ID_TO_SEEK"
private let authorizationToken = "JWT_TOKEN"

var body: some View {
VStack {
// Load playlist with the playback SDK
PlaybackSDKManager.shared.loadPlaylist(entryIDs: entryIDs, entryIDToPlay: entryIDToPlay, authorizationToken: authorizationToken) { errors in
handlePlaybackError(errors)
}
.onReceive(pluginManager.selectedPlugin!.event) { event in
if let event = event as? PlaylistTransitionEvent { // Playlist Event
if let from = event.from.metadata?["entryId"], let to = event.to.metadata?["entryId"] {
print("Playlist event changed from \(from) to \(to)")
}
}
}
.onDisappear {
// Remove the player here
}

Spacer()

Button {
// You can use the following playlist controls
pluginManager.selectedPlugin?.first() // Play the first video
pluginManager.selectedPlugin?.playPrevious() // Play the previous video
pluginManager.selectedPlugin?.playNext() // Play the next video
pluginManager.selectedPlugin?.last() // Play the last video
pluginManager.selectedPlugin?.seek(to: entryIdToSeek) { success in // Seek to a specific video
if (!success) {
let errorMessage = "Unable to seek to \(entryIdToSeek)"
}
}
pluginManager.selectedPlugin?.activeEntryId() // Get the active video Id
} label: {
Image(systemName: "list.triangle")
}

Spacer()
}
.padding()
}

private func handlePlaybackErrors(_ errors: [PlaybackAPIError]) {

for error in errors {
switch error {
case .apiError(let statusCode, let message, let reason):
let message = "\(message) Status Code \(statusCode), Reason: \(reason)"
print(message)
default:
print("Error code and errorrMessage not found: \(error.localizedDescription)")
}
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import SwiftUI
import PlaybackSDK

struct PlayerTestPlaylistView: View {

private let entryIDs = ["ENTRY_ID1", "ENTRY_ID_2", "ENTRY_ID_3"]
private let entryIDToPlay = "ENTRY_ID_2" // Optional parameter
private let authorizationToken = "JWT_TOKEN"

var body: some View {
VStack {
// Load playlist with the playback SDK
PlaybackSDKManager.shared.loadPlaylist(entryIDs: entryIDs, entryIDToPlay: entryIDToPlay, authorizationToken: authorizationToken) { errors in
handlePlaybackError(errors)
}
.onDisappear {
// Remove the player here
}
Spacer()
}
.padding()
}

private func handlePlaybackErrors(_ errors: [PlaybackAPIError]) {

for error in errors {
switch error {
case .apiError(let statusCode, let message, let reason):
let message = "\(message) Status Code \(statusCode), Reason: \(reason)"
print(message)
default:
print("Error code and errorrMessage not found: \(error.localizedDescription)")
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,26 @@

@Code(name: "PlayerTestView.swift", file: PlayerTestView.swift)
}
@Step {
Load the player passing a playlist using the Playback SDK and handle any playlist errors.

In this step, the code utilizes the **loadPlaylist** function provided by the Playback SDK to initialize and load the video player. The function takes an array of entry ID, the starting entry ID to play and an authorization token as parameters. Additionally, it includes a closure to handle any potential playlist errors that may occur during the loading process.
The **handlePlaybackErrors** function is called within the closure to handle the playlist errors.
It's an array of PlaybackError and for every error it switches on the type of error received and provides appropriate error handling based on the type of error encountered.
The code also includes a placeholder comment to indicate where the removal of the player could be implemented in the **onDisappear** modifier.
If you want to allow users to access free content or if you're implementing a guest mode, you can pass an empty string or **nil** value as the **authorizationToken** when calling the **loadPlaylist** function. This will bypass the need for authentication, enabling unrestricted access to the specified contents.

@Code(name: "PlayerTestPlaylistView.swift", file: PlayerTestPlaylistView.swift)
}
@Step {
Playlist controls and events

Declaring the **VideoPlayerPluginManager** singleton instance as **@StateObject** variable like in the example, allow you to access to the playlist controls as well as the playlist events
In the **onReceive** modifier, you can listen to the player events such as the **PlaylistTransitionEvent** that gives you information regarding the transition between a video to another
Through the **pluginManager.selectedPlugin** is possible to interact with playlist controls like in the example and get to know the current video that is playing with **activeEntryId** function.

@Code(name: "PlayerTestPlaylistControlsAndEventsView.swift", file: PlayerTestPlaylistControlsAndEventsView.swift, previousFile: PlayerTestPlaylistView.swift)
}
@Step {
Handle the playback errors from Playback SDK.

Expand Down
6 changes: 6 additions & 0 deletions preview_docc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/bash

# This is a convenience script to preview Swift DocC documentation to prepare for GitHub Pages publishing
# Source: https://swiftlang.github.io/swift-docc-plugin/documentation/swiftdoccplugin/previewing-documentation

swift package --disable-sandbox preview-documentation --target PlaybackSDK

0 comments on commit 7280775

Please sign in to comment.