全部產品
Search
文件中心

ApsaraVideo VOD:播放器生命週期策略

更新時間:Sep 10, 2026

播放器生命週期策略 (Player Lifecycle Strategy) 是 AliPlayerKit 的核心架構設計,用於統一管理播放器執行個體的建立、複用、回收與銷毀,在不同業務情境下實現更合理的資源調度與效能最佳化。

概念介紹

什麼是播放器生命週期策略?

播放器生命週期策略是用於管理播放器執行個體生命週期的架構機制。它定義了播放器執行個體的擷取(acquire)、回收(recycle)、清理(clear)等核心操作,將播放器資源管理從業務代碼中解耦出來。

不同的業務情境對播放器執行個體的管理有不同的需求:

情境

需求特點

推薦策略

普通視頻播放

簡單直接,無需複用

Default

短視頻列表

頻繁切換,需要快速起播

ReusePool

視頻預先載入

ID 與執行個體綁定,支援預先載入

IdScopedPool

記憶體敏感情境

全域唯一執行個體,最小記憶體佔用

Singleton

核心價值

通過策略模式管理播放器生命週期,帶來以下核心優勢:

  • 解耦:業務代碼無需關心播放器執行個體的建立和銷毀細節。

  • 靈活:運行時選擇不同策略,無需修改業務代碼。

  • 可擴充:可實現自訂策略,滿足特定業務需求。

  • 可觀測:統一的生命週期管理,便於監控和調試。

設計背景

播放器生命週期策略源於阿里雲微短劇解決方案中的多執行個體播放器池,旨在應對資訊流快速滑動情境下對首幀速度、切換流暢度及記憶體控制的嚴苛要求。AliPlayerKit 將該實踐抽象為策略模式,構建了更通用、靈活的播放器生命週期管理架構。

功能特性

核心能力

能力

說明

執行個體擷取

acquirePlayer 擷取播放器執行個體,由策略決定建立或複用

執行個體回收

recyclePlayer:force: 回收執行個體,由策略決定銷毀或保留

資源清理

clear 清理策略持有的所有播放器執行個體,恢複初始狀態

預先載入

preloadWithCount: 預建立執行個體到池中,減少首幀耗時(@optional)

ID 綁定

acquirePlayerWithUniqueId: 按業務唯一標識擷取執行個體(@optional)

工廠注入

setupWithFactory: 注入播放器工廠,由 AliPlayerController 自動調用

內建策略

AliPlayerKit 提供 4 種內建的播放器生命週期策略:

策略

類名

說明

適用情境

預設策略

DefaultLifecycleStrategy

每次建立新執行個體,用完立即銷毀

普通播放

複用池策略

ReusePoolLifecycleStrategy

維護空閑池,優先複用池中執行個體

短視頻列表

ID 繫結原則

IdScopedPoolLifecycleStrategy

為每個 uniqueId 維護獨立執行個體,LRU 淘汰

視頻預先載入

單例策略

SingletonLifecycleStrategy

全域唯一執行個體,所有擷取返回同一執行個體

列表播放、記憶體敏感情境

架構層次

┌──────────────────────────────────────────────────────────────┐
│                  AliPlayerController                          │
│       initWithLifecycleStrategy: 注入策略                      │
│       configure: 內部調用 recycle(舊) + acquire(新)             │
│       destroy: 內部調用 recycle(player, force:YES)              │
├──────────────────────────────────────────────────────────────┤
│              PlayerLifecycleStrategy 協議                      │
│   setupWithFactory: / acquirePlayer / recyclePlayer:force:     │
│   clear / preloadWithCount: / acquirePlayerWithUniqueId:       │
├──────────────────────────────────────────────────────────────┤
│                 BaseLifecycleStrategy 基類                     │
│            factory / createPlayer / destroyPlayer:             │
├──────────┬──────────┬─────────────────┬──────────────────────┤
│ Default  │ReusePool │  IdScopedPool   │     Singleton        │
│ 每次建立  │ 池複用    │  ID 綁定 + LRU  │     全域唯一          │
└──────────┴──────────┴─────────────────┴──────────────────────┘
│                                                                │
│              PlayerFactory 協議 / DefaultPlayerFactory          │
│            createPlayer / destroyPlayer:                        │
└──────────────────────────────────────────────────────────────┘

