WWDC Quick Look 💓 By SwiftGGTeam
Deliver a great playback experience on tvOS

Deliver a great playback experience on tvOS

元の動画を見る

ハイライト

Apple は、tvOS 15 で AVPlayerViewController 標準再生インターフェイスを再設計しました。開発者は、タイトル、再生コントロール、コンテンツ タグ、コンテキスト操作をシステム プレーヤーに統合し、カスタム再生 UI のメンテナンス コストを削減できます。

主要内容

tvOS メディア アプリの構築で最も難しい部分は、多くの場合、ビデオ自体を再生しないことです。

ユーザーはリモコンを持ち、字幕を開いたり、オーディオ トラックを切り替えたり、現在の番組をブックマークしたり、タイトルをスキップしたり、チャプターを表示したりしたいと考えています。以前は、基本プレーヤーのみを使用していた場合、これらのエントリはカスタム メニューに分散していました。また、リモコンのジェスチャー、フォーカスの移動、ピクチャー・イン・ピクチャー、Siri コマンド、および将来のシステムの動作にも対処する必要があります。

このタイプのカスタム プレーヤーは、システムの再生インターフェイスと簡単に競合できます。スピーチでは、標準の再生 UI に干渉し、将来的に機能しなくなる可能性があるため、プレーヤーに追加のジェスチャを追加しないことが明確に推奨されました。

Apple は tvOS 15 で標準の再生インターフェイスを再設計しました。AVPlayerViewController再生、ジャンプ、スキャン、ドラッグ、Siri コマンド、インタースティシャル、およびリモコンのサポートを引き続き担当します。開発者は独自の情報と操作をそれに追加します。

新たな出入り口は4か所に集中。

Title View現在のコンテンツのタイトルとサブタイトルを表示します。Transport Bar Controls収集や設定などの操作を進行状況バーの上に配置します。Content Tabs再生インターフェイスに情報、チャプター、推奨コンテンツを表示します。Contextual Actions特定の時間帯に「先頭をスキップ」や「振り返る」などのアクションを表示します。

ユーザーはプレーヤーから離れる必要はありません。開発者はプレーヤー シェルを再実装する必要はありません。

これらの新しいインターフェイスを使用するには、アプリを tvOS 15 SDK にリンクする必要があります。古いアプリは引き続き tvOS 14 のデフォルトの再生インターフェイスを取得します。これは、Apple が互換性を維持するために使用する境界です。

詳細

タイトル ビュー: 現在何が再生されているかをプレーヤーに知らせます

03:08

タイトル ビューはトランスポート バー (再生コントロール バー) の上にあります。それは現在から始まりますAVPlayerItemメタデータはタイトルとサブタイトルを読み取ります。

スピーチでは次の 2 つの分野について言及しました。commonIdentifierTitleそしてiTunesMetadataTrackSubtitle。メディア ファイルにメタデータが埋め込まれていない場合、または情報を補足する必要がある場合は、次のように設定できます。AVPlayerItem.externalMetadata

import AVFoundation
import AVKit

func configureTitleView(
    playerItem: AVPlayerItem,
    playerViewController: AVPlayerViewController,
    title: String,
    subtitle: String
) {
    let titleItem = AVMutableMetadataItem()
    titleItem.identifier = .commonIdentifierTitle
    titleItem.value = title as NSString

    let subtitleItem = AVMutableMetadataItem()
    subtitleItem.identifier = .iTunesMetadataTrackSubtitle
    subtitleItem.value = subtitle as NSString

    playerItem.externalMetadata = [titleItem, subtitleItem]
    playerViewController.transportBarIncludesTitleView = true
}

キーポイント:

  • import AVFoundation導入AVPlayerItemメタデータの種類。
  • import AVKit導入AVPlayerViewController
  • configureTitleView現在のプレイアイテムとプレーヤーコントローラーを受け取ります。
  • AVMutableMetadataItem()書き込み可能なメタデータ項目を作成します。
  • titleItem.identifier = .commonIdentifierTitle講義のタイトルビューで使用されるタイトルフィールドに対応します。
  • titleItem.value = title as NSStringタイトルのテキストを書きます。
  • subtitleItem.identifier = .iTunesMetadataTrackSubtitleスピーチの字幕フィールドに対応します。
  • subtitleItem.value = subtitle as NSString字幕テキストを書きます。
  • playerItem.externalMetadata外部メタデータを含む完全なメディア情報。
  • transportBarIncludesTitleView = trueタイトルビューを表示したままにします。表示したくない場合は、次のように設定できますfalse

