Coupures publicitaires
Le SDK expéditeur iOS est compatible avec les coupures publicitaires et les annonces associées dans un flux multimédia donné.
Pour en savoir plus sur leur fonctionnement, consultez la page Présentation des coupures publicitaires Web Receiver.
Bien que les coupures puissent être spécifiées à la fois sur l'émetteur et sur le récepteur, il est recommandé de le faire sur le Web Receiver et le récepteur Android TV afin de maintenir un comportement cohérent sur l'ensemble des plates-formes.
Sur iOS, spécifiez les coupures publicitaires dans une commande de chargement à l'aide de GCKAdBreakClipInfo
et 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]];
Vitesse de lecture variable
Votre application peut afficher l'élément multimédia en cours et en modifier la vitesse de lecture.
Vous pouvez définir la vitesse à l'aide de -[setPlaybackRate:]
ou -[setPlaybackRate:customData:]
de GCKRemoteMediaClient
, accéder au GCKUIPlaybackRateController
à l'aide de playbackRateController
de GCKUIMediaController
et afficher la vitesse de lecture actuelle avec playbackRate
de la GCKUIPlaybackRateController
.
Exemple de code
Les deux fichiers suivants implémentent GCKUIPlaybackRateController
, qui contrôle la vitesse de lecture à l'aide d'une commande segmentée comportant des boutons "normal", "deux fois de vitesse" et "double vitesse" :
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
Ajouter un critère personnalisé
Le framework Cast propose deux méthodes pour créer un canal permettant d'envoyer des messages personnalisés à un récepteur Web:
GCKCastChannel
est destiné à être sous-classé pour implémenter des canaux non triviaux associés à un état.GCKGenericChannel
est fourni comme alternative au sous-classement. Il transmet ses messages reçus à un délégué afin qu'ils puissent être traités ailleurs.
Voici un exemple d'implémentation 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
Un canal peut être enregistré à tout moment. Si la session n'est pas actuellement connectée, le canal est automatiquement connecté lorsque la session elle-même est connectée, à condition que l'espace de noms du canal figure dans la liste des espaces de noms compatibles avec les métadonnées de l'application Web Receiver.
Chaque canal personnalisé est défini par un espace de noms unique et doit commencer par le préfixe urn:x-cast:
(par exemple, urn:x-cast:com.example.custom
). Il est possible d'avoir plusieurs critères personnalisés, chacun avec un espace de noms unique. Elle peut également envoyer et recevoir des messages avec le même espace de noms.
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); }
Pour fournir la logique qui doit s'exécuter lorsqu'un canal particulier est connecté ou déconnecté, remplacez les méthodes -[didConnect]
et -[didDisconnect]
si vous utilisez GCKCastChannel
, ou fournissez des implémentations pour les méthodes -[castChannelDidConnect:]
et -[castChannelDidDisconnect:]
de GCKGenericChannelDelegate
si vous utilisez GCKGenericChannel
.
Compatibilité avec la lecture automatique
Consultez la page API de lecture automatique et de mise en file d'attente.
Remplacer la sélection et la mise en cache des images
Différents composants du framework (à savoir la boîte de dialogue Caster, le mini-contrôleur, la télécommande agrandie et GCKUIMediaController
, le cas échéant) afficheront des illustrations pour le contenu multimédia en cours de diffusion. Les URL de l'illustration de l'image sont généralement incluses dans le fichier GCKMediaMetadata
pour le contenu multimédia, mais l'application émettrice peut disposer d'une autre source pour les URL.
Le protocole GCKUIImagePicker
définit un moyen de sélectionner une image adaptée à une utilisation donnée et à la taille souhaitée. Elle comporte une seule méthode, -[getImageWithHints:fromMetadata:]
, qui accepte un objet GCKUIImageHints
et un objet GCKMediaMetadata
comme paramètres, puis renvoie un objet GCKImage
comme résultat. Le framework fournit une implémentation par défaut de GCKUIImagePicker
, qui sélectionne toujours la première image de la liste des images de l'objet GCKMediaMetadata
, mais l'application peut fournir une autre implémentation en définissant la propriété imagePicker
du singleton GCKCastContext
.
Le protocole GCKUIImageCache
définit également un moyen de mettre en cache les images téléchargées par le framework à l'aide de HTTPS. Le framework fournit une implémentation par défaut de GCKUIImageCache
qui stocke les fichiers image téléchargés dans le répertoire de cache de l'application. Toutefois, l'application peut fournir une autre implémentation en définissant la propriété imageCache
du singleton GCKCastContext
.
Étapes suivantes
Voici les fonctionnalités que vous pouvez ajouter à votre application expéditeur iOS. Vous pouvez désormais créer une application émettrice pour une autre plate-forme (Android ou Web) ou un récepteur Web.