Accessible multimedia

Another category of content that can create accessibility problems is multimedia — video, audio, and image content need to be given proper textual alternatives so they can be understood by assistive technologies and their users. This article shows how.

Prerequisites: Basic computer literacy, a basic understanding of HTML, CSS, and JavaScript, an understanding of what accessibility is .
Objective: To understand the accessibility issues behind multimedia, and how to overcome them.

Multimedia and accessibility

So far in this module, we have looked at a variety of content and what needs to be done to ensure its accessibility, ranging from simple text content to data tables, images, native controls such as form elements and buttons, and even more complex markup structures (with WAI-ARIA attributes).

This article on the other hand looks at another general class of content that arguably isn't as easy to ensure accessibility for — multimedia. Images, audio tracks, videos, <canvas> elements, etc., aren't as easily understood by screenreaders or navigated by the keyboard, and we need to give them a helping hand.

But don't despair — here we will help you navigate through the techniques available for making multimedia more accessible.

Simple images

We already covered simple text alternatives for HTML images in our HTML: A good basis for accessibility article — you can refer back to there for the full details. In short, you should ensure that where possible visual content has an alternative text available for screenreaders to pick up and read to their users.

例如:

<img src="dinosaur.png"
     alt="A red Tyrannosaurus Rex: A two legged dinosaur standing upright like a human, with small arms, and a large head with lots of sharp teeth.">

					

Accessible audio and video controls

Implementing controls for web-based audio/video shouldn't be a problem, right? Let's investigate.

The problem with native HTML5 controls

HTML5 video and audio instances even come with a set of inbuilt controls that allow you to control the media straight out of the box. For example (see native-controls.html 源代码 and live ):

<audio controls>
  <source src="viper.mp3" type="audio/mp3">
  <source src="viper.ogg" type="audio/ogg">
  <p>Your browser doesn't support HTML5 audio. Here is a <a href="viper.mp3">link to the audio</a> instead.</p>
</audio>
<br>
<video controls>
  <source src="rabbit320.mp4" type="video/mp4">
  <source src="rabbit320.webm" type="video/webm">
  <p>Your browser doesn't support HTML5 video. Here is a <a href="rabbit320.mp4">link to the video</a> instead.</p>
</video>

					

The controls attribute provides play/pause buttons, seek bar, etc. — the basic controls you'd expect from a media player. It looks like so in Firefox and Chrome:

Screenshot of Video Controls in Firefox

Screenshot of Video Controls in Chrome

However, there are problems with these controls:

  • They are not keyboard-accessible in most browsers, i.e. you can't tab between the controls inside the native player. Opera and Chrome provide this to some degree, but it still isn't ideal.
  • Different browsers give the native controls differing styling and functionality, and they aren't stylable, meaning that they can't be easily made to follow a site style guide.

To remedy this, we can create our own custom controls. Let's look at how.

Creating custom audio and video controls

HTML5 video and audio share an API — HTML Media Element — which allows you to map custom functionality to buttons and other controls — both of which you define yourself.

Let's take the video example from above and add custom controls to them.

Basic setup

First, grab a copy of our custom-controls-start.html , custom-controls.css , rabbit320.mp4 ,和 rabbit320.webm files and save them in a new directory on your hard drive.

Create a new file called main.js and save it in the same directory.

First of all, let's look at the HTML for the video player, in the HTML:

<section class="player">
  <video controls>
    <source src="rabbit320.mp4" type="video/mp4">
    <source src="rabbit320.webm" type="video/webm">
    <p>Your browser doesn't support HTML5 video. Here is a <a href="rabbit320.mp4">link to the video</a> instead.</p>
  </video>
  <div class="controls">
    <button class="playpause">Play</button>
    <button class="stop">Stop</button>
    <button class="rwd">Rwd</button>
    <button class="fwd">Fwd</button>
    <div class="time">00:00</div>
  </div>