使用方式

基本用法 — 預設策略

最簡單的使用方式,無需額外配置。AliPlayerController 預設使用 DefaultLifecycleStrategy:

// 建立控制器(自動使用預設策略)
AliPlayerController *controller = [[AliPlayerController alloc] init];

// 建立播放資料
VideoSource *source = [VideoSource urlSourceWithUrl:@"https://example.com/video.mp4"];
AliPlayerModel *model = [[AliPlayerModel alloc] initWithVideoSource:source];

// 配置並綁定到播放器視圖
[controller configure:model];
[self.playerView attach:controller];

預設策略行為:每次 acquirePlayer 建立新執行個體,每次 recyclePlayer:force: 立即銷毀,不維護任何池。

複用池策略(短視頻情境)

適合短視頻列表、資訊流等頻繁切換視訊的情境:

// 1. 建立複用池策略(最大容量 3)
ReusePoolLifecycleStrategy *strategy =
    [[ReusePoolLifecycleStrategy alloc] initWithMaxPoolSize:3];

// 2. 建立控制器時注入策略
AliPlayerController *controller =
    [[AliPlayerController alloc] initWithLifecycleStrategy:strategy];

// 3. 正常配置和使用
VideoSource *source = [VideoSource urlSourceWithUrl:@"https://example.com/video.mp4"];
AliPlayerModel *model = [[AliPlayerModel alloc] initWithVideoSource:source];
[controller configure:model];
[self.playerView attach:controller];
說明

AliPlayerController 在 initWithLifecycleStrategy: 時自動調用 [strategy setupWithFactory:[AliPlayerKit playerFactory]] 注入預設工廠,調用方無需手動初始化策略。

ID 繫結原則(預先載入情境)

適合需要預先載入和多視頻切換的情境,相同 uniqueId 始終返回同一執行個體:

// 1. 建立 ID 繫結原則(最大容量 3)
IdScopedPoolLifecycleStrategy *strategy =
    [[IdScopedPoolLifecycleStrategy alloc] initWithMaxPoolSize:3];

// 2. 建立控制器時注入策略
AliPlayerController *controller =
    [[AliPlayerController alloc] initWithLifecycleStrategy:strategy];

// 3. 使用 configure 內部通過 VideoSource.uniqueId 進行 ID 綁定
VideoSource *source = [VideoSource vidAuthSourceWithVid:@"your_video_id"
                                              playAuth:@"your_play_auth"];
AliPlayerModel *model = [[AliPlayerModel alloc] initWithVideoSource:source];
[controller configure:model];
[self.playerView attach:controller];

單例策略(列表播放情境)

全域唯一執行個體,所有控制器共用同一播放器:

// 擷取單例策略(dispatch_once 保證全域唯一)
SingletonLifecycleStrategy *strategy =
    [SingletonLifecycleStrategy sharedInstance];

// 建立控制器
AliPlayerController *controller =
    [[AliPlayerController alloc] initWithLifecycleStrategy:strategy];

// 所有使用此策略的控制器共用同一播放器執行個體
VideoSource *source = [VideoSource urlSourceWithUrl:@"https://example.com/video.mp4"];
AliPlayerModel *model = [[AliPlayerModel alloc] initWithVideoSource:source];
[controller configure:model];
[self.playerView attach:controller];
說明

使用單例策略時,多個 AliPlayerController 不可同時持有播放器,否則會導致狀態衝突。SingletonLifecycleStrategy 的 init 方法被標記為 NS_UNAVAILABLE,只能通過 +sharedInstance 擷取。

