Callbacks
The BambuserCommerceSDK provides the BambuserVideoPlayerDelegate protocol for handling communications from a Bambuser video player instance. By implementing this protocol, your class can receive callback messages when new events occur or errors are encountered.
Methods:
onNewEventReceived(id: String, event: BambuserEventPayload):- Called when a new event is received from the video player.
- Parameters:
id: A unique identifier for the video player.event: ABambuserEventPayloadcontaining the event type and associated data.
onErrorOccurred(id: String, error: Error):- Called when an error occurs within the video player.
- Parameters:
id: A unique identifier for the video player.error: The error encountered by the video player.
onVideoStatusChanged(_ id: String, state: BambuserVideoState):- Called when the playback state of the video changes (e.g., playing, paused, ended).
- Parameters:
id: A unique identifier for the video player.state: ABambuserVideoStateenum value indicating the current playback state.
onVideoProgress(_ id: String, duration: Double, currentTime: Double):- Called to report playback progress of the video.
- Parameters:
id: A unique identifier for the video player.duration: The total duration of the video in seconds.currentTime: The current playback time in seconds.
onThumbnailTapped(_ id: String):- Called when the video thumbnail is tapped.
- Parameters:
id: A unique identifier for the video player. Example Implementation
class ViewController: BambuserVideoPlayerDelegate {
func onNewEventReceived(id: String, event: BambuserEventPayload) {
print("Player \(id) sent event: \(event)")
}
func onErrorOccurred(id: String, error: Error) {
print("Error in player \(id): \(error.localizedDescription)")
}
func onVideoStatusChanged(_ id: String, state: BambuserVideoState) {
print("Player \(id) changed state to: \(state)")
}
func onVideoProgress(_ id: String, duration: Double, currentTime: Double) {
print("Player \(id) progress: \(currentTime)/\(duration) seconds")
}
func onThumbnailTapped(_ id: String) {
print("Player [\(id)] thumbnail was tapped")
}
}
Player States
BambuserVideoState values reported via onVideoStatusChanged and accessible through playerView.currentPlayerState:
| State | When it fires |
|---|---|
.loading | Player is initialising or buffering |
.playing | Playback is active (after autoplay or play()) |
.paused | Playback was paused via pause() |
.error | An unrecoverable error occurred (e.g. invalid show ID) |
Error Handling
When the player encounters an unrecoverable error — such as an invalid or unpublished show ID — two callbacks fire:
onVideoStatusChangedwith state.erroronErrorOccurredwith the underlyingError
class ViewController: BambuserVideoPlayerDelegate {
func onVideoStatusChanged(_ id: String, state: BambuserVideoState) {
if state == .error {
// Hide the player and show a fallback UI
DispatchQueue.main.async {
self.playerView.removeFromSuperview()
self.showErrorBanner("This show is unavailable.")
}
}
}
func onErrorOccurred(id: String, error: Error) {
print("Player \(id) error: \(error.localizedDescription)")
// Log to your analytics or crash reporting service
}
}
Common causes of .error state:
- Invalid, deleted, or unpublished show ID passed to
type: .live(id:) - Network failure during player initialisation
Picture-in-Picture (PiP) Delegate
The BambuserCommerceSDK provides Picture-in-Picture (PiP) support through the PictureInPictureController interface, available via each BambuserPlayerView instance. PiP allows video content to continue playing in a floating overlay while users interact with other parts of the app or their device.
PictureInPictureController
The PictureInPictureController lets you control and monitor PiP mode.
Properties:
isEnabled: ABoolindicating whether PiP is allowed for the video container.isActive: ABoolindicating whether PiP is currently active.delegate: An optionalBambuserPictureInPictureDelegateto receive PiP state change callbacks.
Methods:
start(): Starts PiP mode programmatically, enabling the video to continue in a floating overlay.stop(): Stops PiP mode and removes the floating overlay.
Example:
// Access the controller from your player view
let pipController = playerView.pictureInPictureController
// Enable PiP (if not already enabled)
pipController.isEnabled = true
// Start PiP
pipController.start()
// Stop PiP
pipController.stop()
Notes
- PiP is enabled by default for live and pre-recorded videos.
- PiP is disabled by default for shoppable videos.
- Make sure to set
isEnabledappropriately before callingstart()or before PiP mode starts automatically.
BambuserPictureInPictureDelegate Methods:
onPictureInPictureStateChanged(_ id: String, state: PlayerPipState): Called for all PIP changes in the app.- which contains PlayerPipState as follow:
public enum PlayerPipState {
/// Indicates that Picture-in-Picture mode is about to start.
case willStart
/// Indicates that Picture-in-Picture mode is about to stop.
case willStop
/// Indicates that Picture-in-Picture mode has started.
case started
/// Indicates that Picture-in-Picture mode has stopped.
case stopped
/**
Indicates that the Picture-in-Picture session has been restored.
This occurs when the user taps “Go to full screen,” bringing the app back to the foreground (if app is in background) and disabling Picture-in-Picture mode.
*/
case restored
}