Android용 IMA SDK를 앱에 통합하는 가장 빠르고 간단한 방법은 SDK가 모든 광고 재생 로직을 처리하도록 하고 앱에서는 콘텐츠 동영상 재생에 집중하는 것입니다. 'SDK 소유 광고 재생'이라고 하는 이 접근 방식은 시작하기의 기본 옵션입니다.
그러나 동영상 플레이어에서도 광고를 재생하려는 경우 SDK에서 이를 위한 인터페이스를 제공합니다. 이 접근 방식을 '맞춤 광고 재생'이라고 하며 이 가이드의 나머지 부분에서는 구현에 대해 설명합니다.
기본 요건
- 기본 IMA 통합
현재 기본 IMA 통합이 없는 경우 github의 고급 예제를 출발점으로 참고하시기 바랍니다. 이 예에서는 이미 맞춤 광고 재생을 구현하고 있습니다. 이 가이드의 나머지 부분에서는 IMA 광고를 통한 맞춤 광고 재생에 필요한 기능을 설명합니다.
VideoAdPlayer와의 인터페이스
맞춤 광고를 재생하려면 앱에서
VideoAdPlayer
인터페이스를 구현해야 합니다. 이 인터페이스는 SDK에서 앱에 광고 동영상을 재생하도록 알리는 데 사용됩니다. 또한 앱에서 이 인터페이스를 사용하여 SDK에 주요 동영상 광고 이벤트를 알립니다. 인터페이스를 구현하려면 다음 단계를 따르세요.
VideoAdPlayer 만들기
첫 번째 단계는 requestAds()
에서 익명의 VideoAdPlayer
클래스를 만드는 것입니다.
private VideoAdPlayer videoAdPlayer;
...
private void requestAds(String adTagUrl) {
videoAdPlayer = new VideoAdPlayer() {
};
}
동영상 메서드 추가
다음으로 동영상 플레이어에 광고 동영상을 재생, 로드, 중지, 일시중지하도록 지시하는 메서드를 추가합니다. 플레이어를 해제하고 볼륨을 가져오는 메서드도 여기에 추가합니다.
videoAdPlayer = new VideoAdPlayer() {
@Override
public void playAd() {
if (mIsAdDisplayed) {
videoPlayer.resume();
} else {
isAdDisplayed = true;
videoPlayer.play();
}
}
@Override
public void loadAd(String url) {
isAdDisplayed = true;
videoPlayer.setVideoPath(url);
}
@Override
public void stopAd() {
videoPlayer.stopPlayback();
}
@Override
public void pauseAd() {
videoPlayer.pause();
}
@Override
public void release() {
// any clean up that needs to be done
}
@Override
public int getVolume() {
return videoPlayer.getVolume();
}
};
이러한 메서드는 동영상 플레이어 자체의 유사한 메서드를 둘러싼 얇은 래퍼입니다. 이러한 메서드는 광고 표시 여부를 추적하는 데 사용되는 내부 변수를 설정합니다. 맞춤 광고 재생에서는 동영상 플레이어가 콘텐츠 동영상과 동영상 광고를 모두 재생하므로 현재 표시되고 있는 광고를 추적해야 합니다.
광고 재생 진행률
VideoAdPlayer
인터페이스는 또 다른 인터페이스인 AdProgressProvider
를 구현하므로 개발자는 이 인터페이스도 구현해야 합니다. 이 인터페이스에는 SDK가 광고의 재생 정보를 가져오는 데 사용하는 getAdProgress()
메서드가 하나뿐입니다. 익명의 VideoAdPlayer
클래스에서 다른 메서드 아래에 추가합니다.
VideoAdPlayer videoAdPlayer = new VideoAdPlayer() {
...
@Override
public VideoProgressUpdate getAdProgress() {
if (!isAdDisplayed || videoPlayer.getDuration() <= 0) {
return VideoProgressUpdate.VIDEO_TIME_NOT_READY;
}
return new VideoProgressUpdate(videoPlayer.getCurrentPosition(),
videoPlayer.getDuration());
}
};
getAdProgress()
는 VideoProgressUpdate
유형을 반환하며 이 유형은 동영상의 현재 위치와 길이로 구성되어야 합니다. 플레이어에서
광고를 재생하지 않거나 재생 시간을 사용할 수 없는 경우 다음 예와 같이
VideoProgressUpdate.VIDEO_TIME_NOT_READY
를 반환하도록 합니다.
동영상 콜백 관리
맞춤 광고를 재생하려면 앱에서 SDK에 주요 동영상 이벤트를 알려야 합니다. SDK의 뷰에서 VideoAdPlayer.VideoAdPlayerCallback
인터페이스에서 설명하는 콜백입니다.
콜백 메서드 자체에 들어가기 전에 SDK의 요청 시 콜백을 추가하고 삭제할 수 있어야 합니다. 이 작업은 addCallback()
및 removeCallback()
를 사용하여 VideoAdPlayer
내에서 실행됩니다.
private List<VideoAdPlayerCallback> adCallbacks = new ArrayList<>(1);
VideoAdPlayer videoAdPlayer = new VideoAdPlayer() {
...
@Override
public void addCallback(VideoAdPlayerCallback videoAdPlayerCallback) {
adCallbacks.add(videoAdPlayerCallback);
}
@Override
public void removeCallback(VideoAdPlayerCallback videoAdPlayerCallback) {
adCallbacks.remove(videoAdPlayerCallback);
}
};
이 구현은 List<>.add()
및 remove()
메서드를 호출할 콜백에 List<>
를 사용합니다.
콜백 호출
이제 SDK에서 앱에 콜백을 추가 및 삭제하도록 지시할 수 있으므로 콜백이 호출되는 위치를 정의합니다. 동영상 재생, 일시중지 또는 다시 시작과 같은 중요한 동영상 이벤트가 발생하거나 동영상이 종료되거나 오류가 발생할 때 앱에서 이러한 콜백을 호출해야 합니다.
이렇게 하려면 SampleVideoPlayer
를 확장하여 VideoFragment
에서 추가된 동영상 이벤트의 리스너를 추가합니다. 이러한 광고 콜백을 호출하도록 SampleVideoPlayer
에 별도의 리스너를 만드는 이유는 SampleVideoPlayer
가 광고에 관해 전혀 알지 못하므로 광고를 처리할 수 있는 요소에 동영상 이벤트를 전달해야 하기 때문입니다.
public interface OnVideoEventsListener {
void onPlay();
void onResume();
void onPause();
void onError();
}
private final List<OnVideoEventsListener> onVideoEventsListeners = new ArrayList<>(1);
public void addVideoEventsListener(OnVideoEventsListener listener) {
onVideoEventsListeners.add(listener);
}
시작, 일시중지, 다시 시작
새 enum을 만들어 재생 상태를 추적하고 SampleVideoPlayer
의 start()
및 pause()
메서드에 관한 새 재정의를 추가합니다.
private enum PlaybackState {
STOPPED, PAUSED, PLAYING
}
private PlaybackState playbackState = PlaybackState.STOPPED;
@Override
public void start() {
super.start();
switch (playbackState) {
case STOPPED:
for (OnVideoEventsListener listener : onVideoEventsListeners) {
listener.onPlay();
}
break;
case PAUSED:
for (OnVideoEventsListener listener : onVideoEventsListeners) {
listener.onResume();
}
break;
default:
// Already playing; do nothing.
break;
}
playbackState = PlaybackState.PLAYING;
}
@Override
public void pause() {
super.pause();
playbackState = PlaybackState.PAUSED;
for (OnVideoEventsListener listener : onVideoEventsListeners) {
listener.onPause();
}
}
오류 처리
init()
에서 설정한 동영상 플레이어의 익명 오류 리스너를 재정의합니다.
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
playbackState = PlaybackState.STOPPED;
for (OnVideoEventsListener listener : onVideoEventsListeners) {
listener.onError();
}
// Returning true signals to MediaPlayer that the error was handled.
// This prevents the completion handler from being called.
return true;
}
리스너 구현
VideoFragment
로 돌아가서 SampleVideoPlayer
인스턴스에 익명 OnVideoEventsListener
을 추가합니다.
mVideoPlayer.addVideoEventsListener(new OnVideoEventsListener() {
@Override
public void onPlay() {
if (isAdDisplayed) {
for (VideoAdPlayerCallback callback : adCallbacks) {
callback.onPlay();
}
}
}
@Override
public void onResume() {
if (isAdDisplayed) {
for (VideoAdPlayerCallback callback : adCallbacks) {
callback.onResume();
}
}
}
@Override
public void onPause() {
if (isAdDisplayed) {
for (VideoAdPlayerCallback callback : adCallbacks) {
callback.onPause();
}
}
}
@Override
public void onError() {
if (isAdDisplayed) {
for (VideoAdPlayerCallback callback : adCallbacks) {
callback.onError();
}
}
}
});
광고 동영상이 종료된 경우를 처리하려면 OnVideoCompletedListener
의 onVideoCompleted()
메서드를 변경합니다.
public void onVideoCompleted() {
// Handle completed event for playing post-rolls.
if (isAdDisplayed) {
for (VideoAdPlayerCallback callback : adCallbacks) {
callback.onEnded();
}
} else {
if (adsLoader != null) {
adsLoader.contentComplete();
}
}
콘텐츠 및 광고 간 전환
이 예에서는 동일한 동영상 플레이어 인스턴스를 사용하여 콘텐츠와 광고를 모두 재생하므로 플레이어에서 콘텐츠와 광고 간에 전환하려면 몇 가지 로직을 추가해야 합니다. 그러면 콘텐츠 동영상을 새로고침하고 탐색하여 광고가 시작된 지점으로 돌아갈 수 있습니다. 이렇게 하려면 함수 두 개를 추가합니다.
private int savedContentPosition = 0;
private void pauseContent() {
savedContentPosition = videoPlayer.getCurrentPosition();
videoPlayer.stopPlayback();
isAdDisplayed = true;
}
private void resumeContent() {
videoPlayer.setVideoPath(getString(R.string.content_url));
videoPlayer.seekTo(mSavedContentPosition);
videoPlayer.play();
isAdDisplayed = false;
}
이는 각각 VideoFragment.onAdEvent()
에서 CONTENT_PAUSE_REQUESTED
및 CONTENT_RESUME_REQUESTED
이벤트가 수신될 때 호출됩니다.
case CONTENT_PAUSE_REQUESTED:
pauseContent();
break;
case CONTENT_RESUME_REQUESTED:
resumeContent();
break;
맞춤 광고 재생 사용 설정
마지막 단계는 맞춤 광고 재생을 사용 중임을 SDK에 알리는 것입니다.
다음과 같이 VideoAdPlayer
를 AdDisplayContainer
에 전달하면 됩니다.
adDisplayContainer.setPlayer(videoAdPlayer);
플레이어를 setPlayer()
에 전달해야 합니다. 그러지 않으면 SDK가 SDK 소유 재생을 사용합니다.
이제 모두 완료되었습니다. 지금까지 맞춤 광고 재생을 IMA 구현에 추가하는 데 필요한 모든 단계를 살펴봤습니다. 문제가 발생하면 GitHub의 고급 예와 자체 구현을 비교해 볼 수 있습니다.