情境參考:列表播放

ScenePlaylistViewController 展示了 SingletonLifecycleStrategy 實現自動連播的完整用法:

// 初始化播放器生命週期策略
self.lifecycleStrategy = [SingletonLifecycleStrategy sharedInstance];

// 建立控制器並注入策略
self.currentController = [[AliPlayerController alloc]
    initWithLifecycleStrategy:self.lifecycleStrategy];

// 註冊播放完成通知(用於觸發自動播放下一個)
[self.currentController addNotificationDelegate:self];

// 配置資料並綁定(掛載後自動開始播放)
AliPlayerModel *model = [[AliPlayerModel alloc] initWithVideoSource:videoSource];
[self.currentController configure:model];
[self.playerView attach:self.currentController];

// PlayerNotificationDelegate 回調 播放完成後自動播放下一個
- (void)playerDidCompletion {
    [self playNextVideo];
}
說明

列表播放情境通過 SingletonLifecycleStrategy 複用播放器執行個體,避免頻繁建立和銷毀帶來的效能開銷。切換視訊時,configure: 內部自動執行 recycle(舊執行個體) + acquire(新執行個體),無需手動管理播放器生命週期。

策略詳解

DefaultLifecycleStrategy

最簡單的策略,等價於未引入生命週期策略前的原始行為。

@interface DefaultLifecycleStrategy : BaseLifecycleStrategy <PlayerLifecycleStrategy>
@end

特點:

  • 無狀態,每次 acquirePlayer 通過工廠建立新執行個體。

  • 每次 recyclePlayer:force: 直接銷毀執行個體,無論 force 值。

  • 記憶體佔用最低(用完即釋放)。

  • 適合大多數標準播放情境。

核心流程:

操作

行為

acquirePlayer

通過工廠建立新執行個體

recyclePlayer:force:

直接銷毀執行個體(無論 force 為何值)

clear

無操作(不維護任何池)

ReusePoolLifecycleStrategy

基於對象池模式,維護空閑池和活躍列表。

@interface ReusePoolLifecycleStrategy : BaseLifecycleStrategy <PlayerLifecycleStrategy>

/// 池的最大容量,預設為 3。超出此容量時 recycle 將直接銷毀。
@property (nonatomic, assign) NSInteger maxPoolSize;

/// 當前池中空閑播放器數量
@property (nonatomic, assign, readonly) NSInteger idleCount;

/// 當前已 acquire 但未 recycle 的活躍播放器數量
@property (nonatomic, assign, readonly) NSInteger activeCount;

- (instancetype)initWithMaxPoolSize:(NSInteger)maxPoolSize NS_DESIGNATED_INITIALIZER;

@end

特點:

  • 空閑池優先複用,減少播放器初始化開銷。

  • 支援 preloadWithCount: 預填充池。

  • 池容量通過 maxPoolSize 控制。

  • 所有方法安全執行緒。

  • 適合短視頻列表、資訊流情境。

核心流程:

操作

行為

acquirePlayer

優先從空閑池取出,池空則通過工廠建立新執行個體

recyclePlayer:force:NO

停止播放,歸還到空閑池;池滿則銷毀

recyclePlayer:force:YES

立即銷毀執行個體

clear

銷毀所有空閑池中的執行個體,活躍執行個體不受影響

preloadWithCount:

預建立執行個體放入空閑池,數量受 maxPoolSize 限制

IdScopedPoolLifecycleStrategy

為每個 uniqueId 維護獨立的播放器執行個體。相同 uniqueId 始終返回同一執行個體。使用 LRU(最近最少使用) 機制控制執行個體數量。

@interface IdScopedPoolLifecycleStrategy : BaseLifecycleStrategy <PlayerLifecycleStrategy>

