เปิดใช้แอป iOS แคสต์

1. ภาพรวม

โลโก้ Google Cast

Codelab นี้จะสอนวิธีแก้ไขแอปวิดีโอ iOS ที่มีอยู่เพื่อแคสต์เนื้อหาไปยังอุปกรณ์ที่พร้อมใช้งาน Google Cast

Google Cast คืออะไร

Google Cast ช่วยให้ผู้ใช้แคสต์เนื้อหาจากอุปกรณ์เคลื่อนที่ไปยังทีวีได้ จากนั้นผู้ใช้จะใช้อุปกรณ์เคลื่อนที่เป็นรีโมตคอนโทรลในการเล่นสื่อบนทีวีได้

Google Cast SDK ช่วยให้คุณขยายแอปเพื่อควบคุมอุปกรณ์ที่พร้อมใช้งาน Google Cast (เช่น TV หรือระบบเสียง) Cast SDK ช่วยให้คุณเพิ่มคอมโพเนนต์ UI ที่จำเป็นได้ตามรายการตรวจสอบการออกแบบของ Google Cast

รายการตรวจสอบการออกแบบของ Google Cast มีไว้เพื่อมอบประสบการณ์ของผู้ใช้ Cast ที่เรียบง่ายและคาดการณ์ได้ในทุกแพลตฟอร์มที่รองรับ

เรากำลังจะสร้างอะไร

เมื่อทำ Codelab นี้เสร็จแล้ว คุณจะมีแอปวิดีโอ iOS ที่จะแคสต์วิดีโอไปยังอุปกรณ์ Google Cast ได้

สิ่งที่คุณจะได้เรียนรู้

  • วิธีเพิ่ม Google Cast SDK ลงในแอปวิดีโอตัวอย่าง
  • วิธีเพิ่มปุ่ม "แคสต์" สำหรับเลือกอุปกรณ์ Google Cast
  • วิธีเชื่อมต่อกับอุปกรณ์แคสต์และเปิดใช้เครื่องรับสื่อ
  • วิธีแคสต์วิดีโอ
  • วิธีเพิ่มตัวควบคุมขนาดเล็กของ Cast ลงในแอป
  • วิธีเพิ่มตัวควบคุมที่ขยาย
  • วิธีการให้โฆษณาซ้อนทับแนะนำ
  • วิธีปรับแต่งวิดเจ็ตแคสต์
  • วิธีผสานรวม Cast Connect

สิ่งที่ต้องมี

  • Xcode ล่าสุด
  • อุปกรณ์เคลื่อนที่ 1 เครื่องที่ใช้ iOS 9 ขึ้นไป (หรือ Xcode Simulator)
  • สายข้อมูล USB เพื่อเชื่อมต่ออุปกรณ์เคลื่อนที่กับคอมพิวเตอร์การพัฒนา (หากใช้อุปกรณ์)
  • อุปกรณ์ Google Cast เช่น Chromecast หรือ Android TV ที่กำหนดค่าด้วยการเข้าถึงอินเทอร์เน็ต
  • ทีวีหรือจอภาพที่มีอินพุต HDMI
  • โดยจะต้องใช้ Chromecast ที่มี Google TV เพื่อทดสอบการผสานรวม Cast Connect แต่ไม่บังคับสำหรับการใช้งาน Codelab ที่เหลือ หากไม่มี ให้ข้ามขั้นตอนเพิ่มการสนับสนุน Cast Connect ที่อยู่ท้ายบทแนะนำนี้

ประสบการณ์การใช้งาน

  • คุณจะต้องมีความรู้ด้านการพัฒนา iOS มาก่อน
  • คุณต้องมีความรู้เรื่องการดูทีวีมาก่อนด้วย :)

คุณจะใช้บทแนะนำนี้อย่างไร

อ่านเท่านั้น อ่านและทำแบบฝึกหัด

คุณจะให้คะแนนประสบการณ์ในการสร้างแอป iOS อย่างไร

ผู้ฝึกหัด ระดับกลาง ผู้ชำนาญ

คุณจะให้คะแนนประสบการณ์ในการดูทีวีอย่างไร

ผู้ฝึกหัด ระดับกลาง ผู้ชำนาญ

2. รับโค้ดตัวอย่าง

คุณสามารถดาวน์โหลดโค้ดตัวอย่างทั้งหมดลงในคอมพิวเตอร์ของคุณ...

และคลายการบีบอัดไฟล์ ZIP ที่ดาวน์โหลด

3. เรียกใช้แอปตัวอย่าง

โลโก้ Apple iOS

ก่อนอื่น เรามาดูกันว่าแอปตัวอย่างที่สมบูรณ์มีลักษณะอย่างไร แอปนี้เป็นโปรแกรมเล่นวิดีโอพื้นฐาน ผู้ใช้สามารถเลือกวิดีโอจากรายการแล้วเล่นวิดีโอในอุปกรณ์หรือแคสต์ไปยังอุปกรณ์ Google Cast

เมื่อดาวน์โหลดโค้ดแล้ว คำแนะนำต่อไปนี้อธิบายวิธีเปิดและเรียกใช้แอปตัวอย่างที่สมบูรณ์ใน Xcode