トランスポート バー コントロール: 一般的な操作をシステム再生コントロール バーに追加します。

04:01

トランスポート バー コントロールは、プログレス バーの上にある一連のコントロールです。このシステムは、字幕、音声言語、ピクチャー・イン・ピクチャーなどの標準コントロールを提供します。

独自の操作を次のように適用します。AVPlayerViewController.transportBarCustomMenuItemsに追加。それはサポートしますUIActionそしてUIMenu。スピーチでは次のようにも述べられていましたAVPlayerViewController表示されるUIMenu1 レベルのネストをサポートし、使用可能displayInlineオプション。

import AVKit
import UIKit

func configureTransportBarControls(playerViewController: AVPlayerViewController) {
    let favoriteAction = UIAction(
        title: "Favorites",
        image: UIImage(systemName: "heart")
    ) { _ in
        // Add to favorites
    }

    let normalSpeedAction = UIAction(title: "Normal", state: .on) { _ in }
    let fastSpeedAction = UIAction(title: "Fast") { _ in }

    let speedMenu = UIMenu(
        title: "Speed",
        options: [.displayInline, .singleSelection],
        children: [normalSpeedAction, fastSpeedAction]
    )

    let settingsMenu = UIMenu(
        image: UIImage(systemName: "gearshape"),
        children: [speedMenu]
    )

    playerViewController.transportBarCustomMenuItems = [
        favoriteAction,
        settingsMenu
    ]
}

キーポイント:

  • import AVKit供給AVPlayerViewController
  • import UIKit供給UIActionUIMenuそしてUIImage
  • favoriteAction講義のお気に入りの例に対応するお気に入りの操作を作成します。
  • UIImage(systemName: "heart")収集操作にシステム アイコンを追加します。 ・ ハンドラ内のコメント位置は「お気に入りに追加」のビジネスロジックを実行します。
  • normalSpeedActionそしてfastSpeedActionメニュー項目です。
  • state: .on現在選択されているメニュー項目をマークします。
  • speedMenu講義内の Speed サブメニューに対応する Speed メニューを作成します。
  • .displayInlineサブメニューをインラインで表示します。
  • .singleSelection同じグループ内の操作を 1 つだけ選択できることを示します。
  • settingsMenu歯車アイコンを使用してサブメニューをホストします。
  • transportBarCustomMenuItemsカスタム操作は、表示用のシステム再生インターフェイスに任せます。

コンテンツ タブ: 再生中に情報、チャプター、推奨コンテンツを表示します。

05:19

コンテンツ タブを使用すると、再生インターフェイスに補足情報を含めることができます。メディアにメタデータがある場合、AVPlayerViewController「情報」タブが表示されます。AVPlayerItem供給navigationMarkerGroupsを選択すると、「章」ラベルが表示されます。

申請は通過できるcustomInfoViewControllersさらにタグを追加します。 tvOS 15 では、古いプロパティがこの新しいプロパティに置き換えられます。customInfoViewControllerこれは、新しいインターフェイスが複数のビュー コントローラーをサポートしているためです。

import AVKit
import UIKit

func configureContentTabs(
    playerViewController: AVPlayerViewController,
    customViewController: UIViewController
) {
    customViewController.preferredContentSize = CGSize(width: 0, height: 140)
    customViewController.title = "Recommended"

    playerViewController.customInfoViewControllers = [customViewController]
}

キーポイント:

  • configureContentTabsプレーヤー コントローラーとカスタム コンテンツ コントローラーを受け取ります。
  • preferredContentSizeコンテンツラベルの希望の高さを指定します。
  • width: 0つまり、ここでの焦点は高さの設定であり、幅はシステム レイアウトによって処理されます。
  • height: 140講義スニペットの例の高さに対応します。
  • title = "Recommended"タブ名の表示に使用されるタブ タイトルを設定します。
  • customInfoViewControllersカスタム コンテンツ タグの配列を追加します。
  • 複数のラベルが同時に存在する場合、システムは最も高いコンテンツラベルに基づいて全体の高さを計算します。