/// 池的最大容量,預設為 3。超過時 LRU 自動淘汰最近最少使用的執行個體。
/// 修改此值時,如果新值小於當前執行個體數量,會立即按 LRU 順序淘汰多餘執行個體。
@property (nonatomic, assign) NSInteger maxPoolSize;

/// 當前映射表中的播放器執行個體數量(含活躍和空閑)
@property (nonatomic, assign, readonly) NSInteger poolCount;

- (instancetype)initWithMaxPoolSize:(NSInteger)maxPoolSize NS_DESIGNATED_INITIALIZER;

@end

特點:

  • ID 綁定,相同 uniqueId 始終複用同一執行個體。

  • LRU 淘汰機制,自動清理最近最少使用的執行個體。

  • 支援 preloadWithCount: 預建立未綁定執行個體。

  • 所有方法安全執行緒。

  • 設計參考阿里雲微短劇解決方案中的多執行個體播放器池 LRU 管理機制。

  • 適合視頻預先載入、多視頻切換情境。

核心流程:

操作

行為

acquirePlayerWithUniqueId: (ID 命中)

返回已有執行個體,更新 LRU 順序

acquirePlayerWithUniqueId: (ID 未命中)

優先從預先載入隊列取,否則建立新執行個體並綁定 ID

recyclePlayer:uniqueId:force:NO

僅停止播放,保留在映射表中(由 LRU 自動淘汰)

recyclePlayer:uniqueId:force:YES

從映射表移除並立即銷毀

clear

清理預先載入隊列和映射表中的非活躍執行個體,活躍執行個體不受影響

preloadWithCount:

建立未綁定 ID 的執行個體,首次 acquire 新 ID 時從中取出

說明

當策略實現了 acquirePlayerWithUniqueId: 方法時,AliPlayerController 會優先調用它代替 acquirePlayer,通過 VideoSource.uniqueId 實現 ID 綁定。同理,recyclePlayer:uniqueId:force: 會優先於 recyclePlayer:force: 被調用。

SingletonLifecycleStrategy

全域維護唯一一個播放器執行個體。通過 dispatch_once 真單例模式實現。

@interface SingletonLifecycleStrategy : BaseLifecycleStrategy <PlayerLifecycleStrategy>

/// 擷取全域共用的單例策略執行個體
+ (instancetype)sharedInstance;

- (instancetype)init NS_UNAVAILABLE;
+ (instancetype)new NS_UNAVAILABLE;

@end

特點:

  • 全域唯一,所有使用此策略的控制器共用同一播放器執行個體。

  • 記憶體佔用最低。

  • clear 會銷毀當前單例播放器執行個體共置空,之後再次 acquirePlayer 會重新建立

  • 不適合多視頻同時播放情境。

  • 多個 AliPlayerController 不可同時持有播放器,否則會導致狀態衝突。

核心流程:

操作

行為

acquirePlayer

全域執行個體存在則直接返回,否則建立

recyclePlayer:force:NO

僅停止播放,保留執行個體

recyclePlayer:force:YES

銷毀全域執行個體

clear

銷毀單例播放器執行個體共置空

策略對比表

策略

擷取行為

回收行為 (force:NO)

適用情境

首幀速度

安全執行緒

Default

每次建立

立即銷毀

普通播放

慢

—

ReusePool

池中取/建立

歸還到池/池滿銷毀

短視頻列表

快

是

IdScoped

ID 命中/預先載入/建立

保持在映射表/LRU 淘汰

預先載入

最快

是

Singleton

只建立一次

僅停止播放

列表播放

中

—

自訂開發

策略協議 (PlayerLifecycleStrategy)

所有生命週期策略都遵循 PlayerLifecycleStrategy 協議:

@protocol PlayerLifecycleStrategy <NSObject>

@required

/// 注入播放器工廠(由 AliPlayerController 自動調用)
- (void)setupWithFactory:(id<PlayerFactory>)factory;