คำถามที่พบบ่อย

การตั้งค่า CocoaPods

หากต้องการตั้งค่า CocoaPods ให้ไปที่คอนโซลแล้วติดตั้งโดยใช้ Ruby เริ่มต้นที่มีอยู่ใน macOS

sudo gem install cocoapods

หากพบปัญหา โปรดดูเอกสารอย่างเป็นทางการเพื่อดาวน์โหลดและติดตั้งเครื่องมือจัดการทรัพยากร Dependency

ตั้งค่าโครงการ

  1. ไปที่เทอร์มินัลแล้วไปที่ไดเรกทอรี Codelab
  2. ติดตั้งการอ้างอิงจาก Podfile
cd app-done
pod update
pod install
  1. เปิด Xcode และเลือกเปิดโปรเจ็กต์อื่น...
  2. เลือกไฟล์ CastVideos-ios.xcworkspace จากไดเรกทอรี ไอคอนโฟลเดอร์app-done ในโฟลเดอร์โค้ดตัวอย่าง

เรียกใช้แอป

เลือกเป้าหมายและเครื่องจำลอง จากนั้นเรียกใช้แอป

แถบเครื่องมือเครื่องจำลองแอป XCode

คุณควรจะเห็นแอปวิดีโอปรากฏขึ้นหลังจากผ่านไป 2-3 วินาที

อย่าลืมคลิก "อนุญาต" เมื่อการแจ้งเตือนปรากฏขึ้นเพื่อแจ้งว่ายอมรับการเชื่อมต่อเครือข่ายขาเข้า ไอคอน "แคสต์" จะไม่ปรากฏขึ้นหากไม่มีการยอมรับตัวเลือกนี้

กล่องโต้ตอบการยืนยันขอสิทธิ์ในการยอมรับการเชื่อมต่อเครือข่ายขาเข้า

คลิกปุ่ม "แคสต์" และเลือกอุปกรณ์ Google Cast ของคุณ

เลือกวิดีโอ แล้วคลิกปุ่มเล่น

วิดีโอจะเริ่มเล่นบนอุปกรณ์ Google Cast

ตัวควบคุมที่ขยายจะปรากฏขึ้น คุณใช้ปุ่มเล่น/หยุดชั่วคราวเพื่อควบคุมการเล่นได้

กลับไปที่รายการวิดีโอ

ตอนนี้ตัวควบคุมขนาดเล็กจะปรากฏที่ด้านล่างของหน้าจอ

ภาพ iPhone ที่ใช้แอป CastVideos โดยมีตัวควบคุมขนาดเล็กปรากฏที่ด้านล่าง

คลิกปุ่มหยุดชั่วคราวในมินิคอนโทรลเลอร์เพื่อหยุดวิดีโอชั่วคราวบนอุปกรณ์รับสัญญาณ คลิกปุ่มเล่นในตัวควบคุมขนาดเล็กเพื่อเล่นวิดีโอต่ออีกครั้ง

คลิกปุ่ม "แคสต์" เพื่อหยุดแคสต์ไปยังอุปกรณ์ Google Cast

4. เตรียมการเริ่มโปรเจ็กต์

ภาพ iPhone ที่ใช้แอป CastVideos

เราต้องเพิ่มการรองรับ Google Cast ให้กับแอปเริ่มต้นที่คุณดาวน์โหลดมา ต่อไปนี้คือคำศัพท์ของ Google Cast ที่เราจะใช้ใน Codelab

  • แอปของผู้ส่งทำงานบนอุปกรณ์เคลื่อนที่หรือแล็ปท็อป
  • แอปตัวรับจะทำงานในอุปกรณ์ Google Cast

ตั้งค่าโครงการ

ตอนนี้คุณพร้อมที่จะสร้างต่อยอดจากโปรเจ็กต์เริ่มต้นโดยใช้ Xcode แล้ว:

  1. ไปที่เทอร์มินัลแล้วไปที่ไดเรกทอรี Codelab
  2. ติดตั้งการอ้างอิงจาก Podfile
cd app-start
pod update
pod install
  1. เปิด Xcode และเลือกเปิดโปรเจ็กต์อื่น...
  2. เลือกไฟล์ CastVideos-ios.xcworkspace จากไดเรกทอรี ไอคอนโฟลเดอร์app-start ในโฟลเดอร์โค้ดตัวอย่าง

การออกแบบแอป

แอปจะดึงข้อมูลรายการวิดีโอจากเว็บเซิร์ฟเวอร์ระยะไกลและแสดงรายการให้ผู้ใช้เรียกดู ผู้ใช้สามารถเลือกวิดีโอเพื่อดูรายละเอียดหรือเล่นวิดีโอบนอุปกรณ์เคลื่อนที่ก็ได้

แอปประกอบด้วยตัวควบคุมมุมมองหลัก 2 รายการ ได้แก่ MediaTableViewController และ MediaViewController.

MediaTableViewController

UITableViewController นี้แสดงรายการวิดีโอจากอินสแตนซ์ MediaListModel รายการวิดีโอและข้อมูลเมตาที่เกี่ยวข้องจะโฮสต์อยู่บนเซิร์ฟเวอร์ระยะไกลเป็นไฟล์ JSON MediaListModel จะดึงข้อมูล JSON นี้และประมวลผลเพื่อสร้างรายการออบเจ็กต์ MediaItem

