Bir iOS uygulamasını Cast ile etkinleştirin

googlecastnew500.png

Bu kod laboratuvarı, bir Google Cast cihazında içerik oynatmak için mevcut bir iOS video uygulamasının nasıl değiştirileceğini size öğretecektir.

Google Cast nedir?

Google Cast, kullanıcıların bir mobil cihazdan TV'ye içerik yayınlamasına olanak tanır. Kullanıcılar daha sonra mobil cihazlarını TV'de medya oynatmak için uzaktan kumanda olarak kullanabilirler.

Google Cast SDK, uygulamanızı Google Cast özellikli cihazları (ör. Bir TV veya ses sistemi) kontrol edecek şekilde genişletmenize olanak tanır. Cast SDK, Google Cast Tasarım Kontrol Listesi'ne göre gerekli UI bileşenlerini eklemenize olanak tanır.

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

Ne inşa edeceğiz?

Bu kod laboratuvarını tamamladığınızda, videoları bir Google Cast cihazına yayınlayabilecek bir iOS video uygulamasına sahip olacaksınız.

Ne öğreneceksin

  • Google Cast SDK'sı örnek bir video uygulamasına nasıl eklenir?
  • Google Cast cihazı seçmek için Yayın düğmesi nasıl eklenir?
  • Bir Cast cihazına bağlanma ve bir medya alıcısı başlatma.
  • Bir video nasıl yayınlanır.
  • Uygulamanıza Cast mini kumanda nasıl eklenir?
  • Genişletilmiş bir denetleyici nasıl eklenir?
  • Giriş katmanı nasıl sağlanır.
  • Cast widget'ları nasıl özelleştirilir.
  • Cast Connect nasıl entegre edilir

Neye ihtiyacın olacak

  • En son Xcode .
  • İOS 9 veya sonraki bir sürümüne (veya Xcode Simulator) sahip bir mobil cihaz.
  • Mobil cihazınızı geliştirme bilgisayarınıza bağlamak için bir USB veri kablosu (bir cihaz kullanıyorsanız).
  • İnternet erişimi ile yapılandırılmış bir Chromecast veya Android TV gibi bir Google Cast cihazı.
  • HDMI girişli bir TV veya monitör.
  • Cast Connect entegrasyonunu test etmek için Google TV'li bir Chromecast gerekir, ancak Codelab'in geri kalanı için isteğe bağlıdır. Bir hesabınız yoksa, bu eğiticinin sonuna doğru Cast Connect Desteği Ekle adımını atlamaktan çekinmeyin.

Deneyim

  • Daha önce iOS geliştirme bilgisine sahip olmanız gerekecek.
  • Ayrıca önceden TV izleme bilgisine de ihtiyacınız olacak :)

Bu öğreticiyi nasıl kullanacaksınız?

Sadece baştan sona okuyun Okuyun ve alıştırmaları tamamlayın

İOS uygulamaları oluşturma deneyiminizi nasıl değerlendirirsiniz?

Acemi Orta düzey Yetkin

TV izleme deneyiminizi nasıl değerlendirirsiniz?

Acemi Orta düzey Yetkin

Ya tüm örnek kodu bilgisayarınıza indirebilirsiniz ...

Kaynak Kodunu İndir

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

1024px-Apple_iOS_new.svg.png

İlk olarak, tamamlanmış örnek uygulamanın neye benzediğini görelim. Uygulama temel bir video oynatıcıdır. Kullanıcı, listeden bir video seçebilir ve ardından videoyu cihazda yerel olarak oynatabilir veya bir Google Cast cihazında yayınlayabilir.

Kod indirildiğinde, aşağıdaki talimatlar tamamlanmış örnek uygulamanın Xcode'da nasıl açılacağını ve çalıştırılacağını açıklar:

Sıkça Sorulan Sorular

CocoaPods kurulumu

CocoaPod'ları kurmak için konsolunuza gidin ve macOS'ta bulunan varsayılan Ruby'yi kullanarak yükleyin:

sudo gem install cocoapods

Herhangi bir sorununuz varsa, bağımlılık yöneticisini indirmek ve yüklemek için resmi belgelere bakın.