/// 擷取播放器執行個體(由策略決定建立或複用)
- (id<MediaPlayer>)acquirePlayer;

/// 回收播放器執行個體(force:YES 強制銷毀,force:NO 由策略決定)
- (void)recyclePlayer:(nullable id<MediaPlayer>)player force:(BOOL)force;

/// 釋放策略持有的所有播放器執行個體,恢複初始狀態
- (void)clear;

@optional

/// 預先載入指定數量的播放器執行個體到池中
- (void)preloadWithCount:(NSInteger)count;

/// 根據業務唯一標識擷取播放器執行個體(僅 IdScopedPoolLifecycleStrategy 實現)
- (id<MediaPlayer>)acquirePlayerWithUniqueId:(NSString *)uniqueId;

/// 根據業務唯一標識回收播放器執行個體(僅 IdScopedPoolLifecycleStrategy 實現)
- (void)recyclePlayer:(nullable id<MediaPlayer>)player
             uniqueId:(NSString *)uniqueId
                force:(BOOL)force;

@end
說明

setupWithFactory: 由 AliPlayerController 在 initWithLifecycleStrategy: 時自動調用,注入 [AliPlayerKit playerFactory] 返回的工廠執行個體。開發人員通常不需要手動調用此方法。如需預先載入(在建立 Controller 之前),可手動調用 setupWithFactory: 後再調用 preloadWithCount:。

策略基類(BaseLifecycleStrategy)

BaseLifecycleStrategy 是所有內建策略的共用基類,提供工廠管理和模板方法:

@interface BaseLifecycleStrategy : NSObject

/// 當前注入的播放器工廠(唯讀)
@property (nonatomic, strong, readonly) id<PlayerFactory> factory;

/// 注入播放器工廠(等冪,僅首次調用生效,重複調用列印警告並忽略)
- (void)setupWithFactory:(id<PlayerFactory>)factory;

/// 通過工廠建立新的播放器執行個體(子類應調用此方法而非直接調用 factory)
- (id<MediaPlayer>)createPlayer;

/// 通過工廠銷毀播放器執行個體(子類應調用此方法而非直接調用 factory)
- (void)destroyPlayer:(nullable id<MediaPlayer>)player;

@end
說明

BaseLifecycleStrategy 本身不聲明 PlayerLifecycleStrategy 協議一致性,子類需自行聲明並實現 acquirePlayer、recyclePlayer:force:、clear 等方法。子類應通過 createPlayer / destroyPlayer: 模板方法操作播放器執行個體,而非直接調用 factory,以確保操作被統一記錄。

播放器工廠(PlayerFactory)

PlayerFactory 協議定義了播放器執行個體的建立與銷毀介面:

@protocol PlayerFactory <NSObject>

/// 建立播放器執行個體(每次調用建立新執行個體,處於 PlayerStateIdle 狀態)
- (id<MediaPlayer>)createPlayer;

/// 銷毀播放器執行個體(釋放所有資源,nil 時僅記錄警告日誌)
- (void)destroyPlayer:(nullable id<MediaPlayer>)player;

@end

架構內建 DefaultPlayerFactory,使用阿里雲播放器 SDK(AliPlayer)建立標準執行個體。可通過 [AliPlayerKit setPlayerFactory:] 替換為自訂工廠。

自訂策略樣本

以下樣本展示了一個基於 ID 映射的簡單緩衝策略:

@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];
}

@end

註冊並使用:

MyCacheLifecycleStrategy *strategy = [[MyCacheLifecycleStrategy alloc] init];

AliPlayerController *controller =
    [[AliPlayerController alloc] initWithLifecycleStrategy:strategy];
// controller 自動調用 [strategy setupWithFactory:...] 注入工廠

生命週期流程

控制器與策略的互動流程

AliPlayerController 初始化
    ↓
initWithLifecycleStrategy: → 儲存策略引用
    ↓                       → 自動調用 [strategy setupWithFactory:[AliPlayerKit playerFactory]]
    ↓