ออบเจ็กต์ MediaItem จำลองวิดีโอและข้อมูลเมตาที่เกี่ยวข้อง เช่น ชื่อ คำอธิบาย URL สำหรับรูปภาพ และ URL สำหรับสตรีม

MediaTableViewController จะสร้างอินสแตนซ์ MediaListModel จากนั้นจะลงทะเบียนตัวเองเป็น MediaListModelDelegate เพื่อแจ้งให้ทราบเมื่อดาวน์โหลดข้อมูลเมตาของสื่อแล้ว เพื่อให้โหลดมุมมองตารางได้

ระบบจะแสดงรายการภาพขนาดย่อของวิดีโอแก่ผู้ใช้พร้อมคำอธิบายสั้นๆ สำหรับแต่ละวิดีโอ เมื่อเลือกรายการ ระบบจะส่ง MediaItem ที่เกี่ยวข้องไปยัง MediaViewController

MediaViewController

ตัวควบคุมการแสดงผลนี้จะแสดงข้อมูลเมตาเกี่ยวกับวิดีโอหนึ่งๆ และอนุญาตให้ผู้ใช้เล่นวิดีโอดังกล่าวในอุปกรณ์เคลื่อนที่

ตัวควบคุมมุมมองโฮสต์ LocalPlayerView ตัวควบคุมสื่อบางอย่าง และพื้นที่ข้อความเพื่อแสดงคำอธิบายของวิดีโอที่เลือก โปรแกรมเล่นจะครอบคลุมพื้นที่ด้านบนของหน้าจอ เหลือที่ว่างสำหรับคำอธิบายของวิดีโอโดยละเอียดด้านล่าง ผู้ใช้สามารถเล่น/หยุดชั่วคราว หรือค้นหาการเล่นวิดีโอในเครื่องได้

คำถามที่พบบ่อย

5. การเพิ่มปุ่ม "แคสต์"

ภาพประกอบแสดงปุ่ม "แคสต์" ที่มุมบนขวาใน 3 ภาพของ iPhone ที่ใช้แอป CastVideos

แอปพลิเคชันที่พร้อมใช้งาน Cast จะแสดงปุ่ม "แคสต์" ในตัวควบคุมมุมมองแต่ละรายการ การคลิกปุ่ม "แคสต์" จะแสดงรายการอุปกรณ์แคสต์ที่ผู้ใช้สามารถเลือกได้ หากผู้ใช้เล่นเนื้อหาในอุปกรณ์ของผู้ส่ง การเลือกอุปกรณ์แคสต์จะเริ่มเล่นหรือเล่นต่อในอุปกรณ์แคสต์นั้น ผู้ใช้สามารถคลิกปุ่ม "แคสต์" และหยุดแคสต์แอปพลิเคชันไปยังอุปกรณ์แคสต์ได้ทุกเมื่อในระหว่างเซสชันการแคสต์ ผู้ใช้จะต้องสามารถเชื่อมต่อหรือยกเลิกการเชื่อมต่ออุปกรณ์ Cast ได้ขณะอยู่ในหน้าจอใดๆ ของแอปพลิเคชัน ดังที่อธิบายไว้ในรายการตรวจสอบการออกแบบ Google Cast

การกำหนดค่า

โปรเจ็กต์เริ่มต้นต้องมีการตั้งค่าการอ้างอิงและ Xcode แบบเดียวกับที่คุณทำกับแอปตัวอย่างที่สมบูรณ์ กลับไปยังส่วนดังกล่าวและทำตามขั้นตอนเดิมเพื่อเพิ่ม GoogleCast.framework ลงในโปรเจ็กต์เริ่มต้นของแอป

การเริ่มต้น

เฟรมเวิร์กแคสต์มีออบเจ็กต์ Singleton ส่วนกลาง ซึ่งก็คือ GCKCastContext ซึ่งประสานรวมกิจกรรมทั้งหมดของเฟรมเวิร์ก ออบเจ็กต์นี้ต้องเริ่มต้นตั้งแต่เนิ่นๆ ในวงจรของแอปพลิเคชัน ซึ่งโดยทั่วไปจะอยู่ในเมธอด application(_:didFinishLaunchingWithOptions:) ของผู้รับมอบสิทธิ์แอป เพื่อให้การเริ่มเซสชันต่อโดยอัตโนมัติในการรีสตาร์ทแอปพลิเคชันของผู้ส่งสามารถทริกเกอร์ได้อย่างถูกต้องและสามารถเริ่มสแกนหาอุปกรณ์ได้

ต้องระบุออบเจ็กต์ GCKCastOptions เมื่อเริ่มต้น GCKCastContext คลาสนี้มีตัวเลือกที่มีผลต่อลักษณะการทำงานของเฟรมเวิร์ก สิ่งสำคัญที่สุดคือรหัสแอปพลิเคชันฝั่งผู้รับ ซึ่งใช้กรองผลการค้นหาอุปกรณ์แคสต์และเปิดแอปพลิเคชันตัวรับเมื่อเริ่มต้นเซสชันการแคสต์

