iOS uygulamasında yayınlama özelliğini etkinleştirme

1. Genel Bakış

Google Cast logosu

Bu codelab'de, Google Cast uyumlu cihazlarda içerik yayınlamak için mevcut bir iOS video uygulamasını nasıl değiştireceğiniz açıklanmaktadır.

Google Cast nedir?

Google Cast, kullanıcıların mobil cihazdan TV'ye içerik yayınlamasına olanak tanır. Böylece kullanıcılar, TV'de medya oynatmak için mobil cihazlarını uzaktan kumanda olarak kullanabilir.

Google Cast SDK'sı, uygulamanızın kapsamını Google Cast uyumlu cihazları (TV veya ses sistemi gibi) kontrol edecek şekilde genişletmenize olanak tanır. Cast SDK'sı, Google Cast Tasarım Kontrol Listesi'ne göre gerekli kullanıcı arayüzü bileşenlerini eklemenize olanak tanır.

Google Cast Tasarım Kontrol Listesi, desteklenen tüm platformlarda Cast kullanıcı deneyimini basit ve tahmin edilebilir hale getirmek için sağlanmıştır.

Ne oluşturacağız?

Bu codelab'i tamamladığınızda, Google Cast cihazlarına video yayınlayabilecek bir iOS video uygulamanız olacak.

Neler öğreneceksiniz?

  • Google Cast SDK'sını örnek bir video uygulamasına ekleme.
  • Google Cast cihazı seçmek için yayın düğmesi nasıl eklenir?
  • Yayın cihazına bağlanıp medya alıcısı nasıl başlatılır?
  • Video nasıl yayınlanır?
  • Uygulamanıza Cast mini kumandası nasıl eklenir?
  • Genişletilmiş kumanda ekleme
  • Tanıtım yer paylaşımı nasıl sağlanır?
  • Cast widget'ları nasıl özelleştirilir?
  • Cast Connect nasıl entegre edilir?

İhtiyacınız olanlar

  • En son Xcode.
  • iOS 9 veya sonraki sürümlerin yüklü olduğu bir mobil cihaz (ya da Xcode Simülatörü).
  • Mobil cihazınızı geliştirme bilgisayarınıza bağlamak için bir USB veri kablosu (cihaz kullanıyorsanız).
  • Chromecast veya Android TV gibi internet erişimi olan bir Google Cast cihazı.
  • HDMI girişli bir TV veya monitör.
  • Cast Connect entegrasyonunu test etmek için Google TV Yüklü Chromecast gerekir ancak Codelab'in geri kalanı için isteğe bağlıdır. AdSense hesabınız yoksa bu eğiticinin sonuna doğru, Cast Connect Desteği Ekle adımını atlayabilirsiniz.

Deneyim

  • iOS geliştirme için önceden bilgi sahibi olmanız gerekir.
  • TV izleme konusunda önceden bilgiye de sahip olmanız gerekir :)

Bu eğiticiden nasıl yararlanacaksınız?

Yalnızca okuma Okuyun ve alıştırmaları tamamlayın

iOS uygulaması geliştirme deneyiminizi nasıl değerlendirirsiniz?

Acemi Orta Yeterli

TV izleme deneyiminizi nasıl değerlendirirsiniz?

Acemi Orta Yeterli

2. Örnek kodu alın

Tüm örnek kodu bilgisayarınıza indirebilirsiniz...

ve indirilen zip dosyasının paketini açın.

3. Örnek uygulamayı çalıştırma

Apple iOS logosu

Öncelikle tamamlanan örnek uygulamanın nasıl göründüğüne bakalım. Uygulama temel bir video oynatıcıdır. Kullanıcı listeden bir video seçebilir ve daha sonra videoyu cihazda yerel olarak oynatabilir veya bir Google Cast cihazında yayınlayabilir.

Kod indirildikten sonra aşağıdaki talimatlar, tamamlanan örnek uygulamayı Xcode'da nasıl açıp çalıştıracağınızı açıklar:

Sık sorulan sorular

CocoaPods kurulumu

CocoaPods'u kurmak için konsolunuza gidin ve macOS'te bulunan varsayılan Ruby'yi kullanarak yükleyin:

sudo gem install cocoapods

Herhangi bir sorunla karşılaşırsanız bağımlılık yöneticisini indirip yüklemek için resmi belgelere bakın.

Proje ayarlama

  1. Terminale gidip codelab dizinine gidin.
  2. Bağımlılıkları Podfile'den yükleyin.
cd app-done
pod update
pod install
  1. Xcode'u açın ve Başka bir proje aç... seçeneğini belirleyin.
  2. Örnek kod klasöründeki klasör simgesiapp-done dizininden CastVideos-ios.xcworkspace dosyasını seçin.

Uygulamayı çalıştırın

Hedefi ve simülatörü seçip uygulamayı çalıştırın:

XCode uygulama simülatörü araç çubuğu

Birkaç saniye sonra video uygulaması görünecektir.

"İzin ver"i tıkladığınızdan emin olun gelen ağın kabulüyle ilgili bildirim göründüğünde. Bu seçenek kabul edilmezse Yayınla simgesi görünmez.

Gelen ağ bağlantılarını kabul etme izni isteyen onay iletişim kutusu

Yayınla düğmesini tıklayın ve Google Cast cihazınızı seçin.

Bir video seçip oynat düğmesini tıklayın.

Video, Google Cast cihazınızda oynatılmaya başlar.

Genişletilmiş kontrol cihazı gösterilir. Oynatmayı kontrol etmek için oynat/duraklat düğmesini kullanabilirsiniz.

Video listesine geri dönün.

Ekranın alt kısmında artık bir mini kumanda görünüyor.

Alt kısmında mini kumandanın göründüğü, CastVideos uygulamasını çalıştıran iPhone'un resmi

