From be5c99b5a59315650ef8faff5bbbd6b971ae0518 Mon Sep 17 00:00:00 2001 From: Stefano Russello Date: Fri, 1 Nov 2024 13:10:33 +0100 Subject: [PATCH 1/5] CORE-5100 CORE-5085 Playlist documentation - Added example how to toggle autoplay and background playback - Fixed readme discrepancies - Improved readme example - Renamed PlaybackError to PlaybackAPIError --- README.md | 9 ++++++++- .../Documentation.docc/Resources/PlayBackDemoApp.swift | 7 +++++++ .../Resources/PlayBackDemoAppWithUserAgent.swift | 7 +++++++ .../Documentation.docc/Resources/PlayerTestView.swift | 2 +- .../Documentation.docc/Tutorial/GetStarted.tutorial | 2 +- 5 files changed, 24 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6fce273..d80e9b7 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,14 @@ Example: switch result { case .success(let license): - val customPlugin = BitmovinVideoPlayerPlugin() + let customPlugin = BitmovinPlayerPlugin() + + // Setting up player plugin + var config = VideoPlayerConfig() + config.playbackConfig.autoplayEnabled = true // Toggle autoplay + config.playbackConfig.backgroundPlaybackEnabled = true // Toggle background playback + customPlugin.setup(config: config) + VideoPlayerPluginManager.shared.registerPlugin(customPlugin) case .failure(let error): // Handle error diff --git a/Sources/PlaybackSDK/Documentation.docc/Resources/PlayBackDemoApp.swift b/Sources/PlaybackSDK/Documentation.docc/Resources/PlayBackDemoApp.swift index 4cfe637..bac55fe 100644 --- a/Sources/PlaybackSDK/Documentation.docc/Resources/PlayBackDemoApp.swift +++ b/Sources/PlaybackSDK/Documentation.docc/Resources/PlayBackDemoApp.swift @@ -22,6 +22,13 @@ struct PlaybackDemoApp: App { // Register the video player plugin let bitmovinPlugin = BitmovinPlayerPlugin() + + // Setting up player plugin + var config = VideoPlayerConfig() + config.playbackConfig.autoplayEnabled = true // Toggle autoplay + config.playbackConfig.backgroundPlaybackEnabled = true // Toggle background playback + bitmovinPlugin.setup(config: config) + VideoPlayerPluginManager.shared.registerPlugin(bitmovinPlugin) case .failure(let error): diff --git a/Sources/PlaybackSDK/Documentation.docc/Resources/PlayBackDemoAppWithUserAgent.swift b/Sources/PlaybackSDK/Documentation.docc/Resources/PlayBackDemoAppWithUserAgent.swift index 8d7cb0b..1fe1c39 100644 --- a/Sources/PlaybackSDK/Documentation.docc/Resources/PlayBackDemoAppWithUserAgent.swift +++ b/Sources/PlaybackSDK/Documentation.docc/Resources/PlayBackDemoAppWithUserAgent.swift @@ -26,6 +26,13 @@ struct PlaybackDemoApp: App { // Register the video player plugin let bitmovinPlugin = BitmovinPlayerPlugin() + + // Setting up player plugin + var config = VideoPlayerConfig() + config.playbackConfig.autoplayEnabled = true // Toggle autoplay + config.playbackConfig.backgroundPlaybackEnabled = true // Toggle background playback + bitmovinPlugin.setup(config: config) + VideoPlayerPluginManager.shared.registerPlugin(bitmovinPlugin) case .failure(let error): diff --git a/Sources/PlaybackSDK/Documentation.docc/Resources/PlayerTestView.swift b/Sources/PlaybackSDK/Documentation.docc/Resources/PlayerTestView.swift index 28451b3..89141f9 100644 --- a/Sources/PlaybackSDK/Documentation.docc/Resources/PlayerTestView.swift +++ b/Sources/PlaybackSDK/Documentation.docc/Resources/PlayerTestView.swift @@ -20,7 +20,7 @@ struct PlayerTestView: View { .padding() } - private func handlePlaybackError(_ error: PlaybackError) { + private func handlePlaybackError(_ error: PlaybackAPIError) { switch error { case .apiError(let statusCode, let errorMessage, let reason): print("\(errorMessage) Status Code \(statusCode)") diff --git a/Sources/PlaybackSDK/Documentation.docc/Tutorial/GetStarted.tutorial b/Sources/PlaybackSDK/Documentation.docc/Tutorial/GetStarted.tutorial index ddc4496..4f46384 100644 --- a/Sources/PlaybackSDK/Documentation.docc/Tutorial/GetStarted.tutorial +++ b/Sources/PlaybackSDK/Documentation.docc/Tutorial/GetStarted.tutorial @@ -16,7 +16,7 @@ @Steps { @Step { - Initialize the Playback SDK by providing your API key and register the default player plugin. + Initialize the Playback SDK by providing your API key, setup and register the default player plugin. **Make sure this step is done when the app starts.** From 72807756d5872886710a4280e0d556426d852354 Mon Sep 17 00:00:00 2001 From: Stefano Russello Date: Thu, 21 Nov 2024 14:43:49 +0100 Subject: [PATCH 2/5] CORE-5100 Playlist documentation - 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 --- README.md | 20 ++++++ ...kAPIError.swift => PlaybackAPIError.swift} | 0 ...ackDemoApp.swift => PlaybackDemoApp.swift} | 0 ...ift => PlaybackDemoAppWithUserAgent.swift} | 0 ...yerTestPlaylistControlsAndEventsView.swift | 65 +++++++++++++++++++ .../Resources/PlayerTestPlaylistView.swift | 37 +++++++++++ .../Tutorial/GetStarted.tutorial | 20 ++++++ preview_docc | 6 ++ 8 files changed, 148 insertions(+) rename Sources/PlaybackSDK/Documentation.docc/Resources/{PlayBackAPIError.swift => PlaybackAPIError.swift} (100%) rename Sources/PlaybackSDK/Documentation.docc/Resources/{PlayBackDemoApp.swift => PlaybackDemoApp.swift} (100%) rename Sources/PlaybackSDK/Documentation.docc/Resources/{PlayBackDemoAppWithUserAgent.swift => PlaybackDemoAppWithUserAgent.swift} (100%) create mode 100644 Sources/PlaybackSDK/Documentation.docc/Resources/PlayerTestPlaylistControlsAndEventsView.swift create mode 100644 Sources/PlaybackSDK/Documentation.docc/Resources/PlayerTestPlaylistView.swift create mode 100644 preview_docc diff --git a/README.md b/README.md index d80e9b7..60ef98c 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/Sources/PlaybackSDK/Documentation.docc/Resources/PlayBackAPIError.swift b/Sources/PlaybackSDK/Documentation.docc/Resources/PlaybackAPIError.swift similarity index 100% rename from Sources/PlaybackSDK/Documentation.docc/Resources/PlayBackAPIError.swift rename to Sources/PlaybackSDK/Documentation.docc/Resources/PlaybackAPIError.swift diff --git a/Sources/PlaybackSDK/Documentation.docc/Resources/PlayBackDemoApp.swift b/Sources/PlaybackSDK/Documentation.docc/Resources/PlaybackDemoApp.swift similarity index 100% rename from Sources/PlaybackSDK/Documentation.docc/Resources/PlayBackDemoApp.swift rename to Sources/PlaybackSDK/Documentation.docc/Resources/PlaybackDemoApp.swift diff --git a/Sources/PlaybackSDK/Documentation.docc/Resources/PlayBackDemoAppWithUserAgent.swift b/Sources/PlaybackSDK/Documentation.docc/Resources/PlaybackDemoAppWithUserAgent.swift similarity index 100% rename from Sources/PlaybackSDK/Documentation.docc/Resources/PlayBackDemoAppWithUserAgent.swift rename to Sources/PlaybackSDK/Documentation.docc/Resources/PlaybackDemoAppWithUserAgent.swift diff --git a/Sources/PlaybackSDK/Documentation.docc/Resources/PlayerTestPlaylistControlsAndEventsView.swift b/Sources/PlaybackSDK/Documentation.docc/Resources/PlayerTestPlaylistControlsAndEventsView.swift new file mode 100644 index 0000000..971d6b4 --- /dev/null +++ b/Sources/PlaybackSDK/Documentation.docc/Resources/PlayerTestPlaylistControlsAndEventsView.swift @@ -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)") + } + } + } + +} diff --git a/Sources/PlaybackSDK/Documentation.docc/Resources/PlayerTestPlaylistView.swift b/Sources/PlaybackSDK/Documentation.docc/Resources/PlayerTestPlaylistView.swift new file mode 100644 index 0000000..39f6889 --- /dev/null +++ b/Sources/PlaybackSDK/Documentation.docc/Resources/PlayerTestPlaylistView.swift @@ -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)") + } + } + } + +} diff --git a/Sources/PlaybackSDK/Documentation.docc/Tutorial/GetStarted.tutorial b/Sources/PlaybackSDK/Documentation.docc/Tutorial/GetStarted.tutorial index 4f46384..d993dda 100644 --- a/Sources/PlaybackSDK/Documentation.docc/Tutorial/GetStarted.tutorial +++ b/Sources/PlaybackSDK/Documentation.docc/Tutorial/GetStarted.tutorial @@ -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. diff --git a/preview_docc b/preview_docc new file mode 100644 index 0000000..63e762e --- /dev/null +++ b/preview_docc @@ -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 \ No newline at end of file From 858ba2eb13cd4f55b7814b4d491d4aa3adda9c88 Mon Sep 17 00:00:00 2001 From: Stefano Russello Date: Wed, 27 Nov 2024 10:38:19 +0100 Subject: [PATCH 3/5] CORE-5100 Playlist documentation - Fixed Tutorial controls and events - Control and Events on Readme with examples --- README.md | 59 +++++++++++++++++-- .../Tutorial/GetStarted.tutorial | 15 +++-- 2 files changed, 60 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 60ef98c..d305628 100644 --- a/README.md +++ b/README.md @@ -93,8 +93,8 @@ 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 +`entryIDs`: An array of Strings containing the unique identifiers of all the videos in the playlist. +`entryIDToPlay`: (Optional) Specifies the unique video identifier that will be played first in the playlist. If not provided, the first video in the `entryIDs` array will be played. Example: @@ -104,11 +104,58 @@ PlaybackSDKManager.shared.loadPlayer(entryIDs: listEntryId, entryIDToPlay: "0_xx }  ``` -## Control playlist -xxx +## Controlling Playlist Playback +To control playlist playback, declare a VideoPlayerPluginManager singleton instance as a @StateObject variable. This allows you to access various control functions and retrieve information about the current playback state. -## Playlist events -xxx +Here are some of the key functions you can utilize: + +`first()`: Plays the first video in the playlist. +`playPrevious()`: Plays the previous video in the playlist. +`playNext()`: Plays the next video in the playlist. +`last()`: Plays the last video in the playlist. +`seek(to: entryIdToSeek)`: Seek to a specific video Id +`activeEntryId()`: Returns the unique identifier of the currently playing video. + +By effectively leveraging these functions, you can create dynamic and interactive video player experiences. + +Example: + +```swift +@StateObject private var pluginManager = VideoPlayerPluginManager.shared +... +// 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 +``` + +## Receiving Playlist Events +To receive playlist events, declare a VideoPlayerPluginManager singleton instance, similar to how you did in the Controlling Playlist Playback section. +Utilize the `onReceive` modifier to listen for player events, such as the `PlaylistTransitionEvent`. This event provides information about the transition from one video to another. + +Example: + +```swift +@StateObject private var pluginManager = VideoPlayerPluginManager.shared +... +PlaybackSDKManager.shared.loadPlaylist(entryIDs: entryIDs, entryIDToPlay: entryIDToPlay, authorizationToken: authorizationToken) { errors in + ... + } + .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)") + } + } + } +``` # 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: diff --git a/Sources/PlaybackSDK/Documentation.docc/Tutorial/GetStarted.tutorial b/Sources/PlaybackSDK/Documentation.docc/Tutorial/GetStarted.tutorial index d993dda..d11b8c2 100644 --- a/Sources/PlaybackSDK/Documentation.docc/Tutorial/GetStarted.tutorial +++ b/Sources/PlaybackSDK/Documentation.docc/Tutorial/GetStarted.tutorial @@ -43,20 +43,19 @@ @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. + To load a playlist and handle errors, use the **loadPlaylist** function provided by the Playback SDK to initialize and load the video player. This function takes an array of entry IDs, the starting entry ID, 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 iterates through an array of **PlaybackError** objects and, for each error, switches on the error type to provide appropriate error handling. + The code also includes a placeholder comment to indicate where the removal of the player can be implemented in the **onDisappear** modifier. + f you want to allow users to access free content or implement 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 content. @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. + To control playlist playback and events, declare a **VideoPlayerPluginManager** singleton instance as a **@StateObject** variable. This allows you to access playlist controls and listen to player events. + In the **onReceive** modifier, you can listen to player events such as the **PlaylistTransitionEvent**, which provides information about transitions between videos. + Through the **pluginManager.selectedPlugin**, you can interact with playlist controls and retrieve the current video ID using the **activeEntryId** function. @Code(name: "PlayerTestPlaylistControlsAndEventsView.swift", file: PlayerTestPlaylistControlsAndEventsView.swift, previousFile: PlayerTestPlaylistView.swift) } From f224ab963d2618321ec930046ce56b85c5163dfa Mon Sep 17 00:00:00 2001 From: Stefano Russello Date: Thu, 28 Nov 2024 14:16:21 +0100 Subject: [PATCH 4/5] CORE-5100 Playlist documentation - Apply @artem-y-pamediagroup suggestion on PR #26 to the documentation and Readme --- README.md | 12 ++++++------ .../PlayerTestPlaylistControlsAndEventsView.swift | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index d305628..2187119 100644 --- a/README.md +++ b/README.md @@ -109,11 +109,11 @@ To control playlist playback, declare a VideoPlayerPluginManager singleton insta Here are some of the key functions you can utilize: -`first()`: Plays the first video in the playlist. +`playFirst()`: Plays the first video in the playlist. `playPrevious()`: Plays the previous video in the playlist. `playNext()`: Plays the next video in the playlist. -`last()`: Plays the last video in the playlist. -`seek(to: entryIdToSeek)`: Seek to a specific video Id +`playLast()`: Plays the last video in the playlist. +`seek(entryIdToSeek)`: Seek a specific video Id `activeEntryId()`: Returns the unique identifier of the currently playing video. By effectively leveraging these functions, you can create dynamic and interactive video player experiences. @@ -124,11 +124,11 @@ Example: @StateObject private var pluginManager = VideoPlayerPluginManager.shared ... // You can use the following playlist controls -pluginManager.selectedPlugin?.first() // Play the first video +pluginManager.selectedPlugin?.playFirst() // 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 +pluginManager.selectedPlugin?.playLast() // Play the last video +pluginManager.selectedPlugin?.seek(entryIdToSeek) { success in // Seek a specific video if (!success) { let errorMessage = "Unable to seek to \(entryIdToSeek)" } diff --git a/Sources/PlaybackSDK/Documentation.docc/Resources/PlayerTestPlaylistControlsAndEventsView.swift b/Sources/PlaybackSDK/Documentation.docc/Resources/PlayerTestPlaylistControlsAndEventsView.swift index 971d6b4..0081747 100644 --- a/Sources/PlaybackSDK/Documentation.docc/Resources/PlayerTestPlaylistControlsAndEventsView.swift +++ b/Sources/PlaybackSDK/Documentation.docc/Resources/PlayerTestPlaylistControlsAndEventsView.swift @@ -30,11 +30,11 @@ struct PlayerTestPlaylistControlsAndEventsView: View { Button { // You can use the following playlist controls - pluginManager.selectedPlugin?.first() // Play the first video + pluginManager.selectedPlugin?.playFirst() // 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 + pluginManager.selectedPlugin?.playLast() // Play the last video + pluginManager.selectedPlugin?.seek(entryIdToSeek) { success in // Seek a specific video if (!success) { let errorMessage = "Unable to seek to \(entryIdToSeek)" } From c7c2b4a844f4e03e77418021122cc2dfa756ec50 Mon Sep 17 00:00:00 2001 From: Stefano Russello Date: Fri, 29 Nov 2024 10:25:22 +0100 Subject: [PATCH 5/5] CORE-5100 Playlist documentation Applying @artem-y-pamediagroup suggestions on PR #29 - Fix Typo on GetStarted tutorial - Example multiline improving readability --- README.md | 29 +++++++++++++------ .../Tutorial/GetStarted.tutorial | 2 +- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 2187119..12f2957 100644 --- a/README.md +++ b/README.md @@ -85,7 +85,10 @@ To load the player UI in your application, use the `loadPlayer` method of the `P Example: ```swift -PlaybackSDKManager.shared.loadPlayer(entryID: entryId, authorizationToken: authorizationToken) { error in +PlaybackSDKManager.shared.loadPlayer( + entryID: entryId, + authorizationToken: authorizationToken +) { error in // Handle player UI error  }  ``` @@ -99,7 +102,11 @@ To load a sequential list of videos into the player UI, use the `loadPlaylist` m Example: ```swift -PlaybackSDKManager.shared.loadPlayer(entryIDs: listEntryId, entryIDToPlay: "0_xxxxxxxx", authorizationToken: authorizationToken) { errors in +PlaybackSDKManager.shared.loadPlayer( + entryIDs: listEntryId, + entryIDToPlay: "0_xxxxxxxx", + authorizationToken: authorizationToken +) { errors in // Handle player UI playlist errors }  ``` @@ -145,16 +152,20 @@ Example: ```swift @StateObject private var pluginManager = VideoPlayerPluginManager.shared ... -PlaybackSDKManager.shared.loadPlaylist(entryIDs: entryIDs, entryIDToPlay: entryIDToPlay, authorizationToken: authorizationToken) { errors in +PlaybackSDKManager.shared.loadPlaylist( + entryIDs: entryIDs, + entryIDToPlay: entryIDToPlay, + authorizationToken: authorizationToken +) { errors in ... - } - .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)") - } +} +.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)") } } +} ``` # Playing Access-Controlled Content diff --git a/Sources/PlaybackSDK/Documentation.docc/Tutorial/GetStarted.tutorial b/Sources/PlaybackSDK/Documentation.docc/Tutorial/GetStarted.tutorial index d11b8c2..6e47dad 100644 --- a/Sources/PlaybackSDK/Documentation.docc/Tutorial/GetStarted.tutorial +++ b/Sources/PlaybackSDK/Documentation.docc/Tutorial/GetStarted.tutorial @@ -46,7 +46,7 @@ To load a playlist and handle errors, use the **loadPlaylist** function provided by the Playback SDK to initialize and load the video player. This function takes an array of entry IDs, the starting entry ID, 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 iterates through an array of **PlaybackError** objects and, for each error, switches on the error type to provide appropriate error handling. The code also includes a placeholder comment to indicate where the removal of the player can be implemented in the **onDisappear** modifier. - f you want to allow users to access free content or implement 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 content. + If you want to allow users to access free content or implement 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 content. @Code(name: "PlayerTestPlaylistView.swift", file: PlayerTestPlaylistView.swift) }