Brightcove Player 7 Migration Guide

In this topic, you will learn about the new improvements and features with the major version release for Brightcove Player 7.


Version 7 is the latest major version release of Brightcove Player. The changes and improvements to the player include those in Video.js 8 and VHS (Video.js HTTP Streaming) 3.

Features and improvements include:

  • Designed for most modern browsers
  • ES6 by default
  • New viewability events
  • Improved Adaptive Bitrate (ABR) algorithm
  • Content Protection (DRM) support without a plugin
  • Removed support for IE11

The design team is working on additional UX changes for player 7 that will be coming in the near future. These include:

  • New default layout
  • Improved player behavior

The Brightcove Player remains the industry-leading web video player. For an overview, see the What Makes a Great Online Video Player? Announcing Brightcove's Player v7 blog post.

Upgrade to version 7

Brightcove Player 7.0.0 is now available. No existing players have been auto-updated to this version, but you can upgrade your player in the Studio.

  1. In Video Cloud Studio, navigate to the Players module.
  2. Create a new player or open an existing player.

    Player information
  3. In the Player Information section, scroll down to Player Version.
    1. Make sure that Update Mode is set to Automatic. For details, see the Limitations section.
    2. Click Upgrade to Brightcove Player 7.
    3. Click Save.
    4. Click Publish & Embed.
    Upgrade to player 7
  4. Click Publish Changes and then Close.

Browser and Device Support

Updated System Requirements

The system requirements for Brightcove Player 7 are as follows:

Browser/Engine Platforms/OS Minimum Version
Chrome Windows, macOS, Android, iPadOS [1], iOS [1] Current and two previous major versions
Edge Windows, macOS, Android, iPadOS [1], iOS [1] Current and two previous major versions
Firefox Windows, macOS, Android, iPadOS [1], iOS [1] Current and two previous major versions
Safari macOS, iPadOS, iOS Current and two previous major versions

The following notes refer to table above.

[1] On iPadOS and iOS, only the Safari browser engine is allowed. Alternative browsers, like Chrome and Firefox and Edge, use Safari under the hood. Their behavior will not match the real versions of those browsers.

Internet Explorer 11

As of June 15th, 2021 and Brightcove Player 6.56.0, we stopped officially supporting IE11. After this point, we made efforts to not actively break in the IE browser. This is not the case with player 7.

With Brightcove Player 7.0.0, we removed all code for supporting IE11, and the player will not function in IE.

If a viewer tries playback in IE, the player will not work. There won't be an "unsupported browser" message because IE11 can't parse the script to display the message.

Each section below, representing a change, has a bracketed abbreviation that indicates which major component(s) were impacted:

  • BCP7: This change applies to Brightcove Player 7
  • VJS8: This change applies to Video.js 8
  • VHS3: This change applies to Video.js HTTP Streaming 3

What this Guide Does Not Cover

It should be noted that this guide covers only the user-facing changes to the Brightcove Player 7.

It does not cover the significant internal changes related to code organization to make future development of the Player easier for our engineers. We are extremely proud of the fact that Brightcove Player remains the industry-leading web video player even after almost a decade of continuous development.

Features and Enhancements

Features and enhancements refer to net new features of the player or significantly changed or improved features and behaviors.

ES6 By Default

Change applies to VJS8,VHS3,BCP7

Most of Brightcove Player 7 is no longer transpiled into ES5 code - including Video.js and VHS.

Most code is now transpiled to target modern browser engines. One of the nice outcomes of this is that we were able to reduce the overall packaged size of our code by 3-5%.

Migration Considerations

Code that attempts to inherit native ES6 classes, but is ultimately transpiled to ES5 will no longer work with Video.js 8 and Brightcove Player 7. This incompatibility will generally be surfaced by an error being thrown with a message like:

TypeError: Class constructor ___ cannot be invoked without 'new'

This is because transpilation tools like Babel will convert classes into plain JavaScript functions and attempt to call apply() or call() on them. These methods exist on functions, but not ES6 classes.

The only solution is to not transpile ES6 classes to ES5 for use with Video.js 8 and Brightcove Player 7.

