Yayını iOS Uygulamanıza Entegre Edin

Bu geliştirici kılavuzunda, iOS Gönderen SDK'sını kullanarak iOS gönderen uygulamanıza Google Cast desteğinin nasıl ekleneceği açıklanmaktadır.

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

Gönderen çerçevesi, Cast sınıfı kitaplık ikili programını ve gönderende çalışma zamanında mevcut ilişkili kaynakları belirtir. Gönderen uygulaması veya Yayın uygulaması, gönderen üzerinde de çalışan bir uygulamayı ifade eder. Web Alıcısı uygulaması, Web Alıcısında çalışan HTML uygulamasını belirtir.

Gönderen çerçevesi, gönderenleri etkinlikler konusunda bilgilendirmek ve Cast uygulama yaşam döngüsünün çeşitli durumları arasında geçiş yapmak için eşzamansız bir geri çağırma tasarımı kullanır.

Uygulama akışı

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

  • Cast çerçevesi, cihazları taramaya başlamak için GCKCastOptions içinde sağlanan özelliklere göre GCKDiscoveryManager başlar.
  • Kullanıcı, Yayınla düğmesini tıkladığında çerçeve, Yayınlama iletişim kutusunu keşfedilen Yayın cihazlarının listesiyle sunar.
  • Kullanıcı bir Yayın cihazı seçtiğinde çerçeve, Yayın cihazında Web Alıcısı uygulamasını başlatmayı dener.
  • Çerçeve, Web Alıcısı uygulamasının başlatıldığını onaylamak için gönderen uygulamasında geri çağırmaları çağırır.
  • Bu çerçeve, gönderen ile Web Alıcısı uygulamaları arasında bir iletişim kanalı oluşturur.
  • Çerçeve, Web Alıcısı'nda medya oynatmasını yüklemek ve kontrol etmek için iletişim kanalını kullanır.
  • Çerçeve, gönderen ile Web Alıcısı'nın medya oynatma durumunu senkronize eder: Kullanıcı, gönderen kullanıcı arayüzü işlemlerini yaptığında, çerçeve bu medya kontrolü isteklerini Web Alıcı'ya iletir ve Web Alıcısı, medya durumu güncellemelerini gönderdiğinde çerçeve de gönderen kullanıcı arayüzünün durumunu günceller.
  • Kullanıcı, Yayın cihazıyla olan bağlantısını kesmek için Yayın düğmesini tıkladığında çerçeve, gönderen uygulamanın Web Alıcısı ile bağlantısını keser.

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

Google Cast iOS çerçevesindeki tüm sınıfların, yöntemlerin ve etkinliklerin kapsamlı bir listesi için Google Cast iOS API Referansı'nı inceleyin. Aşağıdaki bölümlerde, Cast'i iOS uygulamanıza entegre etme adımları açıklanmaktadır.

Ana iş parçacığının çağrı yöntemleri

Yayınlama bağlamını ilk kullanıma hazırla

Yayın çerçevesi, çerçevenin tüm etkinliklerini koordine eden küresel bir tekil nesneye (GCKCastContext) sahiptir. Bu nesne, gönderen uygulama yeniden başlatılırken otomatik oturum devam ettirmenin düzgün bir şekilde tetiklenebilmesi için uygulamanın yaşam döngüsünde, genellikle delegenin -[application:didFinishLaunchingWithOptions:] yönteminde başlatılmalıdır.

GCKCastContext başlatılırken bir GCKCastOptions nesnesi sağlanmalıdır. Bu sınıf, çerçevenin davranışını etkileyen seçenekler içerir. Bunlar arasından en önemlisi, keşif sonuçlarını filtrelemek ve bir Yayın oturumu başlatıldığında Web Alıcısı uygulamasını başlatmak için kullanılan Web Alıcı uygulama kimliğidir.

-[application:didFinishLaunchingWithOptions:] yöntemi de çerçeveden günlük iletisi almak için bir günlük kaydı yetkilisi oluşturmak için iyi bir yerdir. Bunlar, hata ayıklama ve sorun giderme için yararlı olabilir.

İsviçre
@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

AppTemsilci.h

@interface AppDelegate () <GCKLoggerDelegate>
@end

