Cách nhanh nhất và đơn giản nhất để tích hợp SDK IMA dành cho Android vào ứng dụng là yêu cầu SDK xử lý tất cả logic phát quảng cáo, trong khi ứng dụng tập trung vào việc phát video nội dung. Phương pháp này có tên là "phát quảng cáo do SDK sở hữu" là phương án mặc định trong bài viết Bắt đầu.
Tuy nhiên, nếu bạn cũng muốn phát quảng cáo trong trình phát video, SDK sẽ cung cấp một giao diện để làm việc đó. Chúng tôi gọi phương pháp này là "phát quảng cáo tùy chỉnh" và phần còn lại của hướng dẫn này trình bày cách triển khai.
Điều kiện tiên quyết
- Tích hợp IMA cơ bản.
Bạn nên tham khảo Ví dụ nâng cao trên GitHub nếu bạn hiện chưa tích hợp IMA cơ bản. Ví dụ này đã triển khai tính năng phát quảng cáo tuỳ chỉnh. Phần còn lại của hướng dẫn này sẽ mô tả các tính năng cần thiết để phát quảng cáo tuỳ chỉnh bằng quảng cáo IMA.
Giao diện với VideoAdPlayer
Tính năng phát quảng cáo tuỳ chỉnh yêu cầu ứng dụng của bạn phải triển khai giao diện
VideoAdPlayer
. SDK sử dụng giao diện này để thông báo cho ứng dụng của bạn phát video quảng cáo. Ứng dụng của bạn cũng sử dụng giao diện này để thông báo cho SDK về các sự kiện quảng cáo dạng video chính. Hãy làm theo các bước sau để triển khai giao diện.
Tạo VideoAdPlayer
Bước đầu tiên là tạo một lớp VideoAdPlayer
ẩn danh trong requestAds()
:
private VideoAdPlayer videoAdPlayer;
...
private void requestAds(String adTagUrl) {
videoAdPlayer = new VideoAdPlayer() {
};
}
Thêm phương thức video
Tiếp theo, hãy thêm các phương thức yêu cầu trình phát video phát, tải, dừng và tạm dừng video quảng cáo. Chúng ta cũng thêm các phương thức để phát hành trình phát và lấy âm lượng tại đây:
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();
}
};
Các phương thức này là các trình bao bọc mỏng xung quanh các phương thức tương tự của chính trình phát video. Lưu ý rằng các phương thức này sẽ đặt một biến nội bộ dùng để theo dõi xem quảng cáo có hiển thị hay không. Trong chế độ phát quảng cáo tuỳ chỉnh, trình phát video phát cả quảng cáo nội dung dạng video và quảng cáo dạng video. Vì vậy, bạn cần theo dõi quảng cáo nào đang hiển thị.
Tiến trình phát quảng cáo
Giao diện VideoAdPlayer
triển khai một giao diện khác là AdProgressProvider
, vì vậy, bạn cũng phải triển khai giao diện này. API này chỉ có
một phương thức là getAdProgress()
. Phương thức này được SDK sử dụng để lấy
thông tin phát lại cho quảng cáo. Thêm mã này vào lớp VideoAdPlayer
ẩn danh của bạn, bên dưới các phương thức khác:
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()
trả về loại VideoProgressUpdate
phải bao gồm vị trí và thời lượng hiện tại của video. Nếu trình phát
không phát quảng cáo hoặc không có thời lượng, hãy yêu cầu trình phát trả về
VideoProgressUpdate.VIDEO_TIME_NOT_READY
như trong ví dụ.
Quản lý các lệnh gọi lại video
Để phát quảng cáo tuỳ chỉnh, ứng dụng của bạn phải thông báo cho SDK về các sự kiện video chính. Từ khung hiển thị của SDK, đây là các lệnh gọi lại do giao diện VideoAdPlayer.VideoAdPlayerCallback
mô tả.
Trước khi bắt đầu sử dụng các phương thức gọi lại, bạn cần có khả năng thêm và xoá các phương thức gọi lại theo yêu cầu của SDK. Bạn có thể thực hiện việc này bên trong VideoAdPlayer
bằng cách sử dụng addCallback()
và removeCallback()
:
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);
}
};
Cách triển khai này sử dụng List<>
cho các lệnh gọi lại để gọi phương thức List<>.add()
và remove()
.
Gọi các lệnh gọi lại
Giờ đây, SDK đã có cách để yêu cầu ứng dụng của bạn thêm và xoá lệnh gọi lại, hãy xác định vị trí mà lệnh gọi lại được gọi. Ứng dụng cần gọi những lệnh gọi lại này khi các sự kiện video lớn xảy ra, chẳng hạn như phát, tạm dừng hoặc tiếp tục phát video, hoặc khi một video kết thúc hoặc gặp lỗi.
Để thực hiện việc này, hãy mở rộng SampleVideoPlayer
để có trình nghe cho các sự kiện video này được thêm từ VideoFragment
. Lý do bạn nên tạo
một trình nghe riêng trong SampleVideoPlayer
để gọi các lệnh gọi lại quảng cáo này
là vì SampleVideoPlayer
không biết gì về quảng cáo,
vì vậy, bạn phải chuyển tiếp các sự kiện video của trình nghe này đến một trình nghe có thể xử lý quảng cáo.
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);
}
Bắt đầu, tạm dừng và tiếp tục
Tạo một enum mới để theo dõi trạng thái phát và thêm các cơ chế ghi đè mới cho phương thức start()
và pause()
trong SampleVideoPlayer
:
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();
}
}
Xử lý lỗi
Ghi đè trình nghe lỗi ẩn danh của trình phát video mà bạn đã thiết lập trong 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;
}
Triển khai trình nghe
Quay lại VideoFragment
và thêm một OnVideoEventsListener
ẩn danh vào thực thể 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();
}
}
}
});
Thay đổi phương thức onVideoCompleted()
của OnVideoCompletedListener
để xử lý trường hợp video quảng cáo đã kết thúc:
public void onVideoCompleted() {
// Handle completed event for playing post-rolls.
if (isAdDisplayed) {
for (VideoAdPlayerCallback callback : adCallbacks) {
callback.onEnded();
}
} else {
if (adsLoader != null) {
adsLoader.contentComplete();
}
}
Chuyển đổi giữa nội dung và quảng cáo
Ví dụ này sử dụng cùng một phiên bản của trình phát video để phát cả nội dung và quảng cáo. Vì vậy, bạn cần thêm một số logic để chuyển đổi giữa nội dung và quảng cáo trong trình phát của mình. Sau đó, bạn có thể tải lại và tìm video nội dung để trở về thời điểm bắt đầu quảng cáo. Thêm 2 hàm để thực hiện việc này:
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;
}
Các lệnh này được gọi khi hệ thống nhận được các sự kiện CONTENT_PAUSE_REQUESTED
và CONTENT_RESUME_REQUESTED
lần lượt trong VideoFragment.onAdEvent()
:
case CONTENT_PAUSE_REQUESTED:
pauseContent();
break;
case CONTENT_RESUME_REQUESTED:
resumeContent();
break;
Bật tính năng phát quảng cáo tuỳ chỉnh
Bước cuối cùng là cho SDK biết rằng bạn đang sử dụng chế độ phát quảng cáo tuỳ chỉnh.
Bạn có thể thực hiện việc này bằng cách truyền VideoAdPlayer
vào AdDisplayContainer
:
adDisplayContainer.setPlayer(videoAdPlayer);
Bạn cần phải chuyển trình phát của mình cho setPlayer()
. Nếu không, SDK sẽ sử dụng chế độ phát do SDK sở hữu.
Vậy là xong. Đó là tất cả các bước cần thiết để thêm chế độ phát quảng cáo tuỳ chỉnh vào hoạt động triển khai IMA của bạn. Bạn có thể so sánh cách triển khai của chính mình với Ví dụ nâng cao trên GitHub nếu gặp vấn đề.