Multiple player managers for tvOS
Version 4.4.0 of the Wowza Flowplayer Apple SDK added support to manage more than one AvPlayer
instance simultaneously in your tvOS applications. With the help of these managers, all player instances can be controlled separately as they function independently of each other.
For information related to listening to events, managing media playback, and handling errors, see the following pages:
Set up multiple managers
When using the FlowplayerManager
class, generally only one AVPlayer
instance can be controlled at once. However, if you have multiple AVPlayer
instances in a single view, you can set up multiple managers to handle different players. All events are streamlined into a single source, allowing you to listen to them using the delegate pattern or the NotificationCenter.
In the following example, we create two manager instances with the FlowplayerManager
class, then load specific media for a main player and a secondary player:
// Declare AVPlayer instances
let mainPlayer = AVPlayer()
let secondaryPlayer = AVPlayer()
// Create two manager instances using the FlowplayerManager class
// Associate each manager instances with a player instance
lazy var mainManager = FlowplayerManager(avPlayer: mainPlayer)
lazy var secondaryManager = FlowplayerManager(avPlayer: secondaryPlayer)
// Load the managers and call load() method for each
mainManager.load(...)
secondaryManager.load(...)
Identify a manager instance
To work with each manager instance, you can use the id
property of the FlowplayerAPI protocol. By default, the manager randomly generates and emits the value of this property. You can also set up a manager id
that uses a custom string. For more, see Set a custom manager identifier.
This section provides examples of how to identify a manager instance, then use the delegate pattern or the notification dispatch mechanism to perform a certain action.
Use delegation to identify a manager
You can use the delegate pattern to listen for an capture the id
of a manager that's triggered a specific event.
The following example monitors changes in the manager's state and responds based on which manager instance triggered the state change. For an event listeners reference, see Listen for events with the delegate method.
// Declare AVPlayer instances
let mainPlayer = AVPlayer()
let secondaryPlayer = AVPlayer()
// Create two manager instances using the FlowplayerManager class
// Associate each manager instances with a player instance
lazy var mainManager = FlowplayerManager(avPlayer: mainPlayer)
lazy var secondaryManager = FlowplayerManager(avPlayer: secondaryPlayer)
// Set delegate property and conform to FlowplayerDelegate protocol
mainManager.delegate = self
secondaryManager.delegate = self
// Use FlowplayerDelegate protocol to observe and respond to manager state changes
func player(manager: FlowplayerAPI, didChangeState state: PlayerState) {
// Compare id property of mainManager variable and manager parameter
guard mainManager.id == manager.id else {
// If not equal, indicate event was triggered by secondaryManager instance
print("secondaryManager triggered this event")
return
}
// If equal, indicate event was triggered by mainManager instance
print("mainManager changed the state to: \(state)")
}
Use notifications to identify a manager
You can also use the notification dispatch mechanism in the Wowza Flowplayer Apple SDK to detect the id
of the manager and respond to manager events.
The following code snippet sets up a notification observer for changes in the manager's state. When a state notification is received, it checks the manager's identifier and performs a certain action based on which manager triggered the event. For more information, see Listen for events with the NotificationCenter.
// Declare player instances
let mainPlayer = FlowplayerView()
let secondaryPlayer = FlowplayerView()
// Create two manager instances using the FlowplayerManager class
// Associate each manager instances with a player instance
lazy var mainManager = FlowplayerManager(avPlayer: mainPlayer)
lazy var secondaryManager = FlowplayerManager(avPlayer: secondaryPlayer)
// Register observer for flowplayerDidChangeState notification
NotificationCenter.default.addObserver(
self,
selector: #selector(onReceivedState),
name: .flowplayerDidChangeState,
object: nil
)
// Call onReceivedState method when notification is received
@objc
private func onReceivedState(_ notification: Notification) {
guard
// Retrieve id from notification's user info and check if it matches mainManager id
let id = notification.userInfo?[\FlowplayerAPI.id] as? String,
mainManager.id == id
else {
// If not equal, indicate event was triggered by secondaryManager instance
print("secondaryManager triggered this event")
return
}
guard let state = notification.object as? PlayerState else {
return
}
// If equal, indicate event was triggered by mainManager instance
print("mainManager changed state to: \(state)")
}
Set a custom manager identifier
The player's default behavior randomly generates and emits the value of an id
property to identify each manager instance. You can also set a manager id
that uses a custom string. This is helpful when you have a requirement to use a specific identifier for your manager.
To set up a manager with a custom id
, you can leverage this FlowplayerManager
initializer:
public init(avPlayer: AVPlayer? = nil, id: String? = nil)
When you add the player to your tvOS project, use the initializer and replace the [some-id]
placeholder with a desired ID value:
// If not AVPlayer is provided FlowplayerManager will create one
let manager = FlowplayerManager(avPlayer: nil, id: "[some-id]")
The avPlayer
and id
parameters are optional. If avPlayer
is omitted, the FlowplayerManager
class creates its own AVPlayer
instance instead of using an instance you provide.