IMA SDK für die dynamische Anzeigenbereitstellung einrichten

Mit IMA SDKs lassen sich Multimedia-Anzeigen ganz einfach in Websites und Apps einbinden. Mit IMA SDKs können Anzeigen von jedem VAST-kompatiblen Ad-Server angefordert und die Anzeigenwiedergabe in Ihren Apps verwaltet werden. Mit IMA DAI SDKs senden Apps eine Streamanfrage für Anzeigen- und Videoinhalte – entweder VOD- oder Liveinhalte. Das SDK gibt dann einen kombinierten Videostream zurück, sodass Sie nicht zwischen Anzeigen- und Inhaltsvideo in Ihrer App wechseln müssen.

Wählen Sie die gewünschte dynamische Anzeigenbereitstellungslösung aus.

Vollständige dynamische Anzeigenbereitstellung

In dieser Anleitung wird gezeigt, wie du das IMA DAI SDK in eine einfache Videoplayer-App einbindest. Wenn du dir eine fertige Beispielintegration ansehen oder ansehen möchtest, lade das BasicExample von GitHub herunter.

IMA DAI – Übersicht

Die Implementierung von IMA-DA umfasst vier Haupt-SDK-Komponenten, wie in diesem Leitfaden gezeigt:

  • IMAAdDisplayContainer – Containerobjekt, das über dem Videowiedergabeelement liegt und die UI-Elemente der Anzeige enthält.
  • IMAAdsLoader: Ein Objekt, das Streams anfordert und Ereignisse verarbeitet, die durch Antwortobjekte von Streamanfragen ausgelöst werden. Sie sollten nur einen Anzeigen-Lademechanismus instanziieren, der während der gesamten Lebensdauer der Anwendung wiederverwendet werden kann.
  • IMAStreamRequest – entweder IMAVODStreamRequest oder IMALiveStreamRequest. Ein Objekt, das eine Streamanfrage definiert. Streamanfragen können sich auf Video-on-Demand- oder Livestreams beziehen. Bei Livestreamanfragen wird ein Asset-Schlüssel angegeben, bei VOD-Anfragen eine CMS-ID und eine Video-ID. Beide Anfragetypen können optional einen API-Schlüssel enthalten, der für den Zugriff auf bestimmte Streams erforderlich ist, sowie einen Google Ad Manager-Netzwerkcode für das IMA SDK, um Anzeigen-IDs gemäß den Google Ad Manager-Einstellungen zu verarbeiten.
  • IMAStreamManager: Ein Objekt, das Streams für die dynamische Anzeigenbereitstellung und Interaktionen mit dem DAI-Backend verarbeitet. Der Streammanager verarbeitet auch Tracking-Pings und leitet Stream- und Anzeigenereignisse an den Publisher weiter.

Vorbereitung

Für den Start ist Folgendes erforderlich:

Außerdem benötigst du die Parameter, mit denen dein Stream vom IMA SDK angefordert wird. Beispiele für Anfrageparameter finden Sie unter Beispielstreams.

Livestream-Parameter
Asset-Schlüssel Der Asset-Schlüssel, mit dem dein Livestream in Google Ad Manager identifiziert wird.
Beispiel: c-rArva4ShKVIAkNfy6HUQ
VOD-Streamparameter
ID der Contentquelle Die ID der Contentquelle aus Google Ad Manager.
Beispiel: 2548831
Video-ID Die Video-ID aus Google Ad Manager.
Beispiel: tears-of-steel
Gemeinsame Parameter (VOD und Livestream)
Netzwerkcode Ihren Google Ad Manager-Netzwerkcode
Beispiel: 21775744923

Neues Xcode-Projekt erstellen

Erstellen Sie in Xcode ein neues iOS-Projekt mit Objective-C namens „BasicExample“.

IMA DAI SDK zum Xcode-Projekt hinzufügen

Du hast drei Möglichkeiten, das IMA DAI SDK zu installieren.

SDK mit CocoaPods installieren (bevorzugt)

