Pulse Plugin for Brightcove Player SDK provides a dynamic library framework for installation.
The Pulse plugin supports INVIDI Technologies Pulse SDK version 2.6.21.6.0 for iOS and version 2.6.21.6.0 for tvOS, Pulse iOS and tvOS SDK Reference. The Podspec for the Pulse Plugin for Brightcove Player SDK references Pulse SDK Release History.
You can use CocoaPods to add the Pulse Plugin for Brightcove Player SDK to your project. You can find the latest Brightcove-Player-Pulse
podspec here. The PulseSDK needs to be added to your project, download the latest version here.
source 'https://github.com/CocoaPods/Specs'
source 'https://github.com/brightcove/BrightcoveSpecs.git'
platform :ios, '12.0'
use_frameworks!
target 'MyApp' do
pod 'Brightcove-Player-Pulse'
end
XCFramework can be installed by appending the /XCFramework
subspec in the pod name.
source 'https://github.com/CocoaPods/Specs'
source 'https://github.com/brightcove/BrightcoveSpecs.git'
platform :ios, '12.0'
use_frameworks!
target 'MyApp' do
pod 'Brightcove-Player-Pulse/XCFramework'
end
To add the Pulse Plugin for Brightcove Player SDK to your project manually:
- Download the latest zipped Brightcove Player SDK framework from the releases page.
- Download the latest zip'ed release of the BrightcovePulse plugin from our release page.
- Download the PulseSDK.
- On the "General" tab of your application target, add the dynamic framework,
BrightcovePlayerSDK.framework
orBrightcovePlayerSDK.xcframework
, from the Brightcove Player SDK download to the list of Frameworks, Libraries, and Embedded Content. The universal Framework and XCFramework are found in the ios/dynamic directory of the download. The Embed setting must be "Embed & Sign". - On the "General" tab of your application target, add
BrightcovePulse.framework
orBrightcovePulse.xcframework
from the Pulse Plugin for Brightcove Player SDK download to the list of Frameworks, Libraries, and Embedded Content. The Embed setting must be "Embed & Sign". - On the "General" tab of your application target, add
PulseSDK.xcframework
andOMSDK_Invidi.xcframework
from the INVIDI Technologies download to the list of Frameworks, Libraries, and Embedded Content. The Embed setting for the XCFrameworks must be "Embed & Sign". - On the "Build Settings" tab of your application target, ensure that the "Framework Search Paths" include the paths to the frameworks. This should have been done automatically unless the framework is stored under a different root directory than your project.
- (Universal Framework only) On the "Build Phases" tab, add a "Run Script" phase with the command
bash ${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/BrightcovePulse.framework/strip-frameworks.sh
. Check "Run script only when installing". This will remove unneeded architectures from the build, which is important for App Store submission. - On the "Build Settings" tab of your application target:
- Ensure that
-ObjC
has been added to the "Other Linker Flags" build setting.
- Ensure that
- (Apple Silicon with Universal Framework only) On the "Build Settings" tab of your application target:
- Ensure that
arm64
has been added to your "Excluded Architectures" build setting forAny iOS Simulator SDK
.
- Ensure that
To add the Pulse Plugin for Brightcove Player SDK to your project with Swift Package Manager:
- First follow the steps to add the Core XCFramework with Swift Package Mananger.
- Add the Pulse package to Swift Package Manager using
https://github.com/brightcove/brightcove-player-sdk-ios-pulse.git
. - Download the PulseSDK.
- On the "General" tab of your application target, add
PulseSDK.xcframework
andOMSDK_Invidi.xcframework
from the INVIDI Technologies download to the list of Frameworks, Libraries, and Embedded Content. The Embed setting for the XCFrameworks must be "Embed & Sign". - On the "Build Settings" tab of your application target, ensure that the "Framework Search Paths" include the paths to the frameworks. This should have been done automatically unless the framework is stored under a different root directory than your project.
The Pulse Plugin for Brightcove Player SDK can be imported into code a few different ways; @import BrightcovePulse;
, #import <BrightcovePulse/BrightcovePulse.h>
or #import <BrightcovePulse/[specific class].h>
. You can import the PulseSDK
and BrightcovePlayerSDK
modules in similar fashion.
The BrightcovePulse plugin is a bridge between PulseSDK and the Brightcove Player SDK for iOS. This snippet shows its basic usage with Server Side Ad Rules.
[1] OOContentMetadata *contentMetadata = [OOContentMetadata new];
contentMetadata.category = <category>;
contentMetadata.tags = @[ <tag1>, <tag2>, ..., <tagN> ];
contentMetadata.flags = @[ <flag1>, <flag2>, ..., <flagN> ];
OORequestSettings *requestSettings = [OORequestSettings new];
requestSettings.linearPlaybackPositions = @[ @(position1), @(position2), ..., @(positionN) ];
NSString *pulseHost = <pulse domain>;
[2] NSDictionary *pulseOptions = @{ kBCOVPulseOptionPulsePlaybackSessionDelegateKey: self,
kBCOVPulseOptionPulsePersistentIdKey: [NSUUID.UUID UUIDString]
};
BCOVPlayerSDKManager *manager = [BCOVPlayerSDKManager sharedManager];
id<BCOVPlaybackController> controller =
[3] [manager createPulsePlaybackControllerWithPulseHost:pulseHost
contentMetadata:contentMetadata
requestSettings:requestSettings
adContainer:self.playerView.contentOverlayView
companionSlots:nil
viewStrategy:nil
options:pulseOptions];
controller.delegate = self;
[videoContainerView addSubview:controller.view];
NSString *policyKey = <your-policy-key>;
NSString *accountId = <your-account-id>;
NSString *videoID = <your-video-id>;
BCOVPlaybackService *playbackService = [[BCOVPlaybackService alloc] initWithAccountId:accountID
policyKey:policyKey];
NSDictionary *configuration = @{
kBCOVPlaybackServiceConfigurationKeyAssetID:videoID
};
[playbackService findVideoWithConfiguration:configuration
queryParameters:nil
completion:^(BCOVVideo *video,
NSDictionary *jsonResponse,
NSError *error) {
[controller setVideos:@[ video ]];
[controller play];
}];
Breaking the code down into steps:
- Create the same OOContentMetadata, OORequestSettings that you would create if you were using INVIDI Technologies's Pulse iOS SDK directly. The Pulse Plugin requires a valid domain and an UIView container to display the ads.
- Optionally, the plugin can receive a NSDictionary with properties to be used in the plugin. The available keys are
kBCOVPulseOptionPulsePlaybackSessionDelegateKey
,kBCOVPulseOptionPulseDeviceContainerKey
andkBCOVPulseOptionPulsePersistentIdKey
. To override the Pulse Session, the PulsePlaybackSessionDelegate needs to be implemented, passing thekBCOVPulseOptionPulsePlaybackSessionDelegateKey
with the class that implements the method. - BrightcovePulse adds some category methods to BCOVPlaybackManager. The first of these is
-createPulsePlaybackControllerWithPulseHost:contentMetadata:requestSettings:adContainer:companionSlots:viewStrategy:options:
. Use this method to create your playback controller.
The Brightcove Pulse Plugin implements custom play and pause logic to ensure the smoothest possible ad experience. Therefore, you will need to make sure that you use the play method on the BCOVPlaybackController
or the -[BCOVSessionProviderExtension pulse_play]
or -[BCOVSessionProviderExtension pulse_pause]
(BCOVSessionProviderExtension), and not the AVPlayer.
As an example, calling play for the first time on BCOVPlaybackController
allows BCOVPulse to process preroll ads without any of the content playing before the preroll. For more information on how BCOVPulse overrides the default BCOVPlaybackController
methods, please check out BCOVSessionProviderExtension.
In your UIViewController
, create a BCOVPUIPlayerView
property called the player view, to contain the playback controls, the video content view, and a special view where Pulse can display its ads.
// PlayerUI's player view
@property (nonatomic) BCOVPUIPlayerView *playerView;
Then create your player view; supply a nil playback controller which will be added later. This player view contains both the video content view and the view that displays playback controls and ad controls. This setup is the same no matter what plugin you are using. Set up the player view to match the video container from your layout (videoView
) when it resizes.
// Create and configure Control View.
BCOVPUIBasicControlView *controlView = [BCOVPUIBasicControlView basicControlViewWithVODLayout];
// Create the player view with a nil playback controller.
self.playerView = [[BCOVPUIPlayerView alloc] initWithPlaybackController:nil options:nil controlsView:controlView];
// Add BCOVPUIPlayerView to your video view.
[self.videoView addSubview:self.playerView];
You'll need to set up the layout for the player view, you can do this with Auto Layout or the older Springs & Struts method.
self.playerView.frame = self.videoView.bounds;
self.playerView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
self.playerView.translatesAutoresizingMaskIntoConstraints = NO;
[NSLayoutConstraint activateConstraints:@[
[self.playerView.topAnchor constraintEqualToAnchor:self.videoView.topAnchor],
[self.playerView.rightAnchor constraintEqualToAnchor:self.videoView.rightAnchor],
[self.playerView.leftAnchor constraintEqualToAnchor:self.videoView.leftAnchor],
[self.playerView.bottomAnchor constraintEqualToAnchor:self.videoView.bottomAnchor],
]];
Creating the playback controller is specific to Pulse. Create your playback controller as you did above, but instead of your video container view, pass in the contentOverlayView
from the player view as your adContainer
. The contentOverlayView
is a special view used for overlaying views on the main video content. You should also use nil
instead of [manager defaultControlsViewStrategy]
if you were using that as your viewStrategy
(this was the older method for using built-in controls).
// Create the playback controller.
id<BCOVPlaybackController> controller =
[manager createPulsePlaybackControllerWithPulseHost:pulseHost
contentMetadata:contentMetadata
requestSettings:requestSettings
adContainer:self.playerView.contentOverlayView
companionSlots:nil
viewStrategy:nil
options:nil];
controller.delegate = self;
// Assign new playback controller to the player view.
// This associates the playerController's session with the PlayerUI.
// You can keep this player view around and assign new
// playback controllers to it as they are created.
self.playerView.playbackController = self.playbackController;
Now, when playing video with ads, you will see the PlayerUI controls while playing video content, plus ad markers on the timeline scrubber.
The PlayerUI is highly customizable. For more information and sample code, please see Custom Layouts section in the README.md file of the Brightcove Native Player SDK repository.
There are a couple of configuration points in BCOVPulse. You can combine BCOVPulse with another plugin for the Brightcove Player SDK for iOS, you can create a custom view strategy, and you can override the current ads request.
The BCOVPulsePlaybackSessionDelegate
protocol provides a way for the BrightcovePulse plugin to communicate with the host application. This delegate allows you to override the content metadata and request settings before the session starts.
The UIViewController
needs to adopt the BCOVPulsePlaybackSessionDelegate
protocol.
@interface ViewController () <BCOVPulsePlaybackSessionDelegate>
Create a NSDictionary passing the kBCOVPulseOptionPulsePlaybackSessionDelegateKey
with the class that will implement the method to override the session.
NSDictionary *pulseOptions = @{ kBCOVPulseOptionPulsePlaybackSessionDelegateKey: self };
Create a BCOVPlaybackSessionProvider
or BCOVPlaybackController
for Pulse using the methods in BCOVPlaybackManager
, remember to pass the dictionary created in the previous step. This example uses a playback controller.
BCOVPlayerSDKManager *manager = [BCOVPlayerSDKManager sharedManager];
id<BCOVPlaybackController> controller =
[manager createPulsePlaybackControllerWithPulseHost:pulseHost
contentMetadata:[OOContentMetadata new]
requestSettings:[OORequestSettings new]
adContainer:self.playerView.contentOverlayView
companionSlots:nil
viewStrategy:nil
options:pulseOptions];
The createSessionForVideo:withPulseHost:contentMetadata:requestSettings:
method provides the current video, host domain, content metadata and request settings for the session. In this example, the previous objects were empty and will be overriden with a new OOContentMetadata
and OORequestSettings
array.
- (id<OOPulseSession>)createSessionForVideo:(BCOVVideo *)video
withPulseHost:(NSString *)pulseHost
contentMetadata:(OOContentMetadata *)contentMetadata
requestSettings:(OORequestSettings *)requestSettings
{
// Override the content metadata.
contentMetadata.category = @"new_category_for_midrolls";
// Override the request settings.
requestSettings.linearPlaybackPositions = @[ @(15) ];
return [OOPulse sessionWithContentMetadata:contentMetadata requestSettings:requestSettings];
}
You can provide a custom view strategy to the BCOVPlaybackManager when you are constructing your playback controller or session provider, rather than specify the defaultControlsViewStrategy directly. With a custom view strategy, the ad container view and ad companion slots can be tied with the video content view. This is an example of custom view strategy.
BCOVPlaybackControllerViewStrategy customViewStrategy = ^UIView* (UIView *view, id<BCOVPlaybackController> playbackController){
BCOVPlaybackControllerViewStrategy defaultControlsViewStrategy = [playbackManager defaultControlsViewStrategy];
UIView *contentAndDefaultControlsView = defaultControlsViewStrategy(view, playbackController);
[<UIView of video container> addSubview:contentAndDefaultControlsView];
return <UIView of video container>;
};
If you are using more than one plugin to the Brightcove Player SDK for iOS that needs to create a customized playback controller, you must instead compose a chain of session providers and pass the final session provider to the -[BCOVPlayerSDKManager createPlaybackControllerWithSessionProvider:viewStrategy:]
method.
When composing session providers, the session preloading can be enabled from BCOVBasicSessionProvider
.
If you'd like to display your own Ad UI during ad playback you can use the playbackController:playbackSession:didEnterAd:
and playbackController:playbackSession:didExitAdSequence:
delegate methods. Here is an example:
#pragma mark BCOVPlaybackControllerDelegate
- (void)playbackController:(id<BCOVPlaybackController>)controller playbackSession:(id<BCOVPlaybackSession>)session didEnterAd:(BCOVAd *)ad
{
NSTimeInterval duration = CMTimeGetSeconds(ad.duration);
[self displayAdUI:duration];
}
- (void)playbackController:(id<BCOVPlaybackController>)controller playbackSession:(id<BCOVPlaybackSession>)session didExitAdSequence:(BCOVAdSequence *)adSequence
{
...
[self hideAdUI];
}
The Brightcove Pulse plugin does not currently support Picture-in-Picture. Attempting to use Picture-in-Picture functionality with the Pulse plugin will result in unexpected behavior.
This usually happens when the ad container view is not in the view hierarchy, or when the ad view (which is a subview of the ad container view) is covered by other views.
If you have questions, need help or want to provide feedback, please use the Support Portal or contact your Account Manager. To receive notification of new SDK software releases, subscribe to the Brightcove Native Player SDKs Google Group.