การเล่นโฆษณาที่กำหนดเองด้วย IMA SDK สำหรับ Android

วิธีที่เร็วและง่ายที่สุดในการผสานรวม IMA SDK สำหรับ Android ลงในแอปคือการให้ SDK จัดการตรรกะการเล่นโฆษณาทั้งหมด ในขณะที่แอปจะมุ่งเน้นที่การเล่นวิดีโอเนื้อหา แนวทางนี้เรียกว่า "การเล่นโฆษณาที่ SDK เป็นเจ้าของ" เป็นตัวเลือกเริ่มต้นในเริ่มต้นใช้งาน

อย่างไรก็ตาม หากคุณต้องการเล่นโฆษณาในโปรแกรมเล่นวิดีโอด้วย SDK จะมีอินเทอร์เฟซให้ เราเรียกวิธีนี้ว่า "การเล่นโฆษณาที่กำหนดเอง" และส่วนที่เหลือของคู่มือนี้จะพูดถึงการใช้งาน

ข้อกำหนดเบื้องต้น

  • การผสานรวม IMA พื้นฐาน

เราขอแนะนำให้คุณดูตัวอย่างขั้นสูงใน GitHub เป็นจุดเริ่มต้น หากคุณยังไม่มีการผสานรวม IMA พื้นฐาน ตัวอย่างนี้ใช้การเล่นโฆษณาที่กำหนดเองอยู่แล้ว ส่วนที่เหลือของคู่มือนี้จะอธิบายฟีเจอร์ที่จำเป็นสำหรับการเล่นโฆษณาที่กำหนดเองด้วยโฆษณา IMA

อินเทอร์เฟซที่มี VideoAdPlayer

โดยแอปของคุณต้องใช้อินเทอร์เฟซ VideoAdPlayer ในการเล่นวิดีโอโฆษณาที่กำหนดเอง SDK จะใช้อินเทอร์เฟซนี้เพื่อแจ้งแอปของคุณให้เล่นวิดีโอโฆษณา แอปของคุณยังใช้อินเทอร์เฟซนี้เพื่อแจ้ง 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();
        }
};

วิธีการเหล่านี้จะเป็น Wrapper แบบบางๆ ที่มีเมธอดที่คล้ายกันของโปรแกรมเล่นวิดีโอ โปรดทราบว่าเมธอดเหล่านี้จะกำหนดตัวแปรภายในที่ใช้ติดตามว่ามีการแสดงโฆษณาหรือไม่ ในการเล่นโฆษณาที่กำหนดเอง โปรแกรมเล่นวิดีโอจะเล่นทั้งโฆษณาวิดีโอของเนื้อหาและโฆษณาวิดีโอ คุณจึงต้องติดตามโฆษณาที่แสดงอยู่

ความคืบหน้าในการเล่นโฆษณา

อินเทอร์เฟซ 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 ได้ การดำเนินการนี้เสร็จสิ้นภายใน VideoAdPlayer โดยใช้ 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);
        }
};

การติดตั้งใช้งานนี้ใช้ List<> สำหรับโค้ดเรียกกลับที่จะเรียกใช้เมธอด List<>.add() และ remove()

โทรหาหมายเลขติดต่อกลับ

ตอนนี้ SDK มีวิธีบอกให้แอปเพิ่มและนำโค้ดเรียกกลับออกแล้ว ให้กำหนดตำแหน่งที่จะเรียกใช้โค้ดเรียกกลับ แอปของคุณจะต้องเรียกใช้โค้ดเรียกกลับเหล่านี้เมื่อมีเหตุการณ์สำคัญเกิดขึ้นกับวิดีโอ เช่น การเล่น หยุดชั่วคราว หรือทำให้วิดีโอเล่นต่อ หรือเมื่อวิดีโอเล่นจบหรือพบข้อผิดพลาด

ในการดำเนินการดังกล่าว ให้ขยาย SampleVideoPlayer เพื่อให้มี Listener สำหรับเหตุการณ์วิดีโอเหล่านี้ที่เพิ่มจาก VideoFragment เหตุผลที่ต้องสร้าง Listener แยกต่างหากใน 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 ใหม่เพื่อติดตามสถานะการเล่น และเพิ่มการลบล้างใหม่สำหรับเมธอด start() และ pause() ใน 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();
    }
}

จัดการข้อผิดพลาด

ลบล้าง Listener ข้อผิดพลาดแบบไม่ระบุตัวตนของโปรแกรมเล่นวิดีโอที่คุณตั้งค่าไว้ใน 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;
}

ติดตั้งใช้งาน Listener

กลับไปที่ 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();
            }
        }
    }
});

เปลี่ยนเมธอด onVideoCompleted() ของ OnVideoCompletedListener เพื่อจัดการกรณีที่วิดีโอโฆษณาจบลง ดังนี้

public void onVideoCompleted() {
    // Handle completed event for playing post-rolls.
    if (isAdDisplayed) {
        for (VideoAdPlayerCallback callback : adCallbacks) {
            callback.onEnded();
        }
    } else {
        if (adsLoader != null) {
            adsLoader.contentComplete();
    }
}

สลับระหว่างเนื้อหาและโฆษณา

ตัวอย่างนี้ใช้โปรแกรมเล่นวิดีโออินสแตนซ์เดียวกันเพื่อเล่นทั้งเนื้อหาและโฆษณา คุณจึงต้องเพิ่มตรรกะในการสลับระหว่างเนื้อหาและโฆษณาในโปรแกรมเล่นของคุณ จากนั้นคุณจะสามารถโหลดซ้ำและค้นหา วิดีโอเนื้อหาเพื่อกลับมายังจุดที่เริ่มโฆษณา เพิ่ม 2 ฟังก์ชันดังนี้

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 คุณเปรียบเทียบการติดตั้งใช้งานของคุณเองกับตัวอย่างขั้นสูงใน GitHub ได้หากพบปัญหา