Picture-in-Picture Plugin (aka "floating" or "pinned")

In this topic, you will learn how to use the picture-in-picture plugin to enable this mode for the Brightcove Player.

Overview

Picture-in-picture mode allows users to multitask. Once video playback has started, as the user scrolls down the page, picture-in-picture mode will reposition and pin the player to a corner of the web page.

Why it is called Picture-in-Picture

The behavior this plugin enables is also commonly referred to as "floating" or "pinned" behavior. Brightcove uses the term "picture-in-picture" because:

  • Adoption of this verbiage by Apple and Google for their native browsers.
  • W3C standards also reference "picture-in-picture".

Brightcove plugin vs. native functionality

Most modern browsers now include picture-in-picture functionality. In this section you will see the differences between the Picture-in-Picture plugin and the native functionality. This will be followed by reasons why you would want to turn off native functionality and add the plugin to your player.

Native browser functionality

The following details how the native browser picture-in-picture functions:

  • You do not have to do anything to enable the functionality, the icon for picture-in-picture will be in the controlbar.
  • The icon button works as a toggle, viewers toggle the functionality on and off.
  • The native picture-in-picture functionality opens a browser player in an entirely new browser/OS window, which can be controlled independent of the web page that launched it. Hence, the picture-in-picture player is NOT bounded by the browser. The picture-in-picture player will appear in the bottom right of your screen, no matter how your browser is sized.
  • The video in the Brightcove Player is "grayed out" when the native picture-in-picture functionality is toggled on.
  • The native picture-in-picture button does not display when ads are enabled.

See how it works

Watch this video to see the native implementation in use:

Turn off functionality

If you want to turn off the native browser functionality, place the following line of JSON code in the player configuration using Video Cloud Studio's JSON Editor:

"picture_in_picture_control": false,
json editor

Brightcove plugin

The following details how the Brightcove Player Picture-in-Picture plugin functions:

  • Once the plugin is installed the viewer does NOT need to take any action to start the picture-in-picture player, other than scroll the Brightcove Player mostly out of view. There is no button to click to turn on picture-in-picture.
  • When the viewer scrolls the Brightcove Player back into view, the picture-in-picture player will automatically disappear.
  • The picture-in-picture player is displayed (be default) in the bottom-right corner of the browser. Unlike the native functionality, the plugin is bounded by the browser.

See how it works

Watch this video to see the Brightcove Player plugin implementation in use:

Why use the Brightcove Player plugin?

With the native functionality built in, and you don't have to do anything, why would you want to turn off the native functionality and install the Brightcove Player plugin? The following are some of the reasons:

  • The native player does not play client-side ads. It will play SSAI ads, but will not provide the UI customizations that Brightcove Player does and will not prevent the user from seeking through/over those ads.
  • You want the picture-in-picture functionality to be bounded by the browser. You do not want the picture-in-picture player to be placed outside the browser's real estate.
  • You want the functionality to be in effect without any user interaction.
  • The plugin provides more, and easier to implement, customization. Options, methods and events you can use with the plugin are listed near the end of this document.

Player example

Start video playback. (You can then stop it). Scroll down the page to see the picture-in-picture player in the right-hand corner of the web page. You can close the picture-in-picture player or scroll back up to the full-size player.

See the Pen Picture-in-Picture Plugin by Brightcove Learning Services (@bcls1969) on CodePen.

Implement using Players module

To implement the Picture-in-Picture Plugin using the Players module, follow these steps:

  1. Open the PLAYERS module and either create a new player or locate the player to which you wish to add the plugin.
  2. Select the link for the player to open the player's properties.
  3. Select Plugins in the left navigation menu.
  4. Next, select the Add a Plugin button, and then select Brightcove Plugin.

    Add a Plugin button
    Add a Plugin button
  5. Expand the Brightcove Plugin dropdown and select Picture-in-Picture.

    pip
    picture-in-picture
  6. Optional: Enter the configuration options in the Options(JSON) text box. An example for setting the horizontal alignment of the player when it is in picture-in-picture mode is shown here:

    Plugin options
    Plugin options

    See the options section for more details.

  7. Select the Save button.
  8. You will now see the Picture-in-Picture plugin added to the list of plugins for your player.

    Plugin added
    Plugin added
  9. To publish the player, select Publish & Embed > Publish Changes.
  10. To close the open dialog, select Close.
  11. Return to the MEDIA module and publish your video using the player you just updated for picture-in-picture.

  12. In an editor, copy the player embed code into your web page.
  13. The picture-in-picture plugin requires that your player is wrapped by a container element with the class set to vjs-pip-container. Your code should look similar to this:

    <div class="vjs-pip-container">
      <video-js id="myPlayerID"
        data-video-id="5701202551001"
        data-account="1752604059001"
        data-player="default"
        data-embed="default"
        width="640" height="360"
        controls=""></video-js>
      <script src="https://players.brightcove.net/1752604059001/default_default/index.min.js"></script>
    </div>

    If the <div> element above is not found as the parent of the player, the plugin will fail to initialize and you will get the following log warning:

    VIDEOJS: WARN: expected player to be a child of a "vjs-pip-container" element, cannot continue with picture-in-picture plugin
  14. When the video has starts playing, scroll down to see the picture-in-picture player pinned to the bottom of the page.

