Cast'i iOS Uygulamanıza Entegre Edin

Bu geliştirici kılavuzunda, Google Cast desteğini iOS cihazınıza nasıl ekleyeceğiniz açıklanmaktadır. iOS Sender SDK'yı kullanan bir gönderen uygulaması.

Mobil cihaz veya dizüstü bilgisayar, oynatmayı kontrol eden gönderendir ve Google Cast cihazı, içeriği TV'de görüntüleyen alıcıdır.

Gönderen çerçevesi, Cast sınıf kitaplığı ikili programını ve kaynaklar gönderilir. Gönderen uygulaması veya Cast uygulaması gönderen üzerinde de çalışan bir uygulama anlamına gelir. Web Alıcı uygulaması Web Alıcısı'nda çalışan HTML uygulamasını belirtir.

Gönderen çerçevesi, göndereni bilgilendirmek için eşzamansız bir geri çağırma tasarımı kullanır ve Cast uygulaması hayatının çeşitli durumları arasında geçiş yapmak için kullanılan döngüsünü de takip eder.

Uygulama akışı

Aşağıdaki adımlarda, bir gönderen için tipik üst düzey yürütme akışı açıklanmaktadır iOS uygulaması:

  • Cast çerçevesi başlar GCKDiscoveryManager web sitesinde sağlanan GCKCastOptions - cihazları taramaya başlar.
  • Kullanıcı Yayınla düğmesini tıkladığında çerçeve, Yayınla iletişim kutusu gösterilir.
  • Kullanıcı bir yayın cihazı seçtiğinde çerçeve, cihazın ilk birkaç adımını Yayın cihazındaki Web Alıcı uygulaması.
  • Çerçeve, Web Alıcı uygulaması kullanıma sunuldu.
  • Bu çerçeve, gönderen ile gönderen arasında bir iletişim kanalı Web Alıcı uygulamaları.
  • Bu çerçeve, medya içeriklerini yüklemek ve kontrol etmek için iletişim kanalını kullanır. Web Alıcısı'nda oynatma.
  • Çerçeve, medya oynatma durumunu gönderen ve Web Alıcı: Kullanıcı, gönderen kullanıcı arayüzü işlemleri yaptığında çerçeve Web Alıcısı'na göndermek ve Web Alıcısı medya durumu güncellemeleri gönderdiğinde çerçeve, gönderen kullanıcı arayüzünün durumunu günceller.
  • Kullanıcı Yayın cihazı bağlantısını kesmek için Yayın düğmesini tıkladığında çerçeve, gönderen uygulamasının Web Alıcısı ile bağlantısını keser.

Gönderenle ilgili sorunları gidermek için günlük kaydını etkinleştirmeniz gerekir.

Google Cast'teki tüm sınıfların, yöntemlerin ve etkinliklerin kapsamlı listesi için iOS çerçevesi için lütfen Google Cast iOS API'ye bakın Referans. Aşağıdaki bölümlerde adımların Google Cast'i entegre ettiğinizden emin olun.

Ana iş parçacığındaki arama yöntemleri

Yayın bağlamını başlatın

Cast çerçevesinin küresel bir tekil nesnesi vardır. GCKCastContext, hangi ve çerçevenin tüm aktivitelerini koordine eder. Bu nesne başlatılmalıdır ilk aşamalarında, genellikle -[application:didFinishLaunchingWithOptions:] yöntemi, bu nedenle yeniden başlatıldığında otomatik oturum devam ettirmenin düzgün şekilde tetiklenebileceğini söylemiştim.

GCKCastOptions GCKCastContext başlatılırken nesne sağlanmalıdır. Bu sınıf, çerçevenin davranışını etkileyen seçenekler içerir. En Bunlardan en önemlisi, algoritmik verileri filtrelemek için kullanılan en son sürümüne sahip olduğunu ve yayın oturumu başladığında Web Alıcı uygulamasını başladı.

-[application:didFinishLaunchingWithOptions:] yöntemi de iyi bir seçenektir çerçeveden günlük kaydı mesajlarını alacak bir günlük kaydı yetkisi ayarlayın. Bunlar hata ayıklama ve sorun giderme açısından faydalı olabilir.