Alıcıdaki videoyu duraklatmak için mini kumandadaki duraklat düğmesini tıklayın. Videoyu tekrar oynatmaya devam etmek için mini kumandadaki oynat düğmesini tıklayın.

Google Cast cihazına yayını durdurmak için Yayınla düğmesini tıklayın.

4. Başlangıç projesini hazırlama

CastVideos uygulamasını çalıştıran iPhone'un resmi

İndirdiğiniz başlangıç uygulamasına Google Cast desteği eklememiz gerekiyor. Bu codelab'de kullanacağımız Google Cast terminolojilerinden bazıları şunlardır:

  • Mobil cihazda veya dizüstü bilgisayarda çalışan gönderen uygulaması,
  • Google Cast cihazında çalışan bir alıcı uygulaması.

Proje ayarlama

Artık Xcode kullanarak başlangıç projesinin temelini oluşturmaya hazırsınız:

  1. Terminale gidip codelab dizinine gidin.
  2. Bağımlılıkları Podfile'den yükleyin.
cd app-start
pod update
pod install
  1. Xcode'u açın ve Başka bir proje aç... seçeneğini belirleyin.
  2. Örnek kod klasöründeki klasör simgesiapp-start dizininden CastVideos-ios.xcworkspace dosyasını seçin.

Uygulama tasarımı

Uygulama, uzak bir web sunucusundan video listesi getirir ve kullanıcının göz atabileceği bir liste sağlar. Kullanıcılar, ayrıntılarını görmek için bir video seçebilir veya videoyu mobil cihazda yerel olarak oynatabilir.

Uygulama iki ana görünüm denetleyicisinden oluşur: MediaTableViewController ve MediaViewController.

MediaTableViewController

Bu UITableViewController, bir MediaListModel örneğindeki videoların listesini görüntüler. Video listesi ve bunlarla ilişkili meta veriler, uzak sunucuda JSON dosyası olarak barındırılır. MediaListModel, bu JSON'u getirir ve MediaItem nesnenin listesini oluşturmak için işler.

MediaItem nesnesi, bir videoyu ve video ile ilişkili meta verileri (ör. başlığı, açıklaması, resmin URL'si ve akışın URL'si) modeller.

MediaTableViewController, bir MediaListModel örneği oluşturur ve ardından, medya meta verileri indirildiğinde tablo görünümünü yükleyebilmek için bilgilendirilmek üzere kendisini MediaListModelDelegate olarak kaydeder.

Kullanıcıya, her videonun kısa açıklamalarının yer aldığı bir video küçük resimleri listesi sunulur. Bir öğe seçildiğinde karşılık gelen MediaItem, MediaViewController öğesine aktarılır.

MediaViewController

Bu görüntüleme denetleyicisi belirli bir videoyla ilgili meta verileri görüntüler ve kullanıcının videoyu mobil cihazda yerel olarak oynatmasına olanak tanır.

Görüntüleme denetleyicisi, seçilen videonun açıklamasını gösteren bir LocalPlayerView, bazı medya kontrolleri ve metin alanı barındırır. Oynatıcı ekranın üst kısmını kaplayarak altında videonun ayrıntılı açıklaması için yer bırakır. Kullanıcı yerel videoyu oynatabilir/duraklatabilir veya oynatabilir.

Sık sorulan sorular

5. Yayınla düğmesi ekleniyor

Sağ üst köşesinde Yayınla düğmesinin gösterildiği, CastVideos uygulamasını çalıştıran iPhone'un üstteki üçte birlik kısmının görseli

Cast uyumlu bir uygulama, görünüm denetleyicilerinin her birinde Yayınla düğmesini gösterir. Yayın düğmesi tıklandığında, kullanıcının seçebileceği Yayın cihazlarının listesi görüntülenir. Kullanıcı içeriği gönderen cihazda yerel olarak oynatıyorsa bir yayın cihazı seçtiğinde oynatma işlemi o yayın cihazında başlar veya devam ettirilir. Yayın oturumu sırasında herhangi bir zamanda, kullanıcı Yayın düğmesini tıklayabilir ve uygulamanızı Yayın cihazına yayınlamayı durdurabilir. Kullanıcı, Google Cast Tasarım Kontrol Listesi'nde açıklandığı gibi, uygulamanızın herhangi bir ekranında yayın cihazına bağlanabilmeli veya cihazın bağlantısını kesebilmelidir.

Yapılandırma

Başlangıç projesi, tamamlanan örnek uygulama için olduğu gibi aynı bağımlılıkları ve Xcode kurulumunu gerektirir. Bu bölüme dönün ve GoogleCast.framework öğesini başlangıç projesine eklemek için aynı adımları uygulayın.

Başlatma

Cast çerçevesi, çerçevenin tüm etkinliklerini koordine eden GCKCastContext adlı küresel bir tekil nesneye sahiptir. Bu nesne, gönderen uygulamanın yeniden başlatılmasında otomatik oturum devam ettirme işleminin düzgün şekilde tetiklenebilmesi ve cihaz tarama işleminin başlatılabilmesi için uygulamanın yaşam döngüsünün başlarında, genellikle uygulama temsilcisinin application(_:didFinishLaunchingWithOptions:) yönteminde başlatılmalıdır.

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

application(_:didFinishLaunchingWithOptions:) yöntemi, Cast çerçevesinden günlük kaydı mesajlarını alacak günlük kaydı yetkisi ayarlamak için de iyi bir yerdir. Bunlar hata ayıklama ve sorun giderme açısından faydalı olabilir.

Kendi Cast uyumlu uygulamanızı geliştirirken, Cast geliştiricisi olarak kaydolmanız ve ardından uygulamanız için bir uygulama kimliği edinmeniz gerekir. Bu codelab için örnek bir uygulama kimliği kullanacağız.