CocoaPods ist ein Abhängigkeitsmanager für Xcode-Projekte und die empfohlene Methode zum Installieren des IMA DAI SDK. Weitere Informationen zur Installation oder Verwendung von CocoaPods finden Sie in der CocoaPods-Dokumentation. Nachdem du CocoaPods installiert hast, kannst du das IMA DAI SDK mithilfe der folgenden Anleitung installieren:

  1. Erstellen Sie im selben Verzeichnis wie die Datei BasicExample.xcodeproj eine Textdatei namens Podfile und fügen Sie die folgende Konfiguration hinzu:

    source 'https://github.com/CocoaPods/Specs.git'
    
    platform :ios, '14'
    
    target 'BasicExample' do
      pod 'GoogleAds-IMA-iOS-SDK', '~> 3.26.1'
    end
    

  2. Führen Sie im Verzeichnis mit der Podfile Folgendes aus:

    pod install --repo-update

SDK mit dem Swift Package Manager installieren

Das Interactive Media Ads SDK unterstützt ab Version 3.18.4 den Swift Package Manager. Führen Sie die folgenden Schritte aus, um das Swift-Paket zu importieren.

  1. Installiere in Xcode das IMA DAI SDK-Swift-Paket. Gehe dazu zu File > Add Packages (Datei > Pakete hinzufügen).

  2. Suche in der angezeigten Aufforderung nach dem GitHub-Repository für das IMA DAI SDK Swift-Paket:

    https://github.com/googleads/swift-package-manager-google-interactive-media-ads-ios
    
  3. Wähle die Version des IMA DAI SDK Swift-Pakets aus, die du verwenden möchtest. Für neue Projekte empfehlen wir die Option Bis zur nächsten Hauptversion.

Wenn Sie fertig sind, löst Xcode Ihre Paketabhängigkeiten auf und lädt sie im Hintergrund herunter. Weitere Informationen zum Hinzufügen von Paketabhängigkeiten finden Sie im Artikel von Apple.

SDK manuell herunterladen und installieren

Wenn du weder Swift Package Manager noch CocoaPods verwenden möchtest, kannst du das IMA DAI SDK herunterladen und deinem Projekt manuell hinzufügen.

Einfachen Videoplayer erstellen

Implementieren Sie einen Videoplayer in Ihrem Haupt-View-Controller, indem Sie einen AV-Player in einer UI-Ansicht einbetten. Das IMA SDK verwendet die UI-Ansicht, um Anzeigen-UI-Elemente anzuzeigen.

Objective-C

#import "ViewController.h"

#import <AVKit/AVKit.h>

/// Content URL.
static NSString *const kBackupContentUrl =
    @"http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8";

@interface ViewController ()
/// Play button.
@property(nonatomic, weak) IBOutlet UIButton *playButton;

@property(nonatomic, weak) IBOutlet UIView *videoView;
/// Video player.
@property(nonatomic, strong) AVPlayer *videoPlayer;
@end

@implementation ViewController

- (void)viewDidLoad {
  [super viewDidLoad];
  self.view.backgroundColor = [UIColor blackColor];

  // Load AVPlayer with the path to your content.
  NSURL *contentURL = [NSURL URLWithString:kBackupContentUrl];
  self.videoPlayer = [AVPlayer playerWithURL:contentURL];

  // Create a player layer for the player.
  AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.videoPlayer];

  // Size, position, and display the AVPlayer.
  playerLayer.frame = self.videoView.layer.bounds;
  [self.videoView.layer addSublayer:playerLayer];
}

- (IBAction)onPlayButtonTouch:(id)sender {
  [self.videoPlayer play];
  self.playButton.hidden = YES;
}

@end

Swift

// Copyright 2024 Google LLC. All rights reserved.
//
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under
// the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
// ANY KIND, either express or implied. See the License for the specific language governing
// permissions and limitations under the License.

import AVFoundation
import UIKit

class ViewController: UIViewController {

  /// Content URL.
  static let backupStreamURLString =
    "http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8"

  /// Play button.
  @IBOutlet private weak var playButton: UIButton!

  @IBOutlet private weak var videoView: UIView!
  /// Video player.
  private var videoPlayer: AVPlayer?

  override func viewDidLoad() {
    super.viewDidLoad()

    playButton.layer.zPosition = CGFloat(MAXFLOAT)

    // Load AVPlayer with path to our content.
    // note: this unwrap is safe because the URL is a constant string.
    let contentURL = URL(string: ViewController.backupStreamURLString)!
    videoPlayer = AVPlayer(url: contentURL)

    // Create a player layer for the player.
    let playerLayer = AVPlayerLayer(player: videoPlayer)

    // Size, position, and display the AVPlayer.
    playerLayer.frame = videoView.layer.bounds
    videoView.layer.addSublayer(playerLayer)
  }

