support Contact Support | system status System Status
Page Contents

    Using the Pulse plugin with the Native SDK for Android

    In this topic, you will learn how to use the Pulse plugin with Brightcove's Native SDK for Android.

    Introduction

    Brightcove's Pulse plugin enables you to integrate Invidi's Pulse SDK with the Brightcove Native SDK for Android. Pulse is a Video Advertisement Platform. For campaigns and configuration details, see their User Guide.

    Steps

    Once a campaign is created in the Pulse platform, you can start using the Pulse Plugin for the Brightcove Native SDK for Android. Follow these steps to integrate the Pulse Plugin with your project:

    1. In your module build.gradle file, add the Pulse plugin dependency.

      dependencies {
          implementation 'com.brightcove.player:android-pulse-plugin:6.12.0'
      }
    2. Download the Pulse SDK .aar file.

    3. In your app/libs folder, open the build.gradle file from your module. Modify the following:

      dependencies {
          implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
      }
    4. In your MainActivity.java file, initialize the Pulse Plugin by instantiating a PulseComponent with the Pulse host URL created for your campaign.

      @Override
      protected void onCreate(Bundle savedInstanceState) {
          // ...
          // Creating pulse component
          PulseComponent pulseComponent = new PulseComponent(
                  "your pulse host url",
                  brightcoveVideoView.getEventEmitter(),
                  brightcoveVideoView);
          // ...
      }
    5. Set the PulseComponent Listener.

      pulseComponent.setListener(new PulseComponent.Listener() {
        @NonNull
        @Override
        public PulseSession onCreatePulseSession(
          @NonNull String hostUrl,
          @NonNull Video video,
          @NonNull ContentMetadata contentMetadata,
          @NonNull RequestSettings requestSettings) {
          // See step 3a
          return Pulse.createSession(contentMetadata, requestSettings);
        }
      
        @Override
        public void onOpenClickthrough(@NonNull PulseVideoAd pulseVideoAd) {
        }
      });
    6. Implement the onCreatePulseSession method, which creates a PulseSession and returns it to the PulseComponent. There are three parameters:

      • The pulse host
      • The content metadata settings
      • The request settings

      @NonNull
      @Override
      public PulseSession onCreatePulseSession(
          @NonNull String hostUrl,
          @NonNull Video video,
          @NonNull ContentMetadata contentMetadata,
          @NonNull RequestSettings requestSettings) {
        // Set the pulse Host:
        Pulse.setPulseHost(pulseHostUrl, null, null);
      
        // Content metadata settings
        contentMetadata.setCategory("skip-always");
        contentMetadata.setTags(Collections.singletonList("standard-linears"));
        contentMetadata.setIdentifier("demo");
      
        // Request Settings:
        // Adding mid-rolls
        List<Float> midrollCuePoints = new ArrayList<>();
        midrollCuePoints.add(60f);
        requestSettings.setLinearPlaybackPositions(midrollCuePoints);
      
        // Create and return the PulseSession
        return Pulse.createSession(contentMetadata, requestSettings);
      }
    7. Implement the onOpenClickthrough method, which is called when the learn more button from a Linear Ad is clicked. A typical action for this callback is to open the browser with the expected url.

      @Override
      public void onOpenClickthrough(@NonNull PulseVideoAd pulseVideoAd) {
        Intent intent = new Intent(Intent.ACTION_VIEW)
          .setData(Uri.parse(pulseVideoAd.getClickthroughURL().toString()));
        brightcoveVideoView.getContext().startActivity(intent);
        pulseVideoAd.adClickThroughTriggered();
      }
    8. Play your content

      Catalog catalog = new Catalog.Builder(
        eventEmitter,
        getString(R.string.account))
        .setPolicy(getString(R.string.policy))
        .build();
      
      catalog.findVideoByID(getString(R.string.videoId), new VideoListener() {
        // Add the video found to the queue with add().
        // Start playback of the video with start().
        @Override
        public void onVideo(Video video) {
          brightcoveVideoView.add(video);
          brightcoveVideoView.start();
        }
      });

    Pulse Pause Ads

    When the Pulse campaign has "Pause Ads" configured, the Pulse plugin will show the user when the content is paused.

    Error handling

    All errors will be surfaced to the developer using the EventType.AD_ERROR event, as shown below:

    eventEmitter.on(EventType.AD_ERROR, event -> {
        Throwable error = event.getProperty(Event.ERROR, Throwable.class);
        Log.e(TAG, "AD_ERROR: ", error);
    });

    UI Customization

    Internally, the Pulse plugin inflates the PulseAdView using the R.layout.pulse_ad_view layout id. For a different layout, you can create a layout file with the same name and add it to the res/layout directory. This overrides the default layout.

    Use the following ids to replace the defaults:

    Component Views
    Component Views
    Index View Type View Id
    A TextView pulse_ad_number_view
    B TextView pulse_ad_countdown_view
    C TextView pulse_ad_name_view
    D TextView pulse_ad_learn_more_view
    E TextView pulse_skip_ad_view

    Complete code sample

    Here is a complete code sample for using the Pulse plugin with the Native SDK for Android.

    Activity

    Here is a example of the full Activity code:

    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
          setContentView(R.layout.activity_main);
    
          final BrightcoveVideoView videoView = findViewById(R.id.video_view);
          super.onCreate(savedInstanceState);
    
          EventEmitter eventEmitter = videoView.getEventEmitter();
    
          // Pulse setup
          PulseComponent pulseComponent = new PulseComponent(
              "https://pulse-demo.videoplaza.tv",
              eventEmitter,
              videoView);
    
          pulseComponent.setListener(new PulseComponent.Listener() {
              @NonNull
              @Override
              public PulseSession onCreatePulseSession(
                    @NonNull String pulseHostUrl,
                    @NonNull Video video,
                    @NonNull ContentMetadata contentMetadata,
                    @NonNull RequestSettings requestSettings) {
                Pulse.setPulseHost(pulseHostUrl, null, null);
                contentMetadata.setCategory("skip-always");
                contentMetadata.setTags(Collections.singletonList("standard-linears"));
                contentMetadata.setIdentifier("demo");
    
                // Adding mid-rolls
                List<Float> midrollCuePoints = new ArrayList<>();
                midrollCuePoints.add(60f);
                requestSettings.setLinearPlaybackPositions(midrollCuePoints);
    
                return Pulse.createSession(
                  contentMetadata,
                  requestSettings);
              }
    
              @Override
              public void onOpenClickthrough(@NonNull PulseVideoAd ad) {
                Intent intent = new Intent(Intent.ACTION_VIEW)
                  .setData(Uri.parse(ad.getClickthroughURL().toString()));
                videoView.getContext().startActivity(intent);
                ad.adClickThroughTriggered();
              }
          });
    
          Catalog catalog = new Catalog.Builder(eventEmitter, "YourAccountId")
              .setPolicy("YourPolicyKey")
              .build();
          catalog.findVideoByID("YourVideoId", new VideoListener() {
    
            // Add the video found to the queue with add().
            // Start playback of the video with start().
            @Override
            public void onVideo(Video video) {
              videoView.add(video);
              videoView.start();
            }
          });
        }
      }

    Layout

    Here is an example of the layout code for the R.layout.pulse_ad_view.

    <?xml version="1.0" encoding="utf-8"?>
      <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools"
          android:layout_width="match_parent"
          android:layout_height="match_parent">
    
          <RelativeLayout
              android:id="@+id/view_ad_details"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:background="@drawable/pulse_skip_button_background_selector">
    
              <TextView
                  android:id="@+id/pulse_ad_name_view"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:layout_alignParentTop="true"
                  android:layout_marginTop="4dp"
                  android:paddingTop="4dp"
                  android:paddingStart="8dp"
                  android:paddingEnd="8dp"
                  android:textColor="@color/white"
                  android:background="@color/bmc_live"
                  android:textStyle="bold"
                  tools:text="Preroll blue"/>
    
              <TextView
                  android:id="@+id/pulse_ad_number_view"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:paddingStart="8dp"
                  android:paddingEnd="4dp"
                  android:paddingBottom="4dp"
                  android:layout_marginBottom="8dp"
                  android:layout_below="@id/pulse_ad_name_view"
                  android:textColor="@color/white"
                  android:background="@color/white_semi_trans"
                  tools:text="Ad (1 of 2)"/>
    
              <TextView
                  android:id="@+id/pulse_ad_countdown_view"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:paddingStart="4dp"
                  android:paddingEnd="4dp"
                  android:paddingBottom="4dp"
                  android:layout_marginBottom="4dp"
                  android:layout_below="@id/pulse_ad_name_view"
                  android:layout_toEndOf="@+id/pulse_ad_number_view"
                  android:textColor="@color/green_almost_opaque"
                  android:text=""
                  tools:text="00:06"/>
    
              <TextView
                  android:id="@+id/pulse_ad_learn_more_view"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:layout_marginStart="@dimen/pulse_ad_learn_more_margin_left"
                  android:layout_marginTop="@dimen/pulse_ad_learn_more_margin_top"
                  android:layout_marginEnd="@dimen/pulse_ad_learn_more_margin_right"
                  android:layout_marginBottom="@dimen/pulse_ad_learn_more_margin_bottom"
                  android:layout_alignTop="@id/pulse_ad_name_view"
                  android:layout_alignBottom="@id/pulse_ad_countdown_view"
                  android:layout_alignParentEnd="true"
                  android:background="@drawable/pulse_learn_more_button_background"
                  android:paddingStart="12dp"
                  android:paddingEnd="12dp"
                  android:padding="@dimen/pulse_ad_learn_more_padding_default"
                  android:gravity="center"
                  android:shadowColor="@color/brightcove_semitransparent"
                  android:shadowDx="-1"
                  android:shadowDy="1"
                  android:shadowRadius="1.5"
                  android:text="@string/pulse_message_learn_more"
                  android:textColor="@color/pulse_button_text_color"
                  android:nextFocusUp="@id/pulse_skip_ad_view"
                  android:textSize="@dimen/pulse_message_text_size"
                  android:visibility="gone"
                  tools:visibility="visible" />
    
          </RelativeLayout>
    
          <TextView
              android:id="@+id/pulse_skip_ad_view"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:maxWidth="164dp"
              android:layout_alignParentEnd="true"
              android:layout_centerVertical="true"
              android:layout_marginBottom="@dimen/pulse_skip_ad_margin_bottom"
              android:background="@drawable/pulse_skip_button_background_selector"
              android:ellipsize="none"
              android:gravity="center"
              android:maxLines="2"
              android:paddingStart="@dimen/pulse_skip_ad_padding_left"
              android:paddingEnd="@dimen/pulse_skip_ad_padding_right"
              android:paddingTop="@dimen/pulse_skip_ad_padding"
              android:paddingBottom="@dimen/pulse_skip_ad_padding"
              android:scrollHorizontally="false"
              android:shadowColor="@color/brightcove_shadow"
              android:shadowDx="-1"
              android:shadowDy="1"
              android:shadowRadius="1.5"
              android:text="@string/pulse_message_skip_ad"
              android:textColor="@color/pulse_button_text_color"
              android:textSize="@dimen/pulse_message_text_size"
              android:visibility="gone"
              android:nextFocusUp="@id/pulse_ad_learn_more_view"
              android:focusable="true"
              tools:visibility="visible"/>
    
      </RelativeLayout>
      

    Page last updated on 28 Sep 2020