Proje kurulumu

  1. Terminalinize gidin ve codelab dizinine gidin.
  2. Bağımlılıkları Podfile'dan yükleyin.
cd app-done
pod update
pod install
  1. Xcode'u açın ve Başka bir proje aç ... öğesini seçin .
  2. CastVideos-ios.xcworkspace dosyasını seçin. android_studio_folder.png örnek kod klasöründeki app-done dizini.

Uygulamayı çalıştırın

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

6057e56212298a69.png

Birkaç saniye sonra video uygulamasının göründüğünü görmelisiniz.

Gelen ağ bağlantılarının kabul edilmesiyle ilgili bildirim göründüğünde 'İzin Ver'i tıkladığınızdan emin olun. Bu seçenek kabul edilmezse Yayınla simgesi görünmeyecektir.

1a8fc65fae034d9c.png

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

Bir video seçin, oynat düğmesine tıklayın.

Video, Google Cast cihazınızda oynamaya başlayacak.

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

Video listesine geri dönün.

Ekranın altında artık bir mini denetleyici görülebilir.

7a17f847cf25e595.png

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

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

6af3d3be9ca4b71a.png

İndirdiğiniz başlangıç ​​uygulamasına Google Cast desteği eklememiz gerekiyor. Bu kod laboratuvarında kullanacağımız bazı Google Cast terminolojileri şunlardır:

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

Proje kurulumu

Artık Xcode kullanarak başlangıç ​​projesinin üzerine inşa etmeye hazırsınız:

  1. Terminalinize gidin ve codelab dizinine gidin.
  2. Bağımlılıkları Podfile'dan yükleyin.
cd app-start
pod update
pod install
  1. Xcode'u açın ve Başka bir proje aç ... öğesini seçin .
  2. CastVideos-ios.xcworkspace dosyasını seçin. android_studio_folder.png örnek kod klasöründeki app-start dizini.

Uygulama tasarımı

Uygulama, uzak bir web sunucusundan bir video listesi getirir ve kullanıcının göz atması için bir liste sağlar. Kullanıcılar, ayrıntıları 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ğinden bir video listesi görüntüler. Videoların listesi ve ilişkili meta verileri, bir JSON dosyası olarak uzak bir sunucuda barındırılır. MediaListModel bu MediaListModel getirir ve MediaItem nesnelerinin bir listesini oluşturmak için MediaItem .

MediaItem nesnesi, bir videoyu ve bunun başlığı, açıklaması, bir görüntünün URL'si ve akışın URL'si gibi ilişkili meta verilerini modeller.

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

Kullanıcıya, her video için kısa bir açıklama içeren bir video küçük resim listesi sunulur. Bir öğe seçildiğinde, ilgili MediaItem MediaViewController aktarılır.

MediaViewController

Bu görünüm denetleyicisi, belirli bir video hakkındaki meta verileri görüntüler ve kullanıcının videoyu mobil cihazda yerel olarak oynatmasına izin verir.

Görünüm denetleyicisi bir LocalPlayerView , bazı medya denetimleri ve seçilen videonun açıklamasını göstermek için bir metin alanı barındırır. Oynatıcı, ekranın üst kısmını kaplayarak, altındaki videonun ayrıntılı açıklaması için yer bırakır. Kullanıcı, yerel video oynatmayı oynatabilir / duraklatabilir veya arayabilir.

Sıkça Sorulan Sorular

2e90b87c5457892f.png

Cast özellikli bir uygulama, görünüm denetleyicilerinin her birinde Yayın düğmesini görüntüler. Yayın düğmesine tıklamak, bir kullanıcının seçebileceği Yayın cihazlarının bir listesini görüntüler. Kullanıcı, gönderen cihazda yerel olarak içerik oynatıyorsa, bir Cast cihazının seçilmesi o Cast cihazında oynatmayı başlatır veya devam ettirir. Bir Cast oturumu sırasında herhangi bir zamanda, kullanıcı Yayınla 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ındayken Cast cihazına bağlanabilmeli veya bağlantısını kesebilmelidir .