นอกจากนี้ เมธอด application(_:didFinishLaunchingWithOptions:) ก็เป็นที่ที่ดีในการตั้งค่าผู้รับมอบสิทธิ์การบันทึกให้รับข้อความการบันทึกจากเฟรมเวิร์กของ Cast ซึ่งมีประโยชน์ในการแก้ไขข้อบกพร่องและแก้ปัญหา

เมื่อพัฒนาแอปที่พร้อมใช้งาน Cast ของคุณเอง คุณต้องลงทะเบียนเป็นนักพัฒนาซอฟต์แวร์ Cast แล้วรับรหัสแอปพลิเคชันสำหรับแอป สำหรับ Codelab นี้ เราจะใช้รหัสแอปตัวอย่าง

เพิ่มโค้ดต่อไปนี้ลงใน AppDelegate.swift เพื่อเริ่มต้น GCKCastContext ด้วยรหัสแอปพลิเคชันจากค่าเริ่มต้นของผู้ใช้ และเพิ่มตัวบันทึกสำหรับเฟรมเวิร์ก Google Cast

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)")
    }
  }
}

ปุ่ม "แคสต์"

เมื่อเริ่มต้น GCKCastContext แล้ว เราต้องเพิ่มปุ่ม "แคสต์" เพื่ออนุญาตให้ผู้ใช้เลือกอุปกรณ์แคสต์ได้ Cast SDK มีคอมโพเนนต์ปุ่ม "แคสต์" ชื่อ GCKUICastButton เป็นคลาสย่อยของ UIButton คุณเพิ่มชื่อไปยังแถบชื่อของแอปพลิเคชันได้โดยรวมไว้ใน UIBarButtonItem เราต้องเพิ่มปุ่ม "แคสต์" ทั้งใน MediaTableViewController และ MediaViewController

เพิ่มโค้ดต่อไปนี้ลงใน MediaTableViewController.swift และ MediaViewController.swift

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)

    ...
  }
  ...
}

จากนั้น เพิ่มโค้ดต่อไปนี้ลงใน MediaViewController.swift ของคุณ

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)

    ...
  }
  ...
}

เรียกใช้แอป คุณจะเห็นปุ่ม "แคสต์" ในแถบนำทางของแอป และเมื่อคลิกปุ่มดังกล่าว ปุ่ม "แคสต์" จะแสดงอุปกรณ์แคสต์ในเครือข่ายภายในของคุณ GCKCastContext จะเป็นผู้จัดการการค้นพบอุปกรณ์โดยอัตโนมัติ เลือกอุปกรณ์แคสต์ แล้วแอปตัวรับตัวอย่างจะโหลดในอุปกรณ์แคสต์ คุณจะสลับไปมาระหว่างกิจกรรมการท่องเว็บกับกิจกรรมของโปรแกรมเล่นในเครื่องได้ และสถานะของปุ่ม "แคสต์" จะซิงค์กันอยู่เสมอ

เรายังไม่ได้ให้การสนับสนุนการเล่นสื่อ คุณจึงยังไม่สามารถเล่นวิดีโอบนอุปกรณ์แคสต์ได้ คลิกปุ่ม "แคสต์" เพื่อหยุดแคสต์

6. กำลังแคสต์เนื้อหาวิดีโอ

ภาพ iPhone ที่ใช้แอป CastVideos ซึ่งแสดงรายละเอียดของวิดีโอที่เฉพาะเจาะจง ("Tears of Steel") ด้านล่างคือมินิเพลเยอร์

เราจะขยายตัวอย่างแอปให้เล่นวิดีโอจากระยะไกลบนอุปกรณ์แคสต์ด้วย ในการทำเช่นนั้น เราต้องรับฟังเหตุการณ์ต่างๆ ที่สร้างขึ้นโดยเฟรมเวิร์กของ Cast

กำลังแคสต์สื่อ

หากต้องการเล่นสื่อในอุปกรณ์แคสต์ในระดับสูง คุณต้องมีคุณสมบัติต่อไปนี้

  1. สร้างออบเจ็กต์ GCKMediaInformation จาก Cast SDK ที่จำลองรายการสื่อ
  2. ผู้ใช้จะเชื่อมต่อกับอุปกรณ์ Cast เพื่อเปิดแอปพลิเคชันตัวรับสัญญาณ
  3. โหลดออบเจ็กต์ GCKMediaInformation ลงในตัวรับและเล่นเนื้อหา
  4. ติดตามสถานะสื่อ
  5. ส่งคำสั่งการเล่นไปยังเครื่องรับตามการโต้ตอบของผู้ใช้

ขั้นตอนที่ 1 มีหน้าที่จับคู่ออบเจ็กต์หนึ่งกับอีกออบเจ็กต์หนึ่ง GCKMediaInformation เป็นข้อมูลที่ Cast SDK เข้าใจ และ MediaItem เป็นการห่อหุ้มรายการสื่อของแอป เราแมป MediaItem กับ GCKMediaInformation ได้อย่างง่ายดาย เราทําตามขั้นตอนที่ 2 ในส่วนก่อนหน้าไปแล้ว ขั้นตอนที่ 3 ง่ายๆ ด้วย Cast SDK

