Intervalos de anúncio
O SDK do remetente do iOS oferece suporte a intervalos de anúncios e anúncios complementares em um determinado stream de mídia.
Consulte a Visão geral das pausas de anúncios do Web Receiver para mais informações sobre como elas funcionam.
Embora as pausas possam ser especificadas no transmissor e no receptor, é recomendável que elas sejam especificadas no Receptor da Web e no Receptor do Android TV para manter o comportamento consistente em todas as plataformas.
No iOS, especifique os intervalos de anúncios em um comando de carregamento usando
GCKAdBreakClipInfo
e 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]];
Taxa de reprodução variável
O app pode mostrar e mudar a taxa de reprodução do item de mídia atual.
É possível definir a taxa usando -[setPlaybackRate:]
ou
-[setPlaybackRate:customData:]
do
GCKRemoteMediaClient
,
acessar o GCKUIPlaybackRateController
usando playbackRateController
do
GCKUIMediaController
e mostrar a taxa de reprodução atual usando playbackRate
do
GCKUIPlaybackRateController
.
Código de amostra
Os dois arquivos a seguir implementam GCKUIPlaybackRateController
, que controla
a taxa de reprodução usando um controle segmentado com botões "normal", "meia velocidade" e
"dupla velocidade":
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
Adicionar um canal personalizado
O framework do Cast oferece duas maneiras de criar um canal para enviar mensagens personalizadas a um receptor da Web:
GCKCastChannel
é destinado a ser subclassificado para implementar canais não triviais que têm estado associado.GCKGenericChannel
é fornecido como uma alternativa à subclassificação. Ele transmite as mensagens recebidas a um delegado para que elas possam ser processadas em outro lugar.
Confira um exemplo de implementação de 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
Um canal pode ser registrado a qualquer momento. Se a sessão não estiver em um estado conectado, o canal será conectado automaticamente quando a sessão estiver conectada, desde que o namespace do canal esteja presente na lista de namespaces com suporte dos metadados do app do Web Receiver.
Cada canal personalizado é definido por um namespace exclusivo e precisa começar com o
prefixo urn:x-cast:
, por exemplo, urn:x-cast:com.example.custom
. É
possível ter vários canais personalizados, cada um com um namespace exclusivo. O
app Web Receiver também pode enviar e receber
mensagens
usando o mesmo namespace.
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); }
Para fornecer a lógica que precisa ser executada quando um canal específico é
conectado ou desconectado, substitua os métodos -[didConnect]
e -[didDisconnect]
se estiver usando
GCKCastChannel
ou
forneça implementações para os métodos -[castChannelDidConnect:]
e
-[castChannelDidDisconnect:]
do
GCKGenericChannelDelegate
se estiver usando GCKGenericChannel
.
Suporte à reprodução automática
Consulte APIs de reprodução automática e enfileiramento.
Modificar a seleção de imagens e o armazenamento em cache
Vários componentes do framework, como a caixa de diálogo do Google Cast, o minicontrole, o controle expandido e o
GCKUIMediaController
se configurados, vão mostrar a arte da mídia transmitida. Os URLs
da arte da imagem geralmente são incluídos no
GCKMediaMetadata
da mídia, mas o app de envio pode ter uma origem alternativa para os URLs.
O protocolo
GCKUIImagePicker
define uma forma de selecionar uma imagem adequada para um determinado uso
e tamanho desejado. Ele tem um único método, -[getImageWithHints:fromMetadata:]
,
que recebe um objeto
GCKUIImageHints
e um objeto
GCKMediaMetadata
como parâmetros e retorna um
objeto GCKImage
como
resultado. O framework fornece uma implementação padrão de
GCKUIImagePicker
, que sempre seleciona a primeira imagem na lista de imagens no
objeto GCKMediaMetadata
, mas o app pode fornecer uma implementação
alternativa definindo a propriedade imagePicker
do
singleton
GCKCastContext
.
O protocolo
GCKUIImageCache
também define uma forma de armazenar em cache imagens que são transferidas por download pelo
framework usando HTTPS. O framework fornece uma implementação padrão de
GCKUIImageCache
, que armazena arquivos de imagem transferidos por download no diretório de
cache do app, mas o app pode fornecer uma implementação alternativa definindo a
propriedade imageCache
do
singleton
GCKCastContext
.
Próximas etapas
Isso conclui os recursos que você pode adicionar ao seu app de envio do iOS. Agora você pode criar um app de envio para outra plataforma (Android ou Web) ou um Web Receiver.