Создание кастомного плеера

Тренажер по работе с HTML DOM на JavaScript для пользователей с начальным и средним уровнем подготовки.

Тренажер JavaScript: Покоряем HTML DOM

В этом модуле мы отойдем от стандартных атрибутов `controls` тега `<video>` и научимся управлять воспроизведением с помощью JavaScript. Вы создадите функционал кастомного видеоплеера, взаимодействуя с HTMLMediaElement API. Вы научитесь программно запускать и останавливать видео, управлять громкостью, отслеживать прогресс воспроизведения и работать с метаданными. Все задания выполняются с реальным видеофайлом. Обратите внимание: для корректной работы с видео, браузеры часто требуют взаимодействия пользователя со страницей (например, клик), поэтому во всех заданиях код запускается по нажатию на кнопки.

Список тем

Запуск видео

id: 37084_task_player_01

Начнем с самого простого. У нас есть тег `<video>` и кнопка. Ваша задача — найти видео-элемент в DOM-дереве и заставить его воспроизводиться при нажатии на кнопку, используя соответствующий метод API медиа-элементов.

CSS
video { width: 100%; border-radius: 8px; } button { padding: 10px 20px; background: #28a745; color: white; border: none; border-radius: 4px; cursor: pointer; margin-top: 10px; }
HTML
Восстановить HTML
<video id="myVideo" src="https://naytikurs.ru/img/1.mp4" poster="https://naytikurs.ru/img/1.png"></video>
<br>
<button id="playBtn">Запустить видео</button>
JavaScript
const video = document.input__1('video');
const btn = document.querySelector('#playBtn');

btn.addEventListener('click', function() {
  video.input__2();
});
Для поиска элемента используйте `querySelector`. У видео-элементов есть метод `.play()`, который запускает воспроизведение.
Заполнить ответами все поля
Результат
Лог
Выполнить
Показать подсказку

Пауза воспроизведения

id: 37084_task_player_02

Видео уже запущено (мы сделали это автоматически в коде). Ваша задача — дописать обработчик события для кнопки «Пауза», чтобы остановить воспроизведение видео.

CSS
video { width: 100%; border-radius: 8px; } button { padding: 10px 20px; background: #dc3545; color: white; border: none; border-radius: 4px; cursor: pointer; margin-top: 10px; }
HTML
Восстановить HTML
<video id="myVideo" src="https://naytikurs.ru/img/1.mp4" autoplay muted loop></video>
<br>
<button id="pauseBtn">Пауза</button>
JavaScript
const video = document.querySelector('#myVideo');
const btn = document.querySelector('#pauseBtn');

btn.addEventListener('click', () => {
  video.input__1();
});
Противоположностью метода `play()` является метод `pause()`. Он останавливает воспроизведение на текущем моменте.
Заполнить ответами все поля
Результат
Лог
Выполнить
Показать подсказку

Переключение Play/Pause

id: 37084_task_player_03

Обычно для запуска и паузы используется одна и та же кнопка. Реализуйте логику переключения: если видео стоит на паузе — запустите его, иначе — поставьте на паузу. Вам нужно проверить состояние видео.

CSS
video { width: 100%; } button { width: 100%; padding: 12px; background: #007bff; color: white; border: none; margin-top: 5px; cursor: pointer; }
HTML
Восстановить HTML
<video id="player" src="https://naytikurs.ru/img/1.mp4" poster="https://naytikurs.ru/img/2.png"></video>
<button id="toggleBtn">⏯ Play / Pause</button>
JavaScript
const video = document.querySelector('#player');
const btn = document.querySelector('#toggleBtn');

btn.addEventListener('click', () => {
  if (video.input__1) {
    video.play();
  } else {
    video.pause();
  }
});
У видео-элемента есть свойство `.paused` (булевое значение), которое возвращает `true`, если видео стоит на паузе.
Заполнить ответами все поля
Результат
Лог
Выполнить
Показать подсказку

Управление громкостью

id: 37084_task_player_04

Создадим регулятор громкости. Используется `input type="range"`. При изменении ползунка, значение громкости видео должно меняться соответственно. Значение `input` варьируется от 0 до 1.

CSS
video { width: 100%; } .controls { display: flex; align-items: center; gap: 10px; padding: 10px; background: #eee; } input[type=range] { flex-grow: 1; }
HTML
Восстановить HTML
<video id="vid" src="https://naytikurs.ru/img/1.mp4"></video>
<div class="controls">
  <span>🔊</span>
  <input type="range" id="volSlider" min="0" max="1" step="0.1" value="1">
</div>
JavaScript
const video = document.getElementById('vid');
const slider = document.getElementById('volSlider');

// Запускаем видео для теста звука
video.play(); 

slider.addEventListener('input', (e) => {
  video.input__1 = e.target.value;
});
Свойство `.volume` отвечает за громкость видео. Оно принимает значение от 0.0 (тишина) до 1.0 (максимум). В обработчике события `input` значение ползунка находится в `e.target.value`.
Заполнить ответами все поля
Результат
Лог
Выполнить
Показать подсказку

Отключение звука (Mute)

id: 37084_task_player_05

Реализуйте кнопку, которая полностью выключает звук (Mute) или включает его обратно при повторном нажатии. Это делается через переключение логического свойства.

CSS
video { width: 100%; } button { background: #333; color: #fff; border: none; padding: 8px 16px; margin-top: 5px; cursor: pointer; }
HTML
Восстановить HTML
<video id="movie" src="https://naytikurs.ru/img/1.mp4" autoplay></video>
<button id="muteBtn">🔇 Mute Toggle</button>
JavaScript
const video = document.getElementById('movie');
const btn = document.getElementById('muteBtn');

btn.addEventListener('click', () => {
  video.input__1 = !video.input__1;
});
Свойство `.muted` является булевым (true/false). Чтобы переключить его, нужно присвоить ему противоположное текущему значению: `!video.muted`.
Заполнить ответами все поля
Результат
Лог
Выполнить
Показать подсказку

Получение длительности видео

id: 37084_task_player_06

Чтобы отобразить время видео, нужно знать его полную длительность. Длительность становится доступной только после загрузки метаданных видео. Допишите код, чтобы при наступлении события загрузки данных вывести длительность видео в консоль (в нашем случае, в скрытое поле проверки).

CSS
video { width: 100%; } .info { font-family: monospace; background: #f4f4f4; padding: 5px; margin-top: 5px; }
HTML
Восстановить HTML
<video id="clip" src="https://naytikurs.ru/img/1.mp4" preload="metadata"></video>
<div class="info">Ждем загрузки метаданных...</div>
JavaScript
const video = document.getElementById('clip');
const display = document.querySelector('.info');

video.addEventListener('input__1', () => {
  display.textContent = 'Длительность: ' + video.input__2 + ' сек.';
});
Событие `loadedmetadata` срабатывает, когда браузер узнал длительность видео. Сама длительность хранится в свойстве `.duration` (в секундах).
Заполнить ответами все поля
Результат
Лог
Выполнить
Показать подсказку

Отслеживание времени воспроизведения

id: 37084_task_player_07

Для создания таймера (например, 0:05 / 1:30) нам нужно постоянно получать текущее время воспроизведения. Используйте событие, которое часто срабатывает при проигрывании, и свойство текущего времени.

CSS
video { width: 100%; } #timer { font-size: 20px; font-weight: bold; color: #333; text-align: center; margin-top: 10px; }
HTML
Восстановить HTML
<video id="tv" src="https://naytikurs.ru/img/1.mp4" autoplay muted loop></video>
<div id="timer">0.00</div>
JavaScript
const video = document.getElementById('tv');
const timer = document.getElementById('timer');

video.addEventListener('input__1', () => {
  timer.textContent = video.input__2.toFixed(2);
});
Событие `timeupdate` срабатывает несколько раз в секунду при воспроизведении. Текущая секунда хранится в свойстве `.currentTime`.
Заполнить ответами все поля
Результат
Лог
Выполнить
Показать подсказку

Кастомный прогресс-бар

id: 37084_task_player_08

Визуализируем прогресс видео. У нас есть серый блок (фон) и синий блок (прогресс). Вам нужно внутри обработчика обновления времени рассчитать процент просмотренного видео и применить его к ширине синего блока.

CSS
video { width: 100%; } .progress-bg { width: 100%; height: 10px; background: #ddd; margin-top: 5px; } .progress-fill { width: 0%; height: 100%; background: #007bff; transition: width 0.1s; }
HTML
Восстановить HTML
<video id="v" src="https://naytikurs.ru/img/1.mp4" autoplay muted loop></video>
<div class="progress-bg">
  <div id="bar" class="progress-fill"></div>
</div>
JavaScript
const video = document.getElementById('v');
const bar = document.getElementById('bar');

video.addEventListener('timeupdate', () => {
  const percent = (video.currentTime / video.input__1) * 100;
  bar.style.input__2 = percent + '%';
});
Формула процента: `(текущее_время / полная_длительность) * 100`. Изменяйте стиль `width` у элемента прогресса, добавляя знак `%`.
Заполнить ответами все поля
Результат
Лог
Выполнить
Показать подсказку

Перемотка видео

id: 37084_task_player_09

Реализуйте кнопку «+5 сек», которая перематывает видео вперед. Для этого нужно изменить текущее время воспроизведения, прибавив к нему 5 секунд.

CSS
video { width: 100%; } button { background: #6610f2; color: white; border: none; padding: 10px; margin-top: 5px; border-radius: 5px; cursor: pointer; }
HTML
Восстановить HTML
<video id="vidSkip" src="https://naytikurs.ru/img/1.mp4" autoplay muted loop></video>
<button id="skipBtn">Вперед на 5 сек >></button>
JavaScript
const video = document.getElementById('vidSkip');
const btn = document.getElementById('skipBtn');

btn.addEventListener('click', () => {
  video.input__1 += 5;
});
Свойство `.currentTime` можно не только читать, но и записывать. Просто прибавьте к нему число 5.
Заполнить ответами все поля
Результат
Лог
Выполнить
Показать подсказку

Окончание видео

id: 37084_task_player_10

Когда видео заканчивается, плеер обычно сбрасывает кнопку «Пауза» обратно на «Play» или показывает экран завершения. Отследите момент окончания видео и выведите сообщение «Конец фильма» в текстовый блок.

CSS
video { width: 100%; } #status { font-weight: bold; color: red; margin-top: 10px; }
HTML
Восстановить HTML
<video id="finalVid" src="https://naytikurs.ru/img/1.mp4" autoplay muted></video>
<div id="status">Воспроизведение...</div>
<!-- Ускорим видео для теста -->
<script>document.getElementById('finalVid').playbackRate = 8.0;</script>
JavaScript
const video = document.getElementById('finalVid');
const status = document.getElementById('status');

video.addEventListener('input__1', () => {
  status.textContent = "Конец фильма";
});
Событие `ended` срабатывает один раз, когда воспроизведение видео достигает конца.
Заполнить ответами все поля
Результат
Лог
Выполнить
Показать подсказку
НайтиКурс.Ру