Use the IMA DAI SDK on tvOS

Play live streams registered with Google Cloud Video Stitcher API

This guide demonstrates how to use the IMA DAI SDK for tvOS to request and play a livestream for an event registered with the Google Cloud Video Stitcher API, and how to insert an ad break during playback.

This guide expands on the basic example from the Get started guide for IMA DAI.

For information on integrating with other platforms or on using the IMA client-side SDKs, see Interactive Media Ads SDKs.

If you would like to view or follow along with a completed sample integration, download the Cloud video stitcher example for Objective-C or Swift.

Set up a Google Cloud project

Enter the following variables for use in the IMA SDK:

Location
The Google Cloud region where your live config was created: LOCATION
Project number
The Google Cloud project number using the Video Stitcher API: PROJECT_NUMBER
OAuth token

A service account's short lived OAuth token with the Video Stitcher user role:

OAUTH_TOKEN

Read more about creating short-lived credentials for service accounts. The OAuth token can be reused across multiple requests as long as it has not expired.

Network code

The Ad Manager network code for requesting ads: NETWORK_CODE

Live config ID
The live config ID you specified when creating your livestream event: LIVE_CONFIG_ID
Custom asset key
The Ad Manager custom asset key generated during the process of creating a configuration for a livestream event with the Video Stitcher API: CUSTOM_ASSET_KEY

Download and prepare the basic example

Download the IMA DAI examples for tvOS and extract the Basic Example into a new folder. This example is an Xcode project that relies on Cocoapods to load the IMA SDK.

To prepare the sample to run, make sure CocoaPods is installed, then open the basic example's folder in the terminal and run the following command:

pod install --repo-update

Once that command completes, you see a file named BasicExample.xcworkspace in your project folder. Open this file in Xcode and run the sample to ensure that the test video and ads play as expected.

Request a livestream

To replace the sample stream with your livestream, you need to use the IMAVideoStitcherLiveStreamRequest class that automatically creates an ad session with Google Ad Manager. You can use the Google Ad Manager UI to locate the generated DAI sessions for monitoring and debugging purposes.

In the existing sample, there are examples for requesting a VOD stream or a livestream from Google's DAI servers. To make the sample work with the Google Cloud Video Stitcher API, you will need to replace the current requestStream function with one that uses the IMAVideoStitcherLiveStreamRequest class:

ViewController.m

#import <GoogleInteractiveMediaAds/GoogleInteractiveMediaAds.h>

static NSString *const kLiveConfigId = @"LIVE_CONFIG_ID";
static NSString *const kLocation = @"LOCATION";
static NSString *const kProjectNumber = @"PROJECT_NUMBER";
static NSString *const kOAuthToken = @"OAUTH_TOKEN";
static NSString *const kNetworkCode = @"NETWORK_CODE";
static NSString *const kCustomAssetKey = @"CUSTOM_ASSET_KEY";

static NSString *const kBackupStreamURLString =
    @"http://googleimadev-vh.akamaihd.net/i/big_buck_bunny/bbb-,480p,720p,1080p,.mov.csmil/"
    @"master.m3u8";

@interface ViewController () <IMAAdsLoaderDelegate, IMAStreamManagerDelegate>
...
- (void)requestStream {
  IMAAVPlayerVideoDisplay *videoDisplay =
      [[IMAAVPlayerVideoDisplay alloc] initWithAVPlayer:self.playerViewController.player];
  IMAAdDisplayContainer *adDisplayContainer =
      [[IMAAdDisplayContainer alloc] initWithAdContainer:self.adContainerView];

  IMAVideoStitcherLiveStreamRequest *request =
      [[IMAVideoStitcherLiveStreamRequest alloc] initWithLiveStreamEventID:kLiveConfigId
                                                                    region:kLocation
                                                             projectNumber:kProjectNumber
                                                                OAuthToken:kOAuthToken
                                                               networkCode:kNetworkCode
                                                            customAssetKey:kCustomAssetKey
                                                        adDisplayContainer:self.adDisplayContainer
                                                              videoDisplay:self.videoDisplay
                                                               userContext:nil,
                                               videoStitcherSessionOptions:nil];

  [self.adsLoader requestStreamWithRequest:request];
}