Hızlı
@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)
    }
  }
}
Hedef-C

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 kullanıcı deneyimi widget'ları

Cast iOS SDK'sı, Cast Tasarımı ile uyumlu olan bu widget'ları sağlar Yapılacaklar listesi:

  • Tanıtım Yer Paylaşımı: GCKCastContext sınıfının bir yöntemi var. presentCastInstructionsViewControllerOnceWithCastButton, Bu, bir Web Alıcısı ilk kez Yayınla düğmesini ön plana çıkarmak için kullanılabilir kullanılabilir. Gönderen uygulama metni ve başlığın konumunu özelleştirebilir metni ve Kapat düğmesi.

  • Yayınla Düğmesi: Cast iOS gönderen SDK 4.6.0 sürümünden itibaren, yayın düğmesi her zaman görünür durumdadır Gönderenin cihazı kablosuz ağa bağlandığında. Kullanıcı ilk kez dokunduğunda uygulamayı başlattıktan sonra Yayın düğmesinde, izinler iletişim kutusu kullanıcının, şu cihazdaki cihazlara yerel ağ erişimine izin verebilmesi için görünür: ağ. Ardından, kullanıcı yayın düğmesine dokunduğunda bir yayın bulunan cihazların listelendiği iletişim kutusu görüntülenir. Kullanıcı dokunduğunda yayın düğmesine bastığınızda cihazın bağlı olduğu sırada mevcut medya meta verileri (örneğin, kayıt stüdyosunun adı ve küçük resmi) resim) veya kullanıcının yayın cihazıyla olan bağlantısını kesmesine olanak tanır. Kullanıcı kullanılabilir cihaz olmadığında yayın düğmesine dokunduğunda kullanıcıya cihazların neden bulunamadığına dair bilgi veren bir mesaj gösterilir ve nasıl sorun giderileceğini anlatacağım.

  • Mini Kumanda: Kullanıcı içerik yayınlarken geçerli sayfadan ayrıldığında içerik sayfasını veya genişletilmiş denetleyiciyi, gönderen uygulamasındaki başka bir ekrana kullanıcıya izin vermek için ekranın altında mini kumanda görüntülenir. yayınlanan medya meta verilerini görebilir ve oynatmayı kontrol edebilirsiniz.

  • Genişletilmiş Denetleyici: Kullanıcı içerik yayınlarken medya bildirimini veya içeren genişletilmiş kumanda başlatılır. meta verilerini oynatır ve bu medyayı kontrol etmek için bazı düğmeler sağlar. medya oynatmaya dokunun.

Yayınla düğmesi ekle

Çerçeve, bir UIButton alt sınıfı olarak Yayınla düğmesi bileşeni sağlar. O da UIBarButtonItem içine sarmalanarak uygulamanın başlık çubuğuna eklenir. Normal UIViewController alt sınıfı aşağıdaki şekilde bir Yayınla düğmesi yükleyebilir:

Hızlı
let castButton = GCKUICastButton(frame: CGRect(x: 0, y: 0, width: 24, height: 24))
castButton.tintColor = UIColor.gray
navigationItem.rightBarButtonItem = UIBarButtonItem(customView: castButton)
Hedef-C
GCKUICastButton *castButton = [[GCKUICastButton alloc] initWithFrame:CGRectMake(0, 0, 24, 24)];
castButton.tintColor = [UIColor grayColor];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:castButton];

Varsayılan olarak, düğmeye dokunduğunuzda bahsedeceğim.

GCKUICastButton film şeridine de eklenebilir.

Cihaz bulmayı yapılandırın

Bu çerçevede cihaz keşfi otomatik olarak gerçekleşir. Herhangi bir özel bir kullanıcı arayüzü uygulamadığınız sürece keşif işlemini açıkça başlatma veya durdurma.