Konfigürasyon

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

Başlatma

Cast çerçevesi, çerçevenin tüm etkinliklerini koordine eden genel bir tekil nesne olan GCKCastContext sahiptir. Bu nesne, uygulamanın yaşam döngüsünün başlarında, genellikle uygulama temsilcisinin application(_:didFinishLaunchingWithOptions:) yönteminde başlatılmalıdır, böylece gönderen uygulamanın yeniden başlatılmasında otomatik oturum devam ettirme doğru şekilde tetiklenebilir ve cihazlar için tarama başlayabilir.

Bir GCKCastOptions başlatırken bir amacı temin edilmelidir GCKCastContext . Bu sınıf, çerçevenin davranışını etkileyen seçenekleri içerir. Bunlardan en önemlisi, Cast cihazı keşif sonuçlarını filtrelemek ve bir Cast oturumu başladığında alıcı uygulamasını başlatmak için kullanılan alıcı uygulama kimliğidir.

application(_:didFinishLaunchingWithOptions:) yöntemi de Cast çerçevesinden günlük mesajlarını almak üzere bir günlük kaydı temsilcisi ayarlamak için iyi bir yerdir. Bunlar, hata ayıklama ve sorun giderme için yararlı olabilir.

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

GCKCastContext kullanıcı varsayılanlarından alınan uygulama kimliğiyle başlatmak için AppDelegate.swift aşağıdaki kodu ekleyin ve Google Cast çerçevesi için bir günlük kaydedici 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ın düğmesi

Artık 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 gerekiyor. Cast SDK, UIButton alt sınıfı olarak GCKUICastButton adlı bir Yayın düğmesi bileşeni sağlar. Bir UIBarButtonItem sarılarak uygulamanın başlık çubuğuna UIBarButtonItem . Cast butonunu hem MediaTableViewController hem de MediaViewController MediaTableViewController .

MediaTableViewController.swift ve MediaViewController.swift aşağıdaki kodu 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)

    ...
  }
  ...
}

Ardından, MediaViewController.swift aşağıdaki kodu 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örmelisiniz ve üzerine tıkladığınızda, yerel ağınızdaki Yayın cihazlarını listeleyecektir. Cihaz keşfi, GCKCastContext tarafından otomatik olarak yönetilir. Yayın cihazınızı seçin, örnek alıcı uygulaması Yayın cihazına yüklenecektir. Göz atma etkinliği ile yerel oynatıcı etkinliği arasında gezinebilirsiniz ve Yayın düğmesinin durumu senkronize tutulur.

Medya oynatma için herhangi bir destek sağlamadık, bu nedenle Cast cihazında henüz video oynatamazsınız. Yayını durdurmak için Yayınla düğmesini tıklayın.

c3276a930aa8a022.png

Örnek uygulamayı bir Cast cihazında uzaktan video oynatmak için genişleteceğiz. Bunu yapmak için Cast çerçevesi tarafından oluşturulan çeşitli olayları dinlememiz gerekir.

Medya döküm

Yüksek düzeyde, bir medyayı bir Cast cihazında oynatmak istiyorsanız, aşağıdakilerin gerçekleşmesi gerekir:

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

Adım 1, bir nesneyi diğerine eşlemek anlamına gelir; GCKMediaInformation , Cast SDK'nın anladığı bir şeydir ve MediaItem , uygulamamızın bir medya öğesi için kapsüllemesidir; Bir MediaItem bir MediaItem ile kolayca GCKMediaInformation . Önceki bölümde 2. Adımı zaten yaptık. 3. Adımın, Cast SDK ile yapılması kolaydır.

Örnek uygulama MediaViewController , şu numaralandırmayı kullanarak yerel ve uzaktan oynatma arasında zaten ayrım yapmaktadır:

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

private var playbackMode = PlaybackMode.none

Bu kod laboratuarında, tüm örnek oynatıcı mantığının tam olarak nasıl çalıştığını anlamanız sizin için önemli değildir. Uygulamanızın medya oynatıcısının benzer şekilde iki oynatma konumundan haberdar olması için değiştirilmesi gerekeceğini anlamak önemlidir.

