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

1. ภาพรวม

โลโก้ Google Cast

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

Google Cast คืออะไร

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

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

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

เราจะสร้างอะไร

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

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

  • วิธีเพิ่ม Google Cast SDK ลงในแอปวิดีโอตัวอย่าง
  • วิธีเพิ่มปุ่มแคสต์เพื่อเลือกอุปกรณ์ Google Cast
  • วิธีเชื่อมต่อกับอุปกรณ์แคสต์และเปิดใช้งานเครื่องรับสื่อ
  • วิธีแคสต์วิดีโอ
  • วิธีเพิ่มตัวควบคุม Cast Mini ลงในแอป
  • วิธีเพิ่มตัวควบคุมแบบขยาย
  • วิธีใส่ข้อความวางซ้อนแนะนำ
  • วิธีปรับแต่งวิดเจ็ตแคสต์
  • วิธีผสานรวม 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 Manager

การตั้งค่าโปรเจ็กต์

  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. การเพิ่มปุ่มแคสต์

ภาพส่วนบน 1 ใน 3 ของ iPhone ที่ใช้แอป CastVideos ซึ่งแสดงปุ่มแคสต์ที่มุมขวาบน

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

การกำหนดค่า

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

การเริ่มต้น

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

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

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

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

เพิ่มโค้ดต่อไปนี้ลงใน 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 มีคอมโพเนนต์ปุ่ม Cast ชื่อ 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") ที่ด้านล่างคือมินิเพลเยอร์

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

การแคสต์สื่อ

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

  1. สร้างออบเจ็กต์ GCKMediaInformation จาก Cast SDK ที่จำลองรายการสื่อ
  2. ผู้ใช้เชื่อมต่อกับอุปกรณ์แคสต์เพื่อเปิดใช้งานแอปพลิเคชันตัวรับสัญญาณ
  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 สร้างขึ้น

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

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

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

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

คุณเข้าถึงเซสชันที่ใช้งานอยู่ในปัจจุบันได้โดยใช้ 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
      }
    }
  }
  ...
}

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

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
}

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

7. คอนโทรลเลอร์ขนาดเล็ก

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

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

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

สำหรับแอปตัวอย่าง เราจะใช้ GCKUICastContainerViewController ซึ่งรวมตัวควบคุมมุมมองอีกรายการหนึ่งและเพิ่ม 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 เราต้องตั้งค่า Flag androidReceiverCompatible เป็น true ในออบเจ็กต์ 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 ให้เพิ่มโค้ดต่อไปนี้ในคลาส 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 บน 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 จัดการได้โดยการมีหลักเกณฑ์การจัดรูปแบบเริ่มต้นในมุมมองต่างๆ ลองดูตัวอย่างเปลี่ยนสีการแต้มของไอคอน

styler.castViews.iconTintColor = .lightGray

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

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

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

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

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 ในแอปวิดีโอโดยใช้วิดเจ็ต Cast SDK ใน iOS แล้ว

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