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

1. ภาพรวม

โลโก้ Google Cast

Codelab นี้จะสอนวิธีแก้ไขแอปวิดีโอ 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 ลงในแอป
  • วิธีเพิ่มตัวควบคุมแบบขยาย
  • วิธีให้โฆษณาซ้อนทับแนะนำ
  • วิธีปรับแต่งวิดเจ็ตแคสต์
  • วิธีผสานรวม 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 และเลือก Open another project...
  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 และเลือก Open another project...
  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

การกำหนดค่า

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

เซสชันการแคสต์จะได้รับการจัดการโดย 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
      }
    }
  }
  ...
}

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

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. มินิคอนโทรลเลอร์

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

ภาพส่วนล่างของ 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 เป็น "จริง" ในออบเจ็กต์ 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 Receiver บน Android TV ของคุณ การเล่นวิดีโอจากผู้ส่งบนอุปกรณ์เคลื่อนที่ iOS จะเปิดวิดีโอใน Android Receiver และช่วยให้คุณสามารถควบคุมการเล่นโดยใช้รีโมตของอุปกรณ์ Android TV

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

การเริ่มต้น

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

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

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

styler.apply()

การปรับแต่งมุมมองการแคสต์

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

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