Phát quảng cáo tùy chỉnh bằng SDK IMA cho Android

Trong IMA phiên bản 3.30.0 trở xuống, SDK IMA có thể xử lý tất cả logic phát quảng cáo, còn ứng dụng của bạn tập trung vào việc phát video nội dung. Phương pháp này được gọi là "Lượt phát quảng cáo do SDK sở hữu".

Nếu bạn muốn phát quảng cáo trong trình phát video, SDK sẽ cung cấp một giao diện cho việc đó. Chúng tôi gọi phương pháp này là "lựa chọn tuỳ chỉnh phát quảng cáo" và phần còn lại của hướng dẫn này sẽ trình bày về 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 xem xét Ví dụ nâng cao trên github làm điểm bắt đầu nếu bạn hiện không có IMA cơ bản tích hợp. 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 lại quảng cáo tuỳ chỉnh với Quảng cáo IMA.

Giao diện với VideoAdPlayer

Tính năng phát quảng cáo tùy chỉnh yêu cầu ứng dụng của bạn phải triển khai VideoAdPlayer . Giao diện này được SDK sử dụng để thông báo cho ứng dụng của bạn phát quảng cáo video. Ứng dụng của bạn cũng sử dụng giao diện này để thông báo cho SDK về quảng cáo dạng video chính các sự kiện. 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 của bạn phát, tải, dừng và tạm dừng quảng cáo video. Chúng ta cũng thêm các phương thức để huỷ bỏ trình phát và nhận â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 phương thức tương tự của trình phát video của bạn . Lưu ý rằng các phương thức này đặt một biến nội bộ được sử dụng để theo dõi liệu quảng cáo có được hiển thị hay không. Trong tính năng phát quảng cáo tuỳ chỉnh, trình phát video phát cả quảng cáo dạng video và quảng cáo dạng video, vì vậy, bạn cần phải bản nhạc này hiện đang được 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, AdProgressProvider, vì vậy, bạn cũng phải triển khai nó. Chỉ có một phương thức getAdProgress() mà SDK sử dụng để lấy thông tin về lượt phát cho quảng cáo. Thêm vào 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ề một loại VideoProgressUpdate phải bao gồm vị trí hiện tại và thời lượng của video. Nếu trình phát hiện không phát quảng cáo hoặc thời lượng không có sẵn, quảng cáo sẽ được trả lại VideoProgressUpdate.VIDEO_TIME_NOT_READY như trong ví dụ.

Quản lý lệnh gọi lại video

Phát lại quảng cáo tùy chỉnh yêu cầu ứng dụng của bạn thông báo cho SDK về sự kiện video. Theo góc nhìn của SDK, đây là những lệnh gọi lại được mô tả bằng giao diện VideoAdPlayer.VideoAdPlayerCallback. Trước khi tìm hiểu về các phương thức gọi lại, bạn cần có thể thêm và xoá các lệnh gọi lại theo yêu cầu của SDK. Đây là được thực hiện bên trong VideoAdPlayer bằng addCallback()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);
        }
};

Phương thức triển khai này sử dụng List<> cho các lệnh gọi lại cần gọi phương thức List<>.add()remove().

Gọi các lệnh gọi lại

Giờ đây, SDK đã có cách thức để yêu cầu ứng dụng của bạn thêm và xoá các lệnh gọi lại, xác định các vị trí gọi lệnh gọi lại. Ứng dụng của bạn cần gọi các 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 một video hay 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ó một trình nghe cho sự kiện video được thêm từ VideoFragment. Lý do thực hiện một trình nghe riêng biệt 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, nên bạn phải chuyển tiếp các sự kiện video đến nội dung nào đó có thể giải quyết 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ơ chế ghi đè mới cho phương thức start()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 đặt 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 rồi thêm một OnVideoEventsListener ẩn danh cho 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ả hai 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. Sau đó, bạn có thể tải lại và tua video nội dung để quay lại thời điểm quảng cáo bắt đầu. Thêm hai để 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 biến này được gọi khi CONTENT_PAUSE_REQUESTED và Đã nhận được CONTENT_RESUME_REQUESTED sự kiện, theo VideoFragment.onAdEvent(), tương ứng:

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

Bật phát lại quảng cáo tùy chỉnh

Bước cuối cùng là cho SDK biết rằng bạn đang sử dụng tính năng 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 đến AdDisplayContainer:

adDisplayContainer.setPlayer(videoAdPlayer);

Bạn cần truyền trình phát của mình đến setPlayer(). Nếu không, giá trị SDK sử dụng tính năng 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 tính năng phát quảng cáo tuỳ chỉnh vào Triển khai IMA. Bạn có thể so sánh cách triển khai của riêng mình với Ví dụ nâng cao trên github nếu bạn gặp sự cố.