</section>

					

JavaScript basic setup

We've inserted some simple control buttons below our video. These controls of course won't do anything by default; to add functionality, we will use JavaScript.

We will first need to store references to each of the controls — add the following to the top of your JavaScript file:

const playPauseBtn = document.querySelector('.playpause');
const stopBtn = document.querySelector('.stop');
const rwdBtn = document.querySelector('.rwd');
const fwdBtn = document.querySelector('.fwd');
const timeLabel = document.querySelector('.time');

					

Next, we need to grab a reference to the video/audio player itself — add this line below the previous lines:

const player = document.querySelector('video');

					

This holds a reference to a HTMLMediaElement object, which has several useful properties and methods available on it that can be used to wire up functionality to our buttons.

Before moving onto creating our button functionality, let's remove the native controls so they don't get in the way of our custom controls. Add the following, again at the bottom of your JavaScript:

player.removeAttribute('controls');

					

Doing it this way round rather than just not including the controls attribute in the first place has the advantage that if our JavaScript fails for any reason, the user still has some controls available.

Wiring up our buttons

First, let's set up the play/pause button. We can get this to toggle between play and pause with a simple conditional function, like the following. Add it to your code, at the bottom:

playPauseBtn.onclick = function() {
  if(player.paused) {
    player.play();
    playPauseBtn.textContent = 'Pause';
  } else {
    player.pause();
    playPauseBtn.textContent = 'Play';
  }
};

					

Next, add this code to the bottom, which controls the stop button:

stopBtn.onclick = function() {
  player.pause();
  player.currentTime = 0;
  playPauseBtn.textContent = 'Play';
};

					

There is no stop() function available on HTMLMediaElement s, so instead we pause() it, and at the same time set the currentTime 为 0。

Next, our rewind and fast forward buttons — add the following blocks to the bottom of your code:

rwdBtn.onclick = function() {
  player.currentTime -= 3;
};
fwdBtn.onclick = function() {
  player.currentTime += 3;
  if(player.currentTime >= player.duration || player.paused) {
    player.pause();
    player.currentTime = 0;
    playPauseBtn.textContent = 'Play';
  }
};

					

These are very simple, just adding or subtracting 3 seconds to the currentTime each time they are clicked. In a real video player, you'd probably want a more elaborate seeking bar, or similar.

Note that we also check to see if the currentTime is more than the total media duration , or if the media is not playing, when the Fwd button is pressed. If either condition is true, we stop the video, to avoid the user interface going wrong if they attempt to fast forward when the video is not playing or fast forward past the end of the video.

Last of all, add the following to the end of the code, to control the time elapsed display:

player.ontimeupdate = function () {
  const minutes = Math.floor(player.currentTime / 60);
  const seconds = Math.floor(player.currentTime - minutes * 60);
  let minuteValue;
  let secondValue;
  if (minutes < 10) {
    minuteValue = "0" + minutes;
  } else {
    minuteValue = minutes;
  }
  if (seconds < 10) {
    secondValue = "0" + seconds;
  } else {
    secondValue = seconds;
  }
  const mediaTime = minuteValue + ":" + secondValue;
  timeLabel.textContent = mediaTime;
};

					

Each time the time updates (once per second), we fire this function. It works out the number of minutes and seconds from the given currentTime value (which is in seconds), adds a leading 0 if either the minute or second value is less than 10, and then creates the display readout and adds it to the time label.

延伸阅读

This gives you a basic idea of how to add custom player functionality to video/audio player instances. For more information on how to add more complex features to video/audio players, see:

We've also created an advanced example to show how you could create an object-oriented system that finds every video and audio player on the page (no matter how many there are) and adds our custom controls to it. See custom-controls-oojs (also see the source code ).

Audio transcripts

To provide deaf people with access to audio content, you really need to create text transcripts. These can either be included on the same page as the audio in some way or included on a separate page and linked to.