แอปตัวอย่าง MediaViewController แยกระหว่างการเล่นในเครื่องและการเล่นระยะไกลอยู่แล้วโดยใช้ enum นี้

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

private var playbackMode = PlaybackMode.none

ใน Codelab นี้จะไม่จำเป็นต้องทำความเข้าใจให้แน่ชัดว่าตรรกะของโปรแกรมเล่นตัวอย่างทั้งหมดทำงานอย่างไร คุณควรทราบว่าจะต้องแก้ไขโปรแกรมเล่นสื่อของแอปเพื่อให้ทราบถึงตำแหน่งการเล่น 2 ตำแหน่งในลักษณะเดียวกัน

ขณะนี้โปรแกรมเล่นในเครื่องจะอยู่ในสถานะการเล่นในเครื่องเสมอ เนื่องจากยังไม่ทราบข้อมูลเกี่ยวกับสถานะการแคสต์ เราจำเป็นต้องอัปเดต UI ตามการเปลี่ยนสถานะที่เกิดขึ้นในเฟรมเวิร์กของ Cast ตัวอย่างเช่น หากเราเริ่มแคสต์ เราต้องหยุดการเล่นในเครื่องและปิดใช้การควบคุมบางอย่าง ในทำนองเดียวกัน หากเราหยุดแคสต์เมื่ออยู่ในตัวควบคุมมุมมองนี้ เราก็จำเป็นต้องเปลี่ยนไปเล่นในเครื่อง เราต้องจัดการเหตุการณ์ต่างๆ ที่เฟรมเวิร์กของ Cast สร้างขึ้นเพื่อรับมือกับสถานการณ์ดังกล่าว

การจัดการเซสชันการแคสต์

สำหรับเฟรมเวิร์ก Cast เซสชัน Cast จะรวมขั้นตอนการเชื่อมต่ออุปกรณ์ การเปิด (หรือเข้าร่วม) เชื่อมต่อกับแอปพลิเคชันตัวรับสัญญาณ และการเริ่มต้นช่องควบคุมสื่อตามความเหมาะสม ช่องควบคุมสื่อคือวิธีที่เฟรมเวิร์ก Cast ส่งและรับข้อความจากโปรแกรมเล่นสื่อของเครื่องรับ

เซสชันการแคสต์จะเริ่มต้นโดยอัตโนมัติเมื่อผู้ใช้เลือกอุปกรณ์จากปุ่ม "แคสต์" และจะหยุดโดยอัตโนมัติเมื่อผู้ใช้ยกเลิกการเชื่อมต่อ การเชื่อมต่อกับเซสชันตัวรับสัญญาณอีกครั้งเนื่องจากปัญหาเครือข่ายได้รับการจัดการโดยอัตโนมัติด้วยเฟรมเวิร์ก Cast ด้วยเช่นกัน

เซสชันการแคสต์ได้รับการจัดการโดย GCKSessionManager ซึ่งเข้าถึงได้ผ่าน GCKCastContext.sharedInstance().sessionManager โค้ดเรียกกลับของ GCKSessionManagerListener สามารถใช้เพื่อตรวจสอบเหตุการณ์ของเซสชัน เช่น การสร้าง การระงับ การกลับมาทำงานอีกครั้ง และการสิ้นสุด

ก่อนอื่น เราต้องลงทะเบียน Listener เซสชันและเริ่มตัวแปรบางตัว ดังนี้

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 เราอยากแจ้งให้คุณทราบเมื่อเราเชื่อมต่อหรือเลิกเชื่อมต่อกับอุปกรณ์แคสต์ เพื่อให้เราสลับไปยังหรือจากโปรแกรมเล่นในเครื่องได้ โปรดทราบว่าอินสแตนซ์ของแอปพลิเคชันที่ทำงานอยู่ในอุปกรณ์เคลื่อนที่ของคุณอาจหยุดชะงักเท่านั้น แต่อาจเกิดความขัดข้องจากอินสแตนซ์อื่นของแอปพลิเคชัน (หรือแอปพลิเคชันอื่น) ที่ทำงานในอุปกรณ์เคลื่อนที่เครื่องอื่นด้วย

เซสชันที่ใช้งานอยู่ในปัจจุบันเข้าถึงได้ในฐานะ GCKCastContext.sharedInstance().sessionManager.currentCastSession ระบบจะสร้างเซสชันและแยกส่วนออกโดยอัตโนมัติเพื่อตอบสนองต่อท่าทางสัมผัสของผู้ใช้จากกล่องโต้ตอบการแคสต์

กำลังโหลดสื่อ

ใน Cast SDK GCKRemoteMediaClient จะมีชุด API ที่ใช้งานง่ายสำหรับการจัดการการเล่นสื่อระยะไกลบนตัวรับสัญญาณ สำหรับ GCKCastSession ที่รองรับการเล่นสื่อ SDK จะสร้างอินสแตนซ์ของ GCKRemoteMediaClient โดยอัตโนมัติ ซึ่งเข้าถึงได้ในฐานะพร็อพเพอร์ตี้ remoteMediaClient ของอินสแตนซ์ GCKCastSession