Çerçevedeki keşif, sınıf tarafından yönetilir GCKDiscoveryManager, Bu, GCKCastContext. İlgili içeriği oluşturmak için kullanılan çerçeve, cihaz seçimi için varsayılan bir Cast iletişim kutusu bileşeni sağlar ve ve kontrol etmesi gerekir. Cihaz listesi, cihaz dostu ada göre sözlüksel olarak sıralanır.

Oturum yönetiminin işleyiş şekli

Cast SDK'sı, Cast oturumu, Bir cihaza bağlanma, Web'i başlatma (veya Web'e katılma) adımlarını birleştiren kuruluş Alıcı uygulama, bu uygulamaya bağlanma ve medya kontrol kanalını başlatma. Web Buyer'ı göster Uygulama yaşam döngüsü kılavuzu daha fazla bilgi edinmek için Yardım Merkezi'ni ziyaret edebilirsiniz.

Oturumlar sınıf tarafından yönetilir GCKSessionManager, Bu, GCKCastContext. Farklı oturumlar sınıfın alt sınıflarıyla temsil edilir GCKSession: örneğin, GCKCastSession Yayın cihazlarıyla ilgili oturumları temsil eder. Şu anda etkin olan Yayın'a erişebilirsiniz oturumu (varsa) GCKSessionManager öğesinin currentCastSession özelliği olarak değiştirildi.

İlgili içeriği oluşturmak için kullanılan GCKSessionManagerListener arayüz, oturum oluşturma, oturum açma ve görüntüleme gibi oturum etkinliklerini askıya alma, devam ettirme ve feshetme. Çerçeve otomatik olarak askıya alınır gönderen uygulamanın arka plana geçip devam ettirmeye çalıştığı oturumlar uygulama ön plana geri döndüğünde (veya oturum etkinken uygulamanın anormal/aniden kapatılması).

Yayınla iletişim kutusu kullanılıyorsa oturumlar oluşturulur ve kesilir otomatik olarak oluşturabilirsiniz. Aksi takdirde uygulama başlayıp bitebilir oturumları açık ve net bir şekilde GCKSessionManager.

Uygulamanın, oturum yaşam döngüsüne yanıt olarak özel işlem yapması gerekiyorsa etkinlikleri içeren bir veya daha fazla GCKSessionManagerListener örneği kaydedebilir. GCKSessionManager. GCKSessionManagerListener, tanımlama için kullanılan ve oturum başlangıcı, oturum sonu gibi etkinlikler için geri çağırma seçenekleri sunar.

Akış aktarma

Akış aktarımının temeli oturum durumunu korumaktır. Bu yöntemde kullanıcılar sesli komutları, Google Home'u kullanarak mevcut ses ve video akışlarını cihazlar arasında taşıyabilir uygulama veya akıllı ekranlar. Medya bir cihazda (kaynak) duruyor ve başka bir cihazda (kaynaktaki) devam ediyor hedef). En son donanım yazılımına sahip Cast cihazları bir akış aktarımı.

Yayın aktarımı sırasında yeni hedef cihazı almak için GCKCastSession#device sırasında, [sessionManager:didResumeCastSession:] geri arama.

Görüntüleyin Web Alıcısında akış aktarımı konulu videomuzu izleyin.

Otomatik yeniden bağlanma

Cast çerçevesi, yeniden bağlantıyı otomatik olarak işlemek için yeniden bağlanma mantığı ekler aşağıdaki gibi çok daha küçük ölçekli bir senaryoda işe yarar:

  • Geçici kablosuz ağ kaybından kurtulma
  • Cihazı uyku modundan kurtar
  • Uygulamayı arka plana alma durumundan kurtar
  • Uygulama kilitlenirse kurtar

Medya kontrolünün işleyiş şekli

Medyayı destekleyen bir Web Alıcısı uygulamasıyla yayınlama oturumu oluşturulursa Ad alanı, GCKRemoteMediaClient çerçeve tarafından otomatik olarak oluşturulur. bu sayfaya remoteMediaClient özelliği GCKCastSession kullanır.

GCKRemoteMediaClient üzerindeki, Web Alıcısına istekte bulunan tüm yöntemler şunu döndürür: GCKRequest nesne istek takibi için kullanılabilir. CEVAP GCKRequestDelegate nihai sonuç hakkında bildirim almak için bu nesneye atanabilir anlamına gelir.

GCKRemoteMediaClient örneğinin olması beklenir uygulamanın çeşitli bölümleri ve hatta bazı dahili bileşenleri tarafından paylaşılmış olabilir. Cast iletişim kutusu ve mini medya denetimleri gibi çerçevenin içindeki kullanır. Bu doğrultuda, GCKRemoteMediaClient birden çok öğenin kaydedilmesini GCKRemoteMediaClientListeners.

Medya meta verilerini ayarla

İlgili içeriği oluşturmak için kullanılan GCKMediaMetadata class , yayınlamak istediğiniz medya öğesiyle ilgili bilgileri temsil eder. Aşağıdakiler example, bir filmin yeni GCKMediaMetadata örneğini oluşturur ve başlığı ayarlar, altyazı, kayıt stüdyosunun adı ve iki resim.

Hızlı
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))
Hedef-C
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]];

