• Molecule
  • CORE COMPONENT
  • Taxonomic name: M-MEDIA-PLAYER
  • Extension: MEDIA
  • Added on: v3.0.0 (15/09/17)
  • Updated on: v5.6.0 (20/04/21)

Video player

Video can be used to enhance content and can be an engaging way to illustrate content or provide updates. The Framework video player takes advantage of this by styling and enhancing a browser's native video player to present a video stream.


Design and usage

  • Videos require a title and description.
  • One or more subtitles can be added.
  • Users may choose to switch to full screen mode when viewing video.
  • A text alternative or transcript must be provided with videos.
  • Always include a fallback so that any video can be viewed by alternative means if it can't be viewed in the browser.
  • Do not auto-play videos.
  • The video tag does not work in IE8; a native video player is used for IE9, IE10 and mobile devices.

Optional card block

A card block can be added below the video module promoting other video content and highlighting the video shown in the module above the block. This card block should follow the standard rules for navigation cards - see navigation cards page for details.

Examples

Interactive example

Code example

Standard video player

<div itemprop="video" itemscope itemtype="https://schema.org/VideoObject">
	<h2 class="a-heading a-heading--2 a-heading--light" itemprop="name">...</h2>
	<p itemprop="description">Description for the video</p>
	<video src="..." poster="..." controls data-module="m-media-player">
		<meta itemprop="duration" content="..." />
		<meta itemprop="thumbnailUrl" content="..." />
		<meta itemprop="embedURL" content="..." />
		<meta itemprop="uploadDate" content="..." />
		<meta itemprop="height" content="..." />
		<meta itemprop="width" content="..." />
		<meta itemprop="encodingFormat" content="mpeg4" />		<track label="..." kind="subtitles" srclang="..." src="..." />
	...		<a href="..." class="m-media-player-download">
			<picture class="m-media-player-download__image">
				<source type="image/webp" media="(min-width: ...)" srcset="..." width="..." height="..." />
				...
				<source type="image/webp" srcset="..." width="..." height="..." />
				<img src="..." decoding="async" width="..." height="..." alt="" />
			</picture>
			<span class="m-media-player-download__text a-button a-button--download">Download MP4 video file<span class="u-hidden--visually"> of ...</span></span>
		</a>
	</video>
	<div class="m-showhide m-showhide--transcript" data-module="m-showhide" data-module-load="true">
		<h3 class="a-heading a-heading--3 a-heading--light m-showhide__heading">Transcript</h3>
		<div class="m-showhide__content" itemprop="transcript">
			...
		</div>
	</div>
</div>

Optional card block

A card block can be added below the video module promoting other video content and highlighting the video shown in the module above the block. Please note that this code is for display purposes only, and any functionality (for example to shift between videos and so on) will need to be team / project-specific.

<ul class="a-list-plain l-columns l-columns--2-medium l-columns--4-large [ Modifiers ]">
	<li class="l-columns__column m-card m-card--link [ Modifiers ]">
		<div class="m-card-image">
			<img src="..." decoding="async" width="..." height="..." alt="...">
			<div class="m-card-image__play"></div>
			<div class="m-card-image__duration"><p>...</p></div>
		</div>
		<div class="m-card-content">
			<div class="m-card-content__inner">
				<p class="m-card-tagline">...</p>
				<h2 class="a-heading a-heading--2 a-heading--semibold"><a class="m-card__link" href="..." aria-describedby="...">...</a></h2>
				<p>...</p>
				<p class="m-card-readmore" id="..." aria-hidden="true"><span>...</span></p>
			</div>
			<div class="m-card-content__inner m-card-content__inner--bottom">
				<p class="m-card-dateline">...</p>
			</div>
		</div>
	</a>
	...
	<!-- Optional now playing card - note that this element is a div not an anchor -->
	<li class="l-columns__column m-card [ Modifiers ]">
		<div class="m-card-image">
			<img src="..." decoding="async" width="..." height="..." alt="...">
			<div class="m-card-image__now-playing" aria-hidden="true">Now playing</div>
		</div>
		<div class="m-card-content m-card-content--left">
			<div class="m-card-content__inner">
				<p class="m-card-tagline">...</p>
				<h2 class="a-heading a-heading--2 a-heading--semibold">...</h2>
				<p>...</p>
				<p><strong>Now playing</strong></p>
			</div>
			<div class="m-card-content__inner m-card-content__inner--bottom">
				<p class="m-card-dateline">...</p>
			</div>
		</div>
	</li>