TVMediaItemContentConfiguration: システム スタイルを使用して推奨コンテンツを表示します

07:08

関連ビデオのグループをコンテンツ タブに表示する場合は、TVUIKit (tvOS UI ツール フレームワーク) によって提供される新しいコンテンツ構成を使用できます。

TVMediaItemContentConfiguration.wideCell()16:9 メディア カードで使用します。写真、タイトル、字幕、バッジ、再生の進行状況を設定できます。

import TVUIKit
import UIKit

func configureMediaCell(cell: UICollectionViewCell) {
    var contentConfiguration = TVMediaItemContentConfiguration.wideCell()
    contentConfiguration.image = UIImage(imageLiteralResourceName: "tanu")
    contentConfiguration.text = "Title"
    contentConfiguration.secondaryText = "Secondary text"
    contentConfiguration.badgeText = "NEW"
    contentConfiguration.badgeProperties.backgroundColor = .systemRed
    contentConfiguration.playbackProgress = 0.75

    cell.contentConfiguration = contentConfiguration
}

キーポイント:

  • import TVUIKittvOS のコンテンツ構成タイプの紹介。
  • import UIKit導入UICollectionViewCellそしてUIImage
  • configureMediaCellコレクションビューセルを設定します。
  • TVMediaItemContentConfiguration.wideCell()16:9 メディア カード構成を作成します。
  • imageカードの絵柄を設定します。
  • textメインタイトルを設定します。
  • secondaryTextサブタイトルを設定します。
  • badgeText = "NEW"カードのバッジ テキストを表示します。
  • badgeProperties.backgroundColor = .systemRedバッジの背景色を設定します。
  • playbackProgress = 0.7575% の視聴進行状況を示しています。
  • cell.contentConfiguration構成をセルに適用します。

TVMonogramContentConfiguration: 再生インターフェイスに文字を表示します

07:36

コンテンツ タグに人物や役割が示されている場合は、音声を使用することをお勧めします。TVMonogramContentConfiguration

現在のメディアに関連する領域に俳優、ゲスト、講演者、または登場人物の情報を表示するのに適しています。

import TVUIKit
import UIKit

func configureMonogramCell(cell: UICollectionViewCell) {
    var contentConfiguration = TVMonogramContentConfiguration.cell()
    contentConfiguration.image = UIImage(imageLiteralResourceName: "jad")
    contentConfiguration.text = "Jad"

    cell.contentConfiguration = contentConfiguration
}

キーポイント:

  • TVMonogramContentConfiguration.cell()キャラクターアバタースタイルでセル構成を作成します。
  • imageキャラクターの絵を設定します。
  • textキャラクター名を設定します。
  • cell.contentConfigurationコレクション ビュー セルにこのシステム スタイルを使用させます。
  • この構成とメディア カード構成の両方で、コンテンツ タブのリスト コンテンツが提供されます。

コンテキストアクション: 適切なタイミングでのみアクションを表示します。

07:52

コンテキスト アクションは、再生中の即時の操作に使用されます。講演で挙げられた例は、「イントロをスキップ」と「要約」です。

アプローチは、AVPlayerViewController.contextualActions、1 つ以上を提供しますUIAction。アプリケーションは多くの場合、プレーヤー時間をリッスンし、関連するフラグメントが表示されたときに操作を表示し、終了時にプロパティを空の配列にリセットする必要があります。

import AVFoundation
import AVKit
import UIKit

func showSkipIntroAction(
    playerViewController: AVPlayerViewController,
    player: AVPlayer
) {
    let skipIntroAction = UIAction(title: "Skip Intro") { _ in
        let targetTime = CMTime(seconds: 90, preferredTimescale: 600)
        player.seek(to: targetTime)
    }

    playerViewController.contextualActions = [skipIntroAction]
}

func hideContextualActions(playerViewController: AVPlayerViewController) {
    playerViewController.contextualActions = []
}

キーポイント:

  • import AVFoundation供給AVPlayerそしてCMTime
  • showSkipIntroAction適切なフラグメントが現れたときに呼び出されます。
  • UIAction(title: "Skip Intro")講義の「イントロをスキップ」の例に対応する、イントロをスキップする操作を作成します。
  • CMTime(seconds: 90, preferredTimescale: 600)ジャンプ先の再生時間を示します。
  • player.seek(to:)ジャンプを実行します。
  • contextualActions = [skipIntroAction]プレーヤーでアクションを表示します。
  • hideContextualActions必要のないときに呼び出されます。
  • contextualActions = []現在のコンテキスト操作を非表示にします。