  @IBAction func onPlayButtonTouch(_ sender: Any) {
    videoPlayer?.play()
    playButton.isHidden = true
  }
}

Anzeigen-Ladeprogramm initialisieren

Importiere das IMA SDK in deinen View Controller und verwende die Protokolle IMAAdsLoaderDelegate und IMAStreamManagerDelegate, um Ereignisse des Anzeigen-Ladeprogramms und des Stream-Managers zu verarbeiten.

Füge diese privaten Properties hinzu, um wichtige IMA SDK-Komponenten zu speichern:

  • IMAAdsLoader: Verwaltet Streamanfragen während der gesamten Lebensdauer deiner App.
  • IMAAdDisplayContainer: Verwaltet das Einfügen und Verwalten von Elementen der Anzeigenbenutzeroberfläche.
  • IMAAVPlayerVideoDisplay: Vermittelt die Kommunikation zwischen dem IMA SDK und dem Mediaplayer und verarbeitet zeitgesteuerte Metadaten.
  • IMAStreamManager: Verwaltet die Streamwiedergabe und löst anzeigebezogene Ereignisse aus.

Initiiere den Anzeigen-Lademechanismus, den Anzeigen-Displaycontainer und das Videodisplay, nachdem der Videofeed geladen wurde.

Objective-C

@import GoogleInteractiveMediaAds;

// ...

@interface ViewController () <IMAAdsLoaderDelegate, IMAStreamManagerDelegate>
/// The entry point for the IMA DAI SDK to make DAI stream requests.
@property(nonatomic, strong) IMAAdsLoader *adsLoader;
/// The container where the SDK renders each ad's user interface elements and companion slots.
@property(nonatomic, strong) IMAAdDisplayContainer *adDisplayContainer;
/// The reference of your video player for the IMA DAI SDK to monitor playback and handle timed
/// metadata.
@property(nonatomic, strong) IMAAVPlayerVideoDisplay *imaVideoDisplay;
/// References the stream manager from the IMA DAI SDK after successful stream loading.
@property(nonatomic, strong) IMAStreamManager *streamManager;

// ...

@end

@implementation ViewController

- (void)viewDidLoad {
  [super viewDidLoad];

  // ...

  self.adsLoader = [[IMAAdsLoader alloc] initWithSettings:nil];
  self.adsLoader.delegate = self;

  // Create an ad display container for rendering each ad's user interface elements and companion
  // slots.
  self.adDisplayContainer =
      [[IMAAdDisplayContainer alloc] initWithAdContainer:self.videoView
                                          viewController:self
                                          companionSlots:nil];

  // Create an IMAAVPlayerVideoDisplay to give the SDK access to your video player.
  self.imaVideoDisplay = [[IMAAVPlayerVideoDisplay alloc] initWithAVPlayer:self.videoPlayer];
}

Swift

import GoogleInteractiveMediaAds
// ...

class ViewController: UIViewController, IMAAdsLoaderDelegate, IMAStreamManagerDelegate {
  // ...

  /// The entry point for the IMA DAI SDK to make DAI stream requests.
  private var adsLoader: IMAAdsLoader?
  /// The container where the SDK renders each ad's user interface elements and companion slots.
  private var adDisplayContainer: IMAAdDisplayContainer?
  /// The reference of your video player for the IMA DAI SDK to monitor playback and handle timed
  /// metadata.
  private var imaVideoDisplay: IMAAVPlayerVideoDisplay!
  /// References the stream manager from the IMA DAI SDK after successfully loading the DAI stream.
  private var streamManager: IMAStreamManager?

  // ...