เพิ่มโค้ดต่อไปนี้ลงใน MediaViewController.swift เพื่อโหลดวิดีโอที่เลือกในปัจจุบันบนเครื่องรับ:

@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
      }
    }
  }
  ...
}

จากนั้นอัปเดตวิธีการต่างๆ ที่มีอยู่เพื่อใช้ตรรกะของเซสชันการแคสต์เพื่อรองรับการเล่นระยะไกล

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
}

คราวนี้ให้เรียกใช้แอปบนอุปกรณ์เคลื่อนที่ เชื่อมต่ออุปกรณ์ Cast และเริ่มเล่นวิดีโอ คุณควรเห็นวิดีโอเล่นบนตัวรับสัญญาณ

7. มินิคอนโทรล

รายการตรวจสอบการออกแบบของ Cast กำหนดให้แอป Cast ทั้งหมดต้องมีตัวควบคุมขนาดเล็กเพื่อให้ปรากฏขึ้นเมื่อผู้ใช้ออกจากหน้าเนื้อหาปัจจุบัน มินิคอนโทรลเลอร์ทำให้เข้าถึงได้ทันทีและการช่วยเตือนที่มองเห็นได้สำหรับเซสชันการแคสต์ปัจจุบัน

ภาพส่วนล่างของ iPhone ที่ใช้แอป CastVideos ซึ่งเน้นไปที่มินิคอนโทรล

Cast SDK มีแถบควบคุม GCKUIMiniMediaControlsViewController ซึ่งสามารถเพิ่มลงในฉากที่ต้องการแสดงตัวควบคุมแบบถาวร

สำหรับแอปตัวอย่าง เราจะใช้ GCKUICastContainerViewController ซึ่งตัดตัวควบคุมมุมมองอีก 1 รายการมาและเพิ่ม GCKUIMiniMediaControlsViewController ที่ด้านล่าง

แก้ไขไฟล์ AppDelegate.swift และเพิ่มโค้ดต่อไปนี้สำหรับเงื่อนไข if useCastContainerViewController ในเมธอดต่อไปนี้

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()
  ...
}

เพิ่มคุณสมบัตินี้และตัวตั้งค่า/ตัวรับสัญญาณเพื่อควบคุมการมองเห็นตัวควบคุมขนาดเล็ก (เราจะใช้รายการเหล่านี้ในส่วนต่อไป):

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

เรียกใช้แอปและแคสต์วิดีโอ เมื่อเริ่มเล่นบนอุปกรณ์รับสัญญาณ คุณจะเห็นมินิคอนโทรลเลอร์ปรากฏที่ด้านล่างของแต่ละฉาก คุณควบคุมการเล่นจากระยะไกลได้โดยใช้ตัวควบคุมขนาดเล็ก หากคุณสลับไปมาระหว่างกิจกรรมการท่องเว็บและกิจกรรมโปรแกรมเล่นในเครื่อง สถานะตัวควบคุมขนาดเล็กควรซิงค์กับสถานะการเล่นสื่อของผู้รับ

8. การวางซ้อนแนะนํา

รายการตรวจสอบการออกแบบของ Google Cast กำหนดให้แอปของผู้ส่งแนะนำปุ่ม "แคสต์" แก่ผู้ใช้เดิมเพื่อแจ้งให้ทราบว่าแอปผู้ส่งรองรับการแคสต์แล้ว และยังช่วยให้ผู้ใช้ที่เพิ่งเคยใช้ Google Cast อีกด้วย

ภาพ iPhone ที่ใช้แอป Castvideos ซึ่งมีปุ่ม "แคสต์" วางซ้อนอยู่ ซึ่งไฮไลต์ปุ่ม "แคสต์" และแสดงข้อความ "แตะเพื่อแคสต์สื่อไปยังทีวีและลำโพง"

คลาส GCKCastContext มีเมธอด presentCastInstructionsViewControllerOnce ซึ่งใช้ไฮไลต์ปุ่ม "แคสต์" เมื่อแสดงต่อผู้ใช้ได้เป็นครั้งแรก เพิ่มโค้ดต่อไปนี้ลงใน MediaViewController.swift และ 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)
  }
}

เมื่อเรียกใช้แอปบนอุปกรณ์เคลื่อนที่ จากนั้นคุณจะเห็นการวางซ้อนของการแนะนำ

9. ตัวควบคุมที่ขยาย

รายการตรวจสอบการออกแบบของ Google Cast กำหนดให้แอปของผู้ส่งต้องมีตัวควบคุมแบบขยายสำหรับสื่อที่กำลังแคสต์ ตัวควบคุมที่ขยายคือเวอร์ชันเต็มหน้าจอของมินิคอนโทรลเลอร์

ภาพ iPhone ที่ใช้แอป CastVideos กำลังเล่นวิดีโอโดยมีตัวควบคุมที่ขยายปรากฏที่ด้านล่าง