Viewability Events and Behaviors

Change applies to BCP7

The viewability of a player is of real importance to advertising integrations as well as some UI treatments like floating players. In this context, we are defining “viewability” as the percentage of a player that is visible in the browser viewport at any given moment. A player is considered “viewable” if some specific percentage of the player is in the viewport.

Brightcove Player 7 introduces viewability tracking DOM events as well as some useful behaviors that depend on the player’s viewable state.

Player Configuration

The player's viewability events and behavior can be configured in your player's JSON configuration. All configurations are available under the viewability property.

Property Description Type Default
viewability_threshold A number between 0 and 1 representing the portion of the player that must be in the viewport for it to count as "viewable". number 0.6
min_duration_for_viewable_impression Represents the number of milliseconds to wait after ad playback begins before testing for a viewable impression.

By default, this means that the player will report whether the ad impression was viewable using a viewable-ad-impression event after 2 seconds of ad playback.
number 2000
threshold_percentage_increment The amount of viewability change required between viewable-percent-change events.

By default, the value 5 means that viewable-percent-change events will only fire if the viewability of the player has changed by 5% (e.g. from 45% to 50%).

It is recommended not to go any more granular with this as it will fire a lot of events..
number 5
delay_autoplay_if_not_viewable Only interacts with players that are configured for autoplay.

If true, the player delays its playback attempt until the player is viewable.

If false, the player will attempt playback regardless of its viewability state. This is the default behavior of an autoplay player..
boolean false
delay_autoplay_on_mobile_only If true, the delay autoplay feature will only be activated on mobile environments (iOS or Android).

NOTE: In this case, tablets are considered mobile environments..
boolean true
pause_when_not_viewable If true, the player will pause playback if it becomes not viewable. When the player becomes viewable again, playback will resume.

If false, the player will not toggle pause or play on viewable-change. This is the default behavior of a player..
boolean false