  override func viewDidLoad() {
    super.viewDidLoad()

    // ...

    adsLoader = IMAAdsLoader(settings: nil)
    adsLoader?.delegate = self

    // Create an ad display container for rendering ad UI elements and the companion ad.
    adDisplayContainer = IMAAdDisplayContainer(
      adContainer: videoView,
      viewController: self,
      companionSlots: nil)

    // Create an IMAAVPlayerVideoDisplay to give the SDK access to your video player.
    imaVideoDisplay = IMAAVPlayerVideoDisplay(avPlayer: videoPlayer)
  }

Streamanfrage stellen

Wenn ein Nutzer auf die Wiedergabeschaltfläche drückt, sende eine neue Streamanfrage. Verwenden Sie die Klasse IMALiveStreamRequest für Livestreams. Verwende für VOD-Streams die Klasse IMAVODStreamRequest.

Die Streamanfrage erfordert deine Streamparameter sowie eine Referenz auf deinen Anzeigendisplaycontainer und dein Videodisplay.

Objective-C

- (IBAction)onPlayButtonTouch:(id)sender {
  [self requestStream];
  self.playButton.hidden = YES;
}

- (void)requestStream {
  // Create a stream request. Use one of "Live stream request" or "VOD request", depending on your
  // type of stream.
  IMAStreamRequest *request;
  if (kStreamType == StreamTypeLive) {
    // Live stream request. Replace the asset key with your value.
    request = [[IMALiveStreamRequest alloc] initWithAssetKey:kLiveStreamAssetKey
                                                 networkCode:kNetworkCode
                                          adDisplayContainer:self.adDisplayContainer
                                                videoDisplay:self.imaVideoDisplay
                                                 userContext:nil];
  } else {
    // VOD request. Replace the content source ID and video ID with your values.
    request = [[IMAVODStreamRequest alloc] initWithContentSourceID:kVODContentSourceID
                                                           videoID:kVODVideoID
                                                       networkCode:kNetworkCode
                                                adDisplayContainer:self.adDisplayContainer
                                                      videoDisplay:self.imaVideoDisplay
                                                       userContext:nil];
  }
  [self.adsLoader requestStreamWithRequest:request];
}

Swift

@IBAction func onPlayButtonTouch(_ sender: Any) {
  requestStream()
  playButton.isHidden = true
}

func requestStream() {
  // Create a stream request. Use one of "Livestream request" or "VOD request".
  if ViewController.requestType == StreamType.live {
    // Livestream request.
    let request = IMALiveStreamRequest(
      assetKey: ViewController.assetKey,
      networkCode: ViewController.networkCode,
      adDisplayContainer: adDisplayContainer!,
      videoDisplay: imaVideoDisplay,
      userContext: nil)
    adsLoader?.requestStream(with: request)
  } else {
    // VOD stream request.
    let request = IMAVODStreamRequest(
      contentSourceID: ViewController.contentSourceID,
      videoID: ViewController.videoID,
      networkCode: ViewController.networkCode,
      adDisplayContainer: adDisplayContainer!,
      videoDisplay: imaVideoDisplay,
      userContext: nil)
    adsLoader?.requestStream(with: request)
  }
}

Auf Stream-Ladevorgänge warten

Die Klasse IMAAdsLoader ruft die Methoden IMAAdsLoaderDelegate bei erfolgreicher Initialisierung oder Fehler der Streamanfrage auf.

Legen Sie in der Delegating-Methode adsLoadedWithData den Wert für IMAStreamManagerDelegate fest. Stream-Manager initialisieren Bei der Initialisierung startet der Streammanager die Wiedergabe.

Protokollieren Sie den Fehler in der delegierten Methode failedWithErrorData. Optional: Wiedergabe des Sicherungsstreams Best Practices für dynamische Anzeigenbereitstellung

Objective-C

- (void)adsLoader:(IMAAdsLoader *)loader adsLoadedWithData:(IMAAdsLoadedData *)adsLoadedData {
  NSLog(@"Stream created with: %@.", adsLoadedData.streamManager.streamId);
  self.streamManager = adsLoadedData.streamManager;
  self.streamManager.delegate = self;
  [self.streamManager initializeWithAdsRenderingSettings:nil];
}

- (void)adsLoader:(IMAAdsLoader *)loader failedWithErrorData:(IMAAdLoadingErrorData *)adErrorData {
  // Log the error and play the content.
  NSLog(@"AdsLoader error, code:%ld, message: %@", adErrorData.adError.code,
        adErrorData.adError.message);
  [self.videoPlayer play];
}

Swift

func adsLoader(_ loader: IMAAdsLoader, adsLoadedWith adsLoadedData: IMAAdsLoadedData) {
  print("DAI stream loaded. Stream session ID: \(adsLoadedData.streamManager!.streamId!)")
  streamManager = adsLoadedData.streamManager!
  streamManager!.delegate = self
  streamManager!.initialize(with: nil)
}

func adsLoader(_ loader: IMAAdsLoader, failedWith adErrorData: IMAAdLoadingErrorData) {
  print("Error loading DAI stream. Error message: \(adErrorData.adError.message!)")
  // Play the backup stream.
  videoPlayer.play()
}

Auf Anzeigenereignisse warten

Die IMAStreamManager ruft die Methoden IMAStreamManagerDelegate auf, um Streamereignisse und ‑fehler an Ihre Anwendung weiterzuleiten.

Protokollieren Sie in diesem Beispiel die wichtigsten Anzeigenereignisse in der Konsole:

Objective-C

- (void)streamManager:(IMAStreamManager *)streamManager didReceiveAdEvent:(IMAAdEvent *)event {
  NSLog(@"Ad event (%@).", event.typeString);
  switch (event.type) {
    case kIMAAdEvent_STARTED: {
      // Log extended data.
      NSString *extendedAdPodInfo = [[NSString alloc]
          initWithFormat:@"Showing ad %ld/%ld, bumper: %@, title: %@, description: %@, contentType:"
                         @"%@, pod index: %ld, time offset: %lf, max duration: %lf.",
                         (long)event.ad.adPodInfo.adPosition, (long)event.ad.adPodInfo.totalAds,
                         event.ad.adPodInfo.isBumper ? @"YES" : @"NO", event.ad.adTitle,
                         event.ad.adDescription, event.ad.contentType,
                         (long)event.ad.adPodInfo.podIndex, event.ad.adPodInfo.timeOffset,
                         event.ad.adPodInfo.maxDuration];

      NSLog(@"%@", extendedAdPodInfo);
      break;
    }
    case kIMAAdEvent_AD_BREAK_STARTED: {
      NSLog(@"Ad break started");
      break;
    }
    case kIMAAdEvent_AD_BREAK_ENDED: {
      NSLog(@"Ad break ended");
      break;
    }
    case kIMAAdEvent_AD_PERIOD_STARTED: {
      NSLog(@"Ad period started");
      break;
    }
    case kIMAAdEvent_AD_PERIOD_ENDED: {
      NSLog(@"Ad period ended");
      break;
    }
    default:
      break;
  }
}

- (void)streamManager:(IMAStreamManager *)streamManager didReceiveAdError:(IMAAdError *)error {
  NSLog(@"StreamManager error with type: %ld\ncode: %ld\nmessage: %@", error.type, error.code,
        error.message);
  [self.videoPlayer play];
}

Swift

func streamManager(_ streamManager: IMAStreamManager, didReceive event: IMAAdEvent) {
  print("Ad event \(event.typeString).")
  switch event.type {
  case IMAAdEventType.STARTED:
    // Log extended data.
    if let ad = event.ad {
      let extendedAdPodInfo = String(
        format: "Showing ad %zd/%zd, bumper: %@, title: %@, "
          + "description: %@, contentType:%@, pod index: %zd, "
          + "time offset: %lf, max duration: %lf.",
        ad.adPodInfo.adPosition,
        ad.adPodInfo.totalAds,
        ad.adPodInfo.isBumper ? "YES" : "NO",
        ad.adTitle,
        ad.adDescription,
        ad.contentType,
        ad.adPodInfo.podIndex,
        ad.adPodInfo.timeOffset,
        ad.adPodInfo.maxDuration)

      print("\(extendedAdPodInfo)")
    }
    break
  case IMAAdEventType.AD_BREAK_STARTED:
    print("Ad break started.")
    break
  case IMAAdEventType.AD_BREAK_ENDED:
    print("Ad break ended.")
    break
  case IMAAdEventType.AD_PERIOD_STARTED:
    print("Ad period started.")
    break
  case IMAAdEventType.AD_PERIOD_ENDED:
    print("Ad period ended.")
    break
  default:
    break
  }
}

func streamManager(_ streamManager: IMAStreamManager, didReceive error: IMAAdError) {
  print("StreamManager error with type: \(error.type)")
  print("code: \(error.code)")
  print("message: \(error.message ?? "Unknown Error")")
}

Führen Sie Ihre App aus. Wenn die Ausführung erfolgreich war, können Sie Google DAI-Streams mit dem IMA SDK anfordern und wiedergeben. Weitere Informationen zu erweiterten SDK-Funktionen finden Sie in den anderen Anleitungen in der linken Seitenleiste oder in den Beispielen auf GitHub.