GCKCastContext uygulamasını kullanıcı varsayılanlarındaki uygulama kimliğiyle başlatmak için AppDelegate.swift hedefine aşağıdaki kodu ekleyin ve Google Cast çerçevesi için bir logger ekleyin:

import GoogleCast

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
  fileprivate var enableSDKLogging = true

  ...

  func application(_: UIApplication,
                   didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

    ...
    let options = GCKCastOptions(discoveryCriteria: GCKDiscoveryCriteria(applicationID: kReceiverAppID))
    options.physicalVolumeButtonsWillControlDeviceVolume = true
    GCKCastContext.setSharedInstanceWith(options)

    window?.clipsToBounds = true
    setupCastLogging()
    ...
  }
  ...
  func setupCastLogging() {
    let logFilter = GCKLoggerFilter()
    let classesToLog = ["GCKDeviceScanner", "GCKDeviceProvider", "GCKDiscoveryManager", "GCKCastChannel",
                        "GCKMediaControlChannel", "GCKUICastButton", "GCKUIMediaController", "NSMutableDictionary"]
    logFilter.setLoggingLevel(.verbose, forClasses: classesToLog)
    GCKLogger.sharedInstance().filter = logFilter
    GCKLogger.sharedInstance().delegate = self
  }
}

...

// MARK: - GCKLoggerDelegate

extension AppDelegate: GCKLoggerDelegate {
  func logMessage(_ message: String,
                  at _: GCKLoggerLevel,
                  fromFunction function: String,
                  location: String) {
    if enableSDKLogging {
      // Send SDK's log messages directly to the console.
      print("\(location): \(function) - \(message)")
    }
  }
}

Yayınla düğmesi

GCKCastContext başlatıldığına göre kullanıcının bir Yayın cihazı seçmesine izin vermek için Yayınla düğmesini eklememiz gerekir. Cast SDK'sı, UIButton alt sınıfı olarak GCKUICastButton adlı bir Yayın düğmesi bileşeni sağlar. UIBarButtonItem içine sarılarak uygulamanın başlık çubuğuna eklenebilir. Yayınla düğmesini hem MediaTableViewController hem de MediaViewController cihazına eklememiz gerekiyor.

Şu kodu MediaTableViewController.swift ve MediaViewController.swift için ekleyin:

import GoogleCast

@objc(MediaTableViewController)
class MediaTableViewController: UITableViewController, GCKSessionManagerListener,
  MediaListModelDelegate, GCKRequestDelegate {
  private var castButton: GCKUICastButton!
  ...
  override func viewDidLoad() {
    print("MediaTableViewController - viewDidLoad")
    super.viewDidLoad()

    ...
    castButton = GCKUICastButton(frame: CGRect(x: CGFloat(0), y: CGFloat(0),
                                               width: CGFloat(24), height: CGFloat(24)))
    // Overwrite the UIAppearance theme in the AppDelegate.
    castButton.tintColor = UIColor.white
    navigationItem.rightBarButtonItem = UIBarButtonItem(customView: castButton)

    ...
  }
  ...
}

Sonra, aşağıdaki kodu MediaViewController.swift cihazınıza ekleyin:

import GoogleCast

@objc(MediaViewController)
class MediaViewController: UIViewController, GCKSessionManagerListener, GCKRemoteMediaClientListener,
  LocalPlayerViewDelegate, GCKRequestDelegate {
  private var castButton: GCKUICastButton!
  ...
  override func viewDidLoad() {
    super.viewDidLoad()
    print("in MediaViewController viewDidLoad")
    ...
    castButton = GCKUICastButton(frame: CGRect(x: CGFloat(0), y: CGFloat(0),
                                               width: CGFloat(24), height: CGFloat(24)))
    // Overwrite the UIAppearance theme in the AppDelegate.
    castButton.tintColor = UIColor.white
    navigationItem.rightBarButtonItem = UIBarButtonItem(customView: castButton)

    ...
  }
  ...
}

Şimdi uygulamayı çalıştırın. Uygulamanın gezinme çubuğunda bir Yayın düğmesi görürsünüz. Bu düğmeyi tıkladığınızda yerel ağınızdaki Yayın cihazları listelenir. Cihaz bulma, GCKCastContext tarafından otomatik olarak yönetilir. Yayın cihazınızı seçtiğinizde örnek alıcı uygulaması yayın cihazınıza yüklenir. Göz atma etkinliği ile yerel oynatıcı etkinliği arasında gezinebilirsiniz ve Yayınla düğmesinin durumu senkronize edilir.

Medya oynatma için herhangi bir destek kaydetmediğimizden henüz Cast cihazında video oynatamazsınız. Yayını durdurmak için Yayınla düğmesini tıklayın.

6. Video içeriği yayınlama

Belirli bir videoyla ilgili ayrıntıları gösteren CastVideos uygulamasını çalıştıran bir iPhone ("Tears of Çelik") görseli. Altta mini oynatıcı bulunur

Örnek uygulamanın kapsamını, Cast cihazında uzaktan video oynatacak şekilde genişleteceğiz. Bunu yapmak için Cast çerçevesi tarafından oluşturulan çeşitli etkinlikleri dinlememiz gerekiyor.

Medya yayınlanıyor

Genel olarak, bir yayın cihazında medya oynatmak istiyorsanız aşağıdakilerin olması gerekir:

  1. Cast SDK'sından, medya öğesini modelleyen bir GCKMediaInformation nesnesi oluşturun.
  2. Kullanıcı, alıcı uygulamanızı başlatmak için yayın cihazına bağlanır.
  3. GCKMediaInformation nesnesini alıcınıza yükleyin ve içeriği oynatın.
  4. Medya durumunu izleyin.
  5. Kullanıcı etkileşimlerine göre alıcıya oynatma komutları gönderin.