[controller configure:model]
    ↓
    ├── 已有播放器? → [strategy recyclePlayer:舊執行個體 force:NO]
    ↓
    ├── strategy 實現了 acquirePlayerWithUniqueId:?
    │   ├── YES → [strategy acquirePlayerWithUniqueId:source.uniqueId]
    │   └── NO  → [strategy acquirePlayer]
    ↓
    ├── [player setDataSource:model]
    ├── [player prepare]
    └── autoPlay ? → [player start]
    ↓
切換視訊源 → [controller configure:newModel]
    ↓         → recycle(舊) + acquire(新) + setDataSource + prepare
    ↓
[controller destroy]
    ↓
    ├── [strategy recyclePlayer:player force:YES]
    └── 控制器釋放

策略資源清理時機

時機

操作

說明

視頻切換

configure: 內部 recycle + acquire

自動完成,無需手動操作

控制器銷毀

destroy 內部 recyclePlayer:force:YES

自動完成

頁面退出

dealloc 中調用 [controller destroy]

必須手動調用

釋放池資源

[strategy clear]

按需調用(如記憶體警告時)

最佳實務

策略選擇指南

需求情境

推薦策略

原因

普通視頻詳情頁

Default

簡單直接,頁面銷毀即釋放

短視頻上下滑列表

ReusePool

複用執行個體減少建立開銷,提升滑動流暢度

視頻預先載入/秒開

IdScoped

ID 綁定 + 預先載入實現極速起播

列表連續播放

Singleton

全域唯一執行個體,減少初始化次數

低端裝置/記憶體緊張

Singleton

全域唯一,記憶體佔用最小

播客/音頻播放

Singleton

單音頻流情境無需多執行個體

記憶體管理建議

建議

說明

監聽記憶體警告

池策略應監聽 UIApplicationDidReceiveMemoryWarningNotification 並調用 clear

合理設定池容量

每個播放器執行個體約佔用 35~40MB 記憶體,根據裝置效能設定 maxPoolSize

後台釋放空閑池

進入後台時可調用 clear 釋放空閑執行個體

頁面銷毀必須 destroy

dealloc 中必須調用 [controller destroy],否則會導致記憶體流失

// 監聽記憶體警告,釋放池資源
[[NSNotificationCenter defaultCenter]
    addObserver:self
       selector:@selector(handleMemoryWarning:)
           name:UIApplicationDidReceiveMemoryWarningNotification
         object:nil];

- (void)handleMemoryWarning:(NSNotification *)notification {
    [self.lifecycleStrategy clear];
}

頁面生命週期管理

@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 {
    // 必須:銷毀控制器
    if (_controller) {
        [_controller destroy];
    }
    // 可選:如果此頁面是策略的最後使用者,釋放池資源
    if (_lifecycleStrategy) {
        [_lifecycleStrategy clear];
    }
}

@end

注意事項

情境

推薦做法

原因

頁面銷毀

dealloc 中調用 [controller destroy]

避免記憶體流失

策略清理

最後使用者調用 [strategy clear]

釋放池中空閑執行個體

單例策略

不要同時多個 Controller 持有

避免狀態衝突

工廠注入

不要手動調用 setupWithFactory:

Controller 自動注入,且該方法等冪(僅首次生效)

預先載入

在 Controller 建立後調用

Controller 建立時自動注入工廠

常見錯誤

// ✗ 錯誤:忘記在 dealloc 中銷毀控制器
- (void)dealloc {
    [self.playerView detach];
    // 未調用 [_controller destroy],導致記憶體流失
}

