广告插播时间点
iOS Sender SDK 可在应用内提供对广告插播时间点和随播广告的支持, 指定媒体流。
请参阅 网络接收器广告插播概览,了解详情 以便详细了解广告插播时间点的运作方式
虽然可以为发送者和接收者指定广告插播时间点,但建议同时为发送者和接收者指定 在网络接收器中指定,然后 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
。
示例代码
以下两个文件实现了 GCKUIPlaybackRateController
,用于控制
使用具有“正常”“半速”和
“双倍速”按钮:
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
添加自定义渠道
Cast 框架提供了两种方法来创建用于发送自定义消息的频道。 发送到网络接收器:
GCKCastChannel
旨在实现子类化,以实现具有 状态。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
频道可以随时注册;如果会话当前不是处于 处于关联状态时,该频道将在 前提是该通道的命名空间位于 Web Receiver 应用元数据的受支持命名空间列表。
每个自定义渠道都由唯一的命名空间定义,且必须以
前缀 urn:x-cast:
,例如 urn:x-cast:com.example.custom
。时间是
可以有多个自定义渠道,每个渠道都有唯一的命名空间。通过
Web Receiver 应用还可以
消息
同一个命名空间
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
。
支持自动播放
替换图片选择和缓存
框架的各个组件(即“投射”对话框、迷你
控制器、展开的控制器以及
GCKUIMediaController
(如果已配置)会显示当前投放媒体的海报图片。网址
通常包含在
GCKMediaMetadata
但发件人应用可能有备用网址来源。
通过
GCKUIImagePicker
协议定义了一种方式,用于根据指定用途选择合适图片
和所需的尺寸它只有一个方法,即 -[getImageWithHints:fromMetadata:]
,
它接受
GCKUIImageHints
对象和一个
GCKMediaMetadata
对象作为参数,并返回
GCKImage
对象以
结果。框架提供了
GCKUIImagePicker
,它始终选择
GCKMediaMetadata
对象,但应用可以提供备用
通过设置 imagePicker
属性(
GCKCastContext
单例。
通过
GCKUIImageCache
协议还定义了一种可缓存由
使用 HTTPS 进行传输。框架提供了
GCKUIImageCache
,用于将下载的图片文件存储在应用的缓存中
目录,但应用可以通过设置
imageCache
属性的
GCKCastContext
单例。
后续步骤
以上就是可添加到 iOS “发件人”应用中的功能。 您现在可以针对其他平台构建发送者应用 (Android 或 Web)、 或构建网络接收器。