従うべき最低限の tvOS 再生慣行

08:48

講演は 3 つの実践的な提案で終わりました。

まず、プレーヤーに余分なジェスチャーを追加しないでください。これは標準の再生 UI に干渉するため、将来のシステム バージョンでは動作しなくなる可能性があります。

次に、不足しているメタデータを埋めます。タイトル、写真、説明などの情報を追加できます。AVPlayerItem.externalMetadata供給。 Title View タグと Info タグにはこの情報が入力されます。

3 番目に、Picture in Picture を有効にすることを検討してください。これにより、ユーザーは全画面コンテンツとピクチャー・イン・ピクチャーを切り替えたり、ビデオを再生したり他のコンテンツを同時に使用したりすることができます。

import AVKit

func configurePlaybackExperience(playerViewController: AVPlayerViewController) {
    playerViewController.allowsPictureInPicturePlayback = true
    playerViewController.transportBarIncludesTitleView = true
}

キーポイント:

  • allowsPictureInPicturePlayback = trueプレーヤーがピクチャー・イン・ピクチャー機能を使用できるようにします。
  • transportBarIncludesTitleView = trueタイトル領域を表示したままにします。
  • これらの設定は、AVPlayerViewController標準の再生エクスペリエンスに加えて。
  • ジェスチャー、フォーカス、および再生のコントロールは、引き続きシステム インターフェイスによって処理されます。

重要ポイント

1. 動画アプリに「続きを見る」のおすすめタグを追加します。

  • 対処方法: ユーザーが視聴し終わっていないエピソードや関連コンテンツを表示するには、プレーヤーに推奨タグを追加します。
  • 価値がある理由: コンテンツ タブを使用すると、ユーザーは再生インターフェイスに留まりながら、推奨コンテンツを閲覧できます。
  • 開始方法: カスタムを作成しますUIViewController、設定preferredContentSizeそしてtitle、次に入れますAVPlayerViewController.customInfoViewControllers

2. コースビデオにチャプターナビゲーションを追加します

  • 何をすべきか: 再生インターフェイスにコースの章を表示すると、ユーザーは特定のセクションに直接ジャンプできます。
  • 実行する価値がある理由: スピーチで言及AVPlayerItem.navigationMarkerGroupsシステムに「章」ラベルが表示されます。
  • 開始方法:AVPlayerItemチャプターマーカーグループを提供して使用しますAVPlayerViewControllerアイテムを再生します。

3. エピソードに「タイトルをスキップ」ボタンを追加します

  • 対処法: イントロが表示されるとスキップイントロを表示し、イントロが終了すると非表示になります。
  • 実行する価値がある理由: コンテキスト アクションは、再生中の関連操作に特に使用され、インタラクション動作はシステム フォーカスと一致します。
  • 開始方法: プレーヤーの周期または境界時間オブザーバーを使用して時間を監視し、タイトルインターバルに入るときに設定します。contextualActions、終了後に空の配列に設定されます。

4. 再生コントロール バーにコレクション エントリを追加します。

  • 対処方法: ユーザーは番組を視聴しているときに、現在のコンテンツを再生コントロール バーのお気に入りに直接追加できます。
  • 実行する価値がある理由:transportBarCustomMenuItemsサポートUIAction、現在のメディアに強く関連する軽量の操作を配置するのに適しています。
  • 開始方法: 作成するUIAction(title:image:handler:)に追加しますplayerViewController.transportBarCustomMenuItems

5. キャラクターインタビューにゲストタブを追加

  • 何をすべきか: この問題のゲスト、ホスト、またはキャラクターのリストをプレーヤーに表示します。
  • 実行する価値がある理由:TVMonogramContentConfigurationコンテンツ タブのコレクション ビューへの配置に適したキャラクター アバター スタイルを提供します。
  • 開始方法: コレクション ビューを使用して文字リストをホストし、セルに設定します。TVMonogramContentConfiguration.cell()

関連セッション

コメント

GitHub Issues · utterances