// ✓ 正確:銷毀控制器並按需清理策略
- (void)dealloc {
    if (_controller) {
        [_controller destroy];
    }
    if (_lifecycleStrategy) {
        [_lifecycleStrategy clear];
    }
}
// ✗ 錯誤:單例策略下同時持有多個 Controller
SingletonLifecycleStrategy *strategy = [SingletonLifecycleStrategy sharedInstance];
AliPlayerController *controller1 = [[AliPlayerController alloc] initWithLifecycleStrategy:strategy];
AliPlayerController *controller2 = [[AliPlayerController alloc] initWithLifecycleStrategy:strategy];
// controller1 和 controller2 共用同一播放器執行個體,導致狀態衝突

// ✓ 正確:確保同一時間只有一個 Controller 使用單例策略
[controller1 destroy];
AliPlayerController *controller2 = [[AliPlayerController alloc] initWithLifecycleStrategy:strategy];
// ✗ 錯誤:嘗試 alloc init SingletonLifecycleStrategy
SingletonLifecycleStrategy *strategy = [[SingletonLifecycleStrategy alloc] init]; // 編譯錯誤

// ✓ 正確:通過 sharedInstance 擷取
SingletonLifecycleStrategy *strategy = [SingletonLifecycleStrategy sharedInstance];

API 速查

核心類與協議

協議 / 類

說明

PlayerLifecycleStrategy

生命週期策略協議,定義擷取/回收/清理介面

BaseLifecycleStrategy

策略基類,提供工廠管理和 createPlayer/destroyPlayer: 模板方法

PlayerFactory

播放器工廠協議,定義建立/銷毀介面

DefaultPlayerFactory

預設工廠實現,使用阿里雲播放器 SDK 建立執行個體

MediaPlayer

媒體播放器協議,定義播放控制、狀態查詢等介面

內建策略

類

建立方式

關鍵屬性

DefaultLifecycleStrategy

[[... alloc] init]

—

ReusePoolLifecycleStrategy

[[... alloc] initWithMaxPoolSize:]

maxPoolSize、idleCount、activeCount

IdScopedPoolLifecycleStrategy

[[... alloc] initWithMaxPoolSize:]

maxPoolSize、poolCount

SingletonLifecycleStrategy

[... sharedInstance]

—

PlayerLifecycleStrategy方法

方法

必選

說明

setupWithFactory:

是

注入播放器工廠(Controller 自動調用)

acquirePlayer

是

擷取播放器執行個體

recyclePlayer:force:

是

回收播放器執行個體

clear

是

釋放所有緩衝執行個體

preloadWithCount:

否

預先載入執行個體(ReusePool / IdScoped 實現)

acquirePlayerWithUniqueId:

否

按 uniqueId 擷取執行個體(IdScoped 實現)

recyclePlayer:uniqueId:force:

否

按 uniqueId 回收執行個體(IdScoped 實現)

BaseLifecycleStrategy方法

方法/屬性

說明

factory

當前注入的播放器工廠(唯讀)

setupWithFactory:

注入工廠(等冪,僅首次調用生效)

createPlayer

通過工廠建立執行個體,統一記錄日誌

destroyPlayer:

通過工廠銷毀執行個體,統一記錄日誌

force參數說明

force 值

行為

使用情境

NO

策略自行決定:回收到池中或僅停止播放

正常視頻切換(configure: 內部使用)

YES

無論策略如何,立即銷毀執行個體

控制器銷毀(destroy 內部使用)

uniqueId說明

uniqueId 是 VideoSource 上的業務唯一識別屬性,用於區分不同視頻源。不同策略對其使用方式不同:

策略

uniqueId 用途

Default

不使用

ReusePool

不使用

IdScoped

核心標識,同一 uniqueId 始終返回相同執行個體

Singleton

不使用

樣本參考

PlayerKitUsages/UsageLifecycleStrategy 模組提供了完整的播放器生命週期策略使用樣本,示範了四種內建策略(Default、ReusePool、Singleton、IdScopedPool)的切換對比、多視頻源播放下的執行個體複用行為(NEW/REUSED/HIT),以及策略與控制器的資源清理流程。