すべてのプロダクト
Search
ドキュメントセンター

ApsaraVideo VOD:プレーヤーのライフサイクル戦略

最終更新日:Sep 11, 2026

プレーヤーライフサイクル戦略は、AliPlayerKit のコアアーキテクチャ設計です。プレーヤーインスタンスの作成、再利用、リサイクル、破棄の管理を統合し、さまざまなビジネスシナリオにおいて、より効率的なリソーススケジューリングとパフォーマンスの最適化を可能にします。

はじめに

プレーヤーライフサイクル戦略とは

プレーヤーライフサイクル戦略は、プレーヤーインスタンスのライフサイクルを管理するためのアーキテクチャ上の仕組みです。プレーヤーインスタンスの取得、再利用、クリアなどのコア操作を定義します。これにより、プレーヤーのリソース管理とビジネスロジックが疎結合になります。

ビジネスシナリオごとに、プレーヤーインスタンスの管理に対する要件は異なります。

シナリオ

要件

推奨される戦略

通常の動画再生

シンプルで直接的、再利用は不要

デフォルト

ショート動画リスト

頻繁な切り替え、高速起動が必要

ReusePool

動画のプリロード

ID とインスタンスをバインドし、プリロードをサポート

IdScopedPool

メモリ使用量が重視されるシナリオ

単一のグローバルインスタンスでメモリフットプリントを最小化

シングルトン

主な利点

ストラテジーパターンを使用してプレーヤーのライフサイクルを管理することにより、以下のコアとなる利点が得られます。

  • 疎結合: ビジネスロジックでは、プレーヤーインスタンスの作成と破棄の詳細を処理する必要がありません。

  • 柔軟性: ビジネスロジックを変更することなく、ランタイム時に異なる戦略を選択できます。

  • 拡張性: 特定のビジネスニーズを満たすために、カスタムポリシーを実装できます。

  • 可観測性: 統一されたライフサイクル管理により、モニタリングとデバッグが簡素化されます。

設計の背景

プレーヤーライフサイクル戦略は、Alibaba Cloud のショートドラマソリューションにおけるマルチインスタンスプレーヤープールに由来します。これは、高速スクロールフィードにおける最初のフレームまでの時間 (TTFF)、スムーズな切り替え、メモリ制御に対する厳格な要件を満たすように設計されました。AliPlayerKit は、この手法をストラテジーパターンに抽象化し、プレーヤーのライフサイクルを管理するための、より汎用的で柔軟なアーキテクチャを構築しました。

機能

コア機能

機能

説明

インスタンスの取得

acquirePlayer はプレーヤーインスタンスを取得します。ストラテジーは、新しいインスタンスを作成するか、既存のインスタンスを再利用するかを決定します。

インスタンスのリサイクル

recyclePlayer:force: はインスタンスをリサイクルします。ストラテジーは、インスタンスを破棄するか、保持するかを決定します。

リソースのクリーンアップ

clear はストラテジーが保持するすべてのプレーヤーインスタンスをクリーンアップし、初期状態に復元します。

プリロード

preloadWithCount: は、TTFF を短縮するためにプール内にインスタンスを事前に作成します (@optional)。

ID バインディング

acquirePlayerWithUniqueId: は、一意のビジネス ID を使用してインスタンスを取得します (@optional)。

ファクトリインジェクション

setupWithFactory: はプレーヤーファクトリをインジェクションします。これは AliPlayerController が自動的に呼び出します。

組み込みストラテジー

AliPlayerKit は、4 つの組み込みプレーヤーライフサイクルストラテジーを提供します。

ストラテジー

クラス名

説明

シナリオ

デフォルトストラテジー

DefaultLifecycleStrategy

毎回新しいインスタンスを作成します。使用直後に破棄します。

通常再生

再利用プールストラテジー

ReusePoolLifecycleStrategy

アイドルプールを維持します。まずプールからインスタンスを再利用します。

ショート動画リスト

ID バインディングポリシー

IdScopedPoolLifecycleStrategy

uniqueId ごとに個別のインスタンスを維持します。LRU (Least Recently Used) アルゴリズムを使用してインスタンスを削除します。

動画プリロード

シングルトンストラテジー

SingletonLifecycleStrategy

単一のグローバルインスタンスです。すべての取得リクエストは同じインスタンスを返します。

リスト再生、メモリセンシティブなシナリオ

アーキテクチャレイヤー

┌──────────────────────────────────────────────────────────────┐
│                  AliPlayerController                          │
│       initWithLifecycleStrategy: ストラテジーをインジェクションします             │
│       configure: 内部で recycle(old) + acquire(new) を呼び出します   │
│       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. 最大容量が 3 の ID スコープストラテジーを作成します。
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(old instance) + acquire(new instance) を自動的に実行します。プレーヤーのライフサイクルを手動で管理する必要はありません。