UygulamaYetkisi Veren.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 Kontrol Listesi'ne uyan aşağıdaki widget'ları sağlar:

  • Tanıtım yer paylaşımı: GCKCastContext sınıfının bir yöntemi vardır: presentCastInstructionsViewControllerOnceWithCastButton bir Web Alıcısı ilk kez sunulduğunda Yayınla düğmesini ön plana çıkarmak için kullanılabilir. Gönderen uygulama, metni, başlık metninin konumunu ve Kapatma düğmesini özelleştirebilir.

  • Yayın Düğmesi: Yayın iOS göndereni SDK'sı 4.6.0 sürümünden itibaren, gönderici düğmesi kablosuz cihaza bağlandığında her zaman yayınla düğmesi görünür. Kullanıcı, uygulamayı ilk kez başlattıktan sonra Yayınla düğmesine ilk kez dokunduğunda, kullanıcının uygulamaya ağ üzerindeki cihazlara yerel ağ erişimi verebilmesi için bir izin iletişim kutusu görünür. Daha sonra, kullanıcı yayınla düğmesine dokunduğunda, bulunan cihazları listeleyen bir yayınlama iletişim kutusu görüntülenir. Kullanıcı, cihaz bağlıyken yayınla düğmesine dokunduğunda mevcut medya meta verilerini (ör. başlık, kayıt stüdyosunun adı ve küçük resim görüntüsü) görüntüler veya kullanıcının yayın cihazıyla bağlantısını kesmesine izin verir. Kullanılabilir cihaz olmasa da kullanıcı yayınla düğmesine dokunduğunda kullanıcıya cihazların neden bulunamadığı ve nasıl sorun giderileceği hakkında bilgi veren bir ekran görüntülenir.

  • Mini Denetleyici: Kullanıcı içerik yayınlarken geçerli içerik sayfasından veya genişletilmiş kumandadan gönderen uygulamasında başka bir ekrana gittiğinde, kullanıcının en son yayınlanan medya meta verilerini görmesine ve oynatmayı kontrol etmesine olanak tanımak için ekranın alt kısmında mini kumanda görüntülenir.

  • Genişletilmiş Denetleyici: Kullanıcı içerik yayınlarken medya bildirimini veya mini denetleyiciyi tıklarsa genişletilmiş denetleyici açılır ve şu anda oynatılan medya meta verilerini gösterir ve medya oynatmayı kontrol etmek için birkaç düğme sağlar.

Yayınla düğmesi ekle

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

İsviçre
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, çerçeve tarafından sağlanan Google Cast iletişim kutusu açılır.

GCKUICastButton ayrıca doğrudan resimli taslaklara da eklenebilir.

Cihaz keşfini yapılandırma

Çerçeve içinde, cihaz keşfi otomatik olarak gerçekleşir. Özel bir kullanıcı arayüzü uygulamadığınız takdirde keşif sürecini açık bir şekilde başlatmanız veya durdurmanız gerekmez.

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

Oturum yönetiminin işleyiş şekli

Google Cast SDK'sı, bir Cihaza bağlanma, bir Web Alıcısı uygulaması başlatma (ya da birleştirme), bu uygulamaya bağlanma ve medya kontrol kanalı başlatma adımlarını birleştiren Yayın oturumu kavramını tanımlar. Yayınlama oturumları ve Web Alıcı yaşam döngüsü hakkında daha fazla bilgi için Web Alıcısı'na Uygulama yaşam döngüsü kılavuzuna bakın.

Oturumlar, GCKCastContext mülkünün bir özelliği olan GCKSessionManager sınıfı tarafından yönetilir. Her oturum, GCKSession sınıfının alt sınıflarıyla temsil edilir: Örneğin, GCKCastSession, Yayın cihazlarıyla yapılan oturumları temsil eder. Etkin durumdaki Yayın oturumuna (varsa) GCKSessionManager mülkü olarak currentCastSession özelliği ile erişebilirsiniz.

GCKSessionManagerListener arayüzü, oturum oluşturma, askıya alma, devam ettirme ve sonlandırma gibi oturum etkinliklerini izlemek için kullanılabilir. Bu çerçeve, gönderen uygulama arka plana gittiğinde oturumları otomatik olarak askıya alır ve uygulama ön plana geri döndüğünde (veya oturum etkin durumdayken anormal/ani bir uygulama sonlandırıldıktan sonra yeniden başlatılırsa) devam ettirir.

