Подія canplay в JavaScript — медіа готове до відтворення


Загальний опис

canplay — це подія HTML, яка спрацьовує, коли браузер визначає, що медіафайл (наприклад, аудіо або відео) готовий до відтворення принаймні частини даних. Це означає, що медіафайл достатньо завантажений або підготовлений для початкового відтворення, навіть якщо весь файл ще не завантажений.

Ця подія є корисною, коли вам потрібно виконати якісь дії в момент, коли медіафайл досягає стану, що дозволяє його відтворення. Наприклад, ви можете активувати кнопку "Play" для користувача тільки після того, як подія "canplay" спрацює, що гарантує, що медіафайл готовий до відтворення.

Для використання події "canplay", спочатку необхідно отримати доступ до медіаелемента (наприклад, audio або video) у вашому HTML документі, а потім додати слухача події за допомогою методу addEventListener.

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

videoElement.addEventListener('canplay', function(event) {
  console.log('Відео готове до відтворення!');
});

У цьому прикладі ми отримуємо доступ до елемента video за допомогою querySelector і додаємо слухача події "canplay". Коли браузер визначає, що відео готове до відтворення, спрацьовує функція зворотного виклику, яка просто виводить повідомлення в консоль.

Важливо розуміти різницю між подіями "canplay" та "canplaythrough". Подія "canplay" спрацьовує, коли браузер може почати відтворення, але це не означає, що весь медіафайл можна відтворити без зупинки для буферизації. Подія "canplaythrough" спрацьовує, коли браузер вважає, що медіафайл можна відтворити повністю до кінця без будь-якої додаткової буферизації. Якщо ваше завдання — просто почати відтворення медіафайлу якомога швидше, "canplay" буде правильним вибором.

Ще однією корисною властивістю події "canplay" є можливість використовувати її для оптимізації поведінки користувацького інтерфейсу. Наприклад, ви можете показувати індикатор завантаження або прогресу, доки медіафайл не буде готовий до відтворення, а після спрацювання події "canplay" цей індикатор можна приховати, щоб користувач міг почати перегляд або прослуховування.

автор: Bond

Порада

Для уникнення помилок на сторінках із багатьма медіафайлами корисно розуміти, що подія "canplay" може спрацьовувати кілька разів, особливо якщо користувач змінює якість відео або переключається між різними джерелами. В такому випадку може знадобитися видалити слухача події після першого спрацьовування або динамічно оновлювати інтерфейс.

автор: Bond
Порада

Подія "canplay" може бути використана для покращення SEO вашого сайту. Якщо ви автоматично запускаєте відео після його готовності до відтворення, це може покращити час перебування користувачів на вашій сторінці, що позитивно вплине на ранжування в пошукових системах.

автор: Bond
Порада

Іноді корисно використовувати подію "canplay" для моніторингу доступності медіафайлів у реальному часі. Наприклад, ви можете відстежувати подію, щоб записувати в журнал часу, скільки займає завантаження медіафайлу до стану, коли він готовий до відтворення.

автор: Bond

Синтаксис

element.addEventListener('canplay', function(event) {
  // Код обробника події
});

Переглядачі

Підтримка: стаціонарні переглядачі
Переглядач Google Chrome Mozilla Firefox Apple Safari Opera Microsoft EDGE Microsoft Internet Explorer
3 3.5 3.1 10.5 12 9
Підтримка: мобільні переглядачі
Переглядач Mobile Google Android Mobile Google Chrome Mobile Mozilla Firefox Mobile Apple Safari
4.4 18 4 3

Приклади

+ запропонувати свій приклад у пісочниці

HTML

<button id="playButton">Відтворити</button>
<audio id="track" controls preload="metadata">
    Ваш браузер не підтримує тег audio.
</audio>

JS

const audio = document.getElementById('track');
const playButton = document.querySelector('#playButton');

playButton.disabled = true; // Вимикаємо кнопку "Play"

audio.addEventListener('canplay', function() {
  playButton.disabled = false; // Вмикаємо кнопку "Play" після готовності медіа
});

playButton.addEventListener('click', function() {
  audio.play();
});

audio.src = silentWav(30);