Implement using code

To implement the plugin using custom code, you will configure the following plugin properties:

  • scripts - JavaScript supplied for the plugin and will not change for different plugin implementations
  • stylesheets - CSS supplied to you for the plugin and will not change for different plugin implementations
  • plugin name - Always pip
  • plugin options - Contains an array of properties and values

To add the plugin to your code, follow these steps:

  1. Add the styles for the picture-in-picture plugin.
    <link href="https://players.brightcove.net/videojs-pip/2/videojs-pip.css" rel="stylesheet">
  2. Add the JavaScript file to include the picture-in-picture plugin.
    <video-js id="myPlayerID"
      data-video-id="5701202551001"
      data-account="1752604059001"
      data-player="default"
      data-embed="default"
      width="640" height="360"
      controls=""></video-js>
    <script src="https://players.brightcove.net/1752604059001/default_default/index.min.js"></script>
    
    <!-- Script for the picture-in-picture plugin -->
    <script src="https://players.brightcove.net/videojs-pip/2/videojs-pip.min.js"></script>
  3. Wrap the player embed code in a container element with the class set to vjs-pip-container. The picture-in-picture plugin requires that your player is wrapped by this container element.

    <div class="vjs-pip-container">
        <video-js id="myPlayerID"
          data-video-id="5701202551001"
          data-account="1752604059001"
          data-player="default="
          data-embed="default="
          controls=""
          width="640" height="360"></video-js>
        <script src="https://players.brightcove.net/1752604059001/default_default/index.min.js"></script>
      </div>
    
            <!-- Script for the picture-in-picture plugin -->
            <script src="https://players.brightcove.net/videojs-pip/2/videojs-pip.min.js"></script>

    If the <div> element above is not found as the parent of the player, the plugin will fail to initialize and you will get the following log warning:

    expected player to be a child of a "vjs-pip-container" element, cannot continue with picture-in-picture plugin
  4. Add custom script code which does the following:
    • When the player is ready, gets a reference to the Brightcove Player. In this example, we are creating a variable named myPlayer and assigning it a reference to the player.
    • Initializes the picture-in-picture plugin.
    videojs.getPlayer('myPlayerID').ready(function() {
      // When the player is ready, get a reference to it
      var myPlayer = this;
      // Initialize the picture-in-picture plugin
      myPlayer.pip();
    });

    For details, see the codepen example above.

Options

You may pass in an options object to the plugin upon initialization. This object may contain any of the following options:

allowOnMobile

  • allowOnMobile:
    • Type: boolean
    • Default: false
    • By default, picture-in-picture mode will not work on Android or iOS mobile devices. The reason for this is because these CSS fixed positioning does not work on zoomable devices with multiple viewports in the same way it does on desktop devices.

      If you want to enable picture-in-picture on supported mobile devices, you can do so with this option. There are some cases where you might want to enable support:

      • The integrator is willing to take on the responsibility of managing positioning for picture-in-picture player mode.
      • The website using the player is unlikely to be zoomed.
      • Zooming has been disabled using a user-scalable=no directive. Using this directive will make position: fixed behave as it does on desktops, but it is not specifically recommended because it can be an accessibility concern.
        <meta name="viewport" content="width=device-width, user-scalable=no">
    • Example:

      // Allow mobile (iOS and Android) devices to enter PIP mode.
      player.pip({allowOnMobile: true});

closeable

  • closeable:
    • Type: boolean
    • Default: true
    • By default, picture-in-picture mode can be disabled by the user by clicking the X button in the top, right corner of the player. This feature can be disabled by passing false for this option.
    • Example:

      // Do not allow the user to close the PIP mode player.
      player.pip({closeable: false});

scale

  • scale:
    • Type: number
    • Default: 2 / 3
    • The scaling factor applied to the player when it is in picture-in-picture mode. This value must be a number greater than zero and less than or equal to 1.
    • Example:

      // Detach the player, but do not change its size.
      player.pip({scale: 1});
    • Example 2:

      // Detach the player, and change its size to 1/2.
      player.pip({scale: 0.5});