Here's the JSON for a player configuration which includes viewability:

  ... other properties ...
  "viewability": {
    "viewability_threshold": 0.7,
    "pause_when_not_viewable": true

In this example, playback pauses when less than 70% of the player is visible in the browser viewport, caused by the user scrolling the player out of view. Playback resumes when the player becomes visible again.

Viewability Events

Users can hook into three new events related to viewability.

  • viewable-change

    This event fires when the player transitions to or from a viewable state.

    Property Type Description
    viewable boolean Represents whether or not the player is in a viewable state
    viewablePercent number Represents the percentage of the player that is currently in the viewport
    player.on('viewable-change', (e) => {
      if (e.viewable) {
        player.log('the player is viewable!');
      } else {
        player.log('the player is not viewable!');

  • viewable-percent-change

    This event fires when the viewable percentage of the player changes.

    Property Type Description
    viewable boolean Represents whether or not the player is in a viewable state
    viewablePercent number Represents the percentage of the player that is currently in the viewport
    player.on('viewable-percent-change', (e) => {
      player.log(`the player is ${e.viewablePercent}% viewable!`);

  • viewable-ad-impression

    This event will fire when a viewable ad impression is measured. It will not fire outside the context of ad playback.

    In other words, once an ad has started and played for the number of milliseconds represented by min_duration_for_viewable_impression with the player viewable, this event will fire.

    No additional data is passed with this event.

DRM Support by Default

Change applies to BCP7

The existing DRM plugin will no longer be needed with Brightcove Player 7. The player will support DRM out of the box in a manner identical to previous player versions.

This makes it easier to configure DRM by simply enabling DRM protection on your media content without having to remember to also enable it on your players.

No migration is needed. Players that are configured with the DRM plugin and Player 7 will not break.

Timeout Error Enhancements

Change applies to BCP7

Brightcove Player has long supported a special error we call a timeout. What this typically means is that the player expects to be playing content (i.e. it is not paused), but playback is not proceeding. Generally, this means that content cannot be buffered due to network issues or some other condition which caused the player to stall out, such as the TTL on a manifest URL has expired.

While we call this an “error” it is unique from most errors in that it is recoverable. For example, if network conditions improve and content buffering recovers, playback can resume.

With Player 6, the error modal dialog does not close if playback resumes, leading to a poor viewer experience.

Going forward, the player's timeout modal dialog will give the viewer the option to dismiss it or to trigger a reload of the video source from the Playback API, so that new manifest URLs are retrieved. In the latter case, the player will preserve the playback position for VOD streams. While this is not an ideal experience, it's better than a non-functional player.

Unsupported Browser UI

Change applies to BCP7

With Player 6, when it is loaded in an unsupported browser, an error will likely be thrown and logged in the browser console, but nothing will be surfaced to the viewer.

Player 7 has a new UI to make these cases more clear. When the player is loaded in an unsupported browser, you will see a message similar to this:

Unsupported browser message

There are two cases where you could expect to see this error:

  • Unsupported browsers like Internet Explorer
  • An uncaught JavaScript error was thrown during the player initialization process

If you see this message and your browser should be supported, check the browser console. If the error is coming from your own code, you may be able to address it. Otherwise, reach out to Brightcove customer support for help.

Analytics Player Event Renaming

Change applies to BCP7


Prior to version 7, the player triggered analytics_request events and analytics_request_* events where * stood for the analytics beacon event name. For example, when the player sent a beacon representing a video_engagement event, the player would trigger both:

  • analytics_request
  • analytics_request_video_engagement


To be consistent in our event naming, we want to use lower-case-hyphenated event names. When we discuss the small HTTP requests sent to our Data Collection API, we refer to them as “beacons”, so we are using that terminology as well.

We've renamed these events to be the following: (where the * stands for the analytics beacon event name with _ replaced by -)

  • analytics-beacon
  • analytics-beacon-*


If you want to know when the player sent a video_engagement event beacon, you could do something like this:

player.on('analytics-beacon-video-engagement', (e) => {
  // The event object in the callback contains a `params` object, which
  // has a JavaScript object representation of the query params that
  // were sent to the Data Collection API.
  player.log('video_engagement beacon sent!', e.params);

Analytics play_request Event

Change applies to BCP7

Brightcove Player 7 will send a play_request beacon only the first time there is a request to begin playback - either through a viewer hitting the play button or some form of autoplay (i.e. calling the play() method).

In earlier versions, we sent play_request beacons anytime there was a player play event. This included anytime content playback was requested, such as a viewer pausing and resuming or a client-side advertisement ending and returning to content playback.

Brightcove's Product and Data organizations discussed this and determined that the intent of this event was to track the initial request for playback to begin. This means it's likely that anyone tracking play_request metrics will see that number drop after upgrading to Player 7. If this happens, it does not indicate a problem.

Player video_complete Event

Change applies to BCP7

Video Cloud analytics doesn't use the video_complete event, and it was removed from BCP7. That means the following:

  • No analytics-beacon-video-complete event
  • No analytics-beacon event with params.event set to video_complete

Brightcove Namespace

Change applies to BCP7

A source of confusion for our users has been the proliferation of core properties and methods across different objects attached to each instance of Brightcove Player. Some examples of this include bcAnalytics and catalog.

With player 7, we will begin consolidating these disparate features into a new core namespace:

  • brightcove

This namespace will be the single location for Brightcove-specific player enhancements and integrations. This namespace will be attached as a property of each player instance.


The goals for the brightcove namespace include:

  • Internally, the goal is to reduce complexity and duplicate code across multiple sub-components and plugins of Brightcove Player
  • Externally, the goal is to improve the integration developer experience by unifying disparate pieces of core functionality into a single namespace

For now, we are only exposing some utility functions on this namespace, which are accessible under:

  • brightcove.util

A handful of these are copies of Video.js utility functions, but we will be unifying those over time as well. The number of functions exposed on this object is too many to list here, but complete documentation will be forthcoming.

There is no migration necessary here - yet - but exposing functionality via the central brightcove namespace will be an iterative process of porting functionality onto this object and deprecating old properties/methods. It's important to note that we will not break backward compatibility within a major release, so bcAnalytics and catalog are not going away until Brightcove Player 8.

Improved ABR Algorithm

Change applies to VJS8/VHS3/BCP7

The ABR algorithm that VHS and the Brightcove Player use has been improved with the goal of reducing rebuffering events while maintaining a higher bitrate choice. This is achieved by using a moving average bandwidth estimation instead of just the most recent bandwidth estimation.

Further, we aim to optimize bandwidth usage by being smart about when we do a rendition switch to avoid throwing out buffered high quality content in order to switch to a lower rendition.

You can see more about the thinking behind these adjustments in this GitHub Gist and its final implementation in this GitHub pull request.

To learn more about the ABR algorithm, see the Determining Which Rendition Will Play document.

sourceset Event

Change applies to VJS8/BCP7

This event has existed for years in Video.js behind a feature flag. We have now enabled it, by default, as a way to detect if the player's source is changing, potentially before the standard event, loadstart, used for detection of source changes.


player.on('sourceset', (e) => {
  player.log('The media source is changing!');

Retry on Error

Change applies to VJS8/BCP7

If the player is given a list of sources and the first one fails to load, Video.js will now try the next media source in order until it finds one it can play or runs out of sources.

This is more relevant to Player-only customers because, when going through the Playback API, this error condition is unlikely to ever occur.

TitleBar Component

Change applies to VJS8/BCP7

We removed the videojs-dock plugin and re-implemented similar functionality in a new core component for Video.js: the TitleBar component.

The new TitleBar component will show a UI element across the top of the player which displays the title and/or description of the current media in the player. The TitleBar will not show if no title or description is provided.

Video Cloud customers

The TitleBar is automatically populated if your player is integrated with Video Cloud through the Playback API.

Player-only customers

Player-only customers may use one of the following methods to populate the TitleBar:

  • Using loadMedia to Populate the TitleBar

    The easiest way to provide a title and/or description is to use your player's loadMedia method:

      artist: 'Extremely',
      album: 'Oceans',
      title: 'Oceans',
      description: 'Journey in to the depths ... and race with dolphins at play.',
      poster: '',
      src: [{
        src: '',
        type: 'video/mp4'
      }, {
        src: '',
        type: 'video/webm'

    If you're not familiar with the loadMedia method, it's a way to provide additional metadata for your media beyond what is available through the src method alone. As you see in the above example, the title and description are provided and will be used to populate the title bar.

  • Populating the TitleBar Directly

    The TitleBar can also be populated through direct input using the component's update method:

      title: 'Oceans',
      description: 'Journey in to the depths ... and race with dolphins at play.'

    The title and/or description can be removed by passing an empty string for one or both of these values:

      title: '',
      description: ''

    If both are removed, the TitleBar will no longer be visible.

Brightcove Player Migration

It is unlikely that migration for this is needed by the vast majority of Brightcove customers.

However, it's possible that any third party code depending on player.dock would need to be updated to uses the APIs for the TitleBar mentioned in the Player-only customers section.

Video.js Utility Objects

Change applies to VJS8/VHS3/BCP7

Over time, the videojs namespace has become cluttered with a wide variety of utility functions. Brightcove is introducing a more deliberately designed interface for these utility functions.

The guiding principle here was that if a function didn't feel like a core part of the library, but was still potentially useful, we exposed it as part of a utility object instead of a top-level function.

Here are the utility objects attached to videojs in 8.0.0:

Object Description
videojs.dom DOM functions (available previously)
videojs.fn Function... functions
videojs.num Number functions
videojs.obj Object functions
videojs.str String functions
videojs.time Time-related functions
videojs.url URL-related functions
videojs.browser Various user-agent detection values (available previously)

Other Brightcove Player Features and Enhancements

Changes apply to BCP7

  • The not-hover class name has been renamed to vjs-hide-controls.

    The naming of this old class did not follow our naming standards and its purpose was unclear. Any CSS (or JavaScript) targeting that class name would need to be updated.

  • The style element the player creates for Video.js CSS had the id="bc-style-vjs" attribute. This id has been changed to a class attribute.

    In earlier player versions, when using multiple players, this could theoretically create a situation where multiple elements in the DOM shared an id which is against the HTML specification.

Other Video.js Features and Enhancements

Changes apply to VJS8

  • addClass and removeClass methods can now be given multiple class names in a space-separated string, like foo bar.

  • Clicking the playback rate menu button will now open the playback rate menu, bring it into alignment with other menu buttons.

  • Invalid event types will now throw errors instead of log warnings.

Other VHS Features and Enhancements

Changes apply to VHS3

  • Gaps are skip detected immediately instead of waiting the duration of the gap before skipping.

  • Removed the deprecated smoothQualityChange method

  • Improved behavior when encountering output-restricted event handling

  • Cleaned up parameters of excludePlaylist

  • Changed many names for more inclusive language usage, such as:

    • “master” becomes “main”
    • “blacklist” becomes “exclude” or “excludeList”
    • “whitelist” becomes “allow” or “allowList”


Deprecations refer to changes that Brightcove plans to make in the next major version. In general, these will log a warning to the browser console to aid developers in future-proofing their integrations.

Top-Level Utility Functions

Change applies to VJS8/VHS3/BCP7

Over time, the videojs namespace has become cluttered with a wide variety of utility functions. Brightcove has introduced a new organizational principle of exposing utility objects to better organize the videojs API.

As a result, many top-level functions have been deprecated. Each of these functions will now log a warning the first time they are used (and only once, so as not to clutter the browser console).

Deprecated Function Instead, use…
videojs.bind native Function.prototype.bind
videojs.computedStyle videojs.dom.computedStyle
videojs.createTimeRange videojs.time.createTimeRanges
videojs.createTimeRanges videojs.time.createTimeRanges
videojs.defineLazyProperty videojs.obj.defineLazyProperty
videojs.formatTime videojs.time.formatTime
videojs.isCrossOrigin videojs.url.isCrossOrigin
videojs.mergeOptions videojs.obj.merge
videojs.parseUrl videojs.url.parseUrl
videojs.resetFormatTime videojs.time.resetFormatTime
videojs.setFormatTime videojs.time.setFormatTime

There are also a number of older functions that remain usable, but deprecated:

Deprecated Function Instead, use…
videojs.addClass native videojs.dom.addClass
videojs.appendContent videojs.dom.appendContent
videojs.createEl videojs.dom.createEl
videojs.emptyEl videojs.dom.emptyEl
videojs.getAttributes videojs.dom.getAttributes
videojs.hasClass videojs.dom.hasClass
videojs.insertContent videojs.dom.insertContent
videojs.isEl videojs.dom.isEl
videojs.isTextNode videojs.dom.isTextNode
videojs.plugin videojs.registerPlugin
videojs.removeClass videojs.dom.removeClass
videojs.setAttributes videojs.dom.setAttributes
videojs.toggleClass videojs.dom.toggleClass


Anything in this section indicates complete removal of support for something that was previously supported. We try to avoid removing support for things without deprecating them ahead of time, but it sometimes does need to happen to keep the product maintainable into the future.

Graphite Skin

Change applies to BCP7

The Graphite skin is no longer available.

The only skin supported by Brightcove Player 7 upon release is the default Sapphire skin. The only other option is null, which will turn off all CSS, allowing advanced users to write their own skin from scratch.

If you had "skin": "graphite" in your player JSON configuration, remove it. Any customizations based on the Graphite CSS may need to be updated.

Query String Support in In-Page Embeds

Change applies to BCP7

When embedded in-page, Brightcove Player 7 will no longer recognize the autoplay query parameter or t query parameter (or any other query parameter).

Query parameters are an ideal way to provide data at the embed code level for iframe embeds, but for in-page embeds, they would need to exist in the embedding website's URL.

These two parameters were previously supported because older versions of Internet Explorer required workarounds for the Fullscreen API, which was not adequately supported. However, they caused several customers some confusion when their own web page URLs included these parameters for other purposes, but they impacted the behavior of their embedded Brightcove Player.

If you were relying on this support in some way, Brightcove recommends switching to the autoplay or data-start-time attribute for your in-page embeds (or implementing this functionality via JavaScript code).

Top-level Playlist-related Configurations

Change applies to BCP7

With earlier Player versions, there were multiple legacy playlist plugins/implementations and methods of configuration. Maintaining multiple playlist implementations caused a significant amount of confusion and complexity, so Brightcove simplified and clarified playlist implementation.

In short, all top-level, playlist-related configurations are no longer supported in Brightcove Player 7, including:

  • autoadvance
  • media (as an array being interpreted as a playlist)
  • playlist
  • repeat

The top-level playlist configuration could be used in two ways:

However, it had no impact on the Brightcove Playlist UI plugin.


The migration path for playlists is to always use the Brightcove Playlist UI plugin, which is configurable through Studio. The old top-level configurations have never been exposed through Studio.

To use playlists with Player 7, include one of the following plugins:

videojs.extend() Function

Change applies to VJS8/BCP7

The extend() function was previously used to extend Video.js components and advanced plugins.

We are now using native ES6 classes everywhere and the old videojs.extend() function only works with plain function prototypes, making it unusable with the native ES6 classes that make up Video.js 8. So, it has been removed.


For example, the old way to create a component using extend() was:

const Component = videojs.getComponent('Component');

const MyComponent = videojs.extend(Component, {
  constructor: function(player, options) {, player, options);

videojs.registerComponent('MyComponent', MyComponent);


Going forward, only ES6 classes are supported. The equivalent would be:

const Component = videojs.getComponent('Component');

class MyComponent extends Component {
  constructor(player, options) {
    super(player, options);

videojs.registerComponent('MyComponent', MyComponent);

Users whose integration code depends on videojs.extend() will need to update their implementations before updating to Brightcove Player 7.

firstplay Event

Change applies to VJS8/BCP7

The firstplay event was removed. This was a legacy event that was fired the first time a play event was fired. However, there's a better way to hook into the first play event for a given source, using the one() method:

// Each time the source is about to change, listen for the first play event.
player.on('sourceset', () => {'play', callback);

Other Removals

  • [BCP7] The fullscreenControl and techOrder JSON configs are no longer supported. Instead, use fullscreen_control and tech_order respectively.
  • [VJS8] Removed the ability to set aria-*, role, and type attributes via the props argument of createEl methods
  • [VJS8] Removed remaining references and logic related to Flash and SWF files
  • [VJS8] Remove fallbacks for missing CSS flexbox support
  • [VJS8] Removed IE-specific code


All Brightcove Plugins have been updated for the new version of the player. If you're performing a manual update, the following list details the new version numbers available from the Plugin Registry.

Plugin Description registry_id Player 6 Plugin Version Player 7 Plugin Version
Adobe Analytics Player Plugin @brightcove/videojs-bc-aa 1.x 2.x
AirPlay Support @brightcove/videojs-bc-airplay 1.x 2.x
Google Analytics @brightcove/videojs-bc-ga 1.x 2.x
Google Tag Manager @brightcove/videojs-bc-gtm 1.x 2.x
Chromecast @brightcove/
2.x 3.x
Custom Endscreens @brightcove/
3.x 4.x
DRM Support @brightcove/videojs-bc-drm 5.x Not needed for Brightcove Player 7
and should be removed
FreeWheel Ads @brightcove/videojs-bc-freewheel 3.x 4.x
Google IMA3 Ads @brightcove/videojs-bc-ima3 4.x No change
Kollective eCDN Support @brightcove/videojs-bc-kollective 1.x 2.x
Overlays @brightcove/videojs-overlay 2.x 3.x
Picture-in-Picture aka "Floating Player" @brightcove/videojs-pip 1.x 2.x
Playlist Endscreen @brightcove/
1.x 2.x
Playlist UI @brightcove/videojs-bc-playlist-ui 3.x 4.x
Quality Selection Menu @brightcove/videojs-quality-menu 1.x 2.x
Social Sharing @brightcove/videojs-social 3.x 4.x
SSAI Support @brightcove/videojs-ssai 1.x 2.x
Tealium Analytics @brightcove/videojs-bc-tealium 1.x 2.x
Thumbnail Seeking @brightcove/videojs-thumbnails 1.x 2.x