پخش آگهی سفارشی با IMA SDK برای Android

سریع‌ترین و ساده‌ترین راه برای ادغام IMA SDK برای Android در برنامه شما این است که SDK همه منطق پخش آگهی را کنترل کند، در حالی که برنامه شما بر پخش ویدیوی محتوا متمرکز است. این رویکرد که "بازپخش تبلیغات متعلق به SDK" نامیده می شود، گزینه پیش فرض در Get Started است.

با این حال، اگر می خواهید تبلیغات را در پخش کننده ویدیوی خود نیز پخش کنید، SDK یک رابط برای آن فراهم می کند. ما از این رویکرد به عنوان "بازپخش تبلیغات سفارشی" یاد می کنیم و بقیه این راهنما به اجرای آن می پردازد.

پیش نیازها

  • یکپارچگی اساسی IMA.

اگر در حال حاضر یکپارچه سازی اولیه IMA ندارید، توصیه می کنیم به مثال پیشرفته در github به عنوان نقطه شروع نگاه کنید. این مثال از قبل پخش آگهی سفارشی را پیاده سازی می کند. بقیه این راهنما ویژگی های لازم برای پخش آگهی سفارشی با تبلیغات 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();
        }
};

این روش‌ها پوشش‌های نازکی در اطراف روش‌های مشابه خود پخش‌کننده ویدیوی شما هستند. توجه داشته باشید که این روش‌ها یک متغیر داخلی را تنظیم می‌کنند که برای پیگیری نمایش‌دادن یک تبلیغ استفاده می‌شود. در پخش آگهی سفارشی، پخش‌کننده ویدیو هم محتوای ویدیویی و هم تبلیغات ویدیویی را پخش می‌کند، بنابراین باید مواردی که در حال حاضر نمایش داده می‌شوند را پیگیری کنید.

پیشرفت پخش آگهی

رابط 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 برگرداند.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 گسترش دهید تا شنونده ای برای این رویدادهای ویدیویی که از 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 جدید برای پیگیری وضعیت پخش ایجاد کنید و برای متدهای 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();
    }
}

رسیدگی به خطاها

شنونده خطای ناشناس پخش کننده ویدیو را که در 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();
            }
        }
    }
});

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

بین محتوا و تبلیغات جابجا شوید

این مثال از همان نمونه پخش‌کننده ویدیو برای پخش محتوا و تبلیغات استفاده می‌کند، بنابراین باید منطقی برای جابه‌جایی بین محتوا و تبلیغات در پخش‌کننده خود اضافه کنید. سپس می توانید بارگیری مجدد کنید و محتوای ویدیو را جستجو کنید تا به نقطه شروع تبلیغ بازگردید. برای این کار دو تابع اضافه کنید:

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 مقایسه کنید.