ストラテジーの詳細

DefaultLifecycleStrategy

これは最もシンプルなストラテジーです。ライフサイクルストラテジーを導入する前の従来の動作と同等です。

@interface DefaultLifecycleStrategy : BaseLifecycleStrategy <PlayerLifecycleStrategy>
@end

特徴:

  • ステートレス。 acquirePlayer の呼び出しごとにファクトリを介して新しいインスタンスを作成します。

  • recyclePlayer:force: の呼び出しごとに、force の値にかかわらず、インスタンスを直接破棄します。

  • メモリ使用量が最小です (使用後に解放されます)。

  • ほとんどの標準的な再生シナリオに適しています。

コアフロー:

操作

動作

acquirePlayer

ファクトリを使用して新しいインスタンスを作成します

recyclePlayer:force:

force の値に関係なく、インスタンスを直接破棄します

clear

no-op (プールを維持しません)

ReusePoolLifecycleStrategy

このストラテジーは、オブジェクトプールパターンに基づいています。アイドルプールとアクティブリストを維持します。

@interface ReusePoolLifecycleStrategy : BaseLifecycleStrategy <PlayerLifecycleStrategy>

/// プールの最大容量。デフォルトは 3 です。この容量を超えると、リサイクル時にインスタンスは直接破棄されます。
@property (nonatomic, assign) NSInteger maxPoolSize;

/// 現在プール内にあるアイドル状態のプレーヤー数。
@property (nonatomic, assign, readonly) NSInteger idleCount;

