The Player Lifecycle Strategy is a core architectural design in AliPlayerKit. It unifies the management of player instance creation, reuse, recycling, and destruction. This enables more efficient resource scheduling and performance optimization across different business scenarios.
Introduction
What is a player lifecycle strategy?
A player lifecycle strategy is an architectural mechanism that manages the lifecycle of player instances. It defines core operations such as acquiring, recycling, and clearing player instances. This decouples player resource management from your business logic.
Different business scenarios have different requirements for managing player instances:
Scenario | Requirements | Recommended strategy |
Normal video playback | Simple and direct, no reuse needed | Default |
Short-form video list | Frequent switching, requires fast startup | ReusePool |
Video preloading | Binds an ID to an instance, supports preloading | IdScopedPool |
Memory-sensitive scenarios | Single global instance, minimal memory footprint | Singleton |
Core value
Managing the player lifecycle with a strategy pattern provides the following core advantages:
Decoupling: Your business logic does not need to handle the details of player instance creation and destruction.
Flexibility: You can choose different strategies at runtime without changing your business logic.
Extensibility: You can implement custom policies to meet specific business needs.
Observability: Unified lifecycle management simplifies monitoring and debugging.
Design background
The Player Lifecycle Strategy originated from the multi-instance player pool in Alibaba Cloud's short-drama solution. It was designed to meet strict requirements for time-to-first-frame (TTFF), smooth switching, and memory control in fast-scrolling feeds. AliPlayerKit abstracts this practice into a strategy pattern to create a more general and flexible architecture for managing the player lifecycle.
Features
Core capabilities
Capability | Description |
Instance acquisition |
|
Instance recycling |
|
Resource cleanup |
|
Preloading |
|
ID binding |
|
Factory injection |
|
Built-in strategies
AliPlayerKit provides four built-in player lifecycle strategies:
Strategy | Class name | Description | Scenarios |
Default strategy |
| Creates a new instance each time. Destroys it immediately after use. | Normal playback |
Reuse pool strategy |
| Maintains an idle pool. Reuses instances from the pool first. | Short-form video list |
ID Binding Policy |
| Maintains a separate instance for each uniqueId. Evicts instances using a Least Recently Used (LRU) algorithm. | Video preloading |
Singleton strategy |
| A single global instance. All acquisition requests return the same instance. | List playback, memory-sensitive scenarios |
Architecture layers
┌──────────────────────────────────────────────────────────────┐
│ AliPlayerController │
│ initWithLifecycleStrategy: Injects strategy │
│ configure: Internally calls recycle(old) + acquire(new) │
│ destroy: Internally calls recycle(player, force:YES) │
├──────────────────────────────────────────────────────────────┤
│ PlayerLifecycleStrategy protocol │
│ setupWithFactory: / acquirePlayer / recyclePlayer:force: │
│ clear / preloadWithCount: / acquirePlayerWithUniqueId: │
├──────────────────────────────────────────────────────────────┤
│ BaseLifecycleStrategy base class │
│ factory / createPlayer / destroyPlayer: │
├──────────┬──────────┬─────────────────┬──────────────────────┤
│ Default │ReusePool │ IdScopedPool │ Singleton │
│ New each time │ Pool reuse │ ID binding + LRU │ Global singleton │
└──────────┴──────────┴─────────────────┴──────────────────────┘
│ │
│ PlayerFactory protocol / DefaultPlayerFactory │
│ createPlayer / destroyPlayer: │
└──────────────────────────────────────────────────────────────┘Usage
Basic usage — Default strategy
This is the simplest way to use the player. No extra configuration is needed. AliPlayerController uses DefaultLifecycleStrategy by default:
// Create a controller. The default strategy is used automatically.
AliPlayerController *controller = [[AliPlayerController alloc] init];
// Create the playback data.
VideoSource *source = [VideoSource urlSourceWithUrl:@"https://example.com/video.mp4"];
AliPlayerModel *model = [[AliPlayerModel alloc] initWithVideoSource:source];
// Configure the controller and attach it to the player view.
[controller configure:model];
[self.playerView attach:controller];Default strategy behavior: A new instance is created for each acquirePlayer call. The instance is destroyed immediately on each recyclePlayer:force: call. No pool is maintained.
Reuse pool strategy (short-form video scenario)
This strategy is suitable for scenarios with frequent video switching, such as short-form video lists and feeds:
// 1. Create a reuse pool strategy with a maximum capacity of 3.
ReusePoolLifecycleStrategy *strategy =
[[ReusePoolLifecycleStrategy alloc] initWithMaxPoolSize:3];
// 2. Inject the strategy when creating the controller.
AliPlayerController *controller =
[[AliPlayerController alloc] initWithLifecycleStrategy:strategy];
// 3. Configure and use the controller as normal.
VideoSource *source = [VideoSource urlSourceWithUrl:@"https://example.com/video.mp4"];
AliPlayerModel *model = [[AliPlayerModel alloc] initWithVideoSource:source];
[controller configure:model];
[self.playerView attach:controller];AliPlayerController automatically calls [strategy setupWithFactory:[AliPlayerKit playerFactory]] to inject the default factory during the initWithLifecycleStrategy: call. You do not need to initialize the strategy manually.
ID-scoped strategy (preloading scenario)
This strategy is suitable for scenarios that require preloading and switching between multiple videos. The same uniqueId always returns the same instance:
// 1. Create an ID-scoped strategy with a maximum capacity of 3.
IdScopedPoolLifecycleStrategy *strategy =
[[IdScopedPoolLifecycleStrategy alloc] initWithMaxPoolSize:3];
// 2. Inject the strategy when creating the controller.
AliPlayerController *controller =
[[AliPlayerController alloc] initWithLifecycleStrategy:strategy];
// 3. Usage — configure internally binds the ID using VideoSource.uniqueId.
VideoSource *source = [VideoSource vidAuthSourceWithVid:@"your_video_id"
playAuth:@"your_play_auth"];
AliPlayerModel *model = [[AliPlayerModel alloc] initWithVideoSource:source];
[controller configure:model];
[self.playerView attach:controller];Singleton strategy (list playback scenario)
This strategy uses a single global instance. All controllers share the same player:
// Get the singleton strategy. dispatch_once ensures it is globally unique.
SingletonLifecycleStrategy *strategy =
[SingletonLifecycleStrategy sharedInstance];
// Create the controller.
AliPlayerController *controller =
[[AliPlayerController alloc] initWithLifecycleStrategy:strategy];
// All controllers that use this strategy share the same player instance.
VideoSource *source = [VideoSource urlSourceWithUrl:@"https://example.com/video.mp4"];
AliPlayerModel *model = [[AliPlayerModel alloc] initWithVideoSource:source];
[controller configure:model];
[self.playerView attach:controller];When using the singleton strategy, multiple AliPlayerController instances cannot hold the player at the same time. This would cause state conflicts. The init method of SingletonLifecycleStrategy is marked as NS_UNAVAILABLE. You can only obtain the instance through +sharedInstance.
Scenario reference: List playback
ScenePlaylistViewController shows a complete example of using SingletonLifecycleStrategy to implement continuous playback:
// Initialize the player lifecycle strategy.
self.lifecycleStrategy = [SingletonLifecycleStrategy sharedInstance];
// Create the controller and inject the strategy.
self.currentController = [[AliPlayerController alloc]
initWithLifecycleStrategy:self.lifecycleStrategy];
// Register a notification for playback completion to trigger autoplay for the next video.
[self.currentController addNotificationDelegate:self];
// Configure the data and attach the controller. Playback starts automatically after attachment.
AliPlayerModel *model = [[AliPlayerModel alloc] initWithVideoSource:videoSource];
[self.currentController configure:model];
[self.playerView attach:self.currentController];
// PlayerNotificationDelegate callback — Autoplay the next video after playback completes.
- (void)playerDidCompletion {
[self playNextVideo];
}In a list playback scenario, SingletonLifecycleStrategy reuses the player instance. This avoids the performance overhead of frequent creation and destruction. When you switch videos, configure: automatically executes recycle(old instance) + acquire(new instance). You do not need to manage the player lifecycle manually.
Strategy details
DefaultLifecycleStrategy
This is the simplest strategy. It is equivalent to the original behavior before lifecycle strategies were introduced.
@interface DefaultLifecycleStrategy : BaseLifecycleStrategy <PlayerLifecycleStrategy>
@endFeatures:
Stateless. Creates a new instance through the factory for each
acquirePlayercall.Destroys the instance directly for each
recyclePlayer:force:call, regardless of theforcevalue.Lowest memory usage (released after use).
Suitable for most standard playback scenarios.
Core flow:
Operation | Behavior |
| Creates a new instance through the factory |
| Destroys the instance directly, regardless of the |
| No operation (does not maintain a pool) |
ReusePoolLifecycleStrategy
This strategy is based on the object pool pattern. It maintains an idle pool and an active list.
@interface ReusePoolLifecycleStrategy : BaseLifecycleStrategy <PlayerLifecycleStrategy>
/// The maximum capacity of the pool. Default is 3. If this capacity is exceeded, recycle will destroy the instance directly.
@property (nonatomic, assign) NSInteger maxPoolSize;
/// The number of idle players currently in the pool.
@property (nonatomic, assign, readonly) NSInteger idleCount;
/// The number of active players that have been acquired but not yet recycled.
@property (nonatomic, assign, readonly) NSInteger activeCount;
- (instancetype)initWithMaxPoolSize:(NSInteger)maxPoolSize NS_DESIGNATED_INITIALIZER;
@endFeatures:
Reuses instances from the idle pool first to reduce player initialization overhead.
Supports
preloadWithCount:to prefill the pool.Pool capacity is controlled by
maxPoolSize.All methods are thread-safe.
Suitable for short-form video lists and feed scenarios.
Core flow:
Operation | Behavior |
| Gets an instance from the idle pool first. If the pool is empty, creates a new instance through the factory. |
| Stops playback and returns the instance to the idle pool. If the pool is full, destroys the instance. |
| Destroys the instance immediately. |
| Destroys all instances in the idle pool. Active instances are not affected. |
| Pre-creates instances and adds them to the idle pool. The number is limited by |
IdScopedPoolLifecycleStrategy
This strategy maintains a separate player instance for each uniqueId. The same uniqueId always returns the same instance. It uses a Least Recently Used (LRU) mechanism to control the number of instances.
@interface IdScopedPoolLifecycleStrategy : BaseLifecycleStrategy <PlayerLifecycleStrategy>
/// The maximum capacity of the pool. Default is 3. When exceeded, the least recently used instance is automatically evicted by the LRU algorithm.
/// If you change this value and the new value is less than the current number of instances, excess instances are immediately evicted in LRU order.
@property (nonatomic, assign) NSInteger maxPoolSize;
/// The number of player instances in the current mapping table (both active and idle).
@property (nonatomic, assign, readonly) NSInteger poolCount;
- (instancetype)initWithMaxPoolSize:(NSInteger)maxPoolSize NS_DESIGNATED_INITIALIZER;
@endFeatures:
ID binding. The same
uniqueIdalways reuses the same instance.LRU eviction mechanism automatically cleans up the least recently used instances.
Supports
preloadWithCount:to pre-create unbound instances.All methods are thread-safe.
The design is based on the LRU management mechanism of the multi-instance player pool in Alibaba Cloud's short-drama solution.
Suitable for video preloading and multi-video switching scenarios.
Core flow:
Operation | Behavior |
| Returns the existing instance and updates its position in the LRU order. |
| Gets an instance from the preloaded queue first. Otherwise, creates a new instance and binds it to the ID. |
| Stops playback only. The instance remains in the mapping table and is evicted automatically by the LRU algorithm. |
| Removes the instance from the mapping table and destroys it immediately. |
| Cleans up instances in the preloaded queue and the mapping table. |
| Creates instances without a bound ID. These are used the first time a new ID is acquired. |
If a strategy implements the acquirePlayerWithUniqueId: method, AliPlayerController calls it instead of acquirePlayer. This enables ID binding through VideoSource.uniqueId. Similarly, recyclePlayer:uniqueId:force: is called in preference to recyclePlayer:force:.
SingletonLifecycleStrategy
This strategy maintains a single global player instance. It is implemented as a true singleton pattern using dispatch_once.
@interface SingletonLifecycleStrategy : BaseLifecycleStrategy <PlayerLifecycleStrategy>
/// Gets the globally shared singleton strategy instance.
+ (instancetype)sharedInstance;
- (instancetype)init NS_UNAVAILABLE;
+ (instancetype)new NS_UNAVAILABLE;
@endFeatures:
Globally unique. All controllers that use this strategy share the same player instance.
Lowest memory usage.
clearis a no-op. It does not destroy the singleton instance. You must destroy it explicitly by callingrecyclePlayer:force:YES.Not suitable for scenarios where multiple videos play at the same time.
Multiple
AliPlayerControllerinstances cannot hold the player at the same time. This would cause state conflicts.
Core flow:
Operation | Behavior |
| Returns the global instance if it exists. Otherwise, creates it. |
| Stops playback only. The instance is retained. |
| Destroys the global instance. |
| No-op (does not destroy the singleton instance). |
Strategy comparison table
Strategy | Acquisition behavior | Recycling behavior (force:NO) | Scenarios | TTFF | Thread safety |
Default | Each new item | Destroy immediately | Normal playback | Slow | — |
ReusePool | Get from pool / Create new | Return to pool / Destroy if full | Short-form video list | Fast | Yes |
IdScoped | ID hit / Prefilled / Create new | Keep in mapping table / Evict by LRU | Preloading | Fastest | Yes |
Singleton | Create only once | Stop playback only | List playback | Medium | — |
Custom development
Strategy protocol (PlayerLifecycleStrategy)
All lifecycle strategies conform to the PlayerLifecycleStrategy protocol:
@protocol PlayerLifecycleStrategy <NSObject>
@required
/// Injects the player factory. Called automatically by AliPlayerController.
- (void)setupWithFactory:(id<PlayerFactory>)factory;
/// Gets a player instance. The strategy decides whether to create or reuse one.
- (id<MediaPlayer>)acquirePlayer;
/// Recycles a player instance. force:YES forces destruction. force:NO lets the strategy decide.
- (void)recyclePlayer:(nullable id<MediaPlayer>)player force:(BOOL)force;
/// Releases all player instances held by the strategy and restores the initial state.
- (void)clear;
@optional
/// Preloads a specified number of player instances into the pool.
- (void)preloadWithCount:(NSInteger)count;
/// Gets a player instance by a unique business ID. Implemented only by IdScopedPoolLifecycleStrategy.
- (id<MediaPlayer>)acquirePlayerWithUniqueId:(NSString *)uniqueId;
/// Recycles a player instance by a unique business ID. Implemented only by IdScopedPoolLifecycleStrategy.
- (void)recyclePlayer:(nullable id<MediaPlayer>)player
uniqueId:(NSString *)uniqueId
force:(BOOL)force;
@endsetupWithFactory: is called automatically by AliPlayerController during the initWithLifecycleStrategy: call to inject the factory instance returned by [AliPlayerKit playerFactory]. Developers usually do not need to call this method manually. To preload instances before creating a controller, you can manually call setupWithFactory: and then preloadWithCount:.
Strategy base class (BaseLifecycleStrategy)
BaseLifecycleStrategy is the shared base class for all built-in strategies. It provides factory management and template methods:
@interface BaseLifecycleStrategy : NSObject
/// The currently injected player factory (read-only).
@property (nonatomic, strong, readonly) id<PlayerFactory> factory;
/// Injects the player factory. This is idempotent. It only takes effect on the first call. Subsequent calls are ignored and a warning is logged.
- (void)setupWithFactory:(id<PlayerFactory>)factory;
/// Creates a new player instance through the factory. Child classes should call this method instead of calling the factory directly.
- (id<MediaPlayer>)createPlayer;
/// Destroys a player instance through the factory. Child classes should call this method instead of calling the factory directly.
- (void)destroyPlayer:(nullable id<MediaPlayer>)player;
@endBaseLifecycleStrategy itself does not declare conformance to the PlayerLifecycleStrategy protocol. Child classes must declare conformance and implement methods such as acquirePlayer, recyclePlayer:force:, and clear. Child classes should use the createPlayer and destroyPlayer: template methods to operate on player instances instead of calling the factory directly. This ensures that operations are logged uniformly.
Player factory (PlayerFactory)
The PlayerFactory protocol defines the interface for creating and destroying player instances:
@protocol PlayerFactory <NSObject>
/// Creates a player instance. Each call creates a new instance in the PlayerStateIdle state.
- (id<MediaPlayer>)createPlayer;
/// Destroys a player instance. This releases all resources. If the instance is nil, only a warning is logged.
- (void)destroyPlayer:(nullable id<MediaPlayer>)player;
@endThe framework includes the built-in DefaultPlayerFactory, which uses the Alibaba Cloud Player SDK (AliPlayer) to create standard instances. You can replace it with a custom factory using [AliPlayerKit setPlayerFactory:].
Custom strategy example
The following example shows a simple cache policy based on ID mapping:
@interface MyCacheLifecycleStrategy : BaseLifecycleStrategy <PlayerLifecycleStrategy>
@end
@implementation MyCacheLifecycleStrategy {
NSMutableDictionary<NSString *, id<MediaPlayer>> *_playerMap;
}
- (instancetype)init {
self = [super init];
if (self) {
_playerMap = [NSMutableDictionary dictionary];
}
return self;
}
#pragma mark - PlayerLifecycleStrategy
- (id<MediaPlayer>)acquirePlayer {
return [self createPlayer];
}
- (id<MediaPlayer>)acquirePlayerWithUniqueId:(NSString *)uniqueId {
id<MediaPlayer> player = _playerMap[uniqueId];
if (!player) {
player = [self createPlayer];
_playerMap[uniqueId] = player;
}
return player;
}
- (void)recyclePlayer:(id<MediaPlayer>)player
uniqueId:(NSString *)uniqueId
force:(BOOL)force {
if (!player) return;
if (force) {
[_playerMap removeObjectForKey:uniqueId];
[self destroyPlayer:player];
} else {
[player stop];
}
}
- (void)recyclePlayer:(id<MediaPlayer>)player force:(BOOL)force {
if (!player) return;
[self destroyPlayer:player];
}
- (void)clear {
for (id<MediaPlayer> player in _playerMap.allValues) {
[self destroyPlayer:player];
}
[_playerMap removeAllObjects];
}
@endRegistration and usage:
MyCacheLifecycleStrategy *strategy = [[MyCacheLifecycleStrategy alloc] init];
AliPlayerController *controller =
[[AliPlayerController alloc] initWithLifecycleStrategy:strategy];
// The controller automatically calls [strategy setupWithFactory:...] to inject the factory.Lifecycle flow
Interaction flow between controller and strategy
AliPlayerController initialization
↓
initWithLifecycleStrategy: → Saves strategy reference
↓ → Automatically calls [strategy setupWithFactory:[AliPlayerKit playerFactory]]
↓
[controller configure:model]
↓
├── Has player? → [strategy recyclePlayer:old instance force:NO]
↓
├── Does strategy implement acquirePlayerWithUniqueId:?
│ ├── YES → [strategy acquirePlayerWithUniqueId:source.uniqueId]
│ └── NO → [strategy acquirePlayer]
↓
├── [player setDataSource:model]
├── [player prepare]
└── autoPlay ? → [player start]
↓
Switch video source → [controller configure:newModel]
↓ → recycle(old) + acquire(new) + setDataSource + prepare
↓
[controller destroy]
↓
├── [strategy recyclePlayer:player force:YES]
└── Controller releaseWhen to clean up strategy resources
Timing | Operation | Description |
Video switching |
| Automatic, no manual operation needed |
Controller destruction | The | Autocomplete |
Page exit | Call | Must be called manually |
Releasing pool resources |
| Call as needed (for example, on a memory warning) |
Best practices
Strategy selection guide
Scenario | Recommended strategy | Reason |
Normal video product page | Default | Simple and direct. Resources are released when the page is destroyed. |
Vertical scrolling list of short-form videos | ReusePool | Reusing instances reduces creation overhead and improves scrolling smoothness. |
Video preloading / Instant playback | IdScoped | ID binding and preloading enable extremely fast startup. |
Continuous list playback | Singleton | A single global instance reduces the number of initializations. |
Low-end devices / Low memory | Singleton | Single global instance for minimal memory footprint. |
Podcast / Audio playback | Singleton | A single audio stream scenario does not require multiple instances. |
Memory management recommendations
Recommendation | Description |
Listen for memory warnings | Pool-based strategies should listen for |
Set a reasonable pool capacity | Each player instance uses about 35 MB to 40 MB of memory. You should set |
Release the idle pool in the background | You can call |
Call destroy when the page is destroyed | You must call |
// Listen for memory warnings to release pool resources.
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(handleMemoryWarning:)
name:UIApplicationDidReceiveMemoryWarningNotification
object:nil];
- (void)handleMemoryWarning:(NSNotification *)notification {
[self.lifecycleStrategy clear];
}Page lifecycle management
@interface MyViewController ()
@property (nonatomic, strong) AliPlayerView *playerView;
@property (nonatomic, strong) AliPlayerController *controller;
@property (nonatomic, strong) id<PlayerLifecycleStrategy> lifecycleStrategy;
@end
@implementation MyViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.lifecycleStrategy = [[ReusePoolLifecycleStrategy alloc] initWithMaxPoolSize:3];
self.controller = [[AliPlayerController alloc]
initWithLifecycleStrategy:self.lifecycleStrategy];
// ... configure + attach
}
- (void)dealloc {
// Required: Destroy the controller.
if (_controller) {
[_controller destroy];
}
// Optional: If this page is the last user of the strategy, release the pool resources.
if (_lifecycleStrategy) {
[_lifecycleStrategy clear];
}
}
@endNotes
Scenario | Recommended practice | Reason |
Page destruction | Call | Avoid memory leaks |
Strategy cleanup | The last user calls | Release idle instances in the pool |
Singleton strategy | Do not have multiple controllers hold the player at the same time | Avoid state conflicts |
Factory injection | Do not call | The controller injects it automatically, and the method is idempotent (only the first call is effective). |
Preloading | Call after the controller is created | The factory is injected automatically when the controller is created. |
Common mistakes
// ✗ Incorrect: Forgetting to destroy the controller in dealloc.
- (void)dealloc {
[self.playerView detach];
// [_controller destroy] is not called, causing a memory leak.
}
// ✓ Correct: Destroy the controller and clean up the strategy as needed.
- (void)dealloc {
if (_controller) {
[_controller destroy];
}
if (_lifecycleStrategy) {
[_lifecycleStrategy clear];
}
}// ✗ Incorrect: Holding multiple controllers at the same time with a singleton strategy.
SingletonLifecycleStrategy *strategy = [SingletonLifecycleStrategy sharedInstance];
AliPlayerController *controller1 = [[AliPlayerController alloc] initWithLifecycleStrategy:strategy];
AliPlayerController *controller2 = [[AliPlayerController alloc] initWithLifecycleStrategy:strategy];
// controller1 and controller2 share the same player instance, causing a state conflict.
// ✓ Correct: Ensure only one controller uses the singleton strategy at a time.
[controller1 destroy];
AliPlayerController *controller2 = [[AliPlayerController alloc] initWithLifecycleStrategy:strategy];// ✗ Incorrect: Trying to alloc init SingletonLifecycleStrategy.
SingletonLifecycleStrategy *strategy = [[SingletonLifecycleStrategy alloc] init]; // Compile error.
// ✓ Correct: Get the instance through sharedInstance.
SingletonLifecycleStrategy *strategy = [SingletonLifecycleStrategy sharedInstance];API reference
Core classes and protocols
Protocol / Class | Description |
| Lifecycle strategy protocol. Defines interfaces for acquiring, recycling, and clearing instances. |
| Strategy base class. Provides factory management and createPlayer/destroyPlayer: template methods. |
| Player factory protocol. Defines interfaces for creating and destroying instances. |
| Default factory implementation. Uses the Alibaba Cloud Player SDK to create instances. |
| Media player protocol. Defines interfaces for playback control, status queries, and more. |
Built-in strategies
Class | Creation method | Key properties |
|
| — |
|
|
|
|
|
|
|
| — |
PlayerLifecycleStrategy methods
Method | Required | Description |
| Yes | Injects the player factory. Called automatically by the controller. |
| Yes | Gets a player instance. |
| Yes | Recycles a player instance. |
| Yes | Releases all cached instances. |
| No | Preloads instances. Implemented by ReusePool and IdScoped. |
| No | Gets an instance by uniqueId. Implemented by IdScoped. |
| No | Recycles an instance by uniqueId. Implemented by IdScoped. |
BaseLifecycleStrategy methods
Method/Property | Description |
| The currently injected player factory (read-only). |
| Injects the factory. Idempotent, only the first call is effective. |
| Creates an instance through the factory with uniform logging. |
| Destroys an instance through the factory with uniform logging. |
force parameter description
force value | Behavior | Scenario |
| The strategy decides whether to return the instance to the pool or just stop playback. | Normal video switching. Used inside |
| Destroys the instance immediately, regardless of the strategy. | Controller destruction. Used inside |
uniqueId description
uniqueId is a unique business identifier property on VideoSource used to distinguish different video sources. Different strategies use it in different ways:
Strategy | uniqueId purpose |
Default | Not used |
ReusePool | Not used |
IdScoped | Core identifier. The same uniqueId always returns the same instance. |
Singleton | Not used |
Example reference
The PlayerKitUsages/UsageLifecycleStrategy module provides a complete example of how to use player lifecycle strategies. It demonstrates switching between the four built-in strategies (Default, ReusePool, Singleton, and IdScopedPool). It also shows the instance reuse behavior (NEW/REUSED/HIT) for multi-source playback and the resource cleanup flow for strategies and controllers.