使用 Android 版 IMA SDK 自訂廣告播放

在 IMA 3.30.0 以下版本中,IMA SDK 可以處理所有的廣告播放邏輯, 而應用程式則著重於播放內容影片。這個方法就稱為 「SDK 自有廣告播放」。

如果您想在影片播放器中播放廣告,可以使用 SDK 提供的介面我們將這個做法稱為「自訂 廣告播放」本指南的其餘部分將介紹實作方式

必要條件

  • 基本的 IMA 整合。

建議您參閱 進階範例 。如果您目前沒有基本的 IMA 擷取及準備資料、針對特定領域進行預先訓練 調整指示、離線評估和整合這個例子已導入自訂廣告播放功能。餘數 本指南將說明自訂廣告播放方式所需的功能 。

與 VideoAdPlayer 介面

如要自訂廣告播放功能,您的應用程式必須導入 VideoAdPlayer敬上 存取 APISDK 會使用這個介面通知您的應用程式播放廣告 影片。應用程式也會使用這個介面通知主要影片廣告的 SDK 事件。請按照下列步驟實作介面。

建立 VideoAdPlayer

第一步是建立匿名的 VideoAdPlayer 類別 在 requestAds()

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,因此您必須一併實作。僅有 一種方法,也就是 getAdProgress(),SDK 用來取得 廣告的播放資訊。新增至匿名 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<> 處理要呼叫的回呼 List<>.add()remove() 方法。

呼叫回呼

您現在可透過 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);
}

開始、暫停及繼續

建立新的列舉來追蹤播放狀態,並新增覆寫設定 針對 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 並新增匿名 OnVideoEventsListener 傳送至 SampleVideoPlayer 執行個體:

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

變更 OnVideoCompletedListeneronVideoCompleted() 方法 處理廣告影片播放完畢的情況:

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

系統會在 CONTENT_PAUSE_REQUESTED 和 收到 CONTENT_RESUME_REQUESTED 個事件,地區: VideoFragment.onAdEvent()

case CONTENT_PAUSE_REQUESTED:
    pauseContent();
    break;
case CONTENT_RESUME_REQUESTED:
    resumeContent();
    break;

啟用自訂廣告播放功能

最後一步是向 SDK 說明您正在使用自訂廣告播放功能。 方法是將 VideoAdPlayer 傳遞至 AdDisplayContainer

adDisplayContainer.setPlayer(videoAdPlayer);

您必須將播放器傳遞至 setPlayer()。否則, SDK 使用 SDK 擁有的播放方式。

就是這麼簡單!這些是將自訂廣告播放加入 IMA 導入。您可以將自己的實作項目與 進階範例