Yayınlama iletişim kutusu kullanılıyorsa oturumlar, kullanıcı hareketlerine göre otomatik olarak oluşturulur ve yok edilir. Aksi takdirde uygulama, GCKSessionManager alanındaki yöntemleri kullanarak oturumları açıkça başlatıp sonlandırabilir.

Uygulamanın, oturum yaşam döngüsü olaylarına yanıt olarak özel işlem yapması gerekiyorsa GCKSessionManager ile bir veya daha fazla GCKSessionManagerListener örneği kaydedebilir. GCKSessionManagerListener; oturum başlatma, oturum sonu vb. etkinlikler için geri çağırmaları tanımlayan bir protokoldür.

Akış aktarma

Oturum durumunu korumak, kullanıcıların ses komutlarını, Google Home uygulamasını veya akıllı ekranları kullanarak mevcut ses ve video akışlarını cihazlar arasında taşıyabileceği akış aktarımının temelini oluşturur. Medya, bir cihazda (kaynak) oynamayı durdurur ve başka bir cihazda (hedef) devam eder. En son donanım yazılımına sahip tüm Yayın cihazları, akış aktarımında kaynak veya hedef işlevi görebilir.

Akış aktarımı sırasında yeni hedef cihazı almak için [sessionManager:didResumeCastSession:] geri çağırma işlemi sırasında GCKCastSession#device özelliğini kullanın.

Daha fazla bilgi için Web Alıcısı üzerinden akış aktarma bölümüne göz atın.

Otomatik yeniden bağlanma

Cast çerçevesi, aşağıdakiler gibi birçok zor köşe durumunda yeniden bağlantıyı otomatik olarak yönetmek için yeniden bağlantı mantığı ekler:

  • Geçici kablosuz ağ bağlantısı kaybından kurtulma
  • Cihaz uykusundan kurtar
  • Uygulamayı arka planda kurtarın
  • Uygulama kilitlendiyse kurtarma

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

Medya adı alanını destekleyen bir Web Alıcısı uygulamasıyla Yayın oturumu oluşturulursa çerçeve tarafından otomatik olarak bir GCKRemoteMediaClient örneği oluşturulur. Bu örneğe GCKCastSession örneğinin remoteMediaClient özelliği olarak erişilebilir.

GCKRemoteMediaClient tarihinde Web Alıcısına istek gönderen tüm yöntemler, bu isteği izlemek için kullanılabilecek bir GCKRequest nesnesi döndürür. İşlemin nihai sonucuyla ilgili bildirim almak için bu nesneye GCKRequestDelegate atanabilir.

GCKRemoteMediaClient örneğinin uygulamanın birden çok bölümü tarafından paylaşılabilmesi, hatta Yayınlama iletişim kutusu ve mini medya denetimleri gibi çerçevenin bazı dahili bileşenlerinin örneği paylaşması beklenir. Bu amaçla GCKRemoteMediaClient, birden fazla GCKRemoteMediaClientListener kaydının kaydedilmesini destekler.

Medya meta verilerini ayarlama

GCKMediaMetadata sınıfı, yayınlamak istediğiniz medya öğesi hakkındaki bilgileri temsil eder. Aşağıdaki örnekte bir filmin yeni GCKMediaMetadata örneği oluşturulur ve başlık, alt başlık, kayıt stüdyosu adı ve iki resim ayarlanır.

İsviçre
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]];

Medya meta verileriyle resim kullanımı hakkında bilgi için Resim Seçimi ve Önbelleğe Alma bölümüne bakın.

Medya yükle

Bir medya öğesi yüklemek için medyanın meta verilerini kullanarak bir GCKMediaInformation örneği oluşturun. Ardından, mevcut GCKCastSession verisini alın ve alıcı uygulamasına medyayı yüklemek için GCKRemoteMediaClient kullanın. Daha sonra, alıcı üzerinde çalışan bir medya oynatıcı uygulamasını (ör. oynatma, duraklatma ve durdurma) kontrol etmek için GCKRemoteMediaClient öğesini kullanabilirsiniz.

İsviçre
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 ile ilgili bölüme bakın.

4K video biçimi

