IMA SDK ช่วยให้การผสานรวมโฆษณามัลติมีเดียในเว็บไซต์และแอปของคุณทำได้โดยง่าย IMA SDK สามารถ ส่งคำขอโฆษณาจาก เซิร์ฟเวอร์โฆษณาที่ปฏิบัติตามข้อกำหนดของ VAST และจัดการการเล่นโฆษณาในแอปของคุณ ด้วย IMA DAI SDK แอปจะสร้าง คำขอสตรีมสำหรับโฆษณาและวิดีโอเนื้อหา ไม่ว่าจะเป็น VOD หรือเนื้อหาสด จากนั้น SDK จะแสดงผลลัพธ์ สตรีมวิดีโอแบบรวม คุณจึงไม่ต้องคอยจัดการสลับเปลี่ยนระหว่างโฆษณากับเนื้อหาวิดีโอ ภายในแอป
เลือกโซลูชัน DAI ที่คุณสนใจ
DAI บริการเต็มรูปแบบ
คู่มือนี้สาธิตวิธีผสานรวม IMA DAI SDK เข้ากับโปรแกรมเล่นวิดีโอแบบง่าย แอป หากคุณต้องการดูหรือติดตามไปพร้อมกับตัวอย่างที่สมบูรณ์ การผสานรวม ให้ดาวน์โหลด BasicExample จาก GitHub
ภาพรวม IMA DAI
การติดตั้งใช้งาน IMA DAI เกี่ยวข้องกับองค์ประกอบหลักของ SDK 4 อย่างดังที่แสดงใน คู่มือ
StreamDisplayContainer
: ออบเจ็กต์คอนเทนเนอร์ที่อยู่ด้านบนขององค์ประกอบการเล่นวิดีโอและยังมีองค์ประกอบ UI โฆษณาอยู่AdsLoader
: ออบเจ็กต์ที่ขอสตรีมและจัดการเหตุการณ์ที่ทริกเกอร์โดยออบเจ็กต์การตอบกลับของคำขอสตรีม คุณควรสร้างอินสแตนซ์ตัวโหลดโฆษณาเพียงรายการเดียวเท่านั้น ซึ่งสามารถนำไปใช้ซ้ำได้ตลอดอายุการใช้งาน แอปพลิเคชันStreamRequest
: ออบเจ็กต์ที่กำหนดคำขอสตรีม คำขอสตรีมจะเป็นวิดีโอออนดีมานด์หรือแบบสดก็ได้ สตรีม คำขอระบุรหัสเนื้อหา รวมทั้งคีย์ API หรือโทเค็นการตรวจสอบสิทธิ์ และอื่นๆ พารามิเตอร์StreamManager
: ออบเจ็กต์ที่จัดการสตรีมการแทรกโฆษณาแบบไดนามิกและการโต้ตอบกับแบ็กเอนด์ DAI เครื่องมือจัดการสตรีมยังจัดการคําสั่ง ping ในการติดตาม รวมถึงส่งต่อเหตุการณ์ของสตรีมและโฆษณาไปยัง ผู้เผยแพร่โฆษณา
ข้อกำหนดเบื้องต้น
- Android Studio
- ตัวอย่างแอปโปรแกรมเล่นวิดีโอสำหรับการผสานรวม SDK
ดาวน์โหลดและเรียกใช้แอปโปรแกรมเล่นวิดีโอตัวอย่าง
แอปตัวอย่างนี้มีโปรแกรมเล่นวิดีโอที่ใช้งานได้ซึ่งเล่นวิดีโอ HLS ใช้เป็นชื่อ ซึ่งเป็นจุดเริ่มต้นในการผสานรวมความสามารถ DAI ของ IMA DAI SDK
ดาวน์โหลดวิดีโอเพลเยอร์ตัวอย่าง แอป และ แตกข้อมูลออกมา
เริ่ม Android Studio แล้วเลือกเปิดโปรเจ็กต์ Android Studio ที่มีอยู่ หรือหาก Android Studio ทำงานอยู่ ให้เลือกไฟล์ > ใหม่ > นำเข้า โปรเจ็กต์ จากนั้นเลือก
SampleVideoPlayer/build.gradle
เรียกใช้การซิงค์ Gradle โดยเลือก เครื่องมือ > Android > ซิงค์โปรเจ็กต์กับไฟล์ Gradle
ตรวจสอบว่าแอปโปรแกรมเล่นคอมไพล์และทำงานบนอุปกรณ์ Android จริง หรือ อุปกรณ์เสมือน Android ที่ใช้เรียกใช้ > เรียกใช้ "แอป" ซึ่งเป็นเรื่องปกติสำหรับวิดีโอ สตรีมเพื่อใช้เวลาโหลดสักครู่ก่อนที่จะเล่น
ตรวจสอบวิดีโอเพลเยอร์ตัวอย่าง
โปรแกรมเล่นวิดีโอตัวอย่างยังไม่มีโค้ดการผสานรวม IMA DAI SDK ตัวอย่างแอปประกอบด้วย 2 ส่วนหลักดังนี้
samplevideoplayer/SampleVideoPlayer.java
: น. โปรแกรมเล่น HLS ที่ใช้ ExoPlayer ซึ่งทำหน้าที่เป็น เป็นพื้นฐานสำหรับการผสานรวม IMA DAIvideoplayerapp/MyActivity.java
: กิจกรรมนี้จะสร้างวิดีโอเพลเยอร์และ ส่งContext
และSimpleExoPlayerView
เพิ่ม IMA DAI SDK ลงในแอปโปรแกรมเล่น
และต้องใส่การอ้างอิงไปยัง IMA DAI SDK ด้วย ใน Android Studio ให้เพิ่ม
ต่อท้ายไฟล์ build.gradle
ระดับแอปพลิเคชันของคุณ ซึ่งอยู่ที่
app/build.gradle
:
repositories {
google()
mavenCentral()
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'androidx.media3:media3-exoplayer:1.3.1'
implementation 'com.google.ads.interactivemedia.v3:interactivemedia:3.35.0'
}
ผสานรวม IMA DAI SDK
สร้างชั้นเรียนใหม่ชื่อ
SampleAdsWrapper
ในแพ็กเกจvideoplayerapp
(ในapp/java/com.google.ads.interactivemedia.v3.samples/videoplayerapp/
) ถึง รวมSampleVideoPlayer
ที่มีอยู่และเพิ่มตรรกะที่ใช้ IMA DAI ถึง ในการดำเนินการ ก่อนอื่นคุณต้องสร้างAdsLoader
ที่ใช้ในการขอโฆษณา จากเซิร์ฟเวอร์โฆษณาvideoplayerapp/SampleAdsWrapper.java
package com.google.ads.interactivemedia.v3.samples.videoplayerapp; import android.annotation.TargetApi; import android.content.Context; import android.os.Build; import android.view.ViewGroup; import android.webkit.WebView; import com.google.ads.interactivemedia.v3.api.AdErrorEvent; import com.google.ads.interactivemedia.v3.api.AdEvent; import com.google.ads.interactivemedia.v3.api.AdsLoader; import com.google.ads.interactivemedia.v3.api.AdsManagerLoadedEvent; import com.google.ads.interactivemedia.v3.api.CuePoint; import com.google.ads.interactivemedia.v3.api.ImaSdkFactory; import com.google.ads.interactivemedia.v3.api.ImaSdkSettings; import com.google.ads.interactivemedia.v3.api.StreamDisplayContainer; import com.google.ads.interactivemedia.v3.api.StreamManager; import com.google.ads.interactivemedia.v3.api.StreamRequest; import com.google.ads.interactivemedia.v3.api.player.VideoProgressUpdate; import com.google.ads.interactivemedia.v3.api.player.VideoStreamPlayer; import com.google.ads.interactivemedia.v3.samples.samplevideoplayer.SampleVideoPlayer; import java.util.ArrayList; import java.util.HashMap; import java.util.List; public class SampleAdsWrapper implements AdEvent.AdEventListener, AdErrorEvent.AdErrorListener, AdsLoader.AdsLoadedListener { // Livestream asset key. private static final String TEST_ASSET_KEY = "sN_IYUG8STe1ZzhIIE_ksA"; // VOD content source and video IDs. private static final String TEST_CONTENT_SOURCE_ID = "2548831"; private static final String TEST_VIDEO_ID = "tears-of-steel"; private static final String PLAYER_TYPE = "DAISamplePlayer"; /** * Log interface, so you can output the log commands to the UI or similar. */ public interface Logger { void log(String logMessage); } private ImaSdkFactory sdkFactory; private AdsLoader adsLoader; private StreamDisplayContainer displayContainer; private StreamManager streamManager; private List<VideoStreamPlayer.VideoStreamPlayerCallback> playerCallbacks; private SampleVideoPlayer videoPlayer; private Context context; private ViewGroup adUiContainer; private String fallbackUrl; private Logger logger; public SampleAdsWrapper(Context context, SampleVideoPlayer videoPlayer, ViewGroup adUiContainer) { this.videoPlayer = videoPlayer; this.context = context; this.adUiContainer = adUiContainer; sdkFactory = ImaSdkFactory.getInstance(); playerCallbacks = new ArrayList<>(); createAdsLoader(); displayContainer = sdkFactory.createStreamDisplayContainer( this.adUiContainer, videoStreamPlayer ); } private void createAdsLoader() { ImaSdkSettings settings = new ImaSdkSettings(); adsLoader = sdkFactory.createAdsLoader(context); } public void requestAndPlayAds() { adsLoader.addAdErrorListener(this); adsLoader.addAdsLoadedListener(this); adsLoader.requestStream(buildStreamRequest()); } }
เพิ่มเมธอด
buildStreamRequest()
ลงในAdsLoader
เพื่อให้เมธอดสามารถขอ สตรีมแบบมีโฆษณา ซึ่งอาจเป็นสตรีมแบบสดที่มีโฆษณา (ตั้งค่าไว้โดยค่าเริ่มต้น) หรือ สตรีมวิดีโอออนดีมานด์(VOD) ที่เล่นเนื้อหาที่บันทึกไว้ล่วงหน้าแบบมีโฆษณา ถึง เปิดใช้สตรีม VOD, แสดงความคิดเห็นเกี่ยวกับคำขอสตรีมแบบสด และยกเลิกการแสดงความคิดเห็น คำขอสตรีม VODหากต้องการทำงานกับ DAI ผู้เล่นจะต้องส่งเหตุการณ์ ID3 สำหรับสตรีมแบบสดไปยัง IMA DAI SDK ในโค้ดตัวอย่างต่อไปนี้ โค้ดนี้ดำเนินการโดย
callback.onUserTextReceived()
วิธีvideoplayerapp/SampleAdsWrapper.java
private StreamRequest buildStreamRequest() { VideoStreamPlayer videoStreamPlayer = createVideoStreamPlayer(); videoPlayer.setSampleVideoPlayerCallback( new SampleVideoPlayer.SampleVideoPlayerCallback() { @Override public void onUserTextReceived(String userText) { for (VideoStreamPlayer.VideoStreamPlayerCallback callback : playerCallbacks) { callback.onUserTextReceived(userText); } } @Override public void onSeek(int windowIndex, long positionMs) { // See if you would seek past an ad, and if so, jump back to it. long newSeekPositionMs = positionMs; if (streamManager != null) { CuePoint prevCuePoint = streamManager.getPreviousCuePointForStreamTime(positionMs / 1000); if (prevCuePoint != null && !prevCuePoint.isPlayed()) { newSeekPositionMs = (long) (prevCuePoint.getStartTime() * 1000); } } videoPlayer.seekTo(windowIndex, newSeekPositionMs); } @Override public void onContentComplete() { for (VideoStreamPlayer.VideoStreamPlayerCallback callback : playerCallbacks) { callback.onContentComplete(); } } @Override public void onPause() { for (VideoStreamPlayer.VideoStreamPlayerCallback callback : playerCallbacks) { callback.onPause(); } } @Override public void onResume() { for (VideoStreamPlayer.VideoStreamPlayerCallback callback : playerCallbacks) { callback.onResume(); } } @Override public void onVolumeChanged(int percentage) { for (VideoStreamPlayer.VideoStreamPlayerCallback callback : playerCallbacks) { callback.onVolumeChanged(percentage); } } }); // Livestream request. StreamRequest request = sdkFactory.createLiveStreamRequest( TEST_ASSET_KEY, null, displayContainer); // VOD request. Comment the createLiveStreamRequest() line above and uncomment this // createVodStreamRequest() below to switch from a livestream to a VOD stream. // StreamRequest request = sdkFactory.createVodStreamRequest(TEST_CONTENT_SOURCE_ID, // TEST_VIDEO_ID, null, displayContainer); return request; }
และต้องมี
VideoStreamPlayer
เพื่อเล่นสตรีมด้วย โปรดเพิ่มcreateVideoStreamPlayer()
ซึ่งจะสร้างคลาสที่ไม่ระบุตัวตนซึ่ง นำVideoStreamPlayer
มาใช้videoplayerapp/SampleAdsWrapper.java
private VideoStreamPlayer createVideoStreamPlayer() { VideoStreamPlayer player = new VideoStreamPlayer() { @Override public void loadUrl(String url, List<HashMap<String, String>> subtitles) { videoPlayer.setStreamUrl(url); videoPlayer.play(); } @Override public void addCallback( VideoStreamPlayerCallback videoStreamPlayerCallback) { playerCallbacks.add(videoStreamPlayerCallback); } @Override public void removeCallback( VideoStreamPlayerCallback videoStreamPlayerCallback) { playerCallbacks.remove(videoStreamPlayerCallback); } @Override public void onAdBreakStarted() { // Disable player controls. videoPlayer.enableControls(false); log("Ad Break Started\n"); } @Override public void onAdBreakEnded() { // Re-enable player controls. videoPlayer.enableControls(true); log("Ad Break Ended\n"); } @Override public VideoProgressUpdate getContentProgress() { return new VideoProgressUpdate(videoPlayer.getCurrentPosition(), videoPlayer.getDuration()); } @Override public int getVolume() { return videoPlayer.getVolume(); } }; return player; }
ติดตั้งใช้งาน Listener ที่จำเป็นและเพิ่มการสนับสนุนสำหรับการจัดการข้อผิดพลาด
โปรดสังเกตการใช้งาน
AdErrorListener
เนื่องจากเป็นการเรียก URL ทางเลือกหาก โฆษณาไม่เล่น เนื่องจากเนื้อหาและโฆษณาอยู่ในสตรีมเดียว คุณจึงต้อง พร้อมที่จะเรียกสตรีมสำรอง ถ้าสตรีม DAI พบข้อผิดพลาดvideoplayerapp/SampleAdsWrapper.java
/** AdErrorListener implementation **/ @Override public void onAdError(AdErrorEvent event) { // play fallback URL. videoPlayer.setStreamUrl(fallbackUrl); videoPlayer.enableControls(true); videoPlayer.play(); } /** AdEventListener implementation **/ @Override public void onAdEvent(AdEvent event) { switch (event.getType()) { case AD_PROGRESS: // Do nothing or else log are filled by these messages. break; default: log(String.format("Event: %s\n", event.getType())); break; } } /** AdsLoadedListener implementation **/ @Override public void onAdsManagerLoaded(AdsManagerLoadedEvent event) { streamManager = event.getStreamManager(); streamManager.addAdErrorListener(this); streamManager.addAdEventListener(this); streamManager.init(); } /** Sets fallback URL in case ads stream fails. **/ void setFallbackUrl(String url) { fallbackUrl = url; }
เพิ่มโค้ดสำหรับบันทึก
videoplayerapp/SampleAdsWrapper.java
/** Sets logger for displaying events to screen. Optional. **/ void setLogger(Logger logger) { this.logger = logger; } private void log(String message) { if (logger != null) { logger.log(message); } }
แก้ไข
MyActivity
ในvideoplayerapp
เพื่อสร้างอินสแตนซ์และเรียกSampleAdsWrapper
videoplayerapp/MyActivity.java
import android.view.ViewGroup; import android.widget.ScrollView; ... public class MyActivity extends AppCompatActivity { ... @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my); View rootView = findViewById(R.id.videoLayout); videoPlayer = new SampleVideoPlayer(rootView.getContext(), (SimpleExoPlayerView) rootView.findViewById(R.id.playerView)); videoPlayer.enableControls(false); final SampleAdsWrapper sampleAdsWrapper = new SampleAdsWrapper(this, videoPlayer, (ViewGroup) rootView.findViewById(R.id.adUiContainer)); sampleAdsWrapper.setFallbackUrl(DEFAULT_STREAM_URL); final ScrollView scrollView = (ScrollView) findViewById(R.id.logScroll); final TextView textView = (TextView) findViewById(R.id.logText); sampleAdsWrapper.setLogger(new SampleAdsWrapper.Logger() { @Override public void log(String logMessage) { Log.i(APP_LOG_TAG, logMessage); if (textView != null) { textView.append(logMessage); } if (scrollView != null) { scrollView.post(new Runnable() { @Override public void run() { scrollView.fullScroll(View.FOCUS_DOWN); } }); } } }); playButton = (ImageButton) rootView.findViewById(R.id.playButton); // Set up play button listener to play video then hide play button. playButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { sampleAdsWrapper.requestAndPlayAds(); playButton.setVisibility(View.GONE); } }); } ... }
แก้ไขไฟล์เลย์เอาต์ของกิจกรรม
activity_my.xml
เพื่อเพิ่มองค์ประกอบ UI สำหรับ การเข้าสู่ระบบres/layout/activity_my.xml
... <TextView android:id="@+id/playerDescription" android:text="@string/video_description" android:textAlignment="center" android:gravity="center_horizontal" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="0.1" android:textSize="@dimen/font_size" /> <!-- UI element for viewing SDK event log --> <ScrollView android:id="@+id/logScroll" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="0.5" android:padding="5dp" android:background="#DDDDDD"> <TextView android:id="@+id/logText" android:layout_width="match_parent" android:layout_height="wrap_content"> </TextView> </ScrollView> ...
ยินดีด้วย คุณกำลังขอและแสดงโฆษณาวิดีโอใน Android แอป หากต้องการปรับแต่งการใช้งาน โปรดดูที่ บุ๊กมาร์ก, Snapback และ API เอกสารประกอบ
การแก้ปัญหา
หากพบปัญหาในการเล่นโฆษณาวิดีโอ ให้ลองดาวน์โหลด BasicExample หากโค้ดนั้นทำงานอย่างถูกต้องใน BasicExample แสดงว่าอาจมีปัญหาเกิดขึ้นกับ โค้ดการผสานรวม IMA ของแอป
หากยังพบปัญหาอยู่ ให้ไปที่ IMA SDK ฟอรัม