Рекламные паузы
iOS Sender SDK обеспечивает поддержку рекламных пауз и сопутствующей рекламы в рамках заданного медиапотока.
Для получения более подробной информации о том, как работают рекламные паузы, см. раздел «Обзор рекламных пауз в Web Receiver» .
Хотя прерывания можно указать как на отправителе, так и на получателе, рекомендуется указывать их на веб-приемнике и приемнике 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]];
Переменная скорость воспроизведения
Your app can display and change the playback rate for the current media item. You are able to set the rate using -[setPlaybackRate:] or -[setPlaybackRate:customData:] of the GCKRemoteMediaClient , access the GCKUIPlaybackRateController using playbackRateController of the GCKUIMediaController , and display the current playback rate using playbackRate of the 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 .
Поддержка автовоспроизведения
См. API автовоспроизведения и постановки в очередь .
Переопределение выбора изображения и кэширования
Различные компоненты фреймворка (а именно диалоговое окно трансляции, мини-контроллер, расширенный контроллер и GCKUIMediaController , если он настроен соответствующим образом) будут отображать обложки для текущего транслируемого медиаконтента. URL-адреса обложек изображений обычно включаются в GCKMediaMetadata для медиафайла, но приложение-отправитель может иметь альтернативный источник URL-адресов.
The GCKUIImagePicker protocol defines a means for selecting an appropriate image for a given usage and desired size. It has a single method, -[getImageWithHints:fromMetadata:] , which takes a GCKUIImageHints object and a GCKMediaMetadata object as parameters, and returns a GCKImage object as a result. The framework provides a default implementation of GCKUIImagePicker which always selects the first image in the list of images in the GCKMediaMetadata object, but the app can provide an alternate implementation by setting the imagePicker property of the GCKCastContext singleton.
Протокол GCKUIImageCache также определяет способ кэширования изображений, загружаемых фреймворком с использованием HTTPS. Фреймворк предоставляет реализацию GCKUIImageCache по умолчанию, которая хранит загруженные файлы изображений в каталоге кэша приложения, но приложение может предоставить альтернативную реализацию, установив свойство imageCache в синглтоне GCKCastContext .
Следующие шаги
На этом завершается описание функций, которые вы можете добавить в свое приложение-отправитель для iOS. Теперь вы можете создать приложение-отправитель для другой платформы ( Android или Web ) или разработать веб-приемник .