Bkz. Resim Seçimi ve Önbelleğe alma başlıklı bölüm.

Medya yükle

Bir medya öğesini yüklemek için GCKMediaInformation medyanın meta verilerini kullanarak ör. Ardından, GCKCastSession ve kullanın GCKRemoteMediaClient alıcı uygulamaya medyayı yükleyin. Ardından şunu kullanabilirsiniz: GCKRemoteMediaClient alıcıda çalışan bir medya oynatıcı uygulamasını kontrol etmek için (örneğin, oynatma, birçok farklı rol var.

Hızlı
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
}
Hedef-C
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;
}

Ayrıca, medya parçalarını kullanma.

4K video biçimi

Medyanızın hangi video biçimini olduğunu belirlemek için videoInfo özelliğini kullanın. GCKMediaStatus mevcut örneğini almak için GCKVideoInfo. Bu örnek, HDR TV biçiminin türünü ve yüksekliği ile genişliği içerir. piksel. 4K biçiminin varyantları hdrType özelliğinde enum ile gösterilir değerleri GCKVideoInfoHDRType.

Mini kumanda ekle

Cast Tasarımına göre Yapılacaklar listesi gönderen uygulaması, mini denetleyici Kullanıcı geçerli içerik sayfasından ayrıldığında belirmesi gerekir. Mini kumanda, ekranda anında erişim imkanı sunar ve mevcut yayın oturumu.

Cast çerçevesi bir kontrol çubuğu, GCKUIMiniMediaControlsViewController, sahnelere eklenebilir.

Gönderen uygulamanız bir video veya ses canlı yayını oynatırken SDK, oynatma/duraklatma düğmesi yerine otomatik olarak bir oynat/durdur düğmesi görüntüler mini kumandada.

Google Cast widget'larının görünümünü yapılandırabilir.

Mini kumandayı gönderen uygulamasına iki şekilde ekleyebilirsiniz:

  • Kaydırarak Cast çerçevesinin mini kumandanın düzenini yönetmesine izin verin kendi görünüm denetleyicisine kaçırmayın.
  • Mini kumanda widget'ını cihazınıza ekleyerek bu widget'ın düzenini kendiniz yönetebilirsiniz. mevcut görüntüleme denetleyicisini kullanabilirsiniz.

GCKUICastContainerViewController'ı kullanarak sarmalama

İlk yol, GCKUICastContainerViewController Bu, başka bir görünüm denetleyicisini saran ve GCKUIMiniMediaControlsViewController dokunun. Bu yaklaşım, animasyonu için olduğu için kapsayıcı görüntüleme denetleyicisinin davranışını yapılandıramaz.

Bu ilk yöntem genellikle Uygulama yetkilendirmesinin -[application:didFinishLaunchingWithOptions:] yöntemi:

Hızlı
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()

  ...
}
Hedef-C
- (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];
  ...

}
Hızlıca
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
    }
  }
}
Hedef-C

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

Mevcut görünüm denetleyiciye yerleştir

