แคสต์แอป iOS

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

1. ภาพรวม

โลโก้ Google Cast

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

Google Cast คืออะไร

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

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

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

สิ่งที่เรากําลังสร้าง

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

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

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

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

  • Xcode ล่าสุด
  • อุปกรณ์เคลื่อนที่ iOS 9 ขึ้นไป (หรือเครื่องจําลอง Xcode)
  • สายข้อมูล 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. ติดตั้งทรัพยากร Dependency จาก 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. ติดตั้งทรัพยากร Dependency จาก Podfile
cd app-start
pod update
pod install
  1. เปิด Xcode แล้วเลือกเปิดโปรเจ็กต์อื่น...
  2. เลือกไฟล์ CastVideos-ios.xcworkspace จากไดเรกทอรี ไอคอนโฟลเดอร์app-start ในโฟลเดอร์โค้ดตัวอย่าง

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

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

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

MediaViewViewController

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

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

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

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

MediaViewController

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

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

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

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

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

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

การกำหนดค่า

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

การเริ่มต้น

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

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

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

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

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

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

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

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

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

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

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

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 ที่รองรับการเล่นสื่อ ระบบจะสร้างอินสแตนซ์ของ GCKRemoteMediaClient โดยอัตโนมัติโดย SDK คุณสามารถเข้าถึงได้โดยใช้พร็อพเพอร์ตี้ 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
}

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

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

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

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

GCKUICastButton.appearance().tintColor = UIColor.gray

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

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

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