PIP 모드 지원

iOS용 미디어 광고 (IMA) SDK

이 가이드는 기존 IMA 구현에 PIP 지원을 추가하려는 IMA 게시자를 위해 작성되었습니다.

기본 요건

앱에 PIP 모드 지원 추가

SDK 버전 3.1.0부터 IMA는 iPad용 Apple의 PIP 모드를 지원합니다. 앱에 PIP 지원을 추가하려면 아래와 같이 몇 가지 설정을 조정하고 몇 가지 새로운 IMA 클래스를 구현해야 합니다.

백그라운드 재생을 허용하도록 설정 업데이트

PIP 모드를 사용하려면 앱에서 백그라운드 미디어 재생을 허용해야 합니다.

  1. 아래와 같이 오디오, AirPlay, PIP 모드백그라운드 모드ON으로 설정합니다.

  2. AVAudioSession 속성을 설정하여 백그라운드 재생을 지원하고 IMASettings에서 백그라운드 재생을 사용 설정합니다.

    ... (void)viewDidLoad {
     [super viewDidLoad];
    
     self.playButton.layer.zPosition = MAXFLOAT;
    
     [[AVAudioSession sharedInstance] setActive:YES error:nil];
     [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
    
     [self setupAdsLoader];
     [self setUpContentPlayer];
    } (void)setupAdsLoader {
     IMASettings *settings = [[IMASettings alloc] init];
     settings.enableBackgroundPlayback = YES;
     self.adsLoader = [[IMAAdsLoader alloc] initWithSettings:settings];
     self.adsLoader.delegate = self;
    }

PIP 모드를 위한 새 iOS 및 IMA 객체 만들기

PIP를 지원하기 위해 Apple은 AVPictureInPictureControllerAVPictureinPictureControllerDelegate 클래스를 추가했습니다. IMA는 IMAPictureInPictureProxy를 추가했습니다. 프로젝트에 이러한 클래스를 통합하려면 코드에 다음 문을 추가하세요.

...
@interface VideoViewController () <AVPictureInPictureControllerDelegate,
                                   IMAAdsLoaderDelegate,
                                   IMAAdsManagerDelegate,
                                   UIAlertViewDelegate>
...
// PiP objects.
@property(nonatomic, strong) IMAPictureInPictureProxy *pictureInPictureProxy;
@property(nonatomic, strong) AVPictureInPictureController *pictureInPictureController;
...
@end

- (void)setUpContentPlayer {
  ...
  self.pictureInPictureProxy =
      [[IMAPictureInPictureProxy alloc] initWithAVPictureInPictureControllerDelegate:self];
  self.pictureInPictureController =
      [[AVPictureInPictureController alloc] initWithPlayerLayer:self.contentPlayerLayer];
  self.pictureInPictureController.delegate = self.pictureInPictureProxy;
}

광고 요청 수정

IMAAVPlayerVideoDisplay라는 새 객체를 하나 더 만들어야 합니다. 이는 IMAAdsRequest 생성자에 전달되며, 동영상이 PIP 모드로 재생될 때 SDK가 PIP 창에 광고를 삽입할 수 있도록 합니다.

...
- (void)requestAdsWithTag:(NSString *)adTagUrl {
  [self logMessage:@"Requesting ads"];
  // Create an ad request with our ad tag, display container, and optional user context.
  IMAAdsRequest *request = [[IMAAdsRequest alloc]
           initWithAdTagUrl:adTagUrl
         adDisplayContainer:[self createAdDisplayContainer]
       avPlayerVideoDisplay:[[IMAAVPlayerVideoDisplay alloc] initWithAVPlayer:self.contentPlayer]
      pictureInPictureProxy:self.pictureInPictureProxy
                userContext:nil];
  [self.adsLoader requestAdsWithRequest:request];
}

광고 시작

IMA SDK 광고는 PIP 모드에서 시작할 수 없습니다. 따라서 동영상이 표준 재생 모드에 있을 때만 [adsManager start]를 호출해야 합니다.

...
- (void)adsManager:(IMAAdsManager *)adsManager didReceiveAdEvent:(IMAAdEvent *)event {
  [self logMessage:@"AdsManager event (%s).", AdEventNames[event.type]];
  // When the SDK notified you that ads have been loaded, play them.
  switch (event.type) {
    case kIMAAdEvent_LOADED:
      if (![self.pictureInPictureController isPictureInPictureActive]) {
        [adsManager start];
      }
      break;
    ...
    default:
      break;
  }
}

PIP 모드로 들어가기

AVPlayerViewController 없이 AVPlayer를 사용하는 경우 자체 PIP 버튼을 추가해야 합니다. 고급 샘플에서 다음과 같이 구현했습니다.

- (IBAction)onPipButtonClicked:(id)sender {
  if ([self.pictureInPictureController isPictureInPictureActive]) {
    [self.pictureInPictureController stopPictureInPicture];
  } else {
    [self.pictureInPictureController startPictureInPicture];
  }
}

FAQ

동영상이 PIP 모드일 때 광고를 시작하려면 어떻게 해야 하나요?
동영상이 PIP 모드일 때는 광고를 시작할 수 없습니다. 광고는 일반 재생 모드에서만 시작할 수 있습니다.
기존 PIP 통합에서 self.pictureInPictureController.delegate를 자체 클래스로 설정해야 합니다. PIP에서 IMA 광고를 구현하면서도 대리인이 되려면 어떻게 해야 하나요?
IMA SDK는 PIP 모드에서 광고 재생을 사용 설정하기 위해 AVPictureinPictureControllerDelegate 메시지도 수신해야 합니다. 이러한 이유로 AVPictureinPictureController의 대리자를 IMAPictureInPicturyProxy 인스턴스로 설정해야 합니다. 이 프록시 객체는 모든 AVPictureinPictureControllerDelegate 메시지를 앱에 전달할 뿐만 아니라 PIP 모드 지원을 사용 설정하기 위해 IMA에 대한 호출도 전달합니다. AVPlayerLayer에 대한 로컬 핸들도 유지해야 합니다.