Code Snippets using the Native SDK for iOS

The page you are looking for doesn't live here anymore -- redirecting you to in 3 seconds.

In this topic, you will find a collection of code snippets which you may find useful as a reference while developing with the SDK. For more detailed solutions, see the iOS player samples.

Table of contents

Advertising

Analytics

Cue points

Playback

Google Analytics

If you use the Brightcove player and the catalog class, video analytics will be automatically collected and will appear in your Video Cloud Analytics module. For additional metrics, you can add Google Analytics to your app.

To integrate Google Analytics with your app, follow these steps:

  1. In your project Podfile, add the following dependency:

    pod 'Google/Analytics'
  2. Get a Google configuration file and add it to your project.
  3. Initialize analytics for your app:

    // AppDelegate.m
    #import <Google/Analytics.h>
    
    // Configure tracker from GoogleService-Info.plist.
    NSError *configureError;
    [[GGLContext sharedInstance] configureWithError:&configureError];
    NSAssert(!configureError, @"Error configuring Google services: %@", configureError);
    
    // Optional: configure GAI options.
    GAI *gai = [GAI sharedInstance];
    gai.trackUncaughtExceptions = YES;  // report uncaught exceptions
    gai.logger.logLevel = kGAILogLevelVerbose;  // remove before app release
  4. Send screen view to analytcis:

    // ViewController.m
    #import <Google/Analytics.h>
    
    id<GAITracker> tracker = [[GAI sharedInstance] defaultTracker];
    [tracker set:kGAIScreenName value:name];
    [tracker send:[[GAIDictionaryBuilder createScreenView] build]];

For detailed steps, see Google's document to Add Analytics to Your iOS App.

Limiting the bitrate

You can't control which source (rendition) in the HLS manifest gets selected by the AVPlayer, but you can put a bitrate cap on playback. This prevents the player from using sources (renditions) with a bitrate over the specified bitrate.

Set the preferredPeakBitRate to the desired limit, in bits per second, of the network bandwidth consumption for the given AVPlayerItem.

Use one of the following declarations:

// Swift
var preferredPeakBitRate: Double

// Obj-C
@property(nonatomic) double preferredPeakBitRate

Looping a video

In some cases, you may want a video to automatically replay. To do this, you can get the "end of video" lifecycle event, seek to the beginning and play again.

This code assumes that you have set the delegate of the playbackController to the object with this method:

- (void)playbackController:(id<BCOVPlaybackController>)controller playbackSession:(id<BCOVPlaybackSession>)session didReceiveLifecycleEvent:(BCOVPlaybackSessionLifecycleEvent *)lifecycleEvent
{
    if ([kBCOVPlaybackSessionLifecycleEventEnd isEqualToString:lifecycleEvent.eventType])
    {
        [controller seekToTime:kCMTimeZero completionHandler:^(BOOL finished) {
            if (finished)
            {
               [controller play];
            }
        }];
    }
}

Media progress values

During media playback, the values reported to the Player SDK progress delegate method may include an initial value of negative infinity and a final value of positive infinity. These values are used when processing pre-roll and post-roll ads.

If these values are not important to you or interfere with your own progress tracking, they can be easily ignored with a conditional statement like this:

- (void)playbackController:(id<BCOVPlaybackController>)controller playbackSession:(id<BCOVPlaybackSession>)session didProgressTo:(NSTimeInterval)progress
  {
    if (progress < 0.0 || progress >= INFINITY)
        return;

    // Your code here
  }

OnceUX quartile events

When reading OnceUX VMAPS with the Brightcove OnceUX plugin, the quartile events must define valid offset values. In other words, the quartiles must contain offsets within their quartile impressions in order to be fired at that time.

Here are the observed events that are fired through the end of a pre-roll ad, when the quartile offsets are absent:

impression
companionCreativeView
creativeView
complete

Here are the observed events when valid offset values are used:

companionCreativeView
impression
creativeView
start
firstQuartile
midpoint
thirdQuartile
complete