1. adım, bir nesnenin diğeriyle eşlenmesini ifade eder; GCKMediaInformation, Cast SDK'sının anladığı bir şeydir ve MediaItem, uygulamamızın bir medya öğesi için sarmalayıcısıdır; MediaItem'yi GCKMediaInformation ile kolayca eşleyebiliriz. Önceki bölümde yer alan 2. Adım'ı uyguladık. 3. adımı Cast SDK'sı ile kolayca tamamlayabilirsiniz.

Örnek uygulama MediaViewController zaten şu sıralamayı kullanarak yerel oynatma ile uzaktan oynatma arasında ayrım yapıyor:

enum PlaybackMode: Int {
  case none = 0
  case local
  case remote
}

private var playbackMode = PlaybackMode.none

Bu codelab'de, tüm örnek oynatıcı mantığının tam olarak nasıl çalıştığını anlamanız önemli değildir. İki oynatma konumunu benzer şekilde tanımak için uygulamanızın medya oynatıcısının değiştirilmesi gerektiğini anlamanız önemlidir.

Şu anda yerel oynatıcı, Yayınlama durumu hakkında henüz hiçbir şey bilmediğinden her zaman yerel oynatma durumundadır. Kullanıcı arayüzünü, Cast çerçevesinde gerçekleşen durum geçişlerine dayalı olarak güncellememiz gerekir. Örneğin, yayınlamaya başlarsak yerel oynatmayı durdurmamız ve bazı kontrolleri devre dışı bırakmamız gerekir. Benzer şekilde, bu görüntüleme denetleyicisindeyken yayını durdurursak yerel oynatmaya geçmemiz gerekir. Bunun için Cast çerçevesi tarafından oluşturulan çeşitli etkinlikleri dinlememiz gerekir.

Yayın oturumu yönetimi

Cast çerçevesi için bir Cast oturumu; cihaza bağlanma, cihazı başlatma (veya katılma), alıcı uygulamaya bağlanma ve uygun durumlarda medya kontrol kanalını başlatma adımlarını birleştirir. Medya kontrol kanalı, Cast çerçevesinin alıcı medya oynatıcıdan mesaj gönderip alma şeklidir.

Kullanıcı Yayınla düğmesinden bir cihaz seçtiğinde Yayınlama oturumu otomatik olarak başlatılır ve kullanıcı bağlantıyı kestikten sonra otomatik olarak durdurulur. Ağ sorunları nedeniyle alıcı oturumuna yeniden bağlanma işlemi de Cast çerçevesi tarafından otomatik olarak gerçekleştirilir.

Yayın oturumları, GCKCastContext.sharedInstance().sessionManager üzerinden erişilebilen GCKSessionManager tarafından yönetilir. GCKSessionManagerListener geri çağırmaları; oluşturma, askıya alma, devam ettirme ve sonlandırma gibi oturum etkinliklerini izlemek için kullanılabilir.

Öncelikle oturum işleyicimizi kaydetmemiz ve bazı değişkenleri başlatmamız gerekir:

class MediaViewController: UIViewController, GCKSessionManagerListener,
  GCKRemoteMediaClientListener, LocalPlayerViewDelegate, GCKRequestDelegate {

  ...
  private var sessionManager: GCKSessionManager!
  ...

  required init?(coder: NSCoder) {
    super.init(coder: coder)

    sessionManager = GCKCastContext.sharedInstance().sessionManager

    ...
  }

  override func viewWillAppear(_ animated: Bool) {
    ...

    let hasConnectedSession: Bool = (sessionManager.hasConnectedSession())
    if hasConnectedSession, (playbackMode != .remote) {
      populateMediaInfo(false, playPosition: 0)
      switchToRemotePlayback()
    } else if sessionManager.currentSession == nil, (playbackMode != .local) {
      switchToLocalPlayback()
    }

    sessionManager.add(self)

    ...
  }

  override func viewWillDisappear(_ animated: Bool) {
    ...

    sessionManager.remove(self)
    sessionManager.currentCastSession?.remoteMediaClient?.remove(self)
    ...
    super.viewWillDisappear(animated)
  }

  func switchToLocalPlayback() {
    ...

    sessionManager.currentCastSession?.remoteMediaClient?.remove(self)

    ...
  }

  func switchToRemotePlayback() {
    ...

    sessionManager.currentCastSession?.remoteMediaClient?.add(self)

    ...
  }


  // MARK: - GCKSessionManagerListener

  func sessionManager(_: GCKSessionManager, didStart session: GCKSession) {
    print("MediaViewController: sessionManager didStartSession \(session)")
    setQueueButtonVisible(true)
    switchToRemotePlayback()
  }

  func sessionManager(_: GCKSessionManager, didResumeSession session: GCKSession) {
    print("MediaViewController: sessionManager didResumeSession \(session)")
    setQueueButtonVisible(true)
    switchToRemotePlayback()
  }

  func sessionManager(_: GCKSessionManager, didEnd _: GCKSession, withError error: Error?) {
    print("session ended with error: \(String(describing: error))")
    let message = "The Casting session has ended.\n\(String(describing: error))"
    if let window = appDelegate?.window {
      Toast.displayMessage(message, for: 3, in: window)
    }
    setQueueButtonVisible(false)
    switchToLocalPlayback()
  }

  func sessionManager(_: GCKSessionManager, didFailToStartSessionWithError error: Error?) {
    if let error = error {
      showAlert(withTitle: "Failed to start a session", message: error.localizedDescription)
    }
    setQueueButtonVisible(false)
  }

  func sessionManager(_: GCKSessionManager,
                      didFailToResumeSession _: GCKSession, withError _: Error?) {
    if let window = UIApplication.shared.delegate?.window {
      Toast.displayMessage("The Casting session could not be resumed.",
                           for: 3, in: window)
    }
    setQueueButtonVisible(false)
    switchToLocalPlayback()
  }

  ...
}