Şu anda yerel oynatıcı her zaman yerel oynatma durumundadır çünkü henüz Casting durumları hakkında hiçbir şey bilmiyor. Kullanıcı arayüzünü, Cast çerçevesinde gerçekleşen durum geçişlerine göre güncellememiz gerekiyor. Örneğin, yayına başlarsak, yerel oynatmayı durdurmalı ve bazı kontrolleri devre dışı bırakmalıyız. Benzer şekilde, bu görünüm denetleyicisindeyken yayını durdurursak, yerel oynatmaya geçmemiz gerekir. Bunu halletmek için Cast çerçevesi tarafından oluşturulan çeşitli olayları dinlememiz gerekir.

Yayın oturumu yönetimi

Cast çerçevesi için bir Cast oturumu, bir cihaza bağlanma, başlatma (veya katılma), bir alıcı uygulamasına bağlanma ve uygunsa bir medya kontrol kanalını başlatma adımlarını birleştirir. Medya kontrol kanalı, Cast çerçevesinin alıcı medya oynatıcısından mesajları nasıl gönderip aldığıdır.

Yayın oturumu, kullanıcı Yayınla düğmesinden bir cihaz seçtiğinde otomatik olarak başlatılacak ve kullanıcı bağlantısı kesildiğinde otomatik olarak durdurulacaktır. Ağ sorunları nedeniyle bir alıcı oturumuna yeniden bağlanma da Cast çerçevesi tarafından otomatik olarak ele alınır.

Yayın oturumları, GCKCastContext.sharedInstance().sessionManager aracılığıyla erişilebilen GCKSessionManager tarafından yönetilir. GCKSessionManagerListener geri aramaları, oluşturma, askıya alma, devam GCKSessionManagerListener ve sonlandırma gibi oturum olaylarını izlemek için kullanılabilir.

Öncelikle oturum dinleyicimizi kaydetmeli ve bazı değişkenleri başlatmalıyız:

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 , yerel oynatıcıya veya yerel oynatıcıdan geçiş yapabilmemiz için Cast cihazına bağlandığımızda veya bağlantımız kesildiğinde bilgilendirilmek istiyoruz. Bağlantının yalnızca uygulamanızın mobil cihazınızda çalışan örneğiyle değil, aynı zamanda farklı bir mobil cihazda çalışan başka bir (veya başka) uygulamanız tarafından da kesilebileceğini unutmayın.

Şu anda aktif olan oturuma GCKCastContext.sharedInstance().sessionManager.currentCastSession olarak erişilebilir. Oturumlar, Yayın iletişim kutularındaki kullanıcı hareketlerine yanıt olarak otomatik olarak oluşturulur ve parçalanır.

Medya yükleme

Cast SDK'da GCKRemoteMediaClient , alıcıda uzaktan medya oynatmayı yönetmek için bir dizi uygun API sağlar. Bir İçin GCKCastSession destekleri medya oynatma olduğunu, bir örneği GCKRemoteMediaClient SDK tarafından otomatik olarak 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 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 için Yayın Oturumu mantığını kullanmak için çeşitli mevcut yöntemleri 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. Cast cihazınıza bağlanın ve bir video oynatmaya başlayın. Alıcıda oynatılan videoyu görmelisiniz.

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

6443b23c35038979.png

Cast SDK, kalıcı kontrolleri göstermek istediğiniz sahnelere eklenebilen GCKUIMiniMediaControlsViewController bir kontrol çubuğu sağlar.

Örnek uygulamamızda için, kullanacağız GCKUICastContainerViewController başka bir görünüm denetleyicisi sarar ve bir ekler GCKUIMiniMediaControlsViewController dibinde.