height and width

  • height and width:
    • Type: number
    • Default: null
    • By default, the plugin will scale down the player's dimensions by a factor determined by the scale option. However, providing a height (or width) will override the default scaling and set the size of the scaled-down player explicitly.

      If only one dimension is provided, the other will be scaled down to maintain the aspect ratio. If both dimensions are provided, the player will be set to the exact, specified size - allowing a change in aspect ratio.

    • Example:

      // Detach the player and set its width to 300 pixels. Scale its height to
      // maintain its current aspect ratio.
      player.pip({width: 300});

posX

  • posX:
    • Type: string
    • Default: "right"
    • The horizontal alignment of the player when it is in picture-in-picture mode - either "right" or "left".

    • Example:

      // When the player is in PIP mode, align it to the left side of the viewport.
      player.pip({posX: 'left'});

posY

  • posY:
    • Type: string
    • Default: "bottom"
    • The vertical alignment of the player when it is in picture-in-picture mode - either "top" or "bottom".

    • Example:

      // When the player is in PIP mode, align it to the top of the viewport.
      player.pip({posY: 'top'});

viewable

  • viewable:
    • Type: number
    • Default: 0.8
    • The threshold at which the player is considered viewable. In other words, when this percentage of the total player area (height and width) is visible in the browser's viewport, it is considered viewable.

      For example, with the default of 0.8, the player is not considered viewable unless 80% of it is visible in the viewport. The viewable value must be a number greater than or equal to 0 and less than or equal to 1.

    • Example:

      // If more than half the player is outside of the viewport, activate PIP mode.
      player.pip({viewable: 0.5});

manualContainerSize

  • manualContainerSize:
    • Type: boolean
    • Default: false
    • By default, a player with this plugin enabled will keep the physical dimensions of the special container element in sync with the player's dimensions. However, this behavior may not work for all use-cases, so it can be disabled by setting this option to true.

      When doing so, the container element will behave like a normal block element. This means that users of the plugin will need to manage its size on their own.

      This option can also be set in the embed code via the boolean data-manual-container-size attribute on the container. Its presence will set this option to true. Note that any value passed to the plugin will take precedence over any value defined in the embed code.

    • Example:

      // Implementation will handle sizing the container.
      player.pip({manualContainerSize: true});
    • Example using the data-manual-container-size attribute on the container:

      <div class="vjs-pip-container" data-manual-container-size>
        <video-js class="video-js vjs-default-skin">
        </video-js>
      </div>

Using the options

You have two ways you can utilize the option:

  1. In Studio's PLAYERS > PLUGINS section.
  2. Using JavaScript with the player.

Using Studio

In Studio, edit the player and return to the Plugins section. Click on Picture-in-Picture in the name list. Using proper JSON format, list the option (in quotation marks), followed by the appropriate value. If the values are string, they must be in quotes. If they are numeric or boolean, quotes cannot be included:

Plugin options
Plugin options

Using JavaScript

To implement the options in code, you create an object, assign desired options their respective values, then pass the options object when calling the plugin:

videojs.getPlayer('myPlayerID').ready(function() {
  // When the player is ready, get a reference to it
  var myPlayer = this,
      options = {};

  options.scale = 0.5;
  options.posX = "left";
  // Initialize the picture-in-picture plugin
  myPlayer.pip(options);
});

Methods

The following methods let you interact with the picture-in-picture plugin:

Method Description
myPlayer.pip().enable() Enable automatic picture-in-picture behavior
myPlayer.pip().disable() Disable automatic picture-in-picture behavior
myPlayer.pip().toggle() Manually activate or deactivate picture-in-picture mode based on the current state
myPlayer.pip().activate() Manually put the player into picture-in-picture mode
myPlayer.pip().deactivate() Manually take the player out of picture-in-picture mode

Events

The following events are fired from the picture-in-picture plugin:

Event Description
beforepipactive Fires before pip mode is activated
pipactive Fires after pip mode is activated
beforepipinactive Fires before pip mode is deactivated
pipinactive Fires after pip mode is deactivated
beforepipenabled Fires before the videojs-pip plugin is enabled
pipenabled Fires after the videojs-pip plugin is enabled
beforepipdisabled Fires before the videojs-pip plugin is disabled
pipdisabled Fires after the videojs-pip plugin is disabled

Changelog

See the Picture-in-Picture Plugin Release Notes.

For historical release notes, see the changelog here.