Medyanızın hangi video biçimini kullandığını belirlemek için GCKMediaStatus etiketinin videoInfo özelliğini kullanarak geçerli GCKVideoInfo örneğini alın. Bu örnekte HDR TV biçimi türünün yanı sıra piksel cinsinden yükseklik ve genişlik yer almaktadır. 4K biçimindeki varyantlar, hdrType özelliğinde GCKVideoInfoHDRType sıralama değerleriyle gösterilir.

Mini kumanda ekle

Yayın Tasarımı Kontrol Listesi'ne göre, bir gönderen uygulaması, kullanıcı geçerli içerik sayfasından ayrıldığında gösterilecek olan mini denetleyici olarak bilinen kalıcı bir kontrol sağlamalıdır. Mini kumanda, geçerli yayın oturumu için anında erişim ve görünür bir hatırlatıcı sağlar.

Yayın çerçevesi, mini denetleyiciyi göstermek istediğiniz sahnelere eklenebilecek bir kontrol çubuğu (GCKUIMiniMediaControlsViewController) sağlar.

Gönderen uygulamanız bir video veya ses canlı yayını oynatırken SDK, mini kumandadaki oynat/duraklat düğmesinin yerine otomatik olarak bir oynat/dur düğmesi gösterir.

Gönderen uygulamanızın, Yayın widget'larının görünümünü nasıl yapılandırabileceğini öğrenmek için iOS Gönderen kullanıcı arayüzünü özelleştirme bölümüne bakın.

Mini kumandayı bir gönderen uygulamasına eklemenin iki yolu vardır:

  • Mevcut çerçeve denetleyicinizi kendi görünüm denetleyicisiyle sarmalayarak yayın çerçevesinin mini denetleyicinin düzenini yönetmesine izin verin.
  • Mini denetleyici widget'ının düzenini, resimli taslakta bir alt görünüm sağlayarak mevcut görünüm denetleyicinize ekleyerek kendiniz yönetin.

GCKUICastContainerViewController'ı kullanarak sarmalayın

İlk yöntem, başka bir görünüm denetleyiciyi sarmalayan ve alta bir GCKUIMiniMediaControlsViewController ekleyen GCKUICastContainerViewController öğesini kullanmaktır. Bu yaklaşım, animasyonu özelleştiremediğiniz ve kapsayıcı görünümü denetleyicisinin davranışını yapılandıramayacağınız için sınırlıdır.

Bu birinci yöntem, genellikle uygulama yetkilisinin -[application:didFinishLaunchingWithOptions:] yöntemiyle yapılır:

İsviçre
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];
  ...

}
Swift
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

AppTemsilci.h

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (nonatomic, strong) UIWindow *window;
@property (nonatomic, assign) BOOL castControlBarsEnabled;

@end

UygulamaYetkisi Veren.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, GCKUIMiniMediaControlsViewController örneği oluşturmak ve ardından bu tabloyu alt görünüm olarak container görünümü denetleyicisine eklemek için mini denetleyiciyi createMiniMediaControlsViewController kullanarak doğrudan mevcut görünüm denetleyicinize eklemektir.

Uygulama yetkisi verilmiş kullanıcı için görünüm denetleyicinizi ayarlayın:

İsviçre
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 örneği oluşturun ve bunu alt görünüm olarak container görünümü denetleyicisine ekleyin:

İsviçre
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

Kök ContainerViewController.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

Kök ContainerViewController.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

Mini kumandanın görünür olması gerektiğinde GCKUIMiniMediaControlsViewControllerDelegate, ana makine görünüm denetleyicisini bilgilendirir:

İsviçre
  func miniMediaControlsViewController(_: GCKUIMiniMediaControlsViewController,
                                       shouldAppear _: Bool) {
    updateControlBarsVisibility()
  }
Hedef C
- (void)miniMediaControlsViewController:
            (GCKUIMiniMediaControlsViewController *)miniMediaControlsViewController
                           shouldAppear:(BOOL)shouldAppear {
  [self updateControlBarsVisibility];
}

Genişletilmiş kumanda ekle

Google Cast Tasarım Kontrol Listesi için bir gönderen uygulamasının, yayınlanacak medya için genişletilmiş kumanda sağlaması gerekir. Genişletilmiş kumanda, mini kumandanın tam ekran sürümüdür.

