เพิ่มฟีเจอร์ขั้นสูงในแอป iOS ของคุณ

ช่วงพักโฆษณา

iOS Sender SDK รองรับช่วงพักโฆษณาและโฆษณาที่แสดงร่วมภายในสตรีมสื่อที่ระบุ

ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีการทำงานของช่วงพักโฆษณาได้ที่ภาพรวมช่วงพักโฆษณาใน Webรอรับ

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

ใน iOS ให้ระบุช่วงพักโฆษณาในคำสั่งโหลดโดยใช้ GCKAdBreakClipInfo และ GCKAdBreakInfo ดังนี้

สวิฟต์
let breakClip1Builder = GCKAdBreakClipInfoBuilder(adBreakClipID: "bc0")
breakClip1Builder.title = "Clip title"
if let posterUrl = URL(string: "https://www.some.url") {
  breakClip1Builder.posterURL = posterUrl
}
breakClip1Builder.duration = 60
breakClip1Builder.whenSkippable = 5  // Set this field so that the ad is skippable
let breakClip1 = breakClip1Builder.build()

let breakClip2 = ...
let breakClip3 = ...


let break1 = GCKAdBreakInfoBuilder(adBreakID: "b0", adBreakClipIds: ["bc0", "bc1", "bc2"]).build()
let mediaInfoBuilder = GCKMediaInformationBuilder(entity: "entity")
...
mediaInfoBuilder.adBreaks = [break1]
mediaInfoBuilder.adBreakClips = [breakClip1, breakClip2, breakClip3]
...
mediaInformation = mediaInfoBuilder.build()

let mediaLoadRequestDataBuilder = GCKMediaLoadRequestDataBuilder()
mediaLoadRequestDataBuilder.mediaInformation = mediaInformation

sessionManager.currentSession?.remoteMediaClient?.loadMedia(with: mediaLoadRequestDataBuilder.build())
วัตถุประสงค์-ค
GCKAdBreakClipInfoBuilder *breakClipInfoBuilder = [[GCKAdBreakClipInfoBuilder alloc] initWithAdBreakClipID:@"bc0"];
breakClipInfoBuilder.title = @"Clip title";
breakClipInfoBuilder.posterURL = [[NSURL alloc] initWithString:@"https://www.some.url"];
breakClipInfoBuilder.duration = 60;
breakClipInfoBuilder.whenSkippable = 5;
GCKAdBreakClipInfo *breakClip1 = breakClipInfoBuilder.build;

GCKAdBreakClipInfo *breakClip2 = ...
GCKAdBreakClipInfo *breakClip3 = ...

GCKAdBreakInfo *break1 = [[GCKAdBreakInfoBuilder alloc] initWithAdBreakID:@"b0"
                                                           adBreakClipIds:@[@"bc0", @"bc1", @"bc2"]].build;

GCKMediaInformationBuilder *mediaInfoBuilder = [[GCKMediaInformationBuilder alloc]
                                                initWithEntity:@"entity"];
...
mediaInfoBuilder.adBreaks = @[break1];
mediaInfoBuilder.adBreakClips = @[breakClip1, breakClip2, breakClip3];
...
self.mediaInformation = [mediaInfoBuilder build];

GCKMediaLoadRequestDataBuilder *mediaLoadRequestDataBuilder = [[GCKMediaLoadRequestDataBuilder alloc] init];
mediaLoadRequestDataBuilder.mediaInformation = self.mediaInformation;

// Send a load request to the remote media client.
GCKRequest *request = [self.sessionManager.currentSession.remoteMediaClient
                                loadMediaWithLoadRequestData:[mediaLoadRequestDataBuilder build]];

อัตราการเล่นแปรผัน

แอปของคุณสามารถแสดงและเปลี่ยนอัตราการเล่นของรายการสื่อปัจจุบันได้ คุณสามารถตั้งอัตราโดยใช้ -[setPlaybackRate:] หรือ -[setPlaybackRate:customData:] ของ GCKRemoteMediaClient เข้าถึง GCKUIPlaybackRateController โดยใช้ playbackRateController ของ GCKUIMediaController และแสดงอัตราการเล่นปัจจุบันโดยใช้ playbackRate ของ GCKUIPlaybackRateController

รหัสตัวอย่าง

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

สวิฟต์
import GoogleCast

/**
 * An implementation of GCKUIPlaybackRateController that controls playback rate
 * using a segmented control that has "normal", "half speed", and "double speed"
 * buttons.
 */
class SegmentedButtonPlaybackRateController: GCKUIPlaybackRateController {
  static let kSegmentNormal = 0;
  static let kSegmentHalfSpeed = 1;
  static let kSegmentDoubleSpeed = 2;

  var segmentedControl: UISegmentedControl!

