Play: примеры (JAVASCRIPT)
play: PromiseОсновы метода play
В JavaScript метод play() не является самостоятельной функцией, а представляет собой метод объектов HTMLMediaElement (таких как HTMLAudioElement и HTMLVideoElement) и объектов интерфейса Web Audio API (например, AudioBufferSourceNode). Основное назначение метода запуск воспроизведения аудио или видео контента.
Когда используется:
Метод применяется для программного запуска медиафайлов на веб страницах, в веб приложениях, играх и интерактивных проектах, где требуется управление звуком или видео.
Аргументы и возвращаемые значения:
Для HTMLMediaElement метод play() не принимает аргументов в классическом понимании, но возвращает объект Promise. Этот Promise разрешается, когда воспроизведение успешно начато, и отклоняется, если возникает ошибка (например, из за политики автозапуска браузера).
Для AudioBufferSourceNode в Web Audio API метод play(when, offset, duration) может принимать три необязательных аргумента:
when(Number): Время в секундах, когда должно начаться воспроизведение, относительно текущего аудиоконтекста.offset(Number): Смещение в секундах внутри аудиобуфера, с которого начнется воспроизведение.duration(Number): Продолжительность воспроизведения в секундах.
undefined).Простые примеры использования
Пример с HTMLVideoElement:
<video id='myVideo' src='video.mp4' controls></video>
<button onclick='playVideo()'>Воспроизвести</button>
<script>
function playVideo() {
const video = document.getElementById('myVideo');
video.play().then(() => {
console.log('Воспроизведение начато');
}).catch(error => {
console.log('Ошибка:', error);
});
}
</script>// При успешном запуске: 'Воспроизведение начато' // При ошибке (например, без взаимодействия пользователя): 'Ошибка: NotAllowedError'
Пример с AudioBufferSourceNode и параметрами:
// Предполагаем, что audioContext и buffer уже инициализированы
const source = audioContext.createBufferSource();
source.buffer = buffer;
source.connect(audioContext.destination);
// Начать воспроизведение через 2 секунды, с позиции 1.5 секунды в буфере, длительностью 3 секунды
source.start(audioContext.currentTime + 2, 1.5, 3);
// Для AudioBufferSourceNode метод называется start(), но часто в контексте обсуждения упоминается как play.// Начинается воспроизведение через 2 секунды с заданными параметрами.
Похожие методы и библиотеки JavaScript
HTMLMediaElement.pause()
Приостанавливает воспроизведение. Не принимает аргументов и не возвращает Promise.
HTMLMediaElement.load()
Перезагружает медиаэлемент. Полезен для сброса источника.
Библиотека Howler.js
Предоставляет высокоуровневый API для работы со звуком, абстрагируясь от особенностей Web Audio API и HTML5 Audio. Удобна для управления несколькими звуками, создания спрайтов и эффектов.
Библиотека Video.js
Предоставляет обширный API для работы с видео, включая кастомные элементы управления, плагины и адаптацию к разным форматам.
Выбор метода зависит от задачи. Нативный play() подходит для базовых сценариев. Web Audio API используется для продвинутой обработки звука. Библиотеки упрощают сложные задачи и обеспечивают кроссбраузерную совместимость.
Аналоги в других языках программирования
Python (библиотека pygame)
import pygame
pygame.mixer.init()
sound = pygame.mixer.Sound('sound.wav')
sound.play() # Немедленный запуск
# Можно задать количество повторений: sound.play(loops=3)Воспроизводится звук.
Отличие: API синхронное и не основано на Promises.
PHP
PHP как серверный язык не имеет прямых аналогов для воспроизведения медиа на клиенте. Для управления медиа на веб страницах используется генерация HTML/JavaScript кода.
C (библиотека SDL)
#include <SDL2/SDL.h>
#include <SDL2/SDL_mixer.h>
Mix_Chunk *sound = Mix_LoadWAV('sound.wav');
Mix_PlayChannel(-1, sound, 0); // -1 - первый свободный канал, 0 - без повторовОтличие: Низкоуровневый API, требуется управление ресурсами вручную.
MySQL
Не имеет функций для воспроизведения медиа, так как является системой управления базами данных.
Типичные ошибки
1. Игнорирование Promise
const video = document.querySelector('video');
video.play(); // Может молча не сработать из-за политики автозапуска
console.log('Воспроизведение?'); // Выполнится, даже если play() не удался// Вывод в консоль: 'Воспроизведение?' // Видео может не запуститься без обработки ошибки.
2. Повторное использование AudioBufferSourceNode
const source = audioContext.createBufferSource();
source.buffer = buffer;
source.connect(audioContext.destination);
source.start();
source.start(); // ОШИБКА!// Брошено исключение: "Failed to execute 'start' on 'AudioBufferSourceNode'"
3. Вызов метода до установки src или buffer
const audio = new Audio();
audio.play(); // Нет источника// Promise будет отклонен с ошибкой.
Изменения в последних версиях
Ключевое изменение коснулось политики автозапуска в браузерах. Метод play() для HTMLMediaElement теперь всегда возвращает Promise, а не undefined. Это изменение было внедрено несколько лет назад для единообразной обработки асинхронных ошибок, связанных с ограничениями автоматического воспроизведения. Большинство современных браузеров блокируют автозапуск медиа без предварительного взаимодействия пользователя со страницей. Ошибка теперь корректно обрабатывается через отклонение Promise, что требует от разработчиков соответствующей обработки.
Расширенные и нестандартные примеры
1. Последовательное воспроизведение нескольких видео
async function playVideosSequentially(videoElements) {
for (const video of videoElements) {
try {
await video.play();
// Ожидаем события 'ended' перед переходом к следующему видео
await new Promise(resolve => video.onended = resolve);
} catch (error) {
console.error('Ошибка воспроизведения:', error);
break;
}
}
}
// Использование:
const videos = document.querySelectorAll('.clip');
playVideosSequentially([...videos]);2. Создание аудиоплеера с Web Audio API и управлением громкостью
const audioContext = new (window.AudioContext || window.webkitAudioContext)();
let currentSource = null;
async function playBuffer(arrayBuffer) {
// Останавливаем текущее воспроизведение
if (currentSource) {
currentSource.stop();
}
// Декодируем аудиоданные
const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
// Создаем новый источник
currentSource = audioContext.createBufferSource();
currentSource.buffer = audioBuffer;
// Создаем узел громкости (GainNode)
const gainNode = audioContext.createGain();
gainNode.gain.value = 0.5; // Устанавливаем громкость 50%
// Соединяем цепочку: источник -> громкость -> выход
currentSource.connect(gainNode);
gainNode.connect(audioContext.destination);
// Начинаем воспроизведение
currentSource.start();
}
// Пример изменения громкости во время воспроизведения
function changeVolume(value) {
if (gainNode) {
gainNode.gain.value = value;
}
}3. Воспроизведение с задержкой и циклом (Web Audio API)
function playLoop(buffer, startTime, loopStart, loopEnd) {
const source = audioContext.createBufferSource();
source.buffer = buffer;
source.loop = true;
source.loopStart = loopStart;
source.loopEnd = loopEnd;
source.connect(audioContext.destination);
source.start(startTime);
return source; // Для возможности остановки
}
// Начать цикл через 5 секунд, зациклить фрагмент с 2 по 4 секунду буфера
const loopSource = playLoop(myBuffer, audioContext.currentTime + 5, 2, 4);4. Интерактивное видео с перекрытием звуков
// Основное видео
const mainVideo = document.getElementById('mainVid');
// Аудиоэффект для наложения
const effectAudio = new Audio('effect.mp4');
effectAudio.volume = 0.7;
document.getElementById('actionButton').addEventListener('click', () => {
// Проверяем, играет ли основное видео
if (!mainVideo.paused) {
// Накладываем звуковой эффект
effectAudio.currentTime = 0; // Перемотка в начало
effectAudio.play();
}
});