/// 取得済みで、まだリサイクルされていないアクティブなプレーヤー数。
@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 です。上限を超えると、Least Recently Used (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: は、バインドされていないインスタンスの事前作成をサポートします。

  • すべてのメソッドはスレッドセーフです。

  • この設計は、 Alibaba Cloud の短編ドラマソリューションにおけるマルチインスタンスのプレーヤープールの LRU 管理メカニズムに基づいています。

  • 動画のプリロードおよびマルチ動画切り替えのシナリオに適しています。

コアフロー:

操作

動作

acquirePlayerWithUniqueId: (ID ヒット)

既存のインスタンスを返し、LRU の順序における位置を更新します。

acquirePlayerWithUniqueId: (ID ミス)

まずプリロード済みキューからインスタンスを取得します。キューが空の場合は、新しいインスタンスを作成して ID にバインドします。

recyclePlayer:uniqueId:force:NO

再生のみを停止します。インスタンスはマッピングテーブルに残り、 LRU アルゴリズムにより自動的にエビクションされます。

recyclePlayer:uniqueId:force:YES

インスタンスをマッピングテーブルから削除し、直ちに破棄します。

clear

プリロード済みキューとマッピングテーブル内のインスタンスをクリアします。

preloadWithCount:

ID がバインドされていないインスタンスを作成します。これらは、新しい 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 は空の操作であり、シングルトンインスタンスを破棄しません。インスタンスを明示的に破棄するには、recyclePlayer:force:YES を呼び出す必要があります。

  • 複数の動画を同時に再生するシナリオには適していません。

  • 複数の AliPlayerController インスタンスで同時にプレーヤーを保持することはできません。状態の競合が発生する原因となります。

コアフロー:

操作

動作

acquirePlayer

グローバルインスタンスを返します。存在しない場合は、作成してから返します。

recyclePlayer:force:NO

再生のみを停止します。インスタンスは保持されます。

recyclePlayer:force:YES

グローバルインスタンスを破棄します。

clear

no-op (シングルトンインスタンスは破棄されません)。

ストラテジー比較表

ストラテジー

取得時の動作

リサイクル時の動作 (force:NO)

シナリオ

TTFF (Time to First Frame)

スレッドセーフ

Default

毎回新規作成

直ちに破棄

通常再生

遅い

—

ReusePool

プールから取得 / 新規作成

プールに戻す / 満杯の場合は破棄

ショート動画リスト

速い

はい

IdScoped

ID ヒット / プリロード済みを利用 / 新規作成

マッピングテーブルに保持 / LRU によりエビクション

プリロード

最速

はい

Singleton

1 回だけ作成

再生のみ停止

リスト再生

中

—

カスタム開発

ストラテジー プロトコル (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;

/// 一意のビジネス ID でプレーヤーインスタンスを取得します。IdScopedPoolLifecycleStrategy のみが実装します。
- (id<MediaPlayer>)acquirePlayerWithUniqueId:(NSString *)uniqueId;

/// 一意のビジネス ID でプレーヤーインスタンスをリサイクルします。IdScopedPoolLifecycleStrategy のみが実装します。
- (void)recyclePlayer:(nullable id<MediaPlayer>)player
             uniqueId:(NSString *)uniqueId
                force:(BOOL)force;

@end
説明

setupWithFactory: は、AliPlayerController が initWithLifecycleStrategy: の呼び出し時に自動的に呼び出され、[AliPlayerKit playerFactory] が返すファクトリインスタンスをインジェクトします。開発者は通常、このメソッドを手動で呼び出す必要はありません。コントローラーを作成する前にインスタンスをプリロードするには、setupWithFactory: を手動で呼び出してから preloadWithCount: を呼び出すことができます。

ストラテジー 基底クラス (BaseLifecycleStrategy)

BaseLifecycleStrategy は、すべての組み込みストラテジーが共有する基底クラスです。ファクトリ管理とテンプレートメソッドを提供します。

@interface BaseLifecycleStrategy : NSObject

/// 現在インジェクトされているプレーヤーファクトリ (読み取り専用)。
@property (nonatomic, strong, readonly) id<PlayerFactory> factory;

/// プレーヤーファクトリをインジェクトします。この操作はべき等であり、最初の呼び出しでのみ有効です。以降の呼び出しは無視され、警告がログに記録されます。
- (void)setupWithFactory:(id<PlayerFactory>)factory;

/// ファクトリを使用して新しいプレーヤーインスタンスを作成します。子クラスはファクトリを直接呼び出すのではなく、このメソッドを呼び出す必要があります。
- (id<MediaPlayer>)createPlayer;

/// ファクトリを使用してプレーヤーインスタンスを破棄します。子クラスはファクトリを直接呼び出すのではなく、このメソッドを呼び出す必要があります。
- (void)destroyPlayer:(nullable id<MediaPlayer>)player;

@end
説明

BaseLifecycleStrategy 自体は PlayerLifecycleStrategy プロトコルへの準拠を宣言していません。子クラスは準拠を宣言し、acquirePlayer、recyclePlayer:force:、clear などのメソッドを実装する必要があります。子クラスは、factory を直接呼び出すのではなく、createPlayer および destroyPlayer: テンプレートメソッドを使用してプレーヤーインスタンスを操作する必要があります。これにより、操作が統一的にログに記録されます。

プレーヤーファクトリ (PlayerFactory)

PlayerFactory プロトコルは、プレーヤーインスタンスを作成および破棄するためのインターフェイスを定義します。

@protocol PlayerFactory <NSObject>

/// プレーヤーインスタンスを作成します。呼び出しごとに PlayerStateIdle 状態の新しいインスタンスを作成します。
- (id<MediaPlayer>)createPlayer;

/// プレーヤーインスタンスを破棄します。すべてのリソースを解放します。インスタンスが nil の場合、警告のみがログに記録されます。
- (void)destroyPlayer:(nullable id<MediaPlayer>)player;

@end

フレームワークには組み込みの DefaultPlayerFactory が含まれており、Alibaba Cloud Player 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];
// コントローラーは自動的に [strategy setupWithFactory:...] を呼び出してファクトリをインジェクトします。

ライフサイクル フロー

コントローラーとストラテジー間のインタラクション フロー

AliPlayerController の初期化
    ↓
initWithLifecycleStrategy: → ストラテジー参照の保存
    ↓                       → 自動的に [strategy setupWithFactory:[AliPlayerKit playerFactory]] を呼び出し
    ↓
[controller configure:model]
    ↓
    ├── プレーヤーの有無 → [strategy recyclePlayer:古いインスタンス force:NO]
    ↓
    ├── ストラテジーが 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: 内部リサイクル + 取得

自動で処理されるため、手動操作は不要です。

コントローラーの破棄

destroy メソッドは内部で recyclePlayer:force:YES を呼び出します。

自動完了

ページ離脱

dealloc で [controller destroy] を呼び出します。

手動で呼び出す必要があります。

プールリソースの解放

[strategy clear]

必要に応じて呼び出してください (例:メモリ警告時)。

ベストプラクティス

ストラテジー選択ガイド

シナリオ

推奨されるストラテジー

理由

通常の動画製品ページ

デフォルト

シンプルで直接的です。ページが破棄される際にリソースが解放されます。

ショート動画の縦スクロールリスト

ReusePool

インスタンスを再利用することで作成オーバーヘッドが削減され、スクロールの滑らかさが向上します。

動画のプリロード / 即時再生

IdScoped

ID バインディングとプリロードにより、極めて高速な起動が可能になります。

連続リスト再生

シングルトン

単一のグローバルインスタンスにより、初期化の回数が削減されます。

ローエンドデバイス / 低メモリ

シングルトン

単一のグローバルインスタンスにより、最小限のメモリフットプリントを実現します。

ポッドキャスト / 音声再生

シングルトン

単一の音声ストリームシナリオでは、複数のインスタンスは不要です。

メモリ管理の推奨事項

推奨事項

説明

メモリ警告をリッスンする

プールベースのストラテジーは UIApplicationDidReceiveMemoryWarningNotification をリッスンし、 clear を呼び出す必要があります。

適切なプール容量を設定する

各プレーヤーインスタンスは約 35 MB から 40 MB のメモリを使用します。デバイスのパフォーマンスに基づいて 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] を呼び出す