  override var playbackRate: Float {
    didSet {
      var buttonIndex = 0

      // Map the playback rate to one of our three supported speeds.
      if playbackRate == 1.0 {
        buttonIndex = SegmentedButtonPlaybackRateController.kSegmentNormal
      } else if playbackRate < 1.0 {
        buttonIndex = SegmentedButtonPlaybackRateController.kSegmentHalfSpeed
      } else {
        buttonIndex = SegmentedButtonPlaybackRateController.kSegmentDoubleSpeed
      }

      segmentedControl?.selectedSegmentIndex = buttonIndex
    }
  }
  override var inputEnabled: Bool {
    didSet {
      segmentedControl?.isEnabled = inputEnabled
    }
  }

  /**
   * Designated initializer.
   *
   * @param segmentedControl The segmented control for changing/displaying the
   * playback rate.
   */
  convenience init(_ segmentedControl: UISegmentedControl) {
    self.init()
    self.segmentedControl = segmentedControl;

    segmentedControl.addTarget(self,
                               action: #selector(segmentedControlTapped(sender:)),
                               for: UIControl.Event.valueChanged)
  }

  @objc func segmentedControlTapped(sender: UISegmentedControl) {
    var playbackRate: Float = 1.0

    switch segmentedControl?.selectedSegmentIndex {
    case SegmentedButtonPlaybackRateController.kSegmentHalfSpeed:
      playbackRate = 0.5;
    case SegmentedButtonPlaybackRateController.kSegmentDoubleSpeed:
      playbackRate = 2.0;
    case SegmentedButtonPlaybackRateController.kSegmentNormal:
      fallthrough
    default:
      playbackRate = 1.0;
    }

    self.playbackRate = playbackRate
  }
}
วัตถุประสงค์-ค

SegmentedButtonPlaybackRateController.h

#import <GoogleCast/GoogleCast.h>
#import <UIKit/UIKit.h>

/**
 * An implementation of GCKUIPlaybackRateController that controls playback rate
 * using a segmented control that has "normal", "half speed", and "double speed"
 * buttons.
 */
@interface SegmentedButtonPlaybackRateController : GCKUIPlaybackRateController

/**
 * Designated initializer.
 *
 * @param segmentedControl The segmented control for changing/displaying the
 * playback rate.
 */
- (instancetype)initWithSegmentedControl:(UISegmentedControl *)segmentedControl;

@end

SegmentedButtonPlaybackRateController.m

#import "SegmentedButtonPlaybackRateController.h"

@interface SegmentedButtonPlaybackRateController () {
  UISegmentedControl *_segmentedControl;
}

@end

static const NSInteger kSegmentNormal = 0;
static const NSInteger kSegmentHalfSpeed = 1;
static const NSInteger kSegmentDoubleSpeed = 2;

@implementation SegmentedButtonPlaybackRateController

- (instancetype)initWithSegmentedControl:(UISegmentedControl *)segmentedControl {
  if (self = [super init]) {
    _segmentedControl = segmentedControl;
    [_segmentedControl addTarget:self
                          action:@selector(segmentedControlTapped:)
                forControlEvents:UIControlEventValueChanged];
  }
  return self;
}

- (void)setPlaybackRate:(float)playbackRate {
  [super setPlaybackRate:playbackRate];

  NSInteger buttonIndex = 0;

  // Map the playback rate to one of our three supported speeds.
  if (playbackRate == 1.0) {
    buttonIndex = kSegmentNormal;
  } else if (playbackRate < 1.0) {
    buttonIndex = kSegmentHalfSpeed;
  } else {
    buttonIndex = kSegmentDoubleSpeed;
  }

  _segmentedControl.selectedSegmentIndex = buttonIndex;
}

- (void)setInputEnabled:(BOOL)inputEnabled {
  _segmentedControl.enabled = inputEnabled;
  [super setInputEnabled:inputEnabled];
}

- (void)segmentedControlTapped:(id)sender {
  float playbackRate;

  switch (_segmentedControl.selectedSegmentIndex) {
    case kSegmentHalfSpeed:
      playbackRate = 0.5;
      break;

    case kSegmentDoubleSpeed:
      playbackRate = 2.0;
      break;

    case kSegmentNormal:
    default:
      playbackRate = 1.0;
      break;
  }

  self.playbackRate = playbackRate;
}

@end

เพิ่มแชแนลที่กำหนดเอง

เฟรมเวิร์กแคสต์มีวิธีสร้างช่องเพื่อส่งข้อความที่กำหนดเองไปยังเว็บรีซีฟเวอร์ 2 วิธีดังนี้

  1. GCKCastChannel มีไว้เพื่อเป็นคลาสย่อยเพื่อใช้ช่องที่ไม่ใช่ช่องสำคัญซึ่งมีรัฐที่เกี่ยวข้อง
  2. GCKGenericChannel มีไว้เพื่อเป็นทางเลือกในการจัดประเภทย่อย โดยจะส่งข้อความที่ได้รับไปยังผู้รับมอบสิทธิ์เพื่อให้นำไปประมวลผลที่อื่นได้

ตัวอย่างการติดตั้งใช้งาน GCKCastChannel