ตัวควบคุมที่ขยายเป็นมุมมองเต็มหน้าจอซึ่งให้คุณควบคุมการเล่นสื่อจากระยะไกลได้อย่างเต็มรูปแบบ มุมมองนี้ควรอนุญาตให้แอปแคสต์จัดการทุกส่วนที่จัดการได้ของเซสชันการแคสต์ ยกเว้นการควบคุมระดับเสียงของเครื่องรับและวงจรเซสชัน (เชื่อมต่อ/หยุดการแคสต์) และยังให้ข้อมูลสถานะทั้งหมดเกี่ยวกับเซสชันสื่อ (อาร์ตเวิร์ก ชื่อ ชื่อรอง ฯลฯ)

คลาส GCKUIExpandedMediaControlsViewController ใช้งานฟังก์ชันของมุมมองนี้

สิ่งแรกที่คุณต้องทำคือเปิดใช้ตัวควบคุมแบบขยายที่เป็นค่าเริ่มต้นในบริบทการแคสต์ แก้ไข AppDelegate.swift เพื่อเปิดใช้ตัวควบคุมแบบขยายเริ่มต้น

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

เพิ่มโค้ดต่อไปนี้ลงใน MediaViewController.swift เพื่อโหลดตัวควบคุมที่ขยายเมื่อผู้ใช้เริ่มแคสต์วิดีโอ

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

นอกจากนี้ ตัวควบคุมที่ขยายแล้วจะเปิดขึ้นโดยอัตโนมัติเมื่อผู้ใช้แตะตัวควบคุมขนาดเล็ก

เรียกใช้แอปและแคสต์วิดีโอ คุณจะเห็นตัวควบคุมที่ขยายแล้ว กลับไปที่รายการวิดีโอและเมื่อคลิกตัวควบคุมขนาดเล็ก ตัวควบคุมที่ขยายจะโหลดขึ้นอีกครั้ง

10. เพิ่มการรองรับ Cast Connect

ไลบรารี Cast Connect ช่วยให้แอปพลิเคชันของผู้ส่งที่มีอยู่สามารถสื่อสารกับแอปพลิเคชัน Android TV ผ่านโปรโตคอล Cast Cast Connect สร้างขึ้นบนโครงสร้างพื้นฐานของ Cast โดยมีแอป Android TV ทำหน้าที่เป็นตัวรับสัญญาณ

การอ้างอิง

ใน Podfile ให้ตรวจสอบว่า google-cast-sdk ชี้ไปยัง 4.4.8 ขึ้นไปตามที่แสดงด้านล่าง หากแก้ไขไฟล์ ให้เรียกใช้ pod update จากคอนโซลเพื่อซิงค์การเปลี่ยนแปลงกับโปรเจ็กต์

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

GCKLaunchOptions

ในการเปิดใช้งานแอปพลิเคชัน Android TV หรือที่เรียกว่า Android Receiver เราต้องตั้งค่าแฟล็ก androidReceiverCompatible เป็น "จริง" ในออบเจ็กต์ GCKLaunchOptions ออบเจ็กต์ GCKLaunchOptions นี้จะกำหนดวิธีเปิดใช้และส่งไปยัง GCKCastOptions ซึ่งตั้งค่าไว้ในอินสแตนซ์ที่แชร์โดยใช้ GCKCastContext.setSharedInstanceWith

เพิ่มบรรทัดต่อไปนี้ใน 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)

ตั้งค่าข้อมูลเข้าสู่ระบบการเปิดตัว

ในฝั่งผู้ส่ง คุณสามารถระบุ GCKCredentialsData เพื่อแทนผู้ที่เข้าร่วมเซสชันได้ credentials เป็นสตริงที่ผู้ใช้กำหนดได้ ตราบใดที่แอป ATV เข้าใจได้ ระบบจะส่งGCKCredentialsDataไปยังแอป Android TV ในช่วงเปิดตัวหรือเข้าร่วมเท่านั้น หากคุณตั้งค่าอีกครั้งขณะเชื่อมต่อ ระบบจะไม่ส่งข้อมูลนี้ไปยังแอป Android TV

หากต้องการตั้งค่าข้อมูลเข้าสู่ระบบการเปิดใช้งาน คุณต้องกำหนด GCKCredentialsData ได้ทุกเมื่อหลังจากตั้งค่า GCKLaunchOptions แล้ว ในการสาธิต เราจะเพิ่มตรรกะสำหรับปุ่ม Creds เพื่อตั้งค่าข้อมูลเข้าสู่ระบบที่จะส่งผ่านเมื่อมีการสร้างเซสชัน เพิ่มโค้ดต่อไปนี้ลงใน 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))
  }
}

ตั้งค่าข้อมูลเข้าสู่ระบบในคำขอโหลด

ในการจัดการ credentials ทั้งในแอปบนเว็บและ Android TV Receiver โปรดเพิ่มโค้ดต่อไปนี้ในคลาส MediaTableViewController.swift ในส่วนฟังก์ชัน loadSelectedItem

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

SDK จะนำข้อมูลเข้าสู่ระบบข้างต้นไปใช้กับเซสชันที่ดำเนินอยู่โดยอัตโนมัติ ทั้งนี้ขึ้นอยู่กับแอปผู้รับที่ผู้ส่งกำลังแคสต์

กำลังทดสอบ Cast Connect