In terms of actually creating the transcript, your options are:

  • Commercial services — You could pay a professional to do the transcription, see for example companies like Scribie , Casting Words ,或 Rev . Look around and ask for advice to make sure you find a reputable company that you'll be able to work with effectively.
  • Community/grassroots/self transcription — If you are part of an active community or team in your workplace, then you could ask them for help with doing the translations. You could even have a go at doing them yourself.
  • Automated services — There are AI services available, like Trint  or Transcribear . Upload a video/audio file to the site, and it automatically transcribes it for you. On YouTube, you can choose to generate automated captions/transcripts. Depending on how clear the spoken audio is, the resulting transcript quality will vary greatly.

As with most things in life, you tend to get what you pay for; different services will vary in accuracy and time taken to produce the transcript. If you pay a reputable company or AI service to do the transcription, you will probably get it done rapidly and to a high quality. If you don't want to pay for it, you are likely to get it done at a lower quality, and/or slowly.

It is not OK to publish an audio resource but promise to publish the transcript later on — such promises often aren't kept, which will erode trust between you and your users. If the audio you are presenting is something like a face to face meeting or live spoken performance, it would be acceptable to take notes during the performance, publish them in full along with the audio, then seek help in cleaning up the notes afterward.

Transcript examples

If you use an automated service, then you'll probably have to use the user interface that the tool provides. For example, take a look at our  Wait, ARIA Roles Have Categories? video and choose the three-dot menu (. . .) > Show Transcript . You'll see the transcript come up in a separate panel.

If you are creating your own user interface to present your audio and associated transcript, you can do it however you like, but it might make sense to include it in a showable/hideable panel; see our audio-transcript-ui example (also see the 源代码 ).

Audio descriptions

On occasions where there are visuals accompanying your audio, you'll need to provide audio descriptions of some kind to describe that extra content.

In many cases, this will take the form of video, in which case you can implement captions using the techniques described in the next section of the article.

However, there are some edge cases. You might for example have an audio recording of a meeting that refers to an accompanying resource such as a spreadsheet or chart. In such cases, you should make sure that the resources are provided along with the audio + transcript, and specifically link to them in the places where they are referred to in the transcript. This of course will help all users, not just people who are deaf.

注意: An audio transcript will in general help multiple user groups. As well as giving deaf users access to the information contained in the audio, think about a user with a low bandwidth connection, who would find downloading the audio inconvenient. Think also about a user in a noisy environment like a pub or bar, who is trying to access the information but can't hear it over the noise.

Video text tracks