MediaViewController içinde, yayın cihazımıza bağlanıldığında veya cihaz bağlantısı kesildiğinde yerel oynatıcıya geçip geçmediğini bildirmek istiyoruz. Bağlantının yalnızca uygulamanızın mobil cihazınızda çalışmasından kaynaklanabileceğini, aynı zamanda uygulamanızın (veya başka bir uygulamanın farklı bir mobil cihazda) çalışmasından kaynaklanabileceğini de unutmayın.

Şu anda etkin olan oturuma GCKCastContext.sharedInstance().sessionManager.currentCastSession hesabıyla erişilebilir. Oturumlar, Cast iletişim kutularındaki kullanıcı hareketlerine göre otomatik olarak oluşturulur ve bölünür.

Medya yükleniyor

Cast SDK'sında GCKRemoteMediaClient, alıcıdaki uzaktan medya oynatmayı yönetmek için kullanışlı bir dizi API sağlar. Medya oynatmayı destekleyen bir GCKCastSession için SDK tarafından otomatik olarak bir GCKRemoteMediaClient örneği oluşturulur. GCKCastSession örneğinin remoteMediaClient özelliği olarak erişilebilir.

Şu anda seçili videoyu alıcıya yüklemek için MediaViewController.swift alanına aşağıdaki kodu ekleyin:

@objc(MediaViewController)
class MediaViewController: UIViewController, GCKSessionManagerListener,
  GCKRemoteMediaClientListener, LocalPlayerViewDelegate, GCKRequestDelegate {
  ...

  @objc func playSelectedItemRemotely() {
    loadSelectedItem(byAppending: false)
  }

  /**
   * Loads the currently selected item in the current cast media session.
   * @param appending If YES, the item is appended to the current queue if there
   * is one. If NO, or if
   * there is no queue, a new queue containing only the selected item is created.
   */
  func loadSelectedItem(byAppending appending: Bool) {
    print("enqueue item \(String(describing: mediaInfo))")
    if let remoteMediaClient = sessionManager.currentCastSession?.remoteMediaClient {
      let mediaQueueItemBuilder = GCKMediaQueueItemBuilder()
      mediaQueueItemBuilder.mediaInformation = mediaInfo
      mediaQueueItemBuilder.autoplay = true
      mediaQueueItemBuilder.preloadTime = TimeInterval(UserDefaults.standard.integer(forKey: kPrefPreloadTime))
      let mediaQueueItem = mediaQueueItemBuilder.build()
      if appending {
        let request = remoteMediaClient.queueInsert(mediaQueueItem, beforeItemWithID: kGCKMediaQueueInvalidItemID)
        request.delegate = self
      } else {
        let queueDataBuilder = GCKMediaQueueDataBuilder(queueType: .generic)
        queueDataBuilder.items = [mediaQueueItem]
        queueDataBuilder.repeatMode = remoteMediaClient.mediaStatus?.queueRepeatMode ?? .off

        let mediaLoadRequestDataBuilder = GCKMediaLoadRequestDataBuilder()
        mediaLoadRequestDataBuilder.mediaInformation = mediaInfo
        mediaLoadRequestDataBuilder.queueData = queueDataBuilder.build()

        let request = remoteMediaClient.loadMedia(with: mediaLoadRequestDataBuilder.build())
        request.delegate = self
      }
    }
  }
  ...
}

Şimdi, uzaktan oynatmayı desteklemek üzere mevcut çeşitli yöntemleri Yayınlama Oturumu mantığını kullanacak şekilde güncelleyin:

required init?(coder: NSCoder) {
  super.init(coder: coder)
  ...
  castMediaController = GCKUIMediaController()
  ...
}

func switchToLocalPlayback() {
  print("switchToLocalPlayback")
  if playbackMode == .local {
    return
  }
  setQueueButtonVisible(false)
  var playPosition: TimeInterval = 0
  var paused: Bool = false
  var ended: Bool = false
  if playbackMode == .remote {
    playPosition = castMediaController.lastKnownStreamPosition
    paused = (castMediaController.lastKnownPlayerState == .paused)
    ended = (castMediaController.lastKnownPlayerState == .idle)
    print("last player state: \(castMediaController.lastKnownPlayerState), ended: \(ended)")
  }
  populateMediaInfo((!paused && !ended), playPosition: playPosition)
  sessionManager.currentCastSession?.remoteMediaClient?.remove(self)
  playbackMode = .local
}

func switchToRemotePlayback() {
  print("switchToRemotePlayback; mediaInfo is \(String(describing: mediaInfo))")
  if playbackMode == .remote {
    return
  }
  // If we were playing locally, load the local media on the remote player
  if playbackMode == .local, (_localPlayerView.playerState != .stopped), (mediaInfo != nil) {
    print("loading media: \(String(describing: mediaInfo))")
    let paused: Bool = (_localPlayerView.playerState == .paused)
    let mediaQueueItemBuilder = GCKMediaQueueItemBuilder()
    mediaQueueItemBuilder.mediaInformation = mediaInfo
    mediaQueueItemBuilder.autoplay = !paused
    mediaQueueItemBuilder.preloadTime = TimeInterval(UserDefaults.standard.integer(forKey: kPrefPreloadTime))
    mediaQueueItemBuilder.startTime = _localPlayerView.streamPosition ?? 0
    let mediaQueueItem = mediaQueueItemBuilder.build()

    let queueDataBuilder = GCKMediaQueueDataBuilder(queueType: .generic)
    queueDataBuilder.items = [mediaQueueItem]
    queueDataBuilder.repeatMode = .off

    let mediaLoadRequestDataBuilder = GCKMediaLoadRequestDataBuilder()
    mediaLoadRequestDataBuilder.queueData = queueDataBuilder.build()

    let request = sessionManager.currentCastSession?.remoteMediaClient?.loadMedia(with: mediaLoadRequestDataBuilder.build())
    request?.delegate = self
  }
  _localPlayerView.stop()
  _localPlayerView.showSplashScreen()
  setQueueButtonVisible(true)
  sessionManager.currentCastSession?.remoteMediaClient?.add(self)
  playbackMode = .remote
}