// — службове: беззвучний WAV замість медіафайла, збирається просто тут —
function silentWav(seconds = 3, rate = 8000) {
  const size = seconds * rate;  // 8-бітний моно PCM: один байт на семпл
  const le = (value, bytes) => String.fromCharCode(...Array.from({ length: bytes }, (_, i) => value >> 8 * i & 255));
  const head = `RIFF${le(36 + size, 4)}WAVEfmt ${le(16, 4)}${le(1, 2)}${le(1, 2)}${le(rate, 4)}${le(rate, 4)}${le(1, 2)}${le(8, 2)}data${le(size, 4)}`;

  return `data:audio/wav;base64,${btoa(head + '\u0080'.repeat(size))}`;
}
автор: Bond

HTML

<header>
  <h2 class="title">HTML Events: canplay</h2>
  <p class="description">Подія сигналізує, що медіафайл готовий до відтворення.</p>
</header>
<main>
  <div class="result">
    <!-- Відео елемент -->
    <video id="myVideo" width="400" height="225" controls poster="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='400' height='225' viewBox='0 0 64 36' preserveAspectRatio='none'%3E%3Crect width='64' height='36' fill='%23264653'/%3E%3Ccircle cx='32' cy='18' r='10' fill='%23e9c46a'/%3E%3Cpath d='M29 12 38 18 29 24Z' fill='%23264653'/%3E%3C/svg%3E">
      Ваш браузер не підтримує відтворення відео.
    </video>
    
    <!-- Індикатор завантаження -->
    <div id="loadingIndicator">Завантаження відео...</div>
    
    <!-- Кнопки управління -->
    <button id="playButton" disabled>Play</button>
    <button id="pauseButton" disabled>Pause</button>
  </div>
</main>

CSS

body {
  font-size: 16px;
  line-height: 1.5;
  font-family: monospace;
}

header {
  background-color: #f1f1f1;
  margin-bottom: 25px;
  padding: 15px;
  -webkit-box-shadow: 0px 0px 3px 0px rgba(118, 118, 118, 1);
  -moz-box-shadow: 0px 0px 3px 0px rgba(118, 118, 118, 1);
  box-shadow: 0px 0px 3px 0px rgba(118, 118, 118, 1);
}

header h2.title {
  padding-bottom: 15px;
  border-bottom: 1px solid #999;
}

header p.description {
  font-style: italic;
  color: #222;
}

.result {
  background-color: #f8f8f8;
  padding: 15px;
  -webkit-box-shadow: 0px 0px 3px 0px rgba(118, 118, 118, 1);
  -moz-box-shadow: 0px 0px 3px 0px rgba(118, 118, 118, 1);
  box-shadow: 0px 0px 3px 0px rgba(118, 118, 118, 1);
}

#loadingIndicator {
  color: red;
  margin-top: 10px;
}

JS

// Отримуємо елементи з DOM
const video = document.getElementById('myVideo');
const playButton = document.getElementById('playButton');
const pauseButton = document.getElementById('pauseButton');
const loadingIndicator = document.getElementById('loadingIndicator');

// Додаємо обробник події 'canplay'
video.addEventListener('canplay', function () {
  // Приховуємо індикатор завантаження
  loadingIndicator.style.display = 'none';

  // Активуємо кнопки відтворення та паузи
  playButton.disabled = false;
  pauseButton.disabled = false;
});

// Додаємо обробник події для кнопки Play
playButton.addEventListener('click', function () {
  video.play();
});

// Додаємо обробник події для кнопки Pause
pauseButton.addEventListener('click', function () {
  video.pause();
});

// Додаємо обробник події 'waiting', щоб показувати індикатор завантаження при буферизації
video.addEventListener('waiting', function () {
  loadingIndicator.style.display = 'block';
});

// Джерело: беззвучний WAV, зібраний тут-таки (див. silentWav нижче)
video.src = silentWav(30);