สวิฟต์
class HGCTextChannel: GCKCastChannel {
  override func didReceiveTextMessage(_ message: String) {
    print("received message: \(message)")
  }
}
วัตถุประสงค์-ค

HGCTextChannel.h

#import <GoogleCast/GCKCastChannel.h>

@interface HGCTextChannel : GCKCastChannel

@end

HGCTextChannel.m

#import "HGCTextChannel.h"

@implementation HGCTextChannel
- (void)didReceiveTextMessage:(NSString*)message {
  NSLog(@"received message: %@", message);
}

@end

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

แชแนลที่กำหนดเองแต่ละรายการจะกำหนดโดยเนมสเปซที่ไม่ซ้ำกัน และต้องขึ้นต้นด้วยคำนำหน้า urn:x-cast: เช่น urn:x-cast:com.example.custom เป็นไปได้ที่จะมีแชแนลที่กำหนดเองหลายแชแนล โดยแต่ละช่องมีเนมสเปซที่ไม่ซ้ำกัน แอปเว็บรีซีฟเวอร์ยังสามารถส่งและรับข้อความโดยใช้เนมสเปซเดียวกันได้อีกด้วย

สวิฟต์
var error: GCKError?
let textChannel = HGCTextChannel.init(namespace: "urn:x-cast:com.google.cast.sample.helloworld")
sessionManager.currentCastSession?.add(textChannel)
textChannel.sendTextMessage("Hello World", error: &error)

if error != nil {
  print("Error sending text message \(error.debugDescription)")
}
วัตถุประสงค์-ค
NSError *error;
HGCTextChannel *textChannel = [[HGCTextChannel alloc] initWithNamespace:@"urn:x-cast:com.google.cast.sample.helloworld"];
[sessionManager.currentCastSession addChannel:textChannel];
[textChannel sendTextMessage:@"Hello World"
                       error:&error];

if (error != nil) {
  NSLog(@"Error sending text message: %@", error);
}

ในการระบุตรรกะที่จำเป็นต้องดำเนินการเมื่อช่องใดช่องหนึ่งเชื่อมต่อหรือตัดการเชื่อมต่อ ให้ลบล้างเมธอด -[didConnect] และ -[didDisconnect] หากใช้ GCKCastChannel หรือระบุการใช้งานสำหรับเมธอด -[castChannelDidConnect:] และ -[castChannelDidDisconnect:] ของ GCKGenericChannelDelegate หากใช้ GCKGenericChannel

การรองรับการเล่นอัตโนมัติ

ดู API การเล่นอัตโนมัติและการจัดคิว

ลบล้างการเลือกและการแคชรูปภาพ

องค์ประกอบต่างๆ ของเฟรมเวิร์ก (ได้แก่ กล่องโต้ตอบแคสต์ มินิคอนโทรลเลอร์ ตัวควบคุมแบบขยาย และGCKUIMediaController หากกำหนดค่าไว้) จะแสดงอาร์ตเวิร์กสำหรับสื่อที่กำลังแคสต์อยู่ โดยทั่วไปแล้ว URL ของอาร์ตเวิร์กจะรวมอยู่ใน GCKMediaMetadata สำหรับสื่อ แต่แอปของผู้ส่งอาจมีแหล่งที่มาสำรองสำหรับ URL ดังกล่าว

โปรโตคอล GCKUIImagePicker จะกำหนดวิธีการเลือกรูปภาพที่เหมาะสมสำหรับการใช้งานและขนาดที่ต้องการ โดยมีเมธอดเดียว คือ -[getImageWithHints:fromMetadata:] ซึ่งนำออบเจ็กต์ GCKUIImageHints และออบเจ็กต์ GCKMediaMetadata เป็นพารามิเตอร์ และแสดงผลออบเจ็กต์ GCKImage เป็นผลลัพธ์ เฟรมเวิร์กจะแสดงการใช้งาน GCKUIImagePicker ตามค่าเริ่มต้น ซึ่งจะเลือกรูปภาพแรกในรายการรูปภาพในออบเจ็กต์ GCKMediaMetadata เสมอ แต่แอปสามารถติดตั้งใช้งานด้วยวิธีอื่นได้โดยตั้งค่าพร็อพเพอร์ตี้ imagePicker ของ Singleton สำหรับ GCKCastContext

โปรโตคอล GCKUIImageCache ยังกำหนดวิธีการแคชรูปภาพที่ดาวน์โหลดโดยเฟรมเวิร์กโดยใช้ HTTPS ด้วย เฟรมเวิร์กจะแสดงการใช้งานเริ่มต้นของ GCKUIImageCache ซึ่งเก็บไฟล์รูปภาพที่ดาวน์โหลดไว้ในไดเรกทอรีแคชของแอป แต่แอปอาจมีการใช้งานทางเลือกโดยการตั้งค่าพร็อพเพอร์ตี้ imageCache ของ Singleton ของ GCKCastContext

ขั้นตอนถัดไป

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