Angular Reel Player
@reelkit/angular-reel-player で作られた、Angular 用の Instagram/TikTok 風のフルスクリーン縦型メディアプレイヤーです。
機能
インストール
アイコン
デフォルトのコントロールはアイコン(閉じる、サウンド、ナビゲーションの矢印)に lucide-angular を使います。別のアイコンライブラリを使いたい場合は、rkPlayerControls と rkPlayerNavigation のテンプレートスロットで独自のものを渡してください。
基本的な使い方
スタイルシートとスタンドアロンの RkReelPlayerOverlayComponent を、コンポーネントの imports 配列にインポートします。
テンプレートスロット
6 つのテンプレートスロットのディレクティブで、プレイヤーの UI のあらゆる部分をカスタマイズできます。それぞれが厳密に型付けされたコンテキストのオブジェクトを受け取ります。上書きしたいスロットだけを渡してください。残りはデフォルトが使われます。
| ディレクティブ | コンテキストの型 | 説明 |
|---|---|---|
| [rkPlayerControls] | PlayerControlsContext<T> | 独自のグローバルなコントロールバー(閉じる、サウンド切り替えなど) |
| [rkPlayerError] | { $implicit: activeIndex, item, innerActiveIndex } | 独自のエラー表示のテンプレートスロット |
| [rkPlayerLoading] | { $implicit: activeIndex, item, innerActiveIndex } | 独自の読み込み表示のテンプレートスロット |
| [rkPlayerNavigation] | PlayerNavigationContext | 独自の前後のナビゲーション矢印 |
| [rkPlayerNestedNavigation] | PlayerNestedNavigationContext | 内側の横方向のスライダー用の独自の ナビゲーション矢印 |
| [rkPlayerNestedSlide] | PlayerNestedSlideContext | 内側の横方向のスライダーの各スライドの独自の内容 |
| [rkPlayerSlide] | PlayerSlideContext<T> | デフォルトのメディアスライドを置き換える、完全に独自のスライドの内容 |
| [rkPlayerSlideOverlay] | PlayerSlideOverlayContext<T> | スライドごとのオーバーレイ(作者の情報、いいね、説明など) |
| [rkPlayerTimeline] | PlayerTimelineContext<T> | 独自の再生タイムラインバー。条件(タイムラインのモードと最小の長さ)がデフォルトのバーを描画する場合だけ描画されます(同じ auto/always/never の判定)。 |
独自のタイムライン
rkPlayerTimeline のテンプレートスロットが呼ばれるのは、オーバーレイの表示条件がデフォルトのバーを描画する場合(同じ timeline モードと timelineMinDurationSeconds)だけなので、それを実装し直す必要はありません。ルート要素で .rk-reel-timeline クラスを使えば、下端に沿った配置、セーフエリアの余白、タッチ端末での間隔を引き継げます。シークのトラックで state.bindInteractions(el) を呼ぶと、ポインターとキーボードによるシークがつながります。
ネストしたスライダー(複数メディアのアイテム)
ContentItem が複数の media を持つ場合、プレイヤーはそれらを横方向にネストしたスライダー(Instagram のカルーセル風)で描画します。内側のスライドの内容をカスタマイズするには rkPlayerNestedSlide スロットを使います。
コンテンツの読み込みとエラー処理
プレイヤーはスライドごとの読み込み中とエラーの状態を追跡します。読み込み中は波のローダーを、壊れたメディアにはエラーアイコンを表示します。エラーになった URL はキャッシュされるので、再訪すると再試行せずにすぐエラーを表示します。
ライフサイクルのコールバック
rkPlayerSlide のテンプレートスロットを使 う場合は、コンテキストのコールバックで読み込み表示を制御します:
| コールバック | 呼ぶタイミング |
|---|---|
onReady | 画像が読み込まれたか、動画の再生が始まったとき。読み込み中とエラーの状態をクリアします。 |
onWaiting | 再生の途中で動画がバッファリングしているとき。読み込み表示を出します。 |
onError | コンテンツの読み込みに失敗したとき。エラーのオーバーレイを出し、その URL を壊れたものとしてキャッシュします。 |
独自の読み込みとエラーの UI
デフォルトの波のローダーとエラーアイコンを、独自のテンプレートに置き換えます:
タイムライン
オーバーレイは、アクティブな動画の上に組み込みの再生タイムラインバーを描画します。timeline 入力で表示条件を決めます。'auto'(デフォルト)はアクティブなメディアが timelineMinDurationSeconds(デフォルト 30)より長い動画のときに表示し、'always' は動画がアクティブなら常に表示し、'never' で無効にします。完全に独自のシークバーには rkPlayerTimeline のテンプレートディレクティブを使います。そのコンテキストは、内部の TimelineController に支えられた timelineState を公開します。
テーマは --rk-reel-timeline-* の CSS カスタムプロパティで変えます。独自のコンポーネントから直接制御するには、TimelineStateService をインジェクトしてください。
RkTimelineBarComponent
デフォルトの再生シークバーのコンポーネントです。TimelineStateService(RkReelPlayerOverlayComponent が提供します)を使い、トラック、バッファー済みの範囲、進捗の塗り、シーク用のつまみを描画します。セレクター:rk-timeline-bar。入力:class?: string、style?: Record<string, string>。デフォルトのバーを包んだり拡張したりするには rkPlayerTimeline のテンプレートの中で使います。単独で使うのは、そのサービスを提供するコンポーネントの中だけにしてください。
SoundStateService
RkReelPlayerOverlayComponent のレベルで提供されます。デフォルトのサウンドボタンがインジェクトし、コントロールのテンプレートスロットのコンテキストでも公開されます。オーバーレイの 子 である独自のコントロールでインジェクトすれば、直接アクセスできます。
| メンバー | 型 | 説明 |
|---|---|---|
muted() | Signal<boolean> | プレイヤーが現在ミュートかどうか |
disabled() | Signal<boolean> | アクティブなスライドに動画がないか、トランジション中なら true |
toggle() | () => void | ミュートの状態を切り替えます |
URL の状態
ライブデモを見る →RkReelPlayerUrlOverlayComponent は、開閉状態をアドレスバーに持つ別のコンポーネントです。インジェクショ ンコンテキストで createOverlayUrlState を使ってコントローラーを作り、[controller] として渡します。パラメーターがスライドを指すとプレイヤーは開き、なくなると閉じます。リンクは共有でき、戻るボタンでプレイヤーが閉じます。RkReelPlayerOverlayComponent は [isOpen] で制御するままなので、開閉状態を決めるものはそれぞれのコンポーネントで 1 つだけです。
組み込みのキー
スライドは組み込みのキーで指せます。urlIndexKey(位置で指す)か urlStableIdKey(安定した id で指す)をコントローラーに展開してください。どちらも @reelkit/angular から再エクスポートされています。URL の状態のガイド と Core API を参照してください。
ルー ターを使うアプリでは Router に連動したアダプターを渡し、ナビゲーションの信頼できる情報源を Router だけに保ちます。Router の裏で履歴を書くと、その位置情報が古くなり、次のナビゲーションでパラメーターが消えます。@reelkit/angular/ng-router-url-adapter の createRouterUrlAdapter が、用意されたアダプターです。
- 開くと履歴エントリーを 1 つ 積みます。フィードをスワイプするとそれを 置き換え るので、N 回スワイプしてもエントリーは増えず、1 回戻れば必ずプレイヤーから出られます。戻 るとプレイヤーが閉じ、スライドは戻りません。
- 戻るで閉じるのは、アプリ内から開いた場合だけです(リンクがエントリーを積んだ場合)。新しいタブで直接開いた共有リンクには前の履歴がないので、ブラウザーの戻るではサイトを離れます。✕ ボタンか Escape なら、その場でパラメーターを取り除いてページにとどまります。
- ディープリンク
?reel=3は、読み込み時にそのスライドでプレイヤーを開きます。 - どのスライドも指さないパラメーター(古いブックマークや手で書き換えた値)は、開けないスライドをアドレスバーが指したままにならないよう、URL から取り除かれます。
- URL の深さはコントローラーのキーで決まります。投稿だけなら一軸、複数メディアの投稿の内側の画像のインデックスも運ぶなら二軸(
urlIndexTwoAxisKey)です。アプリごとにキーを 1 つ選んでください。形は互いに読み替えられません。
createOverlayUrlState のすべてのオプションは Angular API リファレンス にあります。
キーは 1 つか 2 つか — URL の深さを選ぶ
同じ RkReelPlayerUrlOverlayComponent がどちらの形も扱います。実行時にコントローラーの位置から判別するので、モードを指定する入力はありません。コントローラーを作るときにキーを選んでください:
| キー | 通信形式 | 運ぶもの |
|---|---|---|
urlIndexKey(…) | ?reel=3 | 縦方向の投稿だけ。 |
urlIndexTwoAxisKey(…) | ?reel=3.2 | 投稿 と カルーセルの内側のメディアのインデックス。 |
2 つの通信形式は意図的に区別されています。二軸のキーは厳密にドットで区切る(3.0 で、3 だけにはしない)ので、一軸のリンクが二軸として読まれることはありません。そのため、アプリでキーを切り替えると、それまでに共有されたリンクは無効になります。形を 1 つ選んで使い続けてください。
安定したリンク。 インデックスは位置なので、ブックマークした ?reel=3 はフィードが並べ替えられると別の投稿を開きます。フィードではそれが普通のことです。urlStableIdKey は各投稿の安定した id で指し、現在のフィードを走査します。よくあるケースは 1 回の呼び出しで済みます。
hashCodec: base64UrlCodec を渡すと、URL の id を base64url でエンコードします。元に戻せる難読化で、暗号学的ハッシュではありません。
別のフィールド(slug)で指したい場合や、locateAsync で無限フィードをページングしたい場合は、codec/locator を自分で作ります。2 つは別の役割です。codec は識別子を URL に書き、locator はその識別子がどこにあるかを探します。
無限フィード。 locate は同期なので、読み込み済みの投稿にしか答えられません。20 件を読み込んだフィードの 400 番目の投稿への共有リンクは見つかりません。locateAsync はフォールバックで、locate が見つけられなかったときだけ呼ばれます。必要なページを読み込み、その識別子が最終的に持ったインデックスを返してください。
近道
アイテムの id で指すなら、codec と locator を手書きする必要はありません。locateAsync をそのまま urlStableIdKey({ items, locateAsync }) に渡してください(見つからなければ取得してからインデックスを返します)。下のより完全な例は、別のフィールドで指す場合や、すべてを自分で制御したい場合のものです。
locateAsyncが保留中のあいだ、プレイヤーは閉じたままで、パラメーターはそのまま残るので、ディープリンクは取得のあいだも失われません。nullか reject でパラメーターは取り除かれます。- URL が変わったあと、閉じたあと、アンマウントしたあとに届いた答えは破棄されます。遅い取得が、誰も求めていないスライドを開くことはありません。
- 保留中は何も描画されません。その読み込み状態はすでにページが持っているので、独自のスケルトンを描画してください。
- タイムアウトはありません。プレイヤーにはフィードの長さがわからないからです。ページングが尽きたら
nullで決着をつけてください。そうしないとオーバーレイは閉じたままになります。
独自のデータ型
BaseContentItem を拡張すれば、独自のドメインモデルを使えます。コンポーネントはジェネリックです:RkReelPlayerOverlayComponent<T extends BaseContentItem>。
RkReelPlayerOverlayComponent の入力
| 入力 | 型 | デフォルト | 説明 |
|---|---|---|---|
ariaLabel | string | 'Video player' | ダイアログ領域のアクセシブルなラベル |
aspectRatio | number | undefined | undefined |