To make video accessible for deaf, blind, or even other groups of users (such as those on low bandwidth, or who don't understand the language the video is recorded in), you need to include text tracks along with your video content.

注意: text tracks are also useful for potentially any user, not just those with disabilities. for example, some users may not be able to hear the audio because they are in noisy environments (like a crowded bar when a sports game is being shown) or might not want to disturb others if they are in a quiet place (like a library.)

This is not a new concept — television services have had closed captioning available for quite a long time:

Frame from an old-timey cartoon with closed captioning "Good work, Goldie. Keep it up!"

Whereas many countries offer English films with subtitles written in their own native languages, and different language subtitles are often available on DVDs, for example

An English film with German subtitles "Emo, warum erkennst du nicht die Schonheit dieses Ortes?"

There are different types of text tracks for different purposes. The main ones you'll come across are:

  • Captions — There for the benefit of deaf users who can't hear the audio track, including the words being spoken, and contextual information such as who spoke the words, if the people were angry or sad, and what mood the music is currently creating.
  • Subtitles — Include translations of the audio dialog, for users that don't understand the language being spoken.
  • Descriptions — These include descriptions for blind people who can't see the video, for example, what the scene looks like.
  • Chapter titles — Chapter markers intended to help the user navigate the media resource

Implementing HTML5 video text tracks

Text tracks for displaying with HTML5 video need to be written in WebVTT, a text format containing multiple strings of text along with metadata such as what time in the video you want each text string to be displayed, and even limited styling/positioning information. These text strings are called cues.

A typical WebVTT file will look something like this:

WEBVTT
1
00:00:22.230 --> 00:00:24.606
This is the first subtitle.
2
00:00:30.739 --> 00:00:34.074
This is the second.
...
					

To get this displayed along with the HTML media playback, you need to:

  • Save it as a .vtt file in a sensible place.
  • Link to the .vtt file with the <track> 元素。 <track> should be placed within <audio> or <video> , but after all <source> elements. Use the kind attribute to specify whether the cues are subtitles, captions, or descriptions. Furthermore, use srclang to tell the browser what language you have written the subtitles in.

Here's an example:

<video controls>
  <source src="example.mp4" type="video/mp4">
  <source src="example.webm" type="video/webm">
  <track kind="subtitles" src="subtitles_en.vtt" srclang="en">
</video>

					

This will result in a video that has subtitles displayed, kind of like this:

Video player with standard controls such as play, stop, volume, and captions on and off. The video playing shows a scene of a man holding a spear-like weapon, and a caption reads "Esta hoja tiene pasado oscuro."

For more details, please read Adding captions and subtitles to HTML5 video . You can find the example that goes along with this article on Github, written by Ian Devlin (see the 源代码 too.) This example uses JavaScript to allow users to choose between different subtitles. Note that to turn the subtitles on, you need to press the "CC" button and select an option — English, Deutsch, or Español.

注意: Text tracks and transcriptions also help you with SEO , since search engines especially thrive on text. Text tracks even allow search engines to link directly to a spot partway through the video.

Test your skills!

You've reached the end of this article, but can you remember the most important information?

We've not written a new set of assessments for this article, because there are already assessments available in our HTML Multimedia and embedding module that test your knowledge of the information presented here. If you haven't already, go and try out the assessments at Test your skills: HTML images and Test your skills: Multimedia and embedding .

摘要

This chapter has provided a summary of accessibility concerns for multimedia content, along with some practical solutions.

It is not always easy to make multimedia accessible. If for example, you are dealing with an immersive 3D game or virtual reality app, it really is quite difficult to provide text alternatives for such an experience, and you might argue that blind users are not really in the target audience bracket for such apps.

You can however make sure that such an app has good enough color contrast and clear presentation so it is perceivable to those with low vision/color blindness, and also make it keyboard accessible. Remember that accessibility is about doing as much as you can, rather than striving for 100% accessibility all the time, which is often impossible.

In this module

发现此页面有问题吗?

最后修改: , 由 MDN 贡献者

  1. Complete beginners start here!
  2. Web 快速入门
    1. Getting started with the Web overview
    2. 安装基本软件
    3. What will your website look like?
    4. 处理文件
    5. HTML 基础
    6. CSS 基础
    7. JavaScript 基础
    8. 发布您的网站
    9. How the Web works
  3. HTML — Structuring the Web
  4. HTML 介绍
    1. Introduction to HTML overview
    2. Getting started with HTML
    3. What's in the head? Metadata in HTML
    4. HTML text fundamentals
    5. Creating hyperlinks
    6. Advanced text formatting
    7. Document and website structure
    8. Debugging HTML
    9. Assessment: Marking up a letter
    10. Assessment: Structuring a page of content
  5. 多媒体和嵌入
    1. Multimedia and embedding overview
    2. Images in HTML
    3. Video and audio content
    4. From object to iframe — other embedding technologies
    5. Adding vector graphics to the Web
    6. Responsive images
    7. Assessment: Mozilla splash page
  6. HTML 表格
    1. HTML tables overview
    2. HTML table basics
    3. HTML Table advanced features and accessibility
    4. Assessment: Structuring planet data
  7. CSS — Styling the Web
  8. CSS 第一步
    1. CSS first steps overview
    2. What is CSS?
    3. Getting started with CSS
    4. How CSS is structured
    5. How CSS works
    6. Using your new knowledge
  9. CSS 构建块
    1. CSS building blocks overview
    2. Cascade and inheritance
    3. CSS 选择器
    4. The box model
    5. Backgrounds and borders
    6. Handling different text directions
    7. Overflowing content
    8. Values and units
    9. Sizing items in CSS
    10. Images, media, and form elements
    11. Styling tables
    12. Debugging CSS
    13. Organizing your CSS
  10. 样式化文本
    1. Styling text overview
    2. Fundamental text and font styling
    3. Styling lists
    4. Styling links
    5. Web fonts
    6. Assessment: Typesetting a community school homepage
  11. CSS 布局
    1. CSS layout overview
    2. Introduction to CSS layout
    3. Normal Flow
    4. Flexbox
    5. Grids
    6. Floats
    7. 位置
    8. Multiple-column Layout
    9. Responsive design
    10. Beginner's guide to media queries
    11. Legacy Layout Methods
    12. Supporting Older Browsers
    13. Fundamental Layout Comprehension
  12. JavaScript — Dynamic client-side scripting
  13. JavaScript 第一步
    1. JavaScript first steps overview
    2. What is JavaScript?
    3. A first splash into JavaScript
    4. What went wrong? Troubleshooting JavaScript
    5. Storing the information you need — Variables
    6. Basic math in JavaScript — Numbers and operators
    7. Handling text — Strings in JavaScript
    8. Useful string methods
    9. 数组
    10. Assessment: Silly story generator
  14. JavaScript 构建块
    1. JavaScript building blocks overview
    2. Making decisions in your code — Conditionals
    3. Looping code
    4. Functions — Reusable blocks of code
    5. Build your own function
    6. Function return values
    7. 事件介绍
    8. Assessment: Image gallery
  15. 引入 JavaScript 对象
    1. Introducing JavaScript objects overview
    2. Object basics
    3. 对象原型
    4. Object-oriented programming concepts
    5. Classes in JavaScript
    6. Working with JSON data
    7. Object building practice
    8. Assessment: Adding features to our bouncing balls demo
  16. 异步 JavaScript
    1. Asynchronous JavaScript overview
    2. General asynchronous programming concepts
    3. Introducing asynchronous JavaScript
    4. Cooperative asynchronous Java​Script: Timeouts and intervals
    5. Graceful asynchronous programming with Promises
    6. Making asynchronous programming easier with async and await
    7. Choosing the right approach
  17. 客户端侧 Web API
    1. 客户端侧 Web API
    2. Introduction to web APIs
    3. Manipulating documents
    4. Fetching data from the server
    5. Third party APIs
    6. Drawing graphics
    7. Video and audio APIs
    8. Client-side storage
  18. Web forms — Working with user data
  19. Core forms learning pathway
    1. Web forms overview
    2. Your first form
    3. How to structure a web form
    4. Basic native form controls
    5. The HTML5 input types
    6. Other form controls
    7. Styling web forms
    8. Advanced form styling
    9. UI pseudo-classes
    10. Client-side form validation
    11. Sending form data
  20. Advanced forms articles
    1. How to build custom form controls
    2. Sending forms through JavaScript
    3. CSS property compatibility table for form controls
  21. Accessibility — Make the web usable by everyone
  22. Accessibility guides
    1. Accessibility overview
    2. What is accessibility?
    3. HTML: A good basis for accessibility
    4. CSS and JavaScript accessibility best practices
    5. WAI-ARIA basics
    6. Accessible multimedia
    7. Mobile accessibility
  23. Accessibility assessment
    1. Assessment: Accessibility troubleshooting
  24. Tools and testing
  25. Client-side web development tools
    1. Client-side web development tools index
    2. Client-side tooling overview
    3. Command line crash course
    4. Package management basics
    5. Introducing a complete toolchain
    6. Deploying our app
  26. Introduction to client-side frameworks
    1. Client-side frameworks overview
    2. Framework main features
  27. React
    1. Getting started with React
    2. Beginning our React todo list
    3. Componentizing our React app
    4. React interactivity: Events and state
    5. React interactivity: Editing, filtering, conditional rendering
    6. Accessibility in React
    7. React resources
  28. Ember
    1. Getting started with Ember
    2. Ember app structure and componentization
    3. Ember interactivity: Events, classes and state
    4. Ember Interactivity: Footer functionality, conditional rendering
    5. Routing in Ember
    6. Ember resources and troubleshooting
  29. Vue
    1. Getting started with Vue
    2. Creating our first Vue component
    3. Rendering a list of Vue components
    4. Adding a new todo form: Vue events, methods, and models
    5. Styling Vue components with CSS
    6. Using Vue computed properties
    7. Vue conditional rendering: editing existing todos
    8. Focus management with Vue refs
    9. Vue resources
  30. Svelte
    1. Getting started with Svelte
    2. Starting our Svelte Todo list app
    3. Dynamic behavior in Svelte: working with variables and props
    4. Componentizing our Svelte app
    5. Advanced Svelte: Reactivity, lifecycle, accessibility
    6. Working with Svelte stores
    7. TypeScript support in Svelte
    8. Deployment and next steps
  31. Angular
    1. Getting started with Angular
    2. Beginning our Angular todo list app
    3. Styling our Angular app
    4. Creating an item component
    5. Filtering our to-do items
    6. Building Angular applications and further resources
  32. Git and GitHub
    1. Git and GitHub overview
    2. Hello World
    3. Git Handbook
    4. Forking Projects
    5. About pull requests
    6. Mastering Issues
  33. Cross browser testing
    1. Cross browser testing overview
    2. Introduction to cross browser testing
    3. Strategies for carrying out testing
    4. Handling common HTML and CSS problems
    5. Handling common JavaScript problems
    6. Handling common accessibility problems
    7. Implementing feature detection
    8. Introduction to automated testing
    9. Setting up your own test automation environment
  34. Server-side website programming
  35. 第一步
    1. First steps overview
    2. Introduction to the server-side
    3. Client-Server overview
    4. Server-side web frameworks
    5. Website security
  36. Django Web 框架 (Python)
    1. Django web framework (Python) overview
    2. 介绍
    3. 设置开发环境
    4. Tutorial: The Local Library website
    5. Tutorial Part 2: Creating a skeleton website
    6. Tutorial Part 3: Using models
    7. Tutorial Part 4: Django admin site
    8. Tutorial Part 5: Creating our home page
    9. Tutorial Part 6: Generic list and detail views
    10. Tutorial Part 7: Sessions framework
    11. Tutorial Part 8: User authentication and permissions
    12. Tutorial Part 9: Working with forms
    13. Tutorial Part 10: Testing a Django web application
    14. Tutorial Part 11: Deploying Django to production
    15. Web application security
    16. Assessment: DIY mini blog
  37. Express Web Framework (node.js/JavaScript)
    1. Express Web Framework (Node.js/JavaScript) overview
    2. Express/Node introduction
    3. Setting up a Node (Express) development environment
    4. Express tutorial: The Local Library website
    5. Express Tutorial Part 2: Creating a skeleton website
    6. Express Tutorial Part 3: Using a database (with Mongoose)
    7. Express Tutorial Part 4: Routes and controllers
    8. Express Tutorial Part 5: Displaying library data
    9. Express Tutorial Part 6: Working with forms
    10. Express Tutorial Part 7: Deploying to production
  38. Further resources
  39. Common questions
    1. HTML questions
    2. CSS questions
    3. JavaScript questions
    4. Web mechanics
    5. Tools and setup
    6. Design and accessibility