</ul>

Including multiple formats/bitrates

The format/bitrate that is used will be dependent on the user's browser's support; browsers will attempt the first source listed which matches the required criteria, but if that fails, will then work down the list.

<div itemprop="video" itemscope itemtype="https://schema.org/VideoObject">
	<h2 class="a-heading a-heading--2 a-heading--light" itemprop="name">...</h2>
	<p itemprop="description">Description for the video</p>
	<video src="..." poster="..." controls data-module="m-media-player">
		<source src="..." type="..." data-bitrate="..." data-width="..." />
		<source src="..." type="..." data-bitrate="..." data-width="..." />
		...		<meta itemprop="duration" content="..." />
		<meta itemprop="thumbnailUrl" content="..." />
		<meta itemprop="embedURL" content="..." />
		<meta itemprop="uploadDate" content="..." />
		<meta itemprop="height" content="..." />
		<meta itemprop="width" content="..." />
		<meta itemprop="encodingFormat" content="mpeg4" />		<track label="..." kind="subtitles" srclang="..." src="..." />		<a href="..." class="m-media-player-download">
			<picture class="m-media-player-download__image">
				<source type="image/webp" media="(min-width: ...)" srcset="..." width="..." height="..." />
				...
				<source type="image/webp" srcset="..." width="..." height="..." />
				<img src="..." decoding="async" width="..." height="..." alt="" />
			</picture>
			<span class="m-media-player-download__text a-button a-button--download">Download video<span class="u-hidden--visually"> of ...</span> <small>(MP4)</small></span>
		</a>
	</video>
	<div class="m-showhide m-showhide--transcript" data-module="m-showhide" data-module-load="true">
		<h3 class="a-heading a-heading--3 a-heading--light m-showhide__heading">Transcript</h3>
		<div class="m-showhide__content" itemprop="transcript">
			...
		</div>
	</div>
</div>

WebVTT file (.vtt) format

WEBVTT00:00:02.230 --> 00:00:06.606
This is the first subtitle.00:00:15.739 --> 00:00:18.074
This is the second.00:00:30.159 --> 00:00:32.743
This is the third

Development and test

Notes for developers

A transcript is required for all audio and video files and should contain a transcript of any audio and text contained within the media.

Adobe Analytics (H code) tracking of audio and video files is included by default with the media player. The media file will be recorded within reports using the heading with the itemprop="name" attribute.

Changing locale settings

Default text for the video controls can be changed for a particular locale.

en: {
	mMediaPlayer : {
		progress : 'played',
		progressTime : 'time',
		restart : 'Restart',
		rewind : 'Rewind',
		play : 'Play',
		playVideo : 'Play video',
		playAudio : 'Play audio',
		pause : 'Pause',
		forward : 'Forward',
		mute : 'Mute',
		volume : 'Volume',
		captions : 'Captions',
		subtitles : 'Subtitles',
		fullscreen : 'Fullscreen',
		seconds : 'seconds',
		on : 'on',
		off : 'off',
	},
},

For more information on this, see our page on how to change locale settings within JavaScript.

Subtitle or closed captions

To include subtitles/closed captions with a video use the track tag within the video element with an appropriate transcript in WebVTT format. The file must have the MIME type set correctly to text/vtt at the server.

Multiple subtitle tracks can be added to offer subtitles in multiple languages however the JavaScript video player will currently only offer the first one within the markup.

Do not include the default attribute on any of the tracks as this causes issues on iOS devices.

Visible labels and accessible names

An extra span with the class u-hidden--visually is required within the a-button--download to hold the hidden text required to make the accessible name for the label meaningful to screen readers. The visible label should always come first, with the hidden text following on to extend this by adding meaning and context, for example:

<a href="..." class="m-media-player-download__text a-button a-button--download">Download MP4 video file<span class="u-hidden--visually"> for [ video title  as specified in h3 two levels up the DOM ]</span></a>

Note that the video file format should be included as part of the visible label, as it is not permitted to add extra visible text after the hidden part.

Extension component

This component forms part of the 'media' extension and so requires an additional stylesheet to be loaded in order to be used; include the following code in the header of your page to attach the relevant additional stylesheet:

<link media="all" href="./assets/[ theme type ]/[ release version ]/[ organisation ]/[ theme name ]/css/media.css" rel="stylesheet" />

Controling the media player programatically

The media player can be controlled programatically to play, pause, mute, set and get volume, set and get captions and their settings and set and get a particular point within a media file. The following methods are available for use:

Method Description
play() Play the media file
pause() Pause the media file
mute() Mute / unmute the media file
setVolume( 0 - 10 ) Set the volume to a particular level; set 'volume' to integer between 0 and 10)
getVolume() Returns current volume as an integer between 0 and 10, or 'muted' if audio is muted
setcaptions( on | off | language code ) Sets single closed captions to show the only available captions or, if multiple languages are available, to the specified language; 'off' will hide captions for both variants; set to 'on', 'off' or appropriate language code, for example 'en' or 'fr'
getCaptionsSettings() Returns an object containing the current captions settings; for single captions, this will be on or off; for multiple captions, this will be on or off and the particular language seelcted (null if captions are off)
setTime( time ) Skips media to selected point; set 'time' to integer in seconds
getTime() Returns the current position within video in seconds

For example:

document.addEventListener( 'frameworkready', function () {
	FRAMEWORK.require([ 'blocks/m-media-player' ], function ( mMediaPlayerModule ) {
		var mediaPlayerEl = document.querySelector( '#mediaPlayerTest' ),
			mediaPlayerInstance = mMediaPlayerModule.initInstance( mediaPlayerEl );			mediaPlayerInstance.play();
			mediaPlayerInstance.setCaptions( 'on' );
	});
});

Notes for testers

  • Ensure that all videos files have a fallback included for when they can't be played or loaded.
  • Ensure there are controls which enable users to be in charge of the media and which can be accessed via the keyboard.
  • Ensure that all videos have a full text transcript.
  • Length of playback time should be included for video files
  • Older browsers which do not support HTML5 video should be presented with a download link for the video file.
  • Some browsers, including mobile versions, may play the video file with the native player.

Known accessibility issue

A user can gain focus of the progress bar for the video player, but they are unable to adjust where they are in the video using the keyboard.


Classes overview

The following table gives you a quick overview of the CSS classes that can be applied.

Class Outcome Required Applied to Comments
.m-media-player-download Base style for the fall back link for any video Yes video > a Should link to the video file
.m-media-player-download__image Base style for the fall back placeholder image Yes .m-media-player-download > picture
.m-media-player-download > img
Should be the same image as the poster image for the video
.m-media-player-download__text Base style for video link description Yes .m-media-player-download > .a-button--download Should contain the title of the video and the file type
.m-large-video Container for large video player No div Allows video to fill full 12-column grid at desktop
.m-card-image__play Additional class to include play icon on video card No .m-card-image div  
.m-card-image__duration Additional class to include duration on video card No .m-card-image div  
.m-card-image__now-playing Additional class to indicate video featured in this card is the one now active No .m-card-image div  

Keyboard operations

TAB

Tabbing to an video or audio control will make it clearly visually different so that the focus point on the page is obvious to the user.

SPACE or ENTER

With focus on play, pause, mute or full screen, pressing SPACE or ENTER will trigger the relevant behaviour.

Component releases

  • Added on: v3.0.0 (15/09/17)
  • Updated on: v5.6.0 (20/04/21)

Latest update:

  • updated: To improve page load and layout times the additional attributes decoding="async", width and height must be set on all inline images.
  • updated: Markup has changed to use the picture element to improve page performance by allowing different sized images to be served for different screen sizes.

Full version history

A full history of changes and enhancements detailing all minor and major updates to the component.

View full version history

Want something new in Framework, or to chat about an issue you're having with it?

Contact the team