Skip to content

Commit

Permalink
No public description
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 717802591
  • Loading branch information
gschoppe authored and IMA Developer Relations committed Jan 28, 2025
1 parent b3e7e10 commit 2f4bb1b
Show file tree
Hide file tree
Showing 14 changed files with 971 additions and 252 deletions.
34 changes: 26 additions & 8 deletions Objective-C/BasicExample/app/ViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,26 @@
@import GoogleInteractiveMediaAds;

// [START_EXCLUDE]
typedef NS_ENUM(NSInteger, StreamType) {
/// Live stream.
StreamTypeLive,
/// VOD.
StreamTypeVOD,
};

/// Specifies the ad pod stream type; either `StreamTypeLive` or `StreamTypeVOD`.
///
/// Change to `StreamTypeVOD` to make a VOD request.
static StreamType const kStreamType = StreamTypeLive;
/// Live stream asset key.
static NSString *const kLiveStreamAssetKey = @"c-rArva4ShKVIAkNfy6HUQ";
/// VOD content source ID.
static NSString *const kVODContentSourceID = @"2548831";
/// VOD video ID.
static NSString *const kVODVideoID = @"tears-of-steel";
/// Network code.
static NSString *const kNetworkCode = @"21775744923";

/// The backup stream is only played when an error is detected during the stream creation.
static NSString *const kBackupContentUrl =
@"http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8";
Expand Down Expand Up @@ -77,20 +97,18 @@ - (void)requestStream {
// Create a stream request. Use one of "Live stream request" or "VOD request", depending on your
// type of stream.
IMAStreamRequest *request;
// Switch this variable to NO to make a VOD request.
BOOL useLiveStream = YES;
if (useLiveStream) {
if (kStreamType == StreamTypeLive) {
// Live stream request. Replace the asset key with your value.
request = [[IMALiveStreamRequest alloc] initWithAssetKey:@"c-rArva4ShKVIAkNfy6HUQ"
networkCode:@"21775744923"
request = [[IMALiveStreamRequest alloc] initWithAssetKey:kLiveStreamAssetKey
networkCode:kNetworkCode
adDisplayContainer:self.adDisplayContainer
videoDisplay:self.imaVideoDisplay
userContext:nil];
} else {
// VOD request. Replace the content source ID and video ID with your values.
request = [[IMAVODStreamRequest alloc] initWithContentSourceID:@"2548831"
videoID:@"tears-of-steel"
networkCode:@"21775744923"
request = [[IMAVODStreamRequest alloc] initWithContentSourceID:kVODContentSourceID
videoID:kVODVideoID
networkCode:kNetworkCode
adDisplayContainer:self.adDisplayContainer
videoDisplay:self.imaVideoDisplay
userContext:nil];
Expand Down
175 changes: 87 additions & 88 deletions Objective-C/PodServingExample/app/ViewController.m
Original file line number Diff line number Diff line change
@@ -1,59 +1,63 @@
// Copyright 2024 Google LLC. All rights reserved.
//
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
// file except in compliance with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under
// the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
// ANY KIND, either express or implied. See the License for the specific language governing
// permissions and limitations under the License.

#import "ViewController.h"

#import <AVFoundation/AVFoundation.h>

// [START import_ima_sdk]
@import GoogleInteractiveMediaAds;

typedef enum {liveStream, vodStream} streamType;
/// Specifies the ad pod stream type; either `liveStream` or `vodStream`.
static streamType const kRequestType = liveStream;
// [START_EXCLUDE]
typedef NS_ENUM(NSInteger, StreamType) {
/// Live stream.
StreamTypeLive,
/// VOD.
StreamTypeVOD,
};

/// Specifies the ad pod stream type; either `StreamTypeLive` or `StreamTypeVOD`.
///
/// Change to `StreamTypeVOD` to make a VOD request.
static StreamType const kStreamType = StreamTypeLive;
/// Google Ad Manager network code.
static NSString *const kNetworkCode = @"";
static NSString *const kNetworkCode = @"YOUR_NETWORK_CODE";
/// Livestream custom asset key.
static NSString *const kCustomAssetKey = @"";
static NSString *const kCustomAssetKey = @"YOUR_CUSTOM_ASSET_KEY";
// [START custom_vtp_handler]
/// Custom VTP Handler.
///
/// Returns the stream manifest URL from the video technical partner or manifest manipulator.
static NSString *(^gCustomVTPParser)(NSString *) = ^(NSString *streamID) {
static NSString *(^gCustomVTPHandler)(NSString *) = ^(NSString *streamID) {
// Insert synchronous code here to retrieve a stream manifest URL from your video tech partner
// or manifest manipulation server.
NSString *manifestUrl = @"";
return manifestUrl;
// This example uses a hardcoded URL template, containing a placeholder for the stream
// ID and replaces the placeholder with the stream ID.
NSString *manifestUrl = @"YOUR_MANIFEST_URL_TEMPLATE";
return [manifestUrl stringByReplacingOccurrencesOfString:@"[[STREAMID]]"
withString:streamID];
};

/// Fallback URL in case something goes wrong in loading the stream. If all goes well, this will not
/// be used.
static NSString *const kBackupStreamURLString = @"";
// [END custom_vtp_handler]
/// The backup stream is only played when an error is detected during the stream creation.
static NSString *const kBackupContentUrl =
@"http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8";
// [END_EXCLUDE]

@interface ViewController () <IMAAdsLoaderDelegate, IMAStreamManagerDelegate>
/// The entry point for the IMA DAI SDK to make DAI stream requests.
@property(nonatomic, strong) IMAAdsLoader *adsLoader;
/// The container where the SDK renders each ad's user interface elements and companion slots.
@property(nonatomic, strong) IMAAdDisplayContainer *adDisplayContainer;
/// The reference of your video player for the IMA DAI SDK to monitor playback and handle timed
/// metadata.
@property(nonatomic, strong) IMAAVPlayerVideoDisplay *imaVideoDisplay;
/// References the stream manager from the IMA DAI SDK after successful stream loading.
@property(nonatomic, strong) IMAStreamManager *streamManager;

/// Content video player.
@property(nonatomic, strong) AVPlayer *contentPlayer;

// UI
// [START_EXCLUDE]
/// Play button.
@property(nonatomic, weak) IBOutlet UIButton *playButton;
/// UIView in which we will render our AVPlayer for content.
/// UIView for the video player.
@property(nonatomic, weak) IBOutlet UIView *videoView;

// SDK
/// Entry point for the SDK. Used to make ad requests.
@property(nonatomic, strong) IMAAdsLoader *adsLoader;
/// Main point of interaction with the SDK. Created by the SDK as the result of an ad request.
@property(nonatomic, strong) IMAStreamManager *streamManager;
/// Video display used by the SDK to play ads.
@property(nonatomic, strong) id<IMAVideoDisplay> videoDisplay;
/// Video player to play the DAI stream for both content and ads.
@property(nonatomic, strong) AVPlayer *videoPlayer;
// [END_EXCLUDE]

@end

Expand All @@ -62,104 +66,98 @@ @implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];

// [START_EXCLUDE]
self.playButton.layer.zPosition = MAXFLOAT;

[self setupAdsLoader];
[self setUpContentPlayer];
}

- (IBAction)onPlayButtonTouch:(id)sender {
[self requestStream];
self.playButton.hidden = YES;
}

#pragma mark Content Player Setup

- (void)setUpContentPlayer {
// Load AVPlayer with path to our content.
NSURL *contentURL = [NSURL URLWithString:kBackupStreamURLString];
self.contentPlayer = [AVPlayer playerWithURL:contentURL];
// Load AVPlayer with path to your content.
NSURL *contentURL = [NSURL URLWithString:kBackupContentUrl];
self.videoPlayer = [AVPlayer playerWithURL:contentURL];

// Create a player layer for the player.
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.contentPlayer];
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.videoPlayer];

// Size, position, and display the AVPlayer.
playerLayer.frame = self.videoView.layer.bounds;
[self.videoView.layer addSublayer:playerLayer];
}
// [END_EXCLUDE]

#pragma mark SDK Setup

- (void)setupAdsLoader {
self.adsLoader = [[IMAAdsLoader alloc] initWithSettings:nil];
self.adsLoader.delegate = self;
}

- (void)requestStream {
// Create an ad display container for ad rendering.
IMAAdDisplayContainer *adDisplayContainer =
// Create an ad display container for rendering each ad's user interface elements and companion
// slots.
self.adDisplayContainer =
[[IMAAdDisplayContainer alloc] initWithAdContainer:self.videoView
viewController:self
companionSlots:nil];

// Create an IMAAVPlayerVideoDisplay to give the SDK access to your video player.
self.videoDisplay =
[[IMAAVPlayerVideoDisplay alloc] initWithAVPlayer:self.contentPlayer];
self.imaVideoDisplay = [[IMAAVPlayerVideoDisplay alloc] initWithAVPlayer:self.videoPlayer];
}
// [END import_ima_sdk]

// [START make_stream_request]
- (IBAction)onPlayButtonTouch:(id)sender {
[self requestStream];
self.playButton.hidden = YES;
}

- (void)requestStream {
// Create a stream request.
IMAStreamRequest *request;
if (kRequestType == liveStream) {
// Create a pod serving request for a livestream.
if (kStreamType == StreamTypeLive) {
// Live stream request. Replace the network code and custom asset key with your values.
request = [[IMAPodStreamRequest alloc] initWithNetworkCode:kNetworkCode
customAssetKey:kCustomAssetKey
adDisplayContainer:adDisplayContainer
videoDisplay:self.videoDisplay
pictureInPictureProxy:nil
userContext:nil];
} else {
// Create a pod serving request for a VOD stream.
request = [[IMAPodVODStreamRequest alloc] initWithNetworkCode:kNetworkCode
// VOD request. Replace the network code with your value.
request = [[IMAPodVODStreamRequest alloc] initWithNetworkCode:@kNetworkCode
adDisplayContainer:adDisplayContainer
videoDisplay:self.videoDisplay
pictureInPictureProxy:nil
userContext:nil];
}
[self.adsLoader requestStreamWithRequest:request];
}
// [END make_stream_request]

#pragma mark AdsLoader Delegates

// [START ads_loader_delegates]
- (void)adsLoader:(IMAAdsLoader *)loader adsLoadedWithData:(IMAAdsLoadedData *)adsLoadedData {
// Initialize and listen to stream manager's events.
NSLog(@"Stream created with: %@.", adsLoadedData.streamManager.streamId);
self.streamManager = adsLoadedData.streamManager;
// The stream manager must be initialized before playback for adsRenderingSettings to be
// respected.
[self.streamManager initializeWithAdsRenderingSettings:nil];
self.streamManager.delegate = self;

// Build the Pod serving Stream URL and load into AVPlayer
NSString *streamId = adsLoadedData.streamManager.streamId;
NSString *urlString = gCustomVTPParser(streamId);
// Build the Pod serving Stream URL.
NSString *streamID = adsLoadedData.streamManager.streamId;
// Your custom VTP handler takes the stream ID and returns the stream manifest URL.
NSString *urlString = gCustomVTPHandler(streamID);
NSURL *streamUrl = [NSURL URLWithString:urlString];
if (kRequestType == liveStream) {
if (kStreamType == StreamTypeLive) {
// Load live streams directly into the AVPlayer.
[self.videoDisplay loadStream:streamUrl withSubtitles:@[]];
[self.videoDisplay play];
} else {
// Load VOD streams using the `loadThirdPartyStream` method in IMA SDK's stream manager.
// The stream manager loads the stream, requests metadata, and starts playback.
[self.streamManager loadThirdPartyStream:streamUrl streamSubtitles:@[]];
// There is no need to trigger playback here.
// streamManager.loadThirdPartyStream will load the stream, request metadata, and play
}
NSLog(@"Stream created with: %@.", self.streamManager.streamId);
}

- (void)adsLoader:(IMAAdsLoader *)loader failedWithErrorData:(IMAAdLoadingErrorData *)adErrorData {
// Something went wrong loading ads. Log the error and play the content.
// Log the error and play the content.
NSLog(@"AdsLoader error, code:%ld, message: %@", adErrorData.adError.code,
adErrorData.adError.message);
[self.contentPlayer play];
[self.videoPlayer play];
}
// [END ads_loader_delegates]

#pragma mark StreamManager Delegates

// [START stream_manager_delegates]
- (void)streamManager:(IMAStreamManager *)streamManager didReceiveAdEvent:(IMAAdEvent *)event {
NSLog(@"StreamManager event (%@).", event.typeString);
NSLog(@"Ad event (%@).", event.typeString);
switch (event.type) {
case kIMAAdEvent_STARTED: {
// Log extended data.
Expand Down Expand Up @@ -199,7 +197,8 @@ - (void)streamManager:(IMAStreamManager *)streamManager didReceiveAdEvent:(IMAAd
- (void)streamManager:(IMAStreamManager *)streamManager didReceiveAdError:(IMAAdError *)error {
NSLog(@"StreamManager error with type: %ld\ncode: %ld\nmessage: %@", error.type, error.code,
error.message);
[self.contentPlayer play];
[self.videoPlayer play];
}
// [END stream_manager_delegates]

@end
Loading

0 comments on commit 2f4bb1b

Please sign in to comment.