İkinci yöntem ise mini kumandayı doğrudan mevcut görünümünüze eklemektir. kullanarak denetleyici createMiniMediaControlsViewController oluşturmak için GCKUIMiniMediaControlsViewController kapsayıcı görünümü denetleyicisine alt görünüm olarak eklemelidir.

Uygulama yetkisinde görüntüleme denetleyicinizi ayarlayın:

Hızlı
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
}
Hedef-C
- (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;
}

Kök görünüm denetleyicinizde bir GCKUIMiniMediaControlsViewController oluşturun. kapsayıcı görünümü denetleyicisine alt görünüm olarak ekleyin:

Hızlı
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)
    }
  }

...
Hedef-C

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

İlgili içeriği oluşturmak için kullanılan GCKUIMiniMediaControlsViewControllerDelegate ana makine görünüm denetleyicisine mini denetleyicinin ne zaman görünür olması gerektiğini bildirir:

Hızlı
  func miniMediaControlsViewController(_: GCKUIMiniMediaControlsViewController,
                                       shouldAppear _: Bool) {
    updateControlBarsVisibility()
  }
Hedef-C
- (void)miniMediaControlsViewController:
            (GCKUIMiniMediaControlsViewController *)miniMediaControlsViewController
                           shouldAppear:(BOOL)shouldAppear {
  [self updateControlBarsVisibility];
}

Genişletilmiş denetleyici ekle

Google Cast Tasarım Kontrol Listesi, bir gönderen uygulamasının genişletilmiş bir Google Cast denetleyici doğru dengeyi bulmaya çalıştık. Genişletilmiş denetleyici, için de geçerlidir.

Genişletilmiş kumanda, kullanıcının ekranda yaptığı tüm ayrıntıları kontrol etmenize olanak tanıyan tam ekran görünümüdür. uzaktan medya oynatma. Bu görünüm, bir yayın uygulamasının bir yayın oturumunun, Web Alıcısı ses seviyesi dışında yönetilebilir bir yönü kontrol ve oturum yaşam döngüsü (bağlama/yayını durdurma). Ayrıca proje yönetimiyle ilgili oturum hakkındaki durum bilgilerini (poster, başlık, alt başlık vb.) ).

Bu görünümün işlevselliği GCKUIExpandedMediaControlsViewController sınıfını kullanır.

İlk olarak, varsayılan genişletilmiş denetleyiciyi içeriği yayınlamanızı sağlar. Uygulama temsilcinizi, varsayılan genişletilmiş denetleyiciyi etkinleştirecek şekilde değiştirin:

Hızlı
func applicationDidFinishLaunching(_ application: UIApplication) {
  ..

  GCKCastContext.sharedInstance().useDefaultExpandedMediaControls = true

  ...
}
Hedef-C
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  ...

  [GCKCastContext sharedInstance].useDefaultExpandedMediaControls = YES;

  ..
}

Genişletilmiş denetleyiciyi yüklemek için görünüm denetleyicinize aşağıdaki kodu ekleyin Kullanıcı bir video yayınlamaya başladığında:

Hızlı
func playSelectedItemRemotely() {
  GCKCastContext.sharedInstance().presentDefaultExpandedMediaControls()

  ...

  // Load your media
  sessionManager.currentSession?.remoteMediaClient?.loadMedia(mediaInformation)
}
Hedef-C
- (void)playSelectedItemRemotely {
  [[GCKCastContext sharedInstance] presentDefaultExpandedMediaControls];

  ...

  // Load your media
  [self.sessionManager.currentSession.remoteMediaClient loadMedia:mediaInformation];
}

Genişletilmiş denetleyici, kullanıcı aşağıdaki işlemleri gerçekleştirdiğinde de otomatik olarak başlatılır. mini kumandaya dokunur.

Gönderen uygulamanız bir video veya ses canlı yayını oynatırken SDK, oynatma/duraklatma düğmesi yerine otomatik olarak bir oynat/durdur düğmesi görüntüler ekleyebilirsiniz.

Bkz. iOS Cihazınıza Özel Stiller Uygulama Uygulama gönderen uygulamanızın Cast widget'larının görünümünü nasıl yapılandırabileceğine ilişkin daha fazla bilgi edinin.

