- 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 . 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.