OnceUX maintains an array of events to be fired during playback of ads, and that array is ordered by the event offsets. An event which does not possess a valid offset cannot be added to the array which means it cannot be fired during ad playback. The complete event is a special case which is handled without using the ordered event array.

Programmatically adding cue points

You can add cue points to your video using Video Cloud Studio as shown in the Adding Cue Points to Videos document.

You can also addYou can add cue points to your video programmatically. The code below adds quarterly interval cue points to the video returned from the Playback API:

// programmatically add cue points to a video
    - (void)requestContentFromPlaybackService
    {
    [self.service findVideoWithVideoID:kViewControllerVideoID parameters:nil completion:^(BCOVVideo *video, NSDictionary *jsonResponse, NSError *error) {

      if (video)
      {
        // Get the video duration from the properties dictionary
         NSNumber *durationNumber = video.properties[@"duration"]; // milliseconds
         float duration = durationNumber.floatValue / 1000.0; // convert to seconds

        video = [video update:^(id<BCOVMutableVideo> mutableVideo)
        {
          // Add quarterly interval cue points of your own type
          BCOVCuePoint *cp1 = [[BCOVCuePoint alloc] initWithType:@"Your Cue Point Type" position:CMTimeMake(duration * 250, 1000)];
          BCOVCuePoint *cp2 = [[BCOVCuePoint alloc] initWithType:@"Your Cue Point Type" position:CMTimeMake(duration * 500, 1000)];
          BCOVCuePoint *cp3 = [[BCOVCuePoint alloc] initWithType:@"Your Cue Point Type" position:CMTimeMake(duration * 750, 1000)];
          BCOVCuePoint *cp4 = [[BCOVCuePoint alloc] initWithType:@"Your Cue Point Type" position:CMTimeMake(duration * 1000, 1000)];
          // Create new cue point collection using existing cue points and new cue points
          NSMutableArray *newCuePoints = [[NSMutableArray alloc] initWithArray:mutableVideo.cuePoints.array];
          [newCuePoints addObject:cp1];
          [newCuePoints addObject:cp2];
          [newCuePoints addObject:cp3];
          [newCuePoints addObject:cp4];
          mutableVideo.cuePoints = [[BCOVCuePointCollection alloc] initWithArray:newCuePoints];
        }];

        [self.playbackController setVideos:@[ video ]];
      }
      else
      {
        NSLog(@"ViewController Debug - Error retrieving video: `%@`", error);
      }

    }];
}

The code below listens for your cue points and displays a message:

// listen for cue points and display them
-(void)playbackController:(id<BCOVPlaybackController>)controller playbackSession:(id<BCOVPlaybackSession>)session didPassCuePoints:(NSDictionary *)cuePointInfo {
    BCOVCuePointCollection *cpc = cuePointInfo[@"kBCOVPlaybackSessionEventKeyCuePoints"];
    for (BCOVCuePoint *cp in cpc) {
         if ([cp.type isEqualToString:@"Your Cue Point Type"])
         {
             NSLog(@"Found your cue point at %f", CMTimeGetSeconds(cp.position));
         }
    }
}

Setting the playback rate

To control the playback rate, you can set the rate property on the AVPlayer class exposed on the session. For a BCOVPlaybackSession, you could do something like this:

session.player.rate = 2;

Note the following:

  • For iOS6, a stream can only play at 2X if session.player.currentItem.canPlayFastForward returns YES.
  • For iOS7, you can play up to 2X always, but it won't go higher unless session.player.currentItem.canPlayFastForward returns Yes.

Setting VR Goggles mode for 360° videos

When playing a 360° video, users can select the Video 360 button on the control bar to switch to VR Goggles mode. You may also want to do this programmatically, before playback starts. You can do this by updating the BCOVPlaybackController protocol's viewProjection property as follows:

- (void)playbackController:(id<BCOVPlaybackController>)controller didAdvanceToPlaybackSession:(id<BCOVPlaybackSession>)session
{
  BCOVVideo360ViewProjection *viewProjection = [self.playbackController.viewProjection copy];
  [viewProjection setProjectionStyle:BCOVVideo360ProjectionStyleVRGoggles];
  [self.playbackController setViewProjection:viewProjection];
}