Ses düzeyi kontrolü

Cast çerçevesi, gönderen uygulamasının ses düzeyini otomatik olarak yönetir. İlgili içeriği oluşturmak için kullanılan çerçevesi için Web Alıcı birimi ile otomatik olarak senkronize kullanıcı arayüzü widget'ları. Uygulama tarafından sağlanan kaydırma çubuğunu senkronize etmek için GCKUIDeviceVolumeController.

Fiziksel düğme ses düzeyi kontrolü

Gönderen cihazındaki fiziksel ses düğmeleri, Web Alıcısı'ndaki Yayın oturumunun ses düzeyini physicalVolumeButtonsWillControlDeviceVolume bayrağı GCKCastOptions her bir anahtar kelime için GCKCastContext.

Hızlı
let criteria = GCKDiscoveryCriteria(applicationID: kReceiverAppID)
let options = GCKCastOptions(discoveryCriteria: criteria)
options.physicalVolumeButtonsWillControlDeviceVolume = true
GCKCastContext.setSharedInstanceWith(options)
Hedef-C
GCKDiscoveryCriteria *criteria = [[GCKDiscoveryCriteria alloc]
                                          initWithApplicationID:kReceiverAppID];
GCKCastOptions *options = [[GCKCastOptions alloc]
                                          initWithDiscoveryCriteria :criteria];
options.physicalVolumeButtonsWillControlDeviceVolume = YES;
[GCKCastContext setSharedInstanceWithOptions:options];

Hataları işleme

Gönderen uygulamalarının tüm hata geri çağırmalarıyla ilgilenmesi ve her aşaması için en iyi yanıtı verir. Uygulama, hata iletişim kutuları gönderir veya Cast oturumunu sonlandırmaya karar verebilir.

Günlük Kaydı

GCKLogger çerçeve tarafından günlük kaydı için kullanılan tek bir değerdir. Şunu kullanın: GCKLoggerDelegate günlük mesajlarını işleme biçiminizi özelleştirebilirsiniz.

SDK, GCKLogger öğesini kullanarak hata ayıklama biçiminde günlük çıkışı üretir mesajları, hataları ve uyarıları gösterir. Bu günlük mesajları hata ayıklamaya yardımcı olur ve kullanışlıdır sorunları gidermeye ve belirlemeye yardımcı olur. Varsayılan olarak günlük çıkışı şu şekildedir: atlandı, ancak bir GCKLoggerDelegate atayarak gönderen uygulaması bu mesajları SDK'dan gönderir ve sistem konsoluna kaydeder.

Hızlı
@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)
    }
  }
}
Hedef-C

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

Hata ayıklama mesajlarını ve ayrıntılı mesajları da etkinleştirmek için yetki verdiğinizi ayarlama (daha önce gösterilmiştir):

Hızlı
let filter = GCKLoggerFilter.init()
filter.minimumLevel = GCKLoggerLevel.verbose
GCKLogger.sharedInstance().filter = filter
Hedef-C
GCKLoggerFilter *filter = [[GCKLoggerFilter alloc] init];
[filter setMinimumLevel:GCKLoggerLevelVerbose];
[GCKLogger sharedInstance].filter = filter;

Ayrıca, GCKLogger. Her sınıf için minimum günlük kaydı seviyesini belirleyin. Örneğin:

Hızlı
let filter = GCKLoggerFilter.init()
filter.setLoggingLevel(GCKLoggerLevel.verbose, forClasses: ["GCKUICastButton",
                                                            "GCKUIImageCache",
                                                            "NSMutableDictionary"])
GCKLogger.sharedInstance().filter = filter
Hedef-C
GCKLoggerFilter *filter = [[GCKLoggerFilter alloc] init];
[filter setLoggingLevel:GCKLoggerLevelVerbose
             forClasses:@[@"GCKUICastButton",
                          @"GCKUIImageCache",
                          @"NSMutableDictionary"
                          ]];
[GCKLogger sharedInstance].filter = filter;

Sınıf adları, düz adlar veya glob kalıpları olabilir. Örneğin, GCKUI\* ve GCK\*Session.