(Optional) Add streaming session options

Customize your stream request by adding session options to override the default Cloud Video Stitcher API configuration by populating the videoStitcherSessionOptions parameter in your IMAVideoStitcherLiveStreamRequest. If you provide an unrecognized option, the Cloud Video Stitcher API will respond with an HTTP 400 error. Consult the troubleshooting guide for assistance.

For example, you can override the manifest options with the following code snippet, which requests two stream manifests with renditions ordered from lowest bitrate to highest.

Objective-C

 // Define session options JSON string.
 // The following session options are examples. Use session options
 // that are compatible with your video stream.
 NSString *sessionOptionsStr =
   @"{"
   "  \"manifestOptions\": {"
   "    \"includeRenditions\":["
   "      {\"bitrateBps\": 3000, \"codecs\": \"hvc1.1.4.L126.B0, mp4a.40.2\"},"
   "      {\"bitrateBps\": 2000, \"codecs\": \"avc1.64001f, mp4a.40.2\"},"
   "    ]"
   "  }"
   "}";
 // convert JSON NSString to NSDictionary
 NSData *sessionOptionsData = [sessionOptionsStr dataUsingEncoding:NSUTF8StringEncoding];
 NSError *error = nil;
 NSDictionary *sessionOptions = [NSJSONSerialization
                       JSONObjectWithData:sessionOptionsData
                       options:0
                       error:&error];
 // make stream request
 IMAVideoStitcherLiveStreamRequest *streamRequest =
     [[IMAVideoStitcherLiveStreamRequest alloc] initWithLiveStreamEventID:kLiveConfigID
                                                                   region:kLocation
                                                           projectNumber:kProjectNumber
                                                               OAuthToken:kOAuthToken
                                                             networkCode:kNetworkCode
                                                           customAssetKey:kCustomAssetKey
                                                       adDisplayContainer:adDisplayContainer
                                                             videoDisplay:imaVideoDisplay
                                                             userContext:nil
                                             videoStitcherSessionOptions:sessionOptions];
 [self.adsLoader requestStreamWithRequest:streamRequest];

Swift

 // Define session options JSON string.
 // The following session options are examples. Use session options
 // that are compatible with your video stream.
 let sessionOptionsStr = """
     {
       "manifestOptions": {
         "includeRenditions": [
           {"bitrateBps": 3000, "codecs": "hvc1.1.4.L126.B0, mp4a.40.2"},
           {"bitrateBps": 2000, "codecs": "avc1.64001f, mp4a.40.2"},
         ],
         "bitrateOrder": "ascending"
       }
     }
     """
 // convert JSON string to dictionary
 guard let sessionOptionsData = sessionOptionsStr.data(using: .utf8, allowLossyConversion: false) else { return nil }
 let sessionOptions = try? JSONSerialization.jsonObject(with: sessionOptionsData, options: .mutableContainers)
 // make stream request
 let streamRequest = IMAVideoStitcherLiveStreamRequest(
   liveStreamEventID:ViewController.liveConfigID
   region:ViewController.location
   projectNumber:ViewController.projectNumber
   OAuthToken:ViewController.oAuthToken
   networkCode:ViewController.networkCode
   customAssetKey:ViewController.customAssetKey
   adDisplayContainer:adDisplayContainer
   videoDisplay:imaVideoDisplay
   userContext:nil
   videoStitcherSessionOptions:sessionOptions)
 adsLoader?.requestStream(with: streamRequest)

Run the project, then you can request and play your custom livestream.

Insert an ad break

The Google Cloud Video Stitcher API inserts ads retrieved from the ad tag for each ad break. Ad breaks are denoted in the manifest using ad markers. Ad markers are inserted by the live stream encoder.

The ad is played immediately after the ad break is inserted.

Clean up

Now that you have successfully hosted a live stream using the Google Cloud Video Stitcher API and requested it using the IMA DAI SDK for tvOS, it's important to clean up any serving resources.

Follow the livestream clean up guide to remove any unneeded resources and assets.