// — службове: беззвучний WAV замість медіафайла, збирається просто тут —
function silentWav(seconds = 3, rate = 8000) {
  const size = seconds * rate;  // 8-бітний моно PCM: один байт на семпл
  const le = (value, bytes) => String.fromCharCode(...Array.from({ length: bytes }, (_, i) => value >> 8 * i & 255));
  const head = `RIFF${le(36 + size, 4)}WAVEfmt ${le(16, 4)}${le(1, 2)}${le(1, 2)}${le(rate, 4)}${le(rate, 4)}${le(1, 2)}${le(8, 2)}data${le(size, 4)}`;

  return `data:audio/wav;base64,${btoa(head + '\u0080'.repeat(size))}`;
}
автор: Bond

HTML

<video width="320" height="180" controls poster="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='320' height='180' viewBox='0 0 64 36' preserveAspectRatio='none'%3E%3Crect width='64' height='36' fill='%23264653'/%3E%3Ccircle cx='32' cy='18' r='10' fill='%23e9c46a'/%3E%3Cpath d='M29 12 38 18 29 24Z' fill='%23264653'/%3E%3C/svg%3E">
    Ваш браузер не відтворює відео.
</video>

JS

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

video.addEventListener('canplay', function() {
  alert('Відео готове до відтворення!');
});

video.src = silentWav(30);

// — службове: беззвучний WAV замість медіафайла, збирається просто тут —
function silentWav(seconds = 3, rate = 8000) {
  const size = seconds * rate;  // 8-бітний моно PCM: один байт на семпл
  const le = (value, bytes) => String.fromCharCode(...Array.from({ length: bytes }, (_, i) => value >> 8 * i & 255));
  const head = `RIFF${le(36 + size, 4)}WAVEfmt ${le(16, 4)}${le(1, 2)}${le(1, 2)}${le(rate, 4)}${le(rate, 4)}${le(1, 2)}${le(8, 2)}data${le(size, 4)}`;

  return `data:audio/wav;base64,${btoa(head + '\u0080'.repeat(size))}`;
}
автор: Bond

Коментарі

Коментарів ще немає — будьте першим!

Відповідь для

Як форматувати текст?
Пишемо Виходить
**важливо**
*акцент*
~~застаріле~~
Виділення в тексті. Те саме роблять кнопки панелі, що спливає над виділеним.
## Як працює каскад
### Порядок оголошень
Заголовки всередині тексту. Найбільший не потрібен — він у сторінки вже є.
[[css/property/color]] Посилання на сторінку довідника. Наберіть [[ — поле веде сходинками (розділ → тип → сторінка), а хибний ключ підкреслить хвилею.
[[!sandbox/S0oh1hBm]] Живий приклад окремим рядком — саме вікно результату. Той самий ключ зі знаком !: наберіть [[! і дійдіть сходинками до потрібної сторінки, список покаже її приклади.
[MDN](https://developer.mozilla.org) Посилання на чужий сайт.
![Схема каскаду](https://site.com/схема.png) Картинка. Опис обов'язковий: його читають пошуковик і незрячі.
Задайте `display: grid` контейнеру Код усередині речення.
```css
.card { display: grid }
```
Код блоком. Мова після трьох лапок вмикає підсвітку.
- Походження
1. Походження
Перелік: маркований і нумерований.
- [ ] дописати приклади
- [x] перевірити в Firefox
Перелік завдань із галочками. Пробіл у порожніх дужках обов'язковий.
> Порядок важить лише за рівної ваги. Цитата на всю ширину абзацу.
Специфічність
: вага селектора; більша перемагає
Список означень: термін, а під ним пояснення з відступом. Пробіл після двокрапки обов'язковий.
Каскад має три критерії[^1]
[^1]: Походження, специфічність, порядок.
Виноска: номер у тексті, примітка внизу сторінки. Без згадки [^1] у тексті примітка не з'явиться.
Відповідь: ||сорок два|| Ховає те, що між рисками: читач бачить на цьому місці розмиту пляму, а решта речення лишається звичайною. Клац — і текст відкрито.
|| Показати рішення
Задайте контейнеру `display: grid`.
||
Ховає цілі абзаци. На сторінці видно лише підпис із першого рядка («Показати рішення»), решта розгортається клацанням по ньому. Закривні риски — окремим рядком.
Порожній рядок Новий абзац. Щоб перенести рядок усередині абзацу, поставте \ в його кінці.

Увійдіть — коментар з'явиться одразу, без капчі й очікування перевірки.

Правка
Зворотний зв'язок
Вхід