-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Add ima-dai-sdk skill directory and files. #191
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
copybara-service
wants to merge
1
commit into
main
Choose a base branch
from
test_947251048
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,89 @@ | ||
| --- | ||
| name: ima-dai-sdk | ||
| description: >- | ||
| Integrates the Google Interactive Media Ads (IMA) DAI SDK into websites, web apps, | ||
| mobile apps, or TV apps for Google Dynamic Ad Insertion (DAI) with HLS or DASH streams. | ||
|
|
||
| Use when: | ||
| - Integrating the IMA DAI SDK for Google Dynamic Ad Insertion (DAI), Server-Side Ad Insertion (SSAI), Full Service DAI, or DAI Pod Serving redirect. | ||
| - Requesting HLS (.m3u8) or MPEG-DASH (.mpd) DAI streams on Web, Android, iOS/tvOS, or Roku platforms. | ||
|
|
||
| Don't use for: | ||
| - Client-side ad insertion (CSAI) with VAST and VMAP requests (use the `ima-sdk-client-side` skill instead). | ||
|
|
||
| license: Apache-2.0 | ||
| metadata: | ||
| author: Google LLC | ||
| version: "1.0.0" | ||
| --- | ||
|
|
||
| # IMA SDK DAI Basics | ||
|
|
||
| The Google IMA DAI SDK lets you load a single stream containing both content and | ||
| ads into websites, apps, TVs and other digital platforms. Use an IMA SDK to | ||
| request an HLS or MPEG DASH stream from a video stitcher or stream origin. | ||
|
|
||
| ## Mandatory Prerequisites | ||
|
|
||
| Correct integration requires identifying the streaming protocol, DAI type, and target platform up front. Review the relevant reference guides below to ensure proper setup: | ||
|
|
||
| 1. **Identify the Streaming Protocol:** | ||
|
|
||
| * **HLS (HTTP Live Streaming):** Stream URLs end in `.m3u8`. Read the [HLS Guide](references/hls.md). | ||
| * **MPEG DASH:** Stream URLs end in `.mpd`. Read the [DASH Guide](references/dash.md). | ||
|
|
||
| 2. **Identify the DAI Type:** | ||
|
|
||
| * **Full Service DAI:** Request a Google DAI stream URL using an `assetKey` (Live) or `cmsId`/`videoId` (VOD). Read the [Full Service Guide](references/full-service.md). | ||
| * **Pod Serving DAI:** Request a Google DAI `streamId` using an `assetKey`/`customAssetKey` (linear stream, livestream) or `cmsId`/`videoId` (VOD). Construct a playback stream URL with the `streamId`. Read the [Pod Serving Guide](references/pod-serving.md). | ||
|
|
||
| 3. **Identify the Target Platform:** | ||
|
|
||
| * **Web/NodeJs/ReactJs:** Native JavaScript/TypeScript environments (browsers, Smart TVs). Read the [Web Guide](references/web.md). | ||
| * **Android/AndroidTV:** Native Java/Kotlin environments. Read the [Android Guide](references/android-ima-extension.md). | ||
| * **iOS/tvOS:** Native Swift/Objective-C environments. Read the [iOS/tvOS Guide](references/ios-tvos.md). | ||
| * **Roku:** Native BrightScript/SceneGraph environments. Read the [Roku Guide](references/roku.md). | ||
|
|
||
| -------------------------------------------------------------------------------- | ||
|
|
||
| ## Quick Start (General Workflow) | ||
|
|
||
| For all apps, the integration follows this general logical flow: | ||
|
|
||
| 1. Import the SDK: Set up prerequisites and dependencies. | ||
| 2. Initialization: Early setup, Warmup, Settings Configuration, and Ad UI Setup. | ||
| 3. Ad Stream request: Create the livestream or VOD stream request. | ||
| 4. Ad Stream Load Success/Failure: Handle the stream load event to obtain the `StreamManager` or handle early fatal errors. | ||
| 5. Stream Playback Events: Listen to timed metadata events for forwarding ID3/emsg tags to the IMA DAI SDK, and handle non-fatal LOG events or fatal stream errors. | ||
| 6. Cleanup: Properly destroy the `StreamManager` to release resources and prevent memory leaks. | ||
|
|
||
| ### Basic Web Live Stream Integration Example | ||
|
|
||
| ```typescript | ||
| import { LiveStreamRequest, StreamManager, StreamEvent } from '@google/ima-dai-sdk'; | ||
|
|
||
| const videoElement = document.getElementById('video-player') as HTMLVideoElement; | ||
| const adUiElement = document.getElementById('ad-ui') as HTMLElement; | ||
|
|
||
| // 1. Initialize StreamManager | ||
| const streamManager = new StreamManager(videoElement, adUiElement); | ||
|
|
||
| // 2. Listen for stream loaded event | ||
| streamManager.addEventListener( | ||
| StreamEvent.Type.LOADED, | ||
| (event: StreamEvent) => { | ||
| const streamUrl = event.getStreamData().url; | ||
| videoElement.src = streamUrl; | ||
| videoElement.play(); | ||
| } | ||
| ); | ||
|
|
||
| // 3. Request live stream | ||
| const streamRequest = new LiveStreamRequest(); | ||
| streamRequest.assetKey = 'YOUR_ASSET_KEY'; | ||
| streamRequest.networkCode = 'YOUR_NETWORK_CODE'; | ||
| streamManager.requestStream(streamRequest); | ||
| ``` | ||
|
|
||
| For detailed, platform-specific implementation details, refer to the guides in the **Mandatory Prerequisites** section. | ||
|
|
162 changes: 162 additions & 0 deletions
162
skills/ads/ima-dai-sdk/references/android-ima-extension.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,162 @@ | ||
| # Google IMA SDK DAI - Media3 IMA Extension Integration Guide | ||
|
|
||
| This guide covers integrating the Google IMA SDK for Android DAI using the | ||
| **Media3 IMA Extension** (`androidx.media3:media3-exoplayer-ima`) and | ||
| `ImaServerSideAdInsertionMediaSource`. | ||
|
|
||
| Using the extension is the recommended approach for Media3 ExoPlayer | ||
| integrations as it handles stream wrapping, ad UI overlays, and ad event | ||
| synchronization automatically without requiring a custom `VideoStreamPlayer` | ||
| implementation. | ||
|
|
||
| -------------------------------------------------------------------------------- | ||
|
|
||
| ## 1. Dependencies and Configuration | ||
|
|
||
| Add the Media3 IMA extension dependency to your app's `build.gradle.kts` file. | ||
|
|
||
| Use latest version of the IMA SDK, which is published at | ||
| https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/download.md.txt. | ||
| Use the latest version of the ExoPlayer and IMA extension at | ||
| https://developer.android.com/jetpack/androidx/releases/media3.md.txt. | ||
|
|
||
| ```kotlin | ||
| android { | ||
| defaultConfig { | ||
| minSdk = 23 | ||
| } | ||
| } | ||
|
|
||
| dependencies { | ||
| implementation("androidx.media3:media3-ui:$latestVersion") | ||
| implementation("androidx.media3:media3-exoplayer:$latestVersion") | ||
|
|
||
| // CRITICAL: Add the Media3 IMA Extension | ||
| implementation("androidx.media3:media3-exoplayer-ima:$latestVersion") | ||
| } | ||
| ``` | ||
|
|
||
| -------------------------------------------------------------------------------- | ||
|
|
||
| ### 2. Initialization | ||
|
|
||
| Configure the SDK early to minimize latency, and reuse the SDK settings. | ||
|
|
||
| * **Early Warmup & Settings Reuse (Best Practice):** Call | ||
| `ImaSdkFactory.initialize()` in your `Application.onCreate()` to preload SDK | ||
| resources. | ||
| * Reuse the same `ImaSdkSettings` instance when creating the | ||
| `ImaServerSideAdInsertionMediaSource.AdsLoader.Builder.setImaSdkSettings` to | ||
| avoid cache misses that cause latency spikes. | ||
|
|
||
| ```kotlin | ||
| // 1. Application class for early warmup | ||
| class MyApplication : Application() { | ||
| companion object { | ||
| lateinit var sdkFactory: ImaSdkFactory | ||
| lateinit var imaSettings: ImaSdkSettings | ||
| } | ||
|
|
||
| override fun onCreate() { | ||
| super.onCreate() | ||
| sdkFactory = ImaSdkFactory.getInstance() | ||
|
|
||
| // Configure settings early | ||
| imaSettings = sdkFactory.createImaSdkSettings().apply { | ||
| language = YOUR_LANGUAGE_CODE // Use 2 lowercase letters to identify | ||
| // the language of your app UI. | ||
| isDebugMode = true | ||
| } | ||
|
|
||
| sdkFactory.initialize(this, imaSettings) | ||
| } | ||
| } | ||
| ... | ||
|
|
||
| private ImaServerSideAdInsertionMediaSource.AdsLoader createAdsLoader() { | ||
| val adsLoaderBuilder = new ImaServerSideAdInsertionMediaSource.AdsLoader.Builder(this, playerView); | ||
|
|
||
| return adsLoaderBuilder | ||
| .setImaSdkSettings(getImaSdkSettings()) | ||
| .build(); | ||
| } | ||
| ``` | ||
|
|
||
| ### 3. Build DAI Request UIRs | ||
|
|
||
| Create an `ImaServerSideAdInsertionUriBuilder` to build an SSAI livestream URL. | ||
|
|
||
| Make sure to use an `assetKey`, which is a string of alphanumeric characters as | ||
| a URL-safe base64 encoded value. For example, here are the assetKeys of DAI | ||
| sample streams: `c-rArva4ShKVIAkNfy6HUQ`, | ||
| `XYrjlG09QTa8pxAo5Fzjww`,`PSzZMzAkSXCmlJOWDmRj8Q`. | ||
|
|
||
| ```kotlin | ||
| import android.net.Uri | ||
| import androidx.media3.common.C | ||
| import androidx.media3.exoplayer.ima.ImaServerSideAdInsertionUriBuilder | ||
|
|
||
| // Example 1: HLS Live Stream | ||
| val hlsLiveUri: Uri = ImaServerSideAdInsertionUriBuilder() | ||
| .setAssetKey("YOUR_LIVE_ASSET_KEY") | ||
| .setFormat(C.CONTENT_TYPE_DASH) | ||
| .build() | ||
|
|
||
| // Example 2: HLS VOD Stream | ||
| val hlsVodUri: Uri = ImaServerSideAdInsertionUriBuilder() | ||
| .setContentSourceId("YOUR_CMS_ID") | ||
| .setVideoId("YOUR_VIDEO_ID") | ||
| .setFormat(C.CONTENT_TYPE_DASH) | ||
| .build() | ||
| ``` | ||
|
|
||
| ### 4. Create an ads-aware `MediaSourceFactory` | ||
|
|
||
| When using the ExoPlayer IMA extension, you must use the | ||
| `ImaServerSideAdInsertionMediaSource.AdsLoader` class instead of the | ||
| `ImaAdsLoader` class. | ||
|
|
||
| When creating the `ImaServerSideAdInsertionMediaSource.AdsLoader`, you must | ||
| provide the `PlayerView` object for rendering ad UI elements. | ||
|
|
||
| You must create a `DefaultMediaSourceFactory` object for your content and call | ||
| the `DefaultMediaSourceFactory.setServerSideAdInsertionMediaSourceFactory()` | ||
| method with the `ImaServerSideAdInsertionMediaSource.AdsLoader` object. | ||
|
|
||
| ```kotlin | ||
| // Construct the AdsLoader instance | ||
| val adsLoader = ImaServerSideAdInsertionMediaSource.AdsLoader.Builder(context, playerView) | ||
| .build() | ||
|
|
||
| // Instantiate the factory and bind the AdsLoader for SSAI handling | ||
| val mediaSourceFactory = DefaultMediaSourceFactory(context) | ||
| .setServerSideAdInsertionMediaSourceFactory(adsLoader) | ||
| ``` | ||
|
|
||
| ### 5. Set Up ExoPlayer | ||
|
|
||
| Create the ExoPlayer instance with your ad-aware media source factory and | ||
| provide the ExoPlayer instance to the `AdsLoader` for monitoring ad events. | ||
|
|
||
| ```kotlin | ||
| // Construct the player using the configured factory | ||
| val player = ExoPlayer.Builder(context) | ||
| .setMediaSourceFactory(mediaSourceFactory) | ||
| .build() | ||
|
|
||
| // Bind the player to the AdsLoader immediately | ||
| adsLoader.setPlayer(player) | ||
| ``` | ||
|
|
||
| ### 6. Load the media item | ||
|
|
||
| ### 6. Load Media and Manage the Lifecycle | ||
|
|
||
| Pass your constructed SSAI URI directly into the player as a `MediaItem`. | ||
|
|
||
| When destroying the player activity or handling background events, you must | ||
| execute a strict teardown sequence to preserve the user's session. Call | ||
| `release()` on the `AdsLoader` before releasing the ExoPlayer instance. Capture | ||
| the returned `AdsLoader.State` object and store it securely (e.g., in a | ||
| `ViewModel`). Provide this saved state back to the `AdsLoader.Builder` during | ||
| reinitialization to ensure ad playback resumes exactly where it left off. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| # Google IMA SDK DAI - DASH Integration Guide | ||
|
|
||
| This guide covers DASH stream request configuration with IMA DAI SDK. | ||
|
|
||
| When requesting a DASH stream, you set the stream format as follows. | ||
|
|
||
| * **Web (TypeScript):** | ||
|
|
||
| ```typescript | ||
| const streamRequest = new google.ima.dai.api.LiveStreamRequest(); | ||
| streamRequest.format = 'dash'; // the format property is also available for | ||
| // VODStreamRequest, | ||
| // PodStreamRequest, PodVodStreamRequest. | ||
| ``` | ||
|
|
||
| * **Android (Kotlin):** | ||
|
|
||
| ```kotlin | ||
| val request = sdkFactory.createLiveStreamRequest(...) | ||
| request.format = StreamFormat.DASH | ||
| ``` | ||
|
|
||
| Or if using Media3 SSAI Uri Builder: | ||
|
|
||
| ```kotlin | ||
| val ssaiUri = ImaServerSideAdInsertionUriBuilder() | ||
| .setAssetKey(assetKey) | ||
| .setFormat(androidx.media3.common.C.CONTENT_TYPE_DASH) | ||
| // ... | ||
| .build() | ||
| ``` |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Messenger_creation_1AA44BEC-75C2-4C15-B90C-522D78303B80.mp3