為您的 iOS 應用程式新增進階功能

廣告插播

iOS send SDK 支援特定媒體串流中的廣告插播和隨播廣告。

如要進一步瞭解廣告插播的運作方式,請參閱網路廣告插播總覽

雖然可以同時為傳送者和接收者指定中斷點,但我們建議您透過網路接收器Android TV 接收器指定中斷點,以保持跨平台維持一致的行為。

在 iOS 裝置上,請使用 GCKAdBreakClipInfoGCKAdBreakInfo 在載入指令中指定廣告插播:

Swift
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())
Objective-C
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]];

變動率

應用程式可以顯示及變更目前媒體項目的播放率。您可以使用 GCKRemoteMediaClient-[setPlaybackRate:]-[setPlaybackRate:customData:] 設定費率、使用 GCKUIMediaControllerGCKUIPlaybackRateController 存取 GCKUIPlaybackRateController,並使用 的 GCKUIPlaybackRateController 顯示目前的播放速率。playbackRateControllerplaybackRate

程式碼範例

以下兩個檔案會導入 GCKUIPlaybackRateController,透過具有「一般」、「一半速度」和「雙倍速度」按鈕的區隔控制項控製播放率:

Swift
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
  }
}
Objective-C

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

新增自訂管道

Cast 架構提供兩種方式來建立管道,以便傳送自訂訊息給網路接收器:

  1. GCKCastChannel 的用途是建立子類別,以便實作具有相關狀態的非實用頻道。
  2. GCKGenericChannel 做為子類別的替代方案,其會將收到的訊息傳遞至委派代表,以便在其他位置處理。

以下是 GCKCastChannel 實作的範例:

Swift
class HGCTextChannel: GCKCastChannel {
  override func didReceiveTextMessage(_ message: String) {
    print("received message: \(message)")
  }
}
Objective-C

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。您可能會有多個自訂管道,且每個頻道都有不重複的命名空間。網路接收器應用程式也可以使用相同命名空間收發訊息

Swift
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)")
}
Objective-C
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);
}

如要提供特定管道連線或中斷連線時必須執行的邏輯,請使用 GCKCastChannel 覆寫 -[didConnect]-[didDisconnect] 方法,或者如果使用 GCKGenericChannel,則提供 GCKGenericChannelDelegate-[castChannelDidConnect:]-[castChannelDidDisconnect:] 方法的實作。

支援自動播放功能

請參閱「自動播放和佇列 API」。

覆寫映像檔選取和快取

架構的各種元件 (稱為「投放」對話方塊、迷你控制器、展開的控制器及 GCKUIMediaController (如果有設定)) 會顯示目前投放媒體的藝術品。圖片圖片的網址通常包含在媒體的 GCKMediaMetadata 中,但寄件者應用程式可能會為網址提供替代來源。

GCKUIImagePicker 通訊協定定義特定用途的所需圖片以及所需大小的方法。其中包含單一方法 -[getImageWithHints:fromMetadata:],該方法使用 GCKUIImageHints 物件和 GCKMediaMetadata 物件做為參數,並傳回 GCKImage 物件做為結果。該架構提供 GCKUIImagePicker 的預設實作方式,一律在 GCKMediaMetadata 物件的圖片清單中選取第一張圖片,但應用程式可設定 GCKCastContext 單例模式的 imagePicker 屬性,藉此提供替代的導入作業。

GCKUIImageCache 通訊協定也會定義架構使用 HTTPS 下載圖片的方法。這個架構提供 GCKUIImageCache 的預設實作方式,可在下載圖片的快取目錄中儲存下載的圖片檔,但您可透過設定 GCKCastContext 單例模式的 imageCache 屬性,提供替代的實作方式。

後續步驟

可以瞭解可新增至 iOS 傳送端應用程式的功能。您現在可以為其他平台 (Android網頁) 建構傳送端應用程式,或是建立網路接收器