AppDelegate.swift dosyasını değiştirin ve aşağıdaki yöntemde if useCastContainerViewController koşulu için aşağıdaki kodu ekleyin: Modify the AppDelegate.swift file and add the following code for if useCastContainerViewController condition in the following method:

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 denetleyicinin görünürlüğünü kontrol etmek için bu özelliği ve ayarlayıcı / alıcıyı ekleyin (bunları daha 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ın ve bir video yayınlayın. Alıcıda oynatma başladığında, her sahnenin altında mini denetleyicinin belirdiğini görmelisiniz. Uzaktan oynatmayı mini denetleyiciyi kullanarak kontrol edebilirsiniz. Göz atma etkinliği ve yerel oynatıcı etkinliği arasında gezinirseniz, mini denetleyici durumu alıcı ortam oynatma durumuyla senkronize kalmalıdır.

Google Cast tasarım kontrol listesi, gönderen uygulamanın mevcut kullanıcılara, gönderen uygulamanın artık Yayınlamayı desteklediğini ve ayrıca Google Cast'te yeni olan kullanıcılara yardımcı olduğunu bildirmek için Yayın düğmesini tanıtmasını gerektirir.

4ab027c0c29be56b.png

GCKCastContext sınıfı, kullanıcılara ilk gösterildiğinde Yayın düğmesini vurgulamak için kullanılabilen, presentCastInstructionsViewControllerOnce adlı bir yönteme sahiptir. Aşağıdaki kodu MediaViewController.swift ve MediaTableViewController.swift :

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ırın ve giriş kaplamasını görmelisiniz.

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

7e0128f4b78c0db4.png

Genişletilmiş kontrolör, uzaktan medya oynatımı üzerinde tam kontrol sağlayan tam ekran bir görünümdür. Bu görünüm, bir yayınlama uygulamasının, alıcı ses kontrolü ve oturum yaşam döngüsü (bağlan / yayınlamayı durdur) haricinde, bir yayın oturumunun yönetilebilir her yönünü yönetmesine izin vermelidir. Aynı zamanda medya oturumu hakkındaki tüm durum bilgilerini (sanat eseri, başlık, alt başlık vb.) Sağlar.

Bu görünümün işlevselliği, 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 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ı bir videoyu MediaViewController.swift başladığında genişletilmiş denetleyiciyi yüklemek için aşağıdaki kodu MediaViewController.swift ekleyin:

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

Genişletilmiş denetleyici, kullanıcı mini denetleyiciye dokunduğunda da otomatik olarak başlatılacaktır.

Uygulamayı çalıştırın ve bir video yayınlayın. Genişletilmiş denetleyiciyi görmelisiniz. Video listesine geri dönün ve mini denetleyiciye tıkladığınızda, genişletilmiş denetleyici tekrar yüklenecektir.

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

Bağımlılıklar

Podfile google-cast-sdk Podfile aşağıda listelendiği gibi 4.4.8 veya üstüne işaret ettiğinden emin olun. Dosyada bir değişiklik yaptıysanız, değişikliği projenizle senkronize etmek için konsoldan pod update çalıştırın.

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

GCKLaunchOptions

Android Alıcısı olarak da adlandırılan Android TV uygulamasını başlatmak için, GCKLaunchOptions nesnesinde androidReceiverCompatible bayrağını true olarak ayarlamamız gerekir. Bu GCKLaunchOptions nesnesi, alıcının nasıl başlatıldığını ve GCKCastOptions kullanılarak paylaşılan örnekte ayarlanan GCKCastOptions nasıl geçirildiğini GCKCastContext.setSharedInstanceWith .

AppDelegate.swift aşağıdaki satırları AppDelegate.swift :

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 Ayarlama

Gönderen tarafında, oturuma kimin katıldığını göstermek için GCKCredentialsData belirtebilirsiniz. credentials , ATV uygulamanız anlayabildiği sürece kullanıcı tarafından tanımlanabilen bir dizedir. GCKCredentialsData yalnızca başlatma veya katılma sırasında Android TV uygulamanıza aktarılır. Bağlıyken yeniden ayarlarsanız, Android TV uygulamanıza aktarılmaz.

Ayarlanan Başlatma Kimlik amacıyla GCKCredentialsData sonra her zaman tanımlanması gerekir GCKLaunchOptions ayarlanır. Bunu göstermek için, oturum kurulduğunda geçirilecek kimlik bilgilerini ayarlamak için Krediler düğmesi için bir mantık ekleyelim . MediaTableViewController.swift aşağıdaki kodu MediaTableViewController.swift :

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 Ayarlayın

credentials hem Web hem de Android TV Alıcısı uygulamalarınızda işlemek için, aşağıdaki kodu MediaTableViewController.swift sınıfınıza loadSelectedItem işlevi altında loadSelectedItem :

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

Göndericinizin yayın yaptığı alıcı uygulamasına 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 ile Chromecast'e yükleme adımları

  1. Android TV cihazınızın IP Adresini bulun. Genellikle, Ayarlar> Ağ ve İnternet> (Cihazınızın bağlı olduğu ağ adı) altında bulunur . Sağ tarafta, ayrıntıları ve cihazınızın ağdaki IP'sini gösterecektir.
  2. Terminali kullanarak ADB aracılığıyla cihazınıza bağlanmak için cihazınızın IP adresini kullanın:
$ adb connect <device_ip_address>:5555
  1. Terminal pencerenizden, bu kod laboratuarının başlangıcında indirdiğiniz kod laboratuvarı örnekleri için en üst düzey klasöre gidin. Örneğin:
$ cd Desktop/ios_codelab_src
  1. Bu klasördeki .apk dosyasını aşağıdakileri çalıştırarak Android TV'nize yükleyin:
$ adb -s <device_ip_address>:5555 install android-tv-app.apk
  1. Artık Android TV cihazınızda Uygulamalarınız menüsünde Video Yayınlama adına göre bir uygulamayı görebiliyor olmanız gerekir.
  2. Tamamlandığında, uygulamayı bir emülatörde veya bir mobil cihazda oluşturun ve çalıştırın. Android TV cihazınızla bir yayın oturumu oluştururken, artık Android TV'nizde Android Alıcı uygulamasını başlatması gerekir. İOS mobil göndericinizden bir video oynatmak, videoyu Android Alıcısında başlatmalı ve Android TV cihazınız için uzaktan kumandayı kullanarak oynatmayı kontrol etmenize izin vermelidir.

Başlatma

App-Done 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 kod laboratuarının geri kalanında belirtildiği gibi bir veya daha fazla özelleştirme uygulamayı tamamladığınızda, aşağıdaki kodu çağırarak stilleri tamamlayın

styler.apply()

Yayın görünümlerini özelleştirme

Görünümler arasında varsayılan stil yönergelerine sahip olarak Cast Uygulama Çerçevesinin yönettiği tüm görünümleri özelleştirebilirsiniz. Örnek olarak ikon ton rengini değiştirelim.

styler.castViews.iconTintColor = .lightGray

Gerekirse varsayılanları ekran bazında geçersiz kılabilirsiniz. Örneğin, yalnızca genişletilmiş ortam denetleyicisine yönelik simge renk tonu renginin lightGrayColor değerini geçersiz kılmak.

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

Renkleri değiştirme

Tüm görünümler için (veya her görünüm için ayrı ayrı) arka plan rengini özelleştirebilirsiniz. Aşağıdaki kod, Cast Uygulama Çerçevesi tarafından sağlanan tüm görünümler için arka plan rengini maviye ayarlar.

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

Yazı tiplerini değiştirme

Yazı tiplerini, döküm görünümlerinde görülen farklı etiketler için özelleştirebilirsiniz. Tüm yazı tiplerini gösterim amacıyla 'Courier-Oblique' olarak ayarlayalım.

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 görüntülerini değiştirme

Projeye kendi özel görsellerinizi ekleyin ve onlara stil vermek için görselleri düğmelerinize atayın.

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

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

Ayrıca, UIAppearance Protokolünü kullanarak Cast Widgets temasını da oluşturabilirsiniz. Aşağıdaki kod, GCKUICastButton öğesini göründüğü tüm görünümlerde temalar:

GCKUICastButton.appearance().tintColor = UIColor.gray

Artık iOS'ta Cast SDK widget'larını kullanarak bir video uygulamasını nasıl Cast-etkinleştireceğinizi biliyorsunuz.

GitHub'daki örnek uygulamalarımıza bir göz atın: github.com/googlecast .