プール内のアイドルインスタンスを解放するため

シングルトンストラテジー

複数のコントローラーで同時にプレーヤーを保持しないこと

状態の競合を回避するため

ファクトリインジェクション

setupWithFactory: を手動で呼び出さないこと

コントローラーが自動的にインジェクトします。メソッドはべき等です (最初の呼び出しのみ有効)。

プリロード

コントローラー作成後に呼び出す

コントローラー作成時にファクトリが自動的にインジェクトされるため。

よくある間違い

// ✗ 誤り: dealloc でコントローラーの破棄を忘れる。
- (void)dealloc {
    [self.playerView detach];
    // [_controller destroy] が呼び出されず、メモリリークが発生します。
}

// ✓ 正しい: コントローラーを破棄し、必要に応じてストラテジーをクリーンアップします。
- (void)dealloc {
    if (_controller) {
        [_controller destroy];
    }
    if (_lifecycleStrategy) {
        [_lifecycleStrategy clear];
    }
}
// ✗ 誤り: シングルトンストラテジーで複数のコントローラーを同時に保持する。
SingletonLifecycleStrategy *strategy = [SingletonLifecycleStrategy sharedInstance];
AliPlayerController *controller1 = [[AliPlayerController alloc] initWithLifecycleStrategy:strategy];
AliPlayerController *controller2 = [[AliPlayerController alloc] initWithLifecycleStrategy:strategy];
// controller1 と controller2 が同じプレーヤーインスタンスを共有し、状態の競合が発生します。

// ✓ 正しい: 一度に 1 つのコントローラーのみがシングルトンストラテジーを使用するようにします。
[controller1 destroy];
AliPlayerController *controller2 = [[AliPlayerController alloc] initWithLifecycleStrategy:strategy];
// ✗ 誤り: SingletonLifecycleStrategy を alloc init しようとする。
SingletonLifecycleStrategy *strategy = [[SingletonLifecycleStrategy alloc] init]; // コンパイルエラー。

// ✓ 正しい: sharedInstance を通じてインスタンスを取得します。
SingletonLifecycleStrategy *strategy = [SingletonLifecycleStrategy sharedInstance];

API リファレンス

コアクラスとプロトコル

プロトコル / クラス

説明

PlayerLifecycleStrategy

ライフサイクル ストラテジー プロトコル。インスタンスの取得、リサイクル、クリアのためのインターフェイスを定義します。

BaseLifecycleStrategy

ストラテジー 基底クラス。ファクトリ管理と createPlayer/destroyPlayer: テンプレートメソッドを提供します。

PlayerFactory

プレーヤー ファクトリ プロトコル。インスタンスの作成と破棄のためのインターフェイスを定義します。

DefaultPlayerFactory

デフォルト ファクトリ実装。Alibaba Cloud Player SDK を使用してインスタンスを作成します。

MediaPlayer

メディア プレーヤー プロトコル。再生コントロール、ステータス クエリなどのインターフェイスを定義します。

組み込みストラテジー

クラス

作成メソッド

主要なプロパティ

DefaultLifecycleStrategy

[[... alloc] init]

—

ReusePoolLifecycleStrategy

[[... alloc] initWithMaxPoolSize:]

maxPoolSize, idleCount, activeCount

IdScopedPoolLifecycleStrategy

[[... alloc] initWithMaxPoolSize:]

maxPoolSize, poolCount

SingletonLifecycleStrategy

[... sharedInstance]

—

PlayerLifecycleStrategy メソッド

メソッド

必須

説明

setupWithFactory:

はい

プレーヤー ファクトリを注入します。コントローラーによって自動的に呼び出されます。

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 の用途

デフォルト

使用されません

ReusePool

使用されません

IdScoped

コア識別子。同じ uniqueId は常に同じインスタンスを返します。

シングルトン

使用されません

使用例

PlayerKitUsages/UsageLifecycleStrategy モジュールは、プレーヤーのライフサイクルストラテジーの使用方法に関する完全な例を提供します。このモジュールは、4つの組み込みストラテジー (Default、ReusePool、Singleton、IdScopedPool) 間の切り替え、マルチソース再生でのインスタンスの再利用動作 (NEW/REUSED/HIT)、およびストラテジーとコントローラーのリソース クリーンアップ フローを示します。