ขั้นตอนการติดตั้ง APK ของ Android TV บน Chromecast พร้อม Google TV

  1. ค้นหาที่อยู่ IP ของอุปกรณ์ Android TV ซึ่งโดยปกติจะอยู่ในการตั้งค่า > เครือข่ายและอินเทอร์เน็ต > (ชื่อเครือข่ายที่อุปกรณ์เชื่อมต่ออยู่) ทางด้านขวาจะแสดงรายละเอียดและ IP ของอุปกรณ์ในเครือข่าย
  2. ใช้ที่อยู่ IP ของอุปกรณ์เพื่อเชื่อมต่อผ่าน ADB โดยใช้เทอร์มินัล โดยทำดังนี้
$ adb connect <device_ip_address>:5555
  1. จากหน้าต่างเทอร์มินัล ไปที่โฟลเดอร์ระดับบนสุดของตัวอย่าง Codelab ที่คุณดาวน์โหลดเมื่อเริ่มต้น Codelab นี้ เช่น
$ cd Desktop/ios_codelab_src
  1. ติดตั้งไฟล์ .apk ในโฟลเดอร์นี้ไปยัง Android TV โดยเรียกใช้
$ adb -s <device_ip_address>:5555 install android-tv-app.apk
  1. ตอนนี้คุณควรเห็นแอปตามชื่อแคสต์วิดีโอในเมนูแอปของคุณบนอุปกรณ์ Android TV แล้ว
  2. เมื่อเสร็จแล้ว ให้สร้างและเรียกใช้แอปในโปรแกรมจำลองหรืออุปกรณ์เคลื่อนที่ เมื่อสร้างเซสชันการแคสต์ด้วยอุปกรณ์ Android TV อุปกรณ์ Android TV ควรเปิดแอปพลิเคชัน Android Receiver บน Android TV การเล่นวิดีโอจากผู้ส่งบนอุปกรณ์เคลื่อนที่ iOS ของคุณจะเปิดวิดีโอในตัวรับสัญญาณ Android และช่วยให้คุณควบคุมการเล่นได้โดยใช้รีโมตของอุปกรณ์ Android TV

11. ปรับแต่งวิดเจ็ตแคสต์

การเริ่มต้น

เริ่มต้นจากโฟลเดอร์ "App-Done" เพิ่มข้อมูลต่อไปนี้ลงในเมธอด applicationDidFinishLaunchingWithOptions ในไฟล์ AppDelegate.swift

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

เมื่อคุณใช้การปรับแต่งอย่างน้อย 1 รายการที่กล่าวถึงในส่วนที่เหลือของ Codelab นี้แล้ว ให้คอมมิตสไตล์โดยเรียกใช้โค้ดด้านล่าง

styler.apply()

การกำหนดค่ามุมมองของ Cast

คุณปรับแต่งมุมมองทั้งหมดที่เฟรมเวิร์กแอปพลิเคชัน Cast จัดการได้โดยใช้หลักเกณฑ์การจัดรูปแบบเริ่มต้นในมุมมองต่างๆ มาดูตัวอย่างการเปลี่ยนสีไอคอนกัน

styler.castViews.iconTintColor = .lightGray

คุณลบล้างค่าเริ่มต้นสำหรับแต่ละหน้าจอได้หากจำเป็น ตัวอย่างเช่น เพื่อลบล้างสีอ่อนของสีแต้มสำหรับไอคอนสีอ่อนสำหรับตัวควบคุมสื่อที่ขยายอยู่เท่านั้น

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

การเปลี่ยนสี

คุณสามารถปรับแต่งสีพื้นหลังให้กับทุกมุมมอง (หรือปรับแต่งแยกกันสำหรับแต่ละมุมมอง) ได้ โค้ดต่อไปนี้จะกำหนดสีพื้นหลังเป็นสีฟ้าสำหรับมุมมองที่มีในเฟรมเวิร์กแอปพลิเคชัน Cast ทั้งหมด

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

การเปลี่ยนแบบอักษร

คุณสามารถปรับแต่งแบบอักษรสำหรับป้ายกำกับต่างๆ ที่เห็นภายในมุมมองการแคสต์ มาตั้งค่าแบบอักษรทั้งหมดเป็น "Courier-Oblique" เพื่อประกอบการอธิบาย

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)

กำลังเปลี่ยนภาพปุ่มเริ่มต้น

เพิ่มภาพที่คุณกำหนดเองลงในโครงการ และกำหนดภาพให้กับปุ่มเพื่อจัดรูปแบบ

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

การเปลี่ยนธีมของปุ่ม "แคสต์"

นอกจากนี้คุณยังกำหนดธีมวิดเจ็ตแคสต์ได้โดยใช้โปรโตคอล UIAppearance โค้ดต่อไปนี้กำหนดธีม GCKUICastButton ในมุมมองทั้งหมดที่ปรากฏขึ้น

GCKUICastButton.appearance().tintColor = UIColor.gray

12. ขอแสดงความยินดี

ตอนนี้คุณรู้วิธีเปิดใช้แอปวิดีโอโดยใช้วิดเจ็ต Cast SDK บน iOS แล้ว

สำหรับรายละเอียดเพิ่มเติม โปรดดูคู่มือนักพัฒนาซอฟต์แวร์ iOS Sender