このデベロッパー ガイドでは、iOS デバイスに Google Cast サポートを追加する方法について説明します。 iOS Sender SDK を使って送信する必要があります。
モバイル デバイスまたはノートパソコンが、再生を制御する送信者となり、 Google Cast デバイスがテレビにコンテンツを表示するレシーバーになります。
送信フレームワークは、Cast クラス ライブラリ バイナリを参照し、 リソースが含まれます。送信アプリまたはキャスト アプリ 送信者上でも動作しているアプリを指します。ウェブ レシーバー アプリ Web Receiver で実行される HTML アプリケーションのことを指します。
送信者フレームワークは、非同期コールバック設計を使用して送信者に通知します。 イベントのアプリ、キャストアプリの動作状態の切り替え サイクルです。
アプリケーションの流れ
次の手順は、送信者の一般的な実行フローの概要です。 iOS アプリ:
- キャスト フレームワークが
GCKDiscoveryManager
データの特性に基づいてGCKCastOptions
~ デバイスのスキャンを開始します。 - ユーザーがキャスト ボタンをクリックすると、フレームワークによってキャストが表示されます。 ダイアログに、検出されたキャスト デバイスのリストが表示されます。
- ユーザーがキャスト デバイスを選択すると、フレームワークはデバイスの起動を試行します。 キャスト デバイス上のウェブ レシーバー アプリ
- フレームワークは送信側のアプリでコールバックを呼び出し、 Web Receiver アプリが起動されました。
- フレームワークは、送信側と受信側のエンドポイントの間で ウェブレシーバーアプリ。
- フレームワークは通信チャネルを使用してメディアを読み込み、制御します。 ウェブレシーバーで再生します。
- フレームワークは、送信側と受信側との間でメディアの再生状態を同期します。 Web Receiver: ユーザーが送信者 UI アクションを実行すると、フレームワークは Web Receiver に送信されたメディア コントロール リクエストと、Web Receiver が メディア ステータスの更新を送信すると、フレームワークは送信側の UI の状態を更新します。
- ユーザーがキャスト ボタンをクリックしてキャスト デバイスとの接続を解除すると、 フレームワークによって、送信者アプリと Web Receiver の接続が解除されます。
送信者のトラブルシューティングを行うには、ロギングを有効にする必要があります。
Google Cast のすべてのクラス、メソッド、イベントを網羅したリスト Google Cast iOS API をご覧ください。 リファレンスをご覧ください。以降のセクションでは をご覧ください。
メインスレッドからメソッドを呼び出す
キャスト コンテキストを初期化する
キャスト フレームワークには、グローバル シングルトン オブジェクトである
GCKCastContext
:
フレームワークのすべてのアクティビティを調整します。このオブジェクトは初期化する必要があります
アプリケーションのライフサイクルの早い段階で、
-[application:didFinishLaunchingWithOptions:]
メソッドを呼び出しているため、
送信側のアプリの再起動時に自動的にセッションが再開されるようにする必要があります。
GCKCastOptions
GCKCastContext
を初期化する際は、オブジェクトを指定する必要があります。
このクラスには、フレームワークの動作に影響を与えるオプションが含まれています。最も
その中でも重要なのが Web Receiver アプリケーション ID です。
キャスト セッションの開始時にウェブ レシーバー アプリを起動できます。
開始しました。
-[application:didFinishLaunchingWithOptions:]
メソッドもおすすめ
フレームワークからロギング メッセージを受信するためのロギング デリゲートを設定します。
これらはデバッグやトラブルシューティングに役立ちます。
@UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate, GCKLoggerDelegate { let kReceiverAppID = kGCKDefaultMediaReceiverApplicationID let kDebugLoggingEnabled = true var window: UIWindow? func applicationDidFinishLaunching(_ application: UIApplication) { let criteria = GCKDiscoveryCriteria(applicationID: kReceiverAppID) let options = GCKCastOptions(discoveryCriteria: criteria) GCKCastContext.setSharedInstanceWith(options) // Enable logger. GCKLogger.sharedInstance().delegate = self ... } // MARK: - GCKLoggerDelegate func logMessage(_ message: String, at level: GCKLoggerLevel, fromFunction function: String, location: String) { if (kDebugLoggingEnabled) { print(function + " - " + message) } } }
AppDelegate.h
@interface AppDelegate () <GCKLoggerDelegate> @end
AppDelegate.m
@implementation AppDelegate static NSString *const kReceiverAppID = @"AABBCCDD"; static const BOOL kDebugLoggingEnabled = YES; - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { GCKDiscoveryCriteria *criteria = [[GCKDiscoveryCriteria alloc] initWithApplicationID:kReceiverAppID]; GCKCastOptions *options = [[GCKCastOptions alloc] initWithDiscoveryCriteria:criteria]; [GCKCastContext setSharedInstanceWithOptions:options]; // Enable logger. [GCKLogger sharedInstance].delegate = self; ... return YES; } ... #pragma mark - GCKLoggerDelegate - (void)logMessage:(NSString *)message atLevel:(GCKLoggerLevel)level fromFunction:(NSString *)function location:(NSString *)location { if (kDebugLoggingEnabled) { NSLog(@"%@ - %@, %@", function, message, location); } } @end
Cast UX ウィジェット
Cast iOS SDK には、Cast Design に準拠したウィジェットが用意されています。 チェックリスト:
導入オーバーレイ:
GCKCastContext
クラスには、次のメソッドがあります。presentCastInstructionsViewControllerOnceWithCastButton
、 Web Receiver が初めて実装されたときに、キャスト アイコンにスポットライトを当てるために使用できます。 を利用できます。送信側アプリは、テキストとタイトルの位置をカスタマイズできる 閉じるボタンもあります。キャスト アイコン: Cast iOS Sender SDK 4.6.0 以降、キャスト アイコンが常に表示される 送信元のデバイスが Wi-Fi に接続されているときに通知が送られます。ユーザーが初めてタップしたとき キャスト アイコン、権限ダイアログ、 が表示され、ユーザーはアプリのローカル ネットワークから 通信できます。その後、ユーザーがキャスト アイコンをタップすると、キャストが 検出されたデバイスの一覧を示すダイアログが表示されます。ユーザーが すると、現在のキャスト アイコンが メディアのメタデータ(タイトル、レコーディング スタジオの名前、サムネイルなど) キャスト デバイスとの接続を解除できます。ユーザーが 視聴可能なデバイスがないときにキャスト アイコンをタップした場合、 デバイスが見つからない理由を示す情報が表示される トラブルシューティング方法についても学習しました
ミニ コントローラ: ユーザーがコンテンツをキャスト中で、現在の画面から移動した場合 送信側のアプリで別の画面にコンテンツ ページが開いたら、 ミニ コントローラが表示され、ユーザーは 現在キャスト中のメディアのメタデータを確認したり、再生を操作したりできます。
拡張コントローラ: ユーザーがコンテンツをキャストしているときに、ユーザーがメディア通知または 拡張コントローラが起動し、 現在再生中のメディア メタデータのほか、複数のボタンで メディアの再生。
キャスト アイコンを追加する
フレームワークでは、キャスト アイコン コンポーネントが UIButton
サブクラスとして提供されています。機能
アプリのタイトルバーに追加するには、UIBarButtonItem
でラップします。典型的な
次のように、UIViewController
サブクラスでキャスト アイコンをインストールできます。
let castButton = GCKUICastButton(frame: CGRect(x: 0, y: 0, width: 24, height: 24)) castButton.tintColor = UIColor.gray navigationItem.rightBarButtonItem = UIBarButtonItem(customView: castButton)
GCKUICastButton *castButton = [[GCKUICastButton alloc] initWithFrame:CGRectMake(0, 0, 24, 24)]; castButton.tintColor = [UIColor grayColor]; self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:castButton];
デフォルトでは、ボタンをタップすると、 説明します。
GCKUICastButton
ストーリーボードに直接追加することもできます
デバイスの検出を設定する
フレームワークでは、デバイスの検出は自動的に行われます。インフラストラクチャを 検出プロセスを明示的に開始または停止する(カスタム UI を実装していない限り)。
フレームワーク内の検出はクラスによって管理される
GCKDiscoveryManager
これは Pod の
GCKCastContext
。「
デバイス選択用のデフォルトのキャスト ダイアログ コンポーネントが、
できます。デバイスリストは、デバイスのわかりやすい名前で辞書順に並べ替えられます。
セッション管理の仕組み
Cast SDK には、キャスト セッションというコンセプト、 これは、デバイスへの接続、Web ブラウザの起動(またはウェブ レシーバアプリ、そのアプリへの接続、メディア コントロール チャネルの初期化。Web Receiver を確認する アプリケーション ライフサイクル ガイド をご覧ください。
セッションはクラスによって管理される
GCKSessionManager
これは Pod の
GCKCastContext
。
個々のセッションは、クラスのサブクラスで表される
GCKSession
: たとえば、
GCKCastSession
キャスト デバイスによるセッションを表します。現在アクティブなキャストにアクセスできます
セッション(存在する場合)を GCKSessionManager
の currentCastSession
プロパティとして使用します。
「
GCKSessionManagerListener
インターフェースを使用して、セッション作成、
停止、再開、終了ですフレームワークは自動的に
送信側のアプリがバックグラウンドに移動して再開を試みたときに、
アプリがフォアグラウンドに戻ったとき(または
(セッションがアクティブだったときにアプリが異常終了した、またはアプリが中断されるなど)。
キャスト ダイアログが使用されている場合、セッションが作成されて破棄される
自動的に適用されます。それ以外の場合、アプリの起動と終了は
明示的に許可するセッションを
GCKSessionManager
。
アプリでセッションのライフサイクルに応じて特別な処理を行う必要がある場合
イベントを処理すると、1 つ以上の GCKSessionManagerListener
インスタンスを
GCKSessionManager
。GCKSessionManagerListener
は、サービス アカウントを定義する
セッション開始、セッション終了などのイベントに対するコールバックを呼び出せます。
ストリーミング転送
セッション状態の保持はストリーム転送の基礎であり、 音声コマンドや Google Home を使って、既存の音声ストリームや動画ストリームをデバイス間で移動できます。 アプリ、スマートディスプレイ。メディアの再生を別のデバイス(ソース)で停止し、別のデバイス(ソース)で続行する あります。最新のファームウェアを搭載したキャスト デバイスは、デバイスのソースまたは宛先として機能できます。 ストリーム転送
ストリームの転送中に新しい宛先デバイスを取得するには、次のコマンドを使用します。
GCKCastSession#device
使用し、
[sessionManager:didResumeCastSession:]
呼び出すことができます。
詳しくは、 ウェブレシーバーでのストリーミング転送 をご覧ください。
自動再接続
キャスト フレームワークは再接続を自動的に処理するための再接続ロジックを追加 次のような多くの微妙な特殊なケースで使用します。
- Wi-Fi の一時的な切断から復旧する
- デバイスのスリープからの復帰
- アプリをバックグラウンドから復元する
- アプリがクラッシュした場合を復元する
メディア コントロールの仕組み
メディアに対応している Web Receiver アプリでキャスト セッションが確立されている場合
Namespace に
GCKRemoteMediaClient
フレームワークによって自動的に作成されます。「kubectl get pod my-test-app」
次の remoteMediaClient
プロパティ:
GCKCastSession
作成します。
Web Receiver にリクエストを発行する GCKRemoteMediaClient
のすべてのメソッド
は
GCKRequest
オブジェクトで、
リクエストを追跡できます
GCKRequestDelegate
割り当てられて、結果に関する通知を受け取ることができます。
表示されます。
GCKRemoteMediaClient
のインスタンスは、
アプリの複数の部分、実際には一部の内部コンポーネントで共有される場合があります。
キャスト ダイアログやミニ メディア コントロールなどのフレームワークでは、
作成します。そのために、GCKRemoteMediaClient
では、複数の
GCKRemoteMediaClientListener
。
メディア メタデータを設定する
「
GCKMediaMetadata
クラスは、キャストするメディア アイテムに関する情報を表します。次の
この例では、映画の新しい GCKMediaMetadata
インスタンスを作成し、タイトルを設定します。
サブタイトル、レコーディング スタジオ名、2 つの画像があります。
let metadata = GCKMediaMetadata() metadata.setString("Big Buck Bunny (2008)", forKey: kGCKMetadataKeyTitle) metadata.setString("Big Buck Bunny tells the story of a giant rabbit with a heart bigger than " + "himself. When one sunny day three rodents rudely harass him, something " + "snaps... and the rabbit ain't no bunny anymore! In the typical cartoon " + "tradition he prepares the nasty rodents a comical revenge.", forKey: kGCKMetadataKeySubtitle) metadata.addImage(GCKImage(url: URL(string: "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/BigBuckBunny.jpg")!, width: 480, height: 360))
GCKMediaMetadata *metadata = [[GCKMediaMetadata alloc] initWithMetadataType:GCKMediaMetadataTypeMovie]; [metadata setString:@"Big Buck Bunny (2008)" forKey:kGCKMetadataKeyTitle]; [metadata setString:@"Big Buck Bunny tells the story of a giant rabbit with a heart bigger than " "himself. When one sunny day three rodents rudely harass him, something " "snaps... and the rabbit ain't no bunny anymore! In the typical cartoon " "tradition he prepares the nasty rodents a comical revenge." forKey:kGCKMetadataKeySubtitle]; [metadata addImage:[[GCKImage alloc] initWithURL:[[NSURL alloc] initWithString:@"https://commondatastorage.googleapis.com/" "gtv-videos-bucket/sample/images/BigBuckBunny.jpg"] width:480 height:360]];
詳細は、画像の選択と キャッシュ をご覧ください。
メディアの読み込み
メディア アイテムを読み込むには、
GCKMediaInformation
インスタンスにデータを追加できます。次に、
GCKCastSession
、
使用する
GCKRemoteMediaClient
受信側のアプリにメディアを読み込む必要があります。その後、GCKRemoteMediaClient
を使用できます。
受信機で実行されるメディア プレーヤー アプリの制御(再生、
一時停止、停止できます。
let url = URL.init(string: "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4") guard let mediaURL = url else { print("invalid mediaURL") return } let mediaInfoBuilder = GCKMediaInformationBuilder.init(contentURL: mediaURL) mediaInfoBuilder.streamType = GCKMediaStreamType.none; mediaInfoBuilder.contentType = "video/mp4" mediaInfoBuilder.metadata = metadata; mediaInformation = mediaInfoBuilder.build() guard let mediaInfo = mediaInformation else { print("invalid mediaInformation") return } if let request = sessionManager.currentSession?.remoteMediaClient?.loadMedia(mediaInfo) { request.delegate = self }
GCKMediaInformationBuilder *mediaInfoBuilder = [[GCKMediaInformationBuilder alloc] initWithContentURL: [NSURL URLWithString:@"https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"]]; mediaInfoBuilder.streamType = GCKMediaStreamTypeNone; mediaInfoBuilder.contentType = @"video/mp4"; mediaInfoBuilder.metadata = metadata; self.mediaInformation = [mediaInfoBuilder build]; GCKRequest *request = [self.sessionManager.currentSession.remoteMediaClient loadMedia:self.mediaInformation]; if (request != nil) { request.delegate = self; }
「 メディア トラックの使用。
4K 動画形式
メディアの動画形式を指定するには、次の videoInfo
プロパティを使用します。
GCKMediaStatus
Pod の現在のインスタンスを
GCKVideoInfo
。
このインスタンスには、HDR TV 形式のタイプと、幅と高さが含まれています。
ピクセルです。4K 形式のバリアントは、hdrType
プロパティで列挙型で示されます。
値は GCKVideoInfoHDRType
です。
ミニ コントローラを追加する
Cast デザイン チェックリスト 送信側アプリは、mini データ管理者 ユーザーが現在のコンテンツ ページから移動したときに表示されます。 ミニ コントローラを使用すると、すぐにアクセスでき、 現在のキャスト セッション。
キャスト フレームワークにはコントロール バー、
GCKUIMiniMediaControlsViewController
は、ミニ コントローラを表示するシーンに追加できます。
送信側アプリが動画や音声のライブ配信を再生しているときに、SDK は 再生/一時停止ボタンの代わりに再生/停止ボタンを自動的に表示する 確認できます。
詳しくは、iOS の送信者 UI をカスタマイズするをご覧ください。 送信側アプリは、キャスト ウィジェットの外観を設定できます。
ミニ コントローラを送信アプリに追加する方法は 2 つあります。
- ラッピングにより、Cast フレームワークにミニ コントローラのレイアウトを管理させる 独自のビュー コントローラを使用できるようになります。
- ミニ コントローラ ウィジェットのレイアウトをご自身で管理するには、 既存のビュー コントローラには、ストーリーボードにサブビューを配置できます。
GCKUICastContainerViewController を使用してラップする
1 つ目の方法は、
GCKUICastContainerViewController
これは、別のビュー コントローラをラップして、
GCKUIMiniMediaControlsViewController
] をクリックします。この方法には、カスタム スコープをカスタマイズできない
コンテナ ビュー コントローラの動作は構成できません。
この最初の方法は通常、
アプリ デリゲートの -[application:didFinishLaunchingWithOptions:]
メソッド:
func applicationDidFinishLaunching(_ application: UIApplication) { ... // Wrap main view in the GCKUICastContainerViewController and display the mini controller. let appStoryboard = UIStoryboard(name: "Main", bundle: nil) let navigationController = appStoryboard.instantiateViewController(withIdentifier: "MainNavigation") let castContainerVC = GCKCastContext.sharedInstance().createCastContainerController(for: navigationController) castContainerVC.miniMediaControlsItemEnabled = true window = UIWindow(frame: UIScreen.main.bounds) window!.rootViewController = castContainerVC window!.makeKeyAndVisible() ... }
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { ... // Wrap main view in the GCKUICastContainerViewController and display the mini controller. UIStoryboard *appStoryboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil]; UINavigationController *navigationController = [appStoryboard instantiateViewControllerWithIdentifier:@"MainNavigation"]; GCKUICastContainerViewController *castContainerVC = [[GCKCastContext sharedInstance] createCastContainerControllerForViewController:navigationController]; castContainerVC.miniMediaControlsItemEnabled = YES; self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds]; self.window.rootViewController = castContainerVC; [self.window makeKeyAndVisible]; ... }
var castControlBarsEnabled: Bool { set(enabled) { if let castContainerVC = self.window?.rootViewController as? GCKUICastContainerViewController { castContainerVC.miniMediaControlsItemEnabled = enabled } else { print("GCKUICastContainerViewController is not correctly configured") } } get { if let castContainerVC = self.window?.rootViewController as? GCKUICastContainerViewController { return castContainerVC.miniMediaControlsItemEnabled } else { print("GCKUICastContainerViewController is not correctly configured") return false } } }
AppDelegate.h
@interface AppDelegate : UIResponder <UIApplicationDelegate> @property (nonatomic, strong) UIWindow *window; @property (nonatomic, assign) BOOL castControlBarsEnabled; @end
AppDelegate.m
@implementation AppDelegate ... - (void)setCastControlBarsEnabled:(BOOL)notificationsEnabled { GCKUICastContainerViewController *castContainerVC; castContainerVC = (GCKUICastContainerViewController *)self.window.rootViewController; castContainerVC.miniMediaControlsItemEnabled = notificationsEnabled; } - (BOOL)castControlBarsEnabled { GCKUICastContainerViewController *castContainerVC; castContainerVC = (GCKUICastContainerViewController *)self.window.rootViewController; return castContainerVC.miniMediaControlsItemEnabled; } ... @end
既存のビュー コントローラに埋め込む
2 つ目は、ミニ コントローラを既存のビューに直接追加する方法です。
コントローラで
createMiniMediaControlsViewController
作成してみましょう。
GCKUIMiniMediaControlsViewController
コンテナのビュー コントローラにサブビューとして追加できます。
アプリ デリゲートでビュー コントローラをセットアップします。
<ph type="x-smartling-placeholder">func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { ... GCKCastContext.sharedInstance().useDefaultExpandedMediaControls = true window?.clipsToBounds = true let rootContainerVC = (window?.rootViewController as? RootContainerViewController) rootContainerVC?.miniMediaControlsViewEnabled = true ... return true }
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { ... [GCKCastContext sharedInstance].useDefaultExpandedMediaControls = YES; self.window.clipsToBounds = YES; RootContainerViewController *rootContainerVC; rootContainerVC = (RootContainerViewController *)self.window.rootViewController; rootContainerVC.miniMediaControlsViewEnabled = YES; ... return YES; }
ルート ビュー コントローラで、GCKUIMiniMediaControlsViewController
を作成します。
コンテナのビュー コントローラにサブビューとして追加します。
let kCastControlBarsAnimationDuration: TimeInterval = 0.20 @objc(RootContainerViewController) class RootContainerViewController: UIViewController, GCKUIMiniMediaControlsViewControllerDelegate { @IBOutlet weak private var _miniMediaControlsContainerView: UIView! @IBOutlet weak private var _miniMediaControlsHeightConstraint: NSLayoutConstraint! private var miniMediaControlsViewController: GCKUIMiniMediaControlsViewController! var miniMediaControlsViewEnabled = false { didSet { if self.isViewLoaded { self.updateControlBarsVisibility() } } } var overriddenNavigationController: UINavigationController? override var navigationController: UINavigationController? { get { return overriddenNavigationController } set { overriddenNavigationController = newValue } } var miniMediaControlsItemEnabled = false override func viewDidLoad() { super.viewDidLoad() let castContext = GCKCastContext.sharedInstance() self.miniMediaControlsViewController = castContext.createMiniMediaControlsViewController() self.miniMediaControlsViewController.delegate = self self.updateControlBarsVisibility() self.installViewController(self.miniMediaControlsViewController, inContainerView: self._miniMediaControlsContainerView) } func updateControlBarsVisibility() { if self.miniMediaControlsViewEnabled && self.miniMediaControlsViewController.active { self._miniMediaControlsHeightConstraint.constant = self.miniMediaControlsViewController.minHeight self.view.bringSubview(toFront: self._miniMediaControlsContainerView) } else { self._miniMediaControlsHeightConstraint.constant = 0 } UIView.animate(withDuration: kCastControlBarsAnimationDuration, animations: {() -> Void in self.view.layoutIfNeeded() }) self.view.setNeedsLayout() } func installViewController(_ viewController: UIViewController?, inContainerView containerView: UIView) { if let viewController = viewController { self.addChildViewController(viewController) viewController.view.frame = containerView.bounds containerView.addSubview(viewController.view) viewController.didMove(toParentViewController: self) } } func uninstallViewController(_ viewController: UIViewController) { viewController.willMove(toParentViewController: nil) viewController.view.removeFromSuperview() viewController.removeFromParentViewController() } override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == "NavigationVCEmbedSegue" { self.navigationController = (segue.destination as? UINavigationController) } } ...
RootContainerViewController.h
static const NSTimeInterval kCastControlBarsAnimationDuration = 0.20; @interface RootContainerViewController () <GCKUIMiniMediaControlsViewControllerDelegate> { __weak IBOutlet UIView *_miniMediaControlsContainerView; __weak IBOutlet NSLayoutConstraint *_miniMediaControlsHeightConstraint; GCKUIMiniMediaControlsViewController *_miniMediaControlsViewController; } @property(nonatomic, weak, readwrite) UINavigationController *navigationController; @property(nonatomic, assign, readwrite) BOOL miniMediaControlsViewEnabled; @property(nonatomic, assign, readwrite) BOOL miniMediaControlsItemEnabled; @end
RootContainerViewController.m
@implementation RootContainerViewController - (void)viewDidLoad { [super viewDidLoad]; GCKCastContext *castContext = [GCKCastContext sharedInstance]; _miniMediaControlsViewController = [castContext createMiniMediaControlsViewController]; _miniMediaControlsViewController.delegate = self; [self updateControlBarsVisibility]; [self installViewController:_miniMediaControlsViewController inContainerView:_miniMediaControlsContainerView]; } - (void)setMiniMediaControlsViewEnabled:(BOOL)miniMediaControlsViewEnabled { _miniMediaControlsViewEnabled = miniMediaControlsViewEnabled; if (self.isViewLoaded) { [self updateControlBarsVisibility]; } } - (void)updateControlBarsVisibility { if (self.miniMediaControlsViewEnabled && _miniMediaControlsViewController.active) { _miniMediaControlsHeightConstraint.constant = _miniMediaControlsViewController.minHeight; [self.view bringSubviewToFront:_miniMediaControlsContainerView]; } else { _miniMediaControlsHeightConstraint.constant = 0; } [UIView animateWithDuration:kCastControlBarsAnimationDuration animations:^{ [self.view layoutIfNeeded]; }]; [self.view setNeedsLayout]; } - (void)installViewController:(UIViewController *)viewController inContainerView:(UIView *)containerView { if (viewController) { [self addChildViewController:viewController]; viewController.view.frame = containerView.bounds; [containerView addSubview:viewController.view]; [viewController didMoveToParentViewController:self]; } } - (void)uninstallViewController:(UIViewController *)viewController { [viewController willMoveToParentViewController:nil]; [viewController.view removeFromSuperview]; [viewController removeFromParentViewController]; } - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([segue.identifier isEqualToString:@"NavigationVCEmbedSegue"]) { self.navigationController = (UINavigationController *)segue.destinationViewController; } } ... @end
「
GCKUIMiniMediaControlsViewControllerDelegate
は、ミニ コントローラを表示するタイミングをホスト ビュー コントローラに指示します。
func miniMediaControlsViewController(_: GCKUIMiniMediaControlsViewController, shouldAppear _: Bool) { updateControlBarsVisibility() }
- (void)miniMediaControlsViewController: (GCKUIMiniMediaControlsViewController *)miniMediaControlsViewController shouldAppear:(BOOL)shouldAppear { [self updateControlBarsVisibility]; }
拡張コントローラを追加
Google Cast デザイン チェックリストでは、送信側アプリで拡張 データ管理者 。拡張コントローラは全画面表示で ミニコントローラです
展開されたコントローラは全画面表示で、 リモート メディア再生このビューにより、キャストアプリは ウェブレシーバーの音量レベルを除き、キャスト セッションを管理しやすい セッションのライフサイクル(キャストの接続/停止)を設定できます。また、Kubernetes の メディア セッションに関するステータス情報(アートワーク、タイトル、サブタイトルなど) 参照)。
このビューの機能は、
GCKUIExpandedMediaControlsViewController
クラスです。
まず、デフォルトの拡張コントローラを有効にします コンテキストをキャストします。アプリのデリゲートを変更して、デフォルトの拡張コントローラを有効にします。
<ph type="x-smartling-placeholder">func applicationDidFinishLaunching(_ application: UIApplication) { .. GCKCastContext.sharedInstance().useDefaultExpandedMediaControls = true ... }
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { ... [GCKCastContext sharedInstance].useDefaultExpandedMediaControls = YES; .. }
次のコードをビュー コントローラに追加して、拡張コントローラを読み込みます。 ユーザーが動画のキャストを開始したとき:
<ph type="x-smartling-placeholder">func playSelectedItemRemotely() { GCKCastContext.sharedInstance().presentDefaultExpandedMediaControls() ... // Load your media sessionManager.currentSession?.remoteMediaClient?.loadMedia(mediaInformation) }
- (void)playSelectedItemRemotely { [[GCKCastContext sharedInstance] presentDefaultExpandedMediaControls]; ... // Load your media [self.sessionManager.currentSession.remoteMediaClient loadMedia:mediaInformation]; }
拡張コントローラは、ユーザーが起動したときにも自動的に起動します。 ミニ コントローラをタップします。
送信側アプリが動画や音声のライブ配信を再生しているときに、SDK は 再生/一時停止ボタンの代わりに再生/停止ボタンを自動的に表示する 表示されます
カスタム スタイルを iOS に適用する アプリ をご覧ください。
音量調節
送信側アプリの音量は、キャスト フレームワークによって自動的に管理されます。「
の Web Receiver ボリュームと自動的に同期します。
提供します。アプリのスライダーを同期するには、次のコマンドを使用します。
GCKUIDeviceVolumeController
。
物理ボタンの音量調節
送信側のデバイスの物理的な音量ボタンを使用して、
キャスト セッションの音量を調節できます。
次に関する physicalVolumeButtonsWillControlDeviceVolume
フラグ:
GCKCastOptions
,
設定されます。
GCKCastContext
。
let criteria = GCKDiscoveryCriteria(applicationID: kReceiverAppID) let options = GCKCastOptions(discoveryCriteria: criteria) options.physicalVolumeButtonsWillControlDeviceVolume = true GCKCastContext.setSharedInstanceWith(options)
GCKDiscoveryCriteria *criteria = [[GCKDiscoveryCriteria alloc] initWithApplicationID:kReceiverAppID]; GCKCastOptions *options = [[GCKCastOptions alloc] initWithDiscoveryCriteria :criteria]; options.physicalVolumeButtonsWillControlDeviceVolume = YES; [GCKCastContext setSharedInstanceWithOptions:options];
エラーを処理する
送信側アプリですべてのエラー コールバックを処理し、 Cast のライフサイクルの各ステージで最適なレスポンスを判断できます。アプリは エラー ダイアログをユーザーに表示するか、キャスト セッションの終了を決定できます。
ロギング
GCKLogger
フレームワークによるロギングに使用されるシングルトン。こちらの
GCKLoggerDelegate
ログメッセージの処理方法をカスタマイズできます。
SDK は GCKLogger
を使用して、ロギング出力をデバッグ形式で生成します。
エラー、警告があります。これらのログメッセージはデバッグに役立ち、
問題の特定に役立ちますデフォルトでは、ログ出力は
抑制されていますが、GCKLoggerDelegate
を割り当てると、送信側アプリは
これらのメッセージを SDK から送信し、システム コンソールに記録できます。
@UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate, GCKLoggerDelegate { let kReceiverAppID = kGCKDefaultMediaReceiverApplicationID let kDebugLoggingEnabled = true var window: UIWindow? func applicationDidFinishLaunching(_ application: UIApplication) { ... // Enable logger. GCKLogger.sharedInstance().delegate = self ... } // MARK: - GCKLoggerDelegate func logMessage(_ message: String, at level: GCKLoggerLevel, fromFunction function: String, location: String) { if (kDebugLoggingEnabled) { print(function + " - " + message) } } }
AppDelegate.h
@interface AppDelegate () <GCKLoggerDelegate> @end
AppDelegate.m
@implementation AppDelegate static NSString *const kReceiverAppID = @"AABBCCDD"; static const BOOL kDebugLoggingEnabled = YES; - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { ... // Enable logger. [GCKLogger sharedInstance].delegate = self; ... return YES; } ... #pragma mark - GCKLoggerDelegate - (void)logMessage:(NSString *)message atLevel:(GCKLoggerLevel)level fromFunction:(NSString *)function location:(NSString *)location { if (kDebugLoggingEnabled) { NSLog(@"%@ - %@, %@", function, message, location); } } @end
デバッグ メッセージと詳細メッセージも有効にするには、次の行をコードの後に追加します。 委任の設定(上記で表示):
<ph type="x-smartling-placeholder">let filter = GCKLoggerFilter.init() filter.minimumLevel = GCKLoggerLevel.verbose GCKLogger.sharedInstance().filter = filter
GCKLoggerFilter *filter = [[GCKLoggerFilter alloc] init]; [filter setMinimumLevel:GCKLoggerLevelVerbose]; [GCKLogger sharedInstance].filter = filter;
Cloud Logging によって生成されるログ メッセージを
GCKLogger
。
クラスごとに最小ロギングレベルを設定します。次に例を示します。
let filter = GCKLoggerFilter.init() filter.setLoggingLevel(GCKLoggerLevel.verbose, forClasses: ["GCKUICastButton", "GCKUIImageCache", "NSMutableDictionary"]) GCKLogger.sharedInstance().filter = filter
GCKLoggerFilter *filter = [[GCKLoggerFilter alloc] init]; [filter setLoggingLevel:GCKLoggerLevelVerbose forClasses:@[@"GCKUICastButton", @"GCKUIImageCache", @"NSMutableDictionary" ]]; [GCKLogger sharedInstance].filter = filter;
クラス名は、リテラル名または glob パターンのいずれかにできます。たとえば、
GCKUI\*
と GCK\*Session
。