Play: примеры (JAVASCRIPT)

Использование метода 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. Последовательное воспроизведение нескольких видео

Пример javascript
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 и управлением громкостью

Пример javascript
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)

Пример javascript
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. Интерактивное видео с перекрытием звуков

Пример javascript
// Основное видео
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();
  }
});

JS play function comments

En
Play Begins playback of the media