canplaythrough — медіа можна грати без буферизації


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

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

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

Щоб використати canplaythrough, вам потрібно додати слухача події до медіаелемента (наприклад, audio або video). Після того як подія спрацьовує, ви можете виконати будь-які дії, які необхідні для початку або підготовки відтворення.

const audioElement = document.querySelector('audio');

audioElement.addEventListener('canplaythrough', function(event) {
  console.log('Аудіо готове до безперервного відтворення!');
});

У цьому прикладі подія canplaythrough спрацьовує для елемента audio, коли браузер визначає, що аудіо готове до відтворення без зупинок. Функція обробника просто виводить повідомлення в консоль, що файл готовий до безперервного відтворення.

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

Деякі браузери також можуть мати власні обмеження на завантаження великих медіафайлів, тому використання події canplaythrough має бути добре продуманим для оптимізації продуктивності сайту або веб-додатку.

автор: Bond

Порада

Для більш точного контролю над відтворенням медіафайлів, розгляньте можливість використання canplaythrough разом з іншими подіями, такими як waiting і playing, щоб створити більш адаптивний і надійний плеєр, який реагує на різні стану мережі та завантаження.

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

Використовуйте canplaythrough для відстеження часу, необхідного для повного завантаження медіафайлу. Це може бути корисним для аналітики та покращення продуктивності вашого сайту або додатку, особливо при роботі з великими медіафайлами.

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

Якщо ви працюєте над мобільною версією вашого сайту або додатку, враховуйте, що подія canplaythrough може не завжди бути точним індикатором для мобільних мереж через коливання швидкості завантаження. У таких випадках використовуйте додаткові механізми для управління медіавмістом.

автор: Bond

Синтаксис

element.addEventListener('canplaythrough', 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

<header>
  <h2 class="title">HTML Events: canplaythrough</h2>
  <p class="description">Подія сигналізує, що медіафайл можна відтворити до кінця без паузи для буферизації.</p>
</header>
<main>
  <div class="result">
    <!-- Відео елемент -->
    <video id="myVideo" width="400" controls poster="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='320' height='180' viewBox='0 0 320 180'%3E%3Crect width='320' height='180' fill='%23264653'/%3E%3Cpath d='M138 62 192 90 138 118Z' fill='%23e9c46a'/%3E%3Ctext x='160' y='138' font-family='sans-serif' font-size='15' text-anchor='middle' fill='%23e9c46a'%3Eлише звук%3C/text%3E%3C/svg%3E">
      Ваш браузер не підтримує відтворення відео.
    </video>
    
    <!-- Індикатор завантаження -->
    <div id="loadingIndicator">Завантаження відео...</div>
    
    <!-- Кнопка управління -->
    <button id="playButton" disabled>Play</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;
  display: none; /* Приховуємо за замовчуванням */
}

#playButton {
  margin-top: 15px;
}

JS

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

// Відображаємо індикатор завантаження під час початкового завантаження відео
loadingIndicator.style.display = 'block';

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

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

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

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

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

// Обробник події 'playing', щоб приховати індикатор, коли відео відтворюється
video.addEventListener('playing', function () {
  loadingIndicator.style.display = 'none';
});

// — службове: беззвучний 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

<button id="playButton">Відтворити</button>
<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 320 180'%3E%3Crect width='320' height='180' fill='%23264653'/%3E%3Cpath d='M138 62 192 90 138 118Z' fill='%23e9c46a'/%3E%3Ctext x='160' y='138' font-family='sans-serif' font-size='15' text-anchor='middle' fill='%23e9c46a'%3Eлише звук%3C/text%3E%3C/svg%3E">
    Ваш браузер не відтворює відео.
</video>

JS

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

// Приховуємо кнопку "Play" поки відео не буде готове
playButton.style.display = 'none';

video.src = silentWav(10);

video.addEventListener('canplaythrough', function() {
  // Показуємо кнопку "Play" після готовності відео
  playButton.style.display = 'inline';
});

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

// — службове: беззвучний 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

<audio id="track" controls muted></audio>

JS

const audio = document.getElementById('track');

audio.src = silentWav(3);

audio.addEventListener('canplaythrough', function() {
  // Автоматично відтворюємо аудіо після того, як воно буде готове
  audio.play().catch(function (error) {
    console.log(`Автозапуск заборонено (${error.name}) — натисніть кнопку відтворення`);
  });
});

// Виконуємо додаткову перевірку на випадок, якщо відтворення було заборонено
audio.addEventListener('play', function() {
  console.log('Аудіо відтворюється безперервно.');
});

// — службове: беззвучний 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`.
||
Ховає цілі абзаци. На сторінці видно лише підпис із першого рядка («Показати рішення»), решта розгортається клацанням по ньому. Закривні риски — окремим рядком.
Порожній рядок Новий абзац. Щоб перенести рядок усередині абзацу, поставте \ в його кінці.

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

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