Работа с видео и аудио: HTMLMediaElement, controls, events
Введение: Власть над мультимедиа в твоих руках 🎬
Представь: твой сайт оживает — играет музыка, крутятся ролики, пользователи в восторге. Всё это возможно с HTMLMediaElement — базовым интерфейсом для работы с видео и аудио в JavaScript. Давай разберёмся, как управлять медиаконтентом как профи!
Основы: Встраиваем медиа на страницу
Проще всего добавить медиа через HTML-теги <audio> и <video>. Вот базовый пример:
<audio controls src="sound.mp3"></audio>
<video controls width="600" src="video.mp4"></video>
💡 Атрибут
controlsдобавляет стандартные элементы управления: play/pause, громкость, прогресс-бар.
Но настоящая магия начинается, когда подключаешь JavaScript!
HTMLMediaElement: Сердце медиафункционала 💓
Все методы и свойства медиаэлементов доступны через JavaScript:
const video = document.querySelector('video');
// Основные методы
video.play(); // Запустить воспроизведение
video.pause(); // Приостановить
video.load(); // Перезагрузить источник
// Полезные свойства
console.log(video.duration); // Длительность в секундах
console.log(video.currentTime); // Текущая позиция
video.volume = 0.5; // Громкость (от 0 до 1)
video.playbackRate = 1.5; // Скорость воспроизведения
События: Реагируем на изменения 🚨
Медиаэлементы генерируют множество событий. Вот основные:
video.addEventListener('play', () => {
console.log('Воспроизведение началось!');
});
video.addEventListener('pause', () => {
console.log('Пауза!');
});
video.addEventListener('timeupdate', () => {
console.log(`Текущее время: ${video.currentTime}`);
});
video.addEventListener('ended', () => {
console.log('Ролик закончился! Можно ставить лайк :)');
});
Кастомные элементы управления 🎛️
Хочешь заменить стандартные controls своими? Легко! Создаём свои кнопки:
<video id="myVideo" src="video.mp4"></video>
<div class="controls">
<button id="playBtn">▶️</button>
<input type="range" id="volume" min="0" max="1" step="0.1" value="1">
</div>
const video = document.getElementById('myVideo');
const playBtn = document.getElementById('playBtn');
const volumeControl = document.getElementById('volume');
playBtn.addEventListener('click', () => {
if (video.paused) {
video.play();
playBtn.textContent = '⏸';
} else {
video.pause();
playBtn.textContent = '▶️';
}
});
volumeControl.addEventListener('input', () => {
video.volume = volumeControl.value;
});
Работа с источниками и форматами 🌐
Не все браузеры поддерживают все форматы. Решение — использовать несколько источников:
<video controls>
<source src="video.webm" type="video/webm">
<source src="video.mp4" type="video/mp4">
Ваш браузер не поддерживает HTML5 видео.
</video>
Продвинутые техники: Canvas + Video = Магия ✨
Связываем видео с canvas для обработки кадров:
<video id="sourceVideo" src="video.mp4" hidden></video>
<canvas id="outputCanvas"></canvas>
const video = document.getElementById('sourceVideo');
const canvas = document.getElementById('outputCanvas');
const ctx = canvas.getContext('2d');
video.addEventListener('play', () => {
function processFrame() {
if (video.paused || video.ended) return;
// Рисуем текущий кадр видео на canvas
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
// Можно добавить обработку изображения здесь
requestAnimationFrame(processFrame);
}
processFrame();
});
Буферизация и загрузка 📊
Отслеживаем, сколько медиа загружено:
video.addEventListener('progress', () => {
let loaded = 0;
if (video.buffered.length > 0) {
loaded = video.buffered.end(0) / video.duration * 100;
}
console.log(`Загружено: ${loaded.toFixed(1)}%`);
});
Практический пример: Видеоплеер с предпросмотром
Создадим плеер с миниатюрами при наведении на прогресс-бар:
<div class="video-player">
<video src="video.mp4"></video>
<div class="progress-container">
<div class="progress-bar"></div>
<div class="preview"></div>
</div>
</div>
const progress = document.querySelector('.progress-container');
const preview = document.querySelector('.preview');
const video = document.querySelector('video');
// Создаем миниатюры (в реальном проекте их нужно подготовить заранее)
progress.addEventListener('mousemove', (e) => {
const rect = progress.getBoundingClientRect();
const pos = (e.clientX - rect.left) / rect.width;
const time = pos * video.duration;
// Здесь можно показать миниатюру для времени `time`
preview.style.left = `${pos * 100}%`;
preview.textContent = formatTime(time);
});
function formatTime(seconds) {
const min = Math.floor(seconds / 60);
const sec = Math.floor(seconds % 60);
return `${min}:${sec < 10 ? '0' : ''}${sec}`;
}
🔥 Совет от Данилы Бежина: Для настоящего предпросмотра видео нужно подготовить спрайт с миниатюрами или использовать Web API для генерации превью в реальном времени. Подробнее в его видео про продвинутую работу с видео.
Ошибки и их обработка ❌
Всегда обрабатывайте возможные ошибки:
video.addEventListener('error', () => {
switch(video.error.code) {
case MediaError.MEDIA_ERR_ABORTED:
console.log('Загрузка прервана');
break;
case MediaError.MEDIA_ERR_NETWORK:
console.log('Проблемы с сетью');
break;
case MediaError.MEDIA_ERR_DECODE:
console.log('Ошибка декодирования');
break;
case MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED:
console.log('Формат не поддерживается');
break;
}
});
Оптимизация производительности ⚡
1. Используйте preload="metadata" для лёгкой загрузки:
<video preload="metadata" src="video.mp4"></video>
2. Для длинных видео используйте потоковую передачу.
3. Отключайте обработку событий, когда они не нужны.
Заключение: Твой медиа-арсенал 🛠️
Теперь у тебя есть все необходимые инструменты для создания потрясающих медиа-эффектов на сайте. Экспериментируй, комбинируй техники и создавай нечто уникальное!
Попробуй сделать:
- Аудио-визуализатор с Web Audio API
- Видео-фильтры через canvas
- Интерактивное видео с переходами по клику