Genişletilmiş kumanda, uzaktan medya oynatımı üzerinde tam kontrol sağlayan bir tam ekran görünümüdür. Bu görünüm, Web Alıcısı ses kontrolü ve oturum yaşam döngüsü (yayınlanma/bağlantıyı durdurma) dışında yayın uygulamasının yayın oturumunun tüm yönetilen özelliklerini yönetmesine izin vermelidir. Ayrıca, medya oturumuyla ilgili tüm durum bilgilerini (poster, başlık, alt başlık vb.) de sağlar.

Bu görünümün işlevleri GCKUIExpandedMediaControlsViewController sınıfı tarafından uygulanır.

Yapmanız gereken ilk şey, yayınlama bağlamında varsayılan genişletilmiş kumandayı etkinleştirmektir. Varsayılan genişletilmiş kumandayı etkinleştirmek için uygulama yetkisini değiştirin:

İsviçre
func applicationDidFinishLaunching(_ application: UIApplication) {
  ..

  GCKCastContext.sharedInstance().useDefaultExpandedMediaControls = true

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

  [GCKCastContext sharedInstance].useDefaultExpandedMediaControls = YES;

  ..
}

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

İsviçre
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ş kumanda, kullanıcı mini denetleyiciye dokunduğunda da otomatik olarak başlatılır.

Gönderen uygulamanız bir video veya ses canlı yayını oynatırken SDK, genişletilmiş kumandadaki oynatma/duraklatma düğmesinin yerine otomatik olarak bir oynat/dur düğmesi gösterir.

Gönderen uygulamanızın, Yayın widget'larının görünümünü nasıl yapılandırabileceğini öğrenmek için iOS Stilinize Özel Stiller Uygulama bölümüne bakın.

Ses düzeyi kontrolü

Yayınlama çerçevesi, gönderen uygulamanın ses düzeyini otomatik olarak yönetir. Çerçeve, sağlanan kullanıcı arayüzü widget'larının Web Alıcısı sesleriyle otomatik olarak senkronize edilir. Uygulama tarafından sağlanan bir kaydırma çubuğunu senkronize etmek için GCKUIDeviceVolumeController simgesini kullanın.

Fiziksel düğme ses denetimi

Gönderen cihazdaki fiziksel ses düğmeleri, GCKCastContext üzerinde ayarlanan GCKCastOptions üzerindeki physicalVolumeButtonsWillControlDeviceVolume işaretini kullanarak Web Alıcısı'nda Yayın oturumunun ses düzeyini değiştirmek için kullanılabilir.

İsviçre
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 tüm hata geri çağırmalarını ele alması ve yayınlama yaşam döngüsünün her aşaması için en iyi yanıtı seçmesi çok önemlidir. Uygulama, kullanıcıya hata iletişim kutuları gösterebilir veya Yayın oturumunu sonlandırmaya karar verebilir.

Günlük Kaydı

GCKLogger, çerçeve tarafından günlük kaydı için kullanılan bir tekildir. Günlük mesajlarını işleme yönteminizi özelleştirmek için GCKLoggerDelegate'i kullanın.

SDK, GCKLogger kullanıldığında hata ayıklama mesajları, hatalar ve uyarılar biçiminde günlük kaydı sonuçları oluşturur. Bu günlük mesajları hata ayıklamaya yardımcı olur ve sorunların giderilmesinde yararlı olur. Varsayılan olarak günlük çıkışı sınırlandırılır ancak bir GCKLoggerDelegate atayarak gönderen uygulama bu mesajları SDK'dan alıp sistem konsoluna kaydedebilir.

İsviçre
@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

AppTemsilci.h

@interface AppDelegate () <GCKLoggerDelegate>
@end

UygulamaYetkisi Veren.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 ve ayrıntılı mesajları da etkinleştirmek için, yetki verilen kullanıcıyı ayarladıktan sonra bu satırı koda ekleyin (daha önce gösterilmiştir):

İsviçre
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;

GCKLogger tarafından oluşturulan günlük mesajlarını da filtreleyebilirsiniz. Sınıf başına minimum günlük kaydı düzeyini ayarlayın. Örneğin:

İsviçre
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ı, gerçek adlar veya glob kalıplar olabilir. Örneğin, GCKUI\* ve GCK\*Session.