/* Play has been pressed in the LocalPlayerView. */
func continueAfterPlayButtonClicked() -> Bool {
  let hasConnectedCastSession = sessionManager.hasConnectedCastSession
  if mediaInfo != nil, hasConnectedCastSession() {
    // Display an alert box to allow the user to add to queue or play
    // immediately.
    if actionSheet == nil {
      actionSheet = ActionSheet(title: "Play Item", message: "Select an action", cancelButtonText: "Cancel")
      actionSheet?.addAction(withTitle: "Play Now", target: self,
                             selector: #selector(playSelectedItemRemotely))
    }
    actionSheet?.present(in: self, sourceView: _localPlayerView)
    return false
  }
  return true
}

Şimdi uygulamayı mobil cihazınızda çalıştırın. Yayın cihazınıza bağlanıp video oynatmaya başlayın. Videonun alıcıda oynatıldığını göreceksiniz.

7. Mini kumanda

Yayın Tasarımı Kontrol Listesi, kullanıcı geçerli içerik sayfasından ayrıldığında tüm Cast uygulamalarının mini kumanda tarafından görünmesini gerektirir. Mini kumanda, anında erişim ve mevcut yayın oturumu için görünür bir hatırlatıcı sağlar.

Mini kumandaya odaklanan CastVideos uygulamasını çalıştıran iPhone'un alt kısmının resmi

Cast SDK'sı, kalıcı denetimleri göstermek istediğiniz sahnelere eklenebilecek bir kontrol çubuğu (GCKUIMiniMediaControlsViewController) sağlar.

Örnek uygulamada, başka bir görünüm denetleyicisini sarmalayan ve alt tarafa bir GCKUIMiniMediaControlsViewController ekleyen GCKUICastContainerViewController öğesini kullanacağız.

AppDelegate.swift dosyasını değiştirin ve aşağıdaki yöntemi kullanarak if useCastContainerViewController koşulu için aşağıdaki kodu ekleyin:

func application(_: UIApplication,
                 didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
  ...
  let appStoryboard = UIStoryboard(name: "Main", bundle: nil)
  guard let navigationController = appStoryboard.instantiateViewController(withIdentifier: "MainNavigation")
    as? UINavigationController else { return false }
  let castContainerVC = GCKCastContext.sharedInstance().createCastContainerController(for: navigationController)
    as GCKUICastContainerViewController
  castContainerVC.miniMediaControlsItemEnabled = true
  window = UIWindow(frame: UIScreen.main.bounds)
  window?.rootViewController = castContainerVC
  window?.makeKeyAndVisible()
  ...
}

Mini kumandanın görünürlüğünü kontrol etmek için bu özelliği ve setter/getter'ı ekleyin (bunları sonraki bir bölümde kullanacağız):

var isCastControlBarsEnabled: Bool {
    get {
      if useCastContainerViewController {
        let castContainerVC = (window?.rootViewController as? GCKUICastContainerViewController)
        return castContainerVC!.miniMediaControlsItemEnabled
      } else {
        let rootContainerVC = (window?.rootViewController as? RootContainerViewController)
        return rootContainerVC!.miniMediaControlsViewEnabled
      }
    }
    set(notificationsEnabled) {
      if useCastContainerViewController {
        var castContainerVC: GCKUICastContainerViewController?
        castContainerVC = (window?.rootViewController as? GCKUICastContainerViewController)
        castContainerVC?.miniMediaControlsItemEnabled = notificationsEnabled
      } else {
        var rootContainerVC: RootContainerViewController?
        rootContainerVC = (window?.rootViewController as? RootContainerViewController)
        rootContainerVC?.miniMediaControlsViewEnabled = notificationsEnabled
      }
    }
  }

Uygulamayı çalıştırıp video yayınlayın. Alıcıda oynatma başladığında her sahnenin altında mini kumandayı görürsünüz. Mini kumandayı kullanarak uzaktan oynatmayı kontrol edebilirsiniz. Göz atma etkinliği ile yerel oynatıcı etkinliği arasında geçiş yaparsanız mini kumanda durumu, alıcının medya oynatma durumuyla senkronize olmalıdır.

8. Tanıtım yer paylaşımı

Google Cast tasarım yapılacaklar listesi, bir gönderen uygulamasının mevcut kullanıcılara yayın düğmesini tanıtmasını gerektirir. Bu şekilde kullanıcılar, söz konusu uygulamanın artık yayınlama özelliğini desteklediğini ve Google Cast'i yeni kullanmaya başlayanlara yardımcı olduğunu bildirir.

Yayın düğmesi yer paylaşımına sahip CastVideos uygulamasını çalıştıran, Yayınla düğmesinin vurgulandığı ve "TV'nize ve Hoparlörlerinize medya yayınlamak için dokunun" mesajının gösterildiği bir iPhone'un resmi

GCKCastContext sınıfında, kullanıcılara ilk kez gösterildiğinde Yayınla düğmesini vurgulamak için kullanılabilecek bir (presentCastInstructionsViewControllerOnce) yöntemi vardır. Şu kodu MediaViewController.swift ve MediaTableViewController.swift için ekleyin:

override func viewDidLoad() {
  ...

  NotificationCenter.default.addObserver(self, selector: #selector(castDeviceDidChange),
                                         name: NSNotification.Name.gckCastStateDidChange,
                                         object: GCKCastContext.sharedInstance())
}

@objc func castDeviceDidChange(_: Notification) {
  if GCKCastContext.sharedInstance().castState != .noDevicesAvailable {
    // You can present the instructions on how to use Google Cast on
    // the first time the user uses you app
    GCKCastContext.sharedInstance().presentCastInstructionsViewControllerOnce(with: castButton)
  }
}

Uygulamayı mobil cihazınızda çalıştırdığınızda tanıtım yer paylaşımını göreceksiniz.

9. Genişletilmiş denetleyici

Google Cast tasarım kontrol listesi, bir gönderen uygulamasının yayınlanan medya için genişletilmiş denetleyici sağlamasını gerektirir. Genişletilmiş kumanda, mini kumandanın tam ekran sürümüdür.

Alt tarafta genişletilmiş kumanda görünen bir video oynatan CastVideos uygulamasını çalıştıran bir iPhone'un resmi

Genişletilmiş kumanda, uzaktan medya oynatmanın tam kontrolünü sunan tam ekran görünümüdür. Bu görünüm, yayın uygulamasının alıcı ses seviyesi kontrolü ve oturum yaşam döngüsü (bağlama/yayını durdurma) hariç her bir yayın oturumunun yönetilebilir tüm unsurlarını yönetmesine izin vermelidir. Ayrıca, medya oturumuyla ilgili tüm durum bilgilerini de (poster, başlık, alt başlık vb.) sağlar.

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

Yapmanız gereken ilk şey, yayın bağlamında varsayılan genişletilmiş denetleyiciyi etkinleştirmektir. Varsayılan genişletilmiş denetleyiciyi etkinleştirmek için AppDelegate.swift öğesini değiştirin:

import GoogleCast

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
  ...

  func application(_: UIApplication,
                   didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    ...
    // Add after the setShareInstanceWith(options) is set.
    GCKCastContext.sharedInstance().useDefaultExpandedMediaControls = true
    ...
  }
  ...
}

Kullanıcı video yayınlamaya başladığında genişletilmiş denetleyiciyi yüklemek için MediaViewController.swift için aşağıdaki kodu ekleyin:

@objc func playSelectedItemRemotely() {
  ...
  appDelegate?.isCastControlBarsEnabled = false
  GCKCastContext.sharedInstance().presentDefaultExpandedMediaControls()
}

Genişletilmiş kumanda da kullanıcı mini kumandaya dokunduğunda otomatik olarak başlatılır.

Uygulamayı çalıştırıp video yayınlayın. Genişletilmiş denetleyici göreceksiniz. Video listesine geri dönün. Mini kumandayı tıkladığınızda genişletilmiş kumanda tekrar yüklenir.

10. Cast Connect desteği ekleyin

Cast Connect kitaplığı, mevcut gönderen uygulamalarının Cast protokolü üzerinden Android TV uygulamalarıyla iletişim kurmasına olanak tanır. Cast Connect, Android TV uygulamanızın alıcı görevi gördüğü Cast altyapısını temel alır.

Bağımlılıklar

Podfile cihazınızda google-cast-sdk öğesinin, aşağıda belirtildiği gibi 4.4.8 veya daha üst bir düzeyi işaret ettiğinden emin olun. Dosyada değişiklik yaptıysanız bu değişikliği projenizle senkronize etmek için konsoldan pod update komutunu çalıştırın.

pod 'google-cast-sdk', '>=4.4.8'

GCKLaunchOptions

Android Alıcı olarak da bilinen Android TV uygulamasını başlatmak için GCKLaunchOptions nesnesinde androidReceiverCompatible işaretini doğru değerine ayarlamamız gerekir. Bu GCKLaunchOptions nesnesi, alıcının nasıl başlatılacağını ve GCKCastContext.setSharedInstanceWith kullanılarak paylaşılan örnekte ayarlanan GCKCastOptions öğesine iletileceğini belirtir.

Aşağıdaki satırları AppDelegate.swift sayfanıza ekleyin:

let options = GCKCastOptions(discoveryCriteria:
                          GCKDiscoveryCriteria(applicationID: kReceiverAppID))
...
/** Following code enables CastConnect */
let launchOptions = GCKLaunchOptions()
launchOptions.androidReceiverCompatible = true
options.launchOptions = launchOptions

GCKCastContext.setSharedInstanceWith(options)

Başlatma Kimlik Bilgilerini Ayarlayın

Gönderen tarafında, oturuma kimlerin katılabileceğini belirtmek için GCKCredentialsData belirtebilirsiniz. credentials, ATV uygulamanız anabildiği sürece kullanıcı tarafından tanımlanabilecek bir dizedir. GCKCredentialsData, Android TV uygulamanıza yalnızca başlatma veya katılma sırasında aktarılır. İnternete bağlıyken tekrar ayarlarsanız Android TV uygulamanıza aktarılmaz.

Başlatma Kimlik Bilgilerini ayarlamak için GCKLaunchOptions ayarlandıktan sonra GCKCredentialsData her zaman tanımlanmalıdır. Bunu göstermek amacıyla, oturum oluşturulduğunda iletilecek kimlik bilgilerini ayarlamak için Creds düğmesine bir mantık ekleyelim. MediaTableViewController.swift cihazınıza aşağıdaki kodu ekleyin:

class MediaTableViewController: UITableViewController, GCKSessionManagerListener, MediaListModelDelegate, GCKRequestDelegate {
  ...
  private var credentials: String? = nil
  ...
  override func viewDidLoad() {
    ...
    navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Creds", style: .plain,
                                                       target: self, action: #selector(toggleLaunchCreds))
    ...
    setLaunchCreds()
  }
  ...
  @objc func toggleLaunchCreds(_: Any){
    if (credentials == nil) {
        credentials = "{\"userId\":\"id123\"}"
    } else {
        credentials = nil
    }
    Toast.displayMessage("Launch Credentials: "+(credentials ?? "Null"), for: 3, in: appDelegate?.window)
    print("Credentials set: "+(credentials ?? "Null"))
    setLaunchCreds()
  }
  ...
  func setLaunchCreds() {
    GCKCastContext.sharedInstance()
        .setLaunch(GCKCredentialsData(credentials: credentials))
  }
}

Yükleme İsteğinde Kimlik Bilgilerini Ayarlama

credentials öğesini hem Web hem de Android TV Alıcı uygulamalarınızda işlemek için aşağıdaki kodu MediaTableViewController.swift sınıfınızda loadSelectedItem işlevinin altına ekleyin:

let mediaLoadRequestDataBuilder = GCKMediaLoadRequestDataBuilder()
...
mediaLoadRequestDataBuilder.credentials = credentials
...

Göndereninizin yayın yaptığı alıcı uygulamaya bağlı olarak SDK, yukarıdaki kimlik bilgilerini devam eden oturuma otomatik olarak uygular.

Cast Connect'i test etme

Android TV APK'sını Google TV Yüklü Chromecast'e yükleme adımları

  1. Android TV cihazınızın IP adresini bulun. Bu işlev genellikle Ayarlar > Ağ ve İnternet > (Cihazınızın bağlı olduğu ağ adı). Sağ tarafta ayrıntılar ve cihazınızın ağdaki IP'si gösterilir.
  2. Cihazınıza ADB üzerinden bağlanmak için terminali kullanarak cihazınızın IP adresini kullanın:
$ adb connect <device_ip_address>:5555
  1. Terminal pencerenizden, bu codelab'in başında indirdiğiniz codelab örneklerinin bulunduğu üst düzey klasöre gidin. Örneğin:
$ cd Desktop/ios_codelab_src
  1. Aşağıdaki komutu çalıştırarak bu klasördeki .apk dosyasını Android TV'nize yükleyin:
$ adb -s <device_ip_address>:5555 install android-tv-app.apk
  1. Artık Android TV cihazınızdaki Uygulamalarınız menüsünde Video Yayınla adlı uygulamayı görebilirsiniz.
  2. İşiniz bittiğinde uygulamayı bir emülatörde veya mobil cihazda derleyip çalıştırın. Android TV cihazınızla bir yayın oturumu oluşturduğunuzda, cihazınız artık Android TV'nizde Android Alıcı uygulamasını başlatır. iOS mobil göndereninizden bir video oynatıldığında, video Android Alıcı'da başlatılır ve Android TV cihazınızın uzaktan kumandasını kullanarak oynatmayı kontrol etmenize olanak tanır.

11. Yayınlama widget'larını özelleştirin

Başlatma

Uygulama Bitti klasörüyle başlayın. Aşağıdakileri AppDelegate.swift dosyanızdaki applicationDidFinishLaunchingWithOptions yöntemine ekleyin.

func application(_: UIApplication,
                 didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
  ...
  let styler = GCKUIStyle.sharedInstance()
  ...
}

Bu codelab'in geri kalanında belirtildiği gibi bir veya daha fazla özelleştirmeyi uygulamayı tamamladıktan sonra aşağıdaki kodu çağırarak stilleri uygulayın

styler.apply()

Cast görünümlerini özelleştirme

Cast Uygulama Çerçevesi'nin yönettiği tüm görünümleri, görünümler için varsayılan stil kurallarına sahip olacak şekilde özelleştirebilirsiniz. Örneğin, simge tonu rengini değiştirelim.

styler.castViews.iconTintColor = .lightGray

Gerekirse varsayılanları her ekran için ayrı ayrı geçersiz kılabilirsiniz. Örneğin, yalnızca genişletilmiş medya denetleyicisinde simge tonu rengi için açıkGrayColor'ı geçersiz kılabilirsiniz.

styler.castViews.mediaControl.expandedController.iconTintColor = .green

Renkleri değiştirme

Arka plan rengini tüm görünümler için (veya her görünüm için ayrı ayrı) özelleştirebilirsiniz. Aşağıdaki kod, Cast Uygulaması Çerçevesi'nin sağladığı tüm görünümleriniz için arka plan rengini maviye ayarlar.

styler.castViews.backgroundColor = .blue
styler.castViews.mediaControl.miniController.backgroundColor = .yellow

Yazı tiplerini değiştirme

Yayın görünümlerinde görülen farklı etiketler için yazı tiplerini özelleştirebilirsiniz. Tüm yazı tiplerini ‘Courier-Oblique’ yalnızca örnek olarak verilmiştir.

styler.castViews.headingTextFont = UIFont.init(name: "Courier-Oblique", size: 16) ?? UIFont.systemFont(ofSize: 16)
styler.castViews.mediaControl.headingTextFont = UIFont.init(name: "Courier-Oblique", size: 6) ?? UIFont.systemFont(ofSize: 6)

Varsayılan düğme resimlerini değiştirme

Projeye kendi özel resimlerinizi ekleyin ve stil vermek için düğmelerinize resimler atayın.

let muteOnImage = UIImage.init(named: "yourImage.png")
if let muteOnImage = muteOnImage {
  styler.castViews.muteOnImage = muteOnImage
}

Yayınla düğmesi temasını değiştirme

Cast Widget'larını UIViewance Protocol kullanarak da oluşturabilirsiniz. Aşağıdaki kod, GCKUICastButton'ın göründüğü tüm görünümlerde temaları:

GCKUICastButton.appearance().tintColor = UIColor.gray

12. Tebrikler

Artık iOS'te Cast SDK widget'larını kullanarak bir video uygulamasını nasıl yayınlayabileceğinizi biliyorsunuz.

Daha ayrıntılı bilgi için iOS Sender geliştirici kılavuzuna göz atın.