Ajouter des fonctionnalités avancées à votre application iOS

Coupures publicitaires

Le SDK de l'émetteur iOS est compatible avec les coupures publicitaires et les annonces associées dans un flux multimédia donné.

Pour en savoir plus sur le fonctionnement des coupures publicitaires, consultez la présentation des coupures publicitaires du Web Receiver.

Bien que les coupures puissent être spécifiées à la fois sur l'émetteur et le récepteur, il est recommandé de les spécifier sur le récepteur Web et le récepteur Android TV afin de maintenir un comportement cohérent sur les plates-formes.

Sur iOS, spécifiez les coupures publicitaires dans une commande de chargement à l'aide de GCKAdBreakClipInfo et de GCKAdBreakInfo:

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]];

Vitesse de lecture variable

Votre application peut afficher et modifier la vitesse de lecture de l'élément multimédia en cours. Vous pouvez définir la vitesse à l'aide de -[setPlaybackRate:] ou de -[setPlaybackRate:customData:] de GCKRemoteMediaClient, accéder à GCKUIPlaybackRateController à l'aide de playbackRateController de GCKUIMediaController et afficher la vitesse de lecture actuelle à l'aide de playbackRate de 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 avec des boutons "normal", "demi-vitesse" et "double vitesse" :

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

Ajouter un canal personnalisé

Le framework Cast propose deux façons de créer un canal pour envoyer des messages personnalisés à un récepteur Web:

  1. GCKCastChannel est destiné à être sous-classé pour implémenter des canaux non triviaux associés à un état.
  2. GCKGenericChannel est fourni comme alternative à la sous-classe. Il transmet les messages reçus à un délégué afin qu'ils puissent être traités ailleurs.

Voici un exemple d'implémentation de 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

Une chaîne peut être enregistrée à tout moment. Si la session n'est pas actuellement connectée, la chaîne devient automatiquement connectée lorsque la session elle-même est connectée, à condition que l'espace de noms de la chaîne figure dans la liste des espaces de noms compatibles des 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. Vous pouvez avoir plusieurs canaux personnalisés, chacun avec un espace de noms unique. L'application Web Receiver peut également envoyer et recevoir des messages à l'aide du même espace de noms.

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);
}

Pour fournir la logique à 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.

Prendre en charge la lecture automatique

Consultez la section API de lecture automatique et de mise en file d'attente.

Remplacer la sélection et la mise en cache des images

Divers composants du framework (à savoir la boîte de dialogue Cast, le mini-contrôleur, le contrôleur développé et le GCKUIMediaController, le cas échéant) affichent l'illustration du contenu multimédia en cours de diffusion. Les URL des illustrations sont généralement incluses dans le GCKMediaMetadata pour les contenus multimédias, mais l'application d'envoi peut disposer d'une autre source pour les URL.

Le protocole GCKUIImagePicker définit un moyen de sélectionner une image appropriée pour une utilisation et une taille données. Il ne comporte qu'une seule méthode, -[getImageWithHints:fromMetadata:], qui reçoit un objet GCKUIImageHints et un objet GCKMediaMetadata comme paramètres, et renvoie un objet GCKImage en résultat. Le framework fournit une implémentation par défaut de GCKUIImagePicker qui sélectionne toujours la première image de la liste d'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

Vous avez terminé d'ajouter des fonctionnalités à votre application d'envoi iOS. Vous pouvez maintenant créer une application d'envoi pour une autre plate-forme (Android ou Web) ou un récepteur Web.