Как создать собственный видеоплеер HTML5 с помощью JavaScript
Как создать собственный видеоплеер HTML5 с помощью JavaScript

существует веб-страница середина, просмотр и обмен видеоконтентом является очень распространенной функцией,на протяжении многих лет,Изменился способ внедрения видео в веб-страницы. Сейчас существуют,нассуществоватьсовременные браузерысерединаиспользовать <video> Теги можно использовать для добавления видеофайлов на веб-страницы, а тег поддерживает несколько видеоформатов.

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

В этом уроке я покажу вам, как использовать JavaScript Создайте собственный видеоплеер. Цель — взломать браузер HTML5 Media API чтобы улучшить работу с настройками по умолчанию.

В этом уроке мы создадим его, который выглядит так: YouTube видеоплеер, потому что я подумал, что было бы неплохо воспроизвести некоторые функции, с которыми уже знакомо большинство людей.

Конечно, мы не достигнем YouTube Все функции в плеере, так как это сделает обучение длиннее и сложнее. Однако, я уверен, что после завершения этого руководства вы сможете легко добавлять новые функции.

ты Можетдля просмотранаспостроюизОнлайн-кейс,илисуществовать GitHub Посмотреть исходный код на.

Подготовительные условия

вам нужно JavaScript и DOM Только имея базовое понимание, вы сможете продолжить работу с этим руководством. Я рекомендую вам использовать последнюю версию Google Chrome, поскольку на момент написания этой статьи некоторые функции, которые мы будем добавлять (например, функция «картинка в картинке»), работают только с Google (Webkit Ядро) браузера.

начинать

я здесь GitHub середина Подготовлено для этого уроканачинатьдокумент。нуждающийсяизразговаривать,Вы можете клонировать себя на своей машине.,И открывается редактор существования середина. Вы будете в разлуке index.html и style.css серединапопытаться найтиприезжатьигрокизотметкадокументдокументи Чтостиль,кинасдля тестированияигрокизвидеодокумент。index.js будет все, что нам нужно, чтобы добавить плеер для работы JavaScript кодовое место.

Запустить в терминале npm install установить browser-sync как запуск Web Зависимость разработки для сервера, который автоматически обновляет страницу при изменении любого файла. Затем npm start Запустите проект и следите за браузером http://localhost:3000

Что вы сделали до сих пор?

Видеоплеер теперь сохраняет встроенные элементы управления браузера и работает так, как и следовало ожидать. Пользовательские элементы управления были определены в #video-controls элементы, но они скрыты.

Язык кода:javascript
копировать
<!-- index.html -->
. . .
<div class="video-controls hidden" id="video-controls">
<!-- Custom controls are defined here -->
</div>
. . .

Даже если мы хотим реализовать собственный интерфейс для элемента управления, оставьте <video> стихийно controls свойство — хорошая идея, чтобы пользователь отключил его по какой-либо причине. JavaScript,Собственные элементы управления браузера по-прежнему доступны. для других,Собственные пространства можно легко скрыть и заменить настраиваемыми элементами управления.,Это будет продемонстрировано позже.

К видео добавлено изображение постера, установлено preloadЗначение атрибута metadata,Это указывает браузеру получать только метаданные видео.(например duration)。Чтобы все было просто,нас Толькодобавить в MP4 Тип извидео源документ,Потому что это должно Тип из видео совместимо со всеми основными браузерами,Это очень безопасное значение по умолчанию. Дополнительную информацию о форматах видео и совместимости браузеров см.,Можетссылка Должендокумент

Язык кода:javascript
копировать
<!-- index.html -->
. . .
<video controls class="video" id="video" preload="metadata" poster="poster.jpg">
  <source src="video.mp4" type="video/mp4"></source>
</video>
. . .

Скрыть встроенные элементы управления

Первое, что нам нужно сделать, это подтвердить, что браузер поддерживает HTML5 После видео скройте элементы управления видео по умолчанию и предоставьте собственный интерфейс. в твоем index.js Введите в файл следующий фрагмент кода, чтобы реализовать вышеуказанную функцию:

Язык кода:javascript
копировать
// index.js
// Select elements here
const video = document.getElementById('video');
const videoControls = document.getElementById('video-controls');

const videoWorks = !!document.createElement('video').canPlayType;
if (videoWorks) {
  video.controls = false;
  videoControls.classList.remove('hidden');
}

canPlayType Свойства – это способ проверки поддержки браузером видеоформатов. Чтобы использовать его, нам нужно создать <video> Экземпляр элемента и проверит, поддерживает ли он canPlayType。Если поддерживается,но Можетсмело предположить Чтоподдерживать HTML видео, затем отключите элементы управления по умолчанию и включите наши пользовательские элементы управления.

Элементы управления по умолчанию были заменены пользовательскими элементами управления.

Переключить статус воспроизведения

Начнем с азов начинать. мы следуетпроходить Нажмите кнопку воспроизведения, чтобы воспроизвести или приостановить видео. Изменения должны соответствовать состоянию видео на значке. Мы получаем видео и кнопку воспроизведения с самого начала, код существует. index.js Сверху следующим образом:

Язык кода:javascript
копировать
// index.js
const playButton = document.getElementById('play');

Затем мы создаем функцию для переключения состояния воспроизведения видео:

Язык кода:javascript
копировать
// index.js
// Add functions here

// togglePlay toggles the playback state of the video.
// If the video playback is paused or ended, the video is played
// Если воспроизведение видео приостановлено и видео заканчивается, видео будет воспроизводиться
// otherwise, the video is paused
// В противном случае видео будет приостановлено
function togglePlay() {
  if (video.paused || video.ended) {
    video.play();
  } else {
    video.pause();
  }
}

Наконец, мы создаем прослушиватель времени, который, когда playButton Выполнить после нажатия кнопки togglePlay метод.

Язык кода:javascript
копировать
// index.js
// Add eventlisteners here
playButton.addEventListener('click', togglePlay);

Достаточно просто, не так ли? Пройти Нажмите кнопку воспроизведения серединаиз вашего браузера, чтобы протестировать его. Видео должно воспроизводиться и приостанавливаться правильно.

Это действительно задает тон всему уроку. Обычно мы выбираем элемент управления видео, создаем функцию, реализующую определенную функцию, и подключаем ее через прослушиватели событий.

Давайте продолжим и обновим кнопку воспроизведения в зависимости от статуса видео. Ниже playButton из HTML документ:

Язык кода:javascript
копировать
<!-- index.html -->
. . .
<button data-title="Play (k)" id="play">
  <svg class="playback-icons">
    <use href="#play-icon"></use>
    <use class="hidden" href="#pause"></use>
  </svg>
</button>
. . .

существовать <svg> элементсередина, у нас есть кнопки воспроизведения и паузы, но мы можем показывать только одну из них одновременно, другая скрыта. Теперь существует то, что нам нужно сделать, это переключить каждый значок из hidden класс для отображения правильного значка в зависимости от статуса видео.

первый,существовать index.js Выберите значок в верхней части файла:

Язык кода:javascript
копировать
// index.js
const playbackIcons = document.querySelectorAll('.playback-icons use');

затем,существовать togglePlay Создайте функцию под функцией для обновления кнопки воспроизведения:

Язык кода:javascript
копировать
// index.js
// updatePlayButton updates the playback icon and tooltip
// depending on the playback state
// В зависимости от статуса воспроизведения updatePlayButton Функция обновления значка воспроизведения и подсказки
function updatePlayButton() {
  playbackIcons.forEach(icon => icon.classList.toggle('hidden'));
}

Наконец, добавьте следующие события «Аудиотель» внизу файла:

Язык кода:javascript
копировать
// index.js
video.addEventListener('play', updatePlayButton);
video.addEventListener('pause', updatePlayButton);

когда воспроизведение видео или пауза,updatePlayButton Функция будет выполнена, переключив каждую кнопку серединаиз. hidden добрый. Поскольку значение по умолчанию для элемента кнопки паузы равно hidden добрый,Как только видео будет воспроизведено,Появляется этот значок паузы,Значок воспроизведения будет скрыт. Если видео приостановлено,Произойдет обратное. Вы можете протестировать это в своем браузере.

Дополнительные дела:,при движении мыши приезжать кнопку воспроизведения,Необходимо обновить отображение текста подсказки. Подсказка по умолчанию play(k),Но когда видео воспроизводится, существует,Оперативная информация, которую необходимо обновить, pause(k)k Да, мы добавим воспроизведение или паузу видео с помощью сочетания клавиш позже в этом уроке.

Как следует, обновлено updatePlayButton функция:

Язык кода:javascript
копировать
// index.js
function updatePlayButton() {
  playbackIcons.forEach(icon => icon.classList.toggle('hidden'));

  if (video.paused) {
    playButton.setAttribute('data-title', 'Play (k)')
  } else {
    playButton.setAttribute('data-title', 'Pause (k)')
  }
}

когда видео воспроизводится во время паузы,Движение мыши по кнопке приехать,Текст подсказки должен быть установлен правильно.

Если вы хотите узнать, как отображается подсказка, вы можете просмотреть соответствующую информацию. CSS

Язык кода:javascript
копировать
// style.css
. . .
button::before {
  content: attr(data-title);
  position: absolute;
  display: none;
  right: 0;
  top: -50px;
  background-color: rgba(0, 0, 0, 0.6);
  color: #fff;
  font-weight: bold;
  padding: 4px 6px;
  word-break: keep-all;
  white-space: pre;
}

button:hover::before {
  display: inline-block;
}
. . .

Отображение продолжительности видео и прошедшего времени

Необходимо отображать продолжительность видео.,Потому что это первое, что хотят видеть пользователи.,такнас Следующийобъясним。

Вот маркеры длительности, прошедшего времени и зэлементов:

Язык кода:javascript
копировать
<!-- index.html -->
<div class="time">
  <time id="time-elapsed">00:00</time>
  <span> / </span>
  <time id="duration">00:00</time>
</div>

проходить index.js Выберите эти два элемента управления (элементы) следующим образом:

Язык кода:javascript
копировать
// index.js
const timeElapsed = document.getElementById('time-elapsed');
const duration = document.getElementById('duration');

Как только страница загрузится, мы будем использовать duration Видео показа недвижимости общей продолжительности. Этот атрибут указывает, что «из» — общее количество секунд видео «из», поэтому перед отображением «существует» мы необходимо преобразовать его в доли секунды. мы создаем formatTime Функция для преобразования времени в секунды:

Язык кода:javascript
копировать
// index.js
// formatTime takes a time length in seconds and returns the time in
// minutes and seconds
function formatTime(timeInSeconds) {
  const result = new Date(timeInSeconds * 1000).toISOString().substr(11, 8);

  return {
    minutes: result.substr(3, 2),
    seconds: result.substr(6, 2),
  };
};

затем,нассуществовать formatTime Создать под функцией initializeVideo функция:

Язык кода:javascript
копировать
// index.js
// initializeVideo sets the video duration, and maximum value of the
// progressBar
function initializeVideo() {
  const videoDuration = Math.round(video.duration);
  const time = formatTime(videoDuration);
  duration.innerText = `${time.minutes}:${time.seconds}`;
  duration.setAttribute('datetime', `${time.minutes}m ${time.seconds}s`)
}

как показано выше,Длительность видео округлена,Формат в минутах и ​​секундах,Затемсуществовать Обновление на экране。datetime Синхронно обновляется в виде строки времени, указывающей продолжительность видео.

Далее, как показано ниже, давайте initializeVideo функция, связанная с loadedmetadata на слушателе. После загрузки метаданных продолжительность видео будет обновлена.

Язык кода:javascript
копировать
// index.js
video.addEventListener('loadedmetadata', initializeVideo);

Та же причина,когда процесс воспроизведения видео середина,Обновляем время воспроизведения. Следующая функция может помочь нам достичь этой функции:

Язык кода:javascript
копировать
// index.js
// updateTimeElapsed indicates how far through the video
// the current playback is
function updateTimeElapsed() {
  const time = formatTime(Math.round(video.currentTime));
  timeElapsed.innerText = `${time.minutes}:${time.seconds}`;
  timeElapsed.setAttribute('datetime', `${time.minutes}m ${time.seconds}s`)
}

мы должны timeupdate Видео мониторинга событий. Независимо от времени, видео из currentTime Когда значение атрибута будет обновлено, событие будет инициировано.

Язык кода:javascript
копировать
// index.js
video.addEventListener('timeupdate', updateTimeElapsed);

Приведенный выше код гарантирует, что видео currentTime Обновления будут обновляться соответствующим образом с течением времени.

Обновить индикатор выполнения

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

Язык кода:javascript
копировать
<!-- index.html -->
. . .
<div class="video-progress">
  <progress id="progress-bar" value="0" min="0"></progress>
  <input class="seek" id="seek" value="0" min="0" type="range" step="1">
  <div class="seek-tooltip" id="seek-tooltip">00:00</div>
</div>
. . .

Выше мы имеем progress элемент, используемый для отображения задачи в виде индикатора выполнения, и range Тип из input Позволяет нам просматривать видео быстро и без проблем. Я оформил оба элемента в одном стиле, поэтому они имеют одинаковую ширину и высоту, но input Это прозрачный цвет (за исключением того же цвета, что и точка индикатора на индикаторе выполнения).

Если вам интересно, вы можете посмотреть поближе CSS из контента, посмотрите, как я это сделал. Сделать индикатор выполнения похожим на отдельный изэлемент hack,Но я думаю, что это имеет смысл для нашего варианта использования.

Оба из min свойства установлены на 0,Оба из value Свойство указывает на текущее значение времени. Им нужен еще один max Свойство, для этого свойства будет установлено значение продолжительности видео в секундах, значение свойства берется из video.duration,как показано выше。нас Можетксуществовать initializeVideo Реализовано в функции, но сначала нам нужно выбрать элемент:

Язык кода:javascript
копировать
// index.js
const progressBar = document.getElementById('progress-bar');
const seek = document.getElementById('seek');

Затем обновите следующим образом initializeVideo функция:

Язык кода:javascript
копировать
// index.js
function initializeVideo() {
  const videoDuration = Math.round(video.duration);
  seek.setAttribute('max', videoDuration);
  progressBar.setAttribute('max', videoDuration);
  const time = formatTime(videoDuration);
  duration.innerText = `${time.minutes}:${time.seconds}`;
  duration.setAttribute('datetime', `${time.minutes}m ${time.seconds}s`)
}

сейчассуществовать,индикатор выполненияэлементизввод диапазонасуществовать 0 и в секундах продолжительности видео, например атрибуты min и max свойство. Как вы увидите, это позволяет нам легко синхронизировать индикатор выполнения и временной диапазон в любой момент времени.

продолжать,При воспроизведении видео мы обновим указанное выше значение элемента.,чтобы индикатор выполнения мог работать. следующее,создавать updateProgress функция:

Язык кода:javascript
копировать
// index.js
// updateProgress indicates how far through the video
// the current playback is by updating the progress bar
function updateProgress() {
  seek.value = Math.floor(video.currentTime);
  progressBar.value = Math.floor(video.currentTime);
}

Затем,существуют под первым прослушивателем событий,для video Добавить новое имя timeupdate Слушатель событий:

Язык кода:javascript
копировать
// index.js
video.addEventListener('timeupdate', updateProgress);

Обновите браузер,Тогда попробуйте. когда видео воспроизводилось,Вам следует следить за обновлением индикатора прогресса прибытия.

Перейти вперед

Большинство проигрывателей позволяют вам нажимать на индикатор выполнения, чтобы перейти к указанной точке видео прибытия.,И мы тоже. первый,мы необходимо выбрать элемент сообщения подсказки:

Язык кода:javascript
копировать
// index.js
const seekTooltip = document.getElementById('seek-tooltip');

Затем,добавить функцию,Используется для перемещения курсора по индикатору выполнения прибытия и отображения временной метки в информационном элементе:

Язык кода:javascript
копировать
// index.js
// updateSeekTooltip uses the position of the mouse on the progress bar to
// roughly work out what point in the video the user will skip to if
// the progress bar is clicked at that point
function updateSeekTooltip(event) {
  const skipTo = Math.round((event.offsetX / event.target.clientWidth) * parseInt(event.target.getAttribute('max'), 10));
  seek.setAttribute('data-seek', skipTo)
  const t = formatTime(skipTo);
  seekTooltip.textContent = `${t.minutes}:${t.seconds}`;
  const rect = video.getBoundingClientRect();
  seekTooltip.style.left = `${event.pageX - rect.left}px`;
}

Эта функциясуществовать seek элементсередина,использовать Положение курсора грубо рассчитывается, когда пользователь наводит курсор на поле ввода, а затем информация о положении сохраняется. data-seek Атрибут середина, при обновлении подсказки для отображения местоположения по временной метке.

существовать seek ассоциация в контроллере updateSeekTooltip Функция и mousemove Чтобы увидеть эффект:

Язык кода:javascript
копировать
// index.js
seek.addEventListener('mousemove', updateSeekTooltip);

Если вы щелкнете или перетащите точку индикатора, один раз seek Значение элемента изменится, и мы хотим перейти к data-seek Настройки свойств в момент времени.

существовать updateSeekTooltip В разделе «Функция» создайте новый файл с именем skipAhead изфункция:

Язык кода:javascript
копировать
// index.js
// skipAhead jumps to a different point in the video when
// the progress bar is clicked
function skipAhead(event) {
  const skipTo = event.target.dataset.seek ? event.target.dataset.seek : event.target.value;
  video.currentTime = skipTo;
  progressBar.value = skipTo;
  seek.value = skipTo;
}

использовать input мониторинг событий seek Эта функция выполняется при изменении элемента. Тогда мы получим data-seek из значения и проверьте, действительно ли оно. Если оно действительно, мы получаем значение и обновляем время воспроизведения видео и положение индикатора выполнения. если data-seek Атрибут не существует в существовании (например, в существовании мобильного телефона) и заменяется на использовать. seek элементизценить。

Это приводит к перемещению видео в указанное место.

Язык кода:javascript
копировать
// index.js
seek.addEventListener('input', skipAhead);

управление звуком

Язык кода:javascript
копировать
<!-- index.html -->
. . .
<div class="volume-controls">
  <button data-title="Mute (m)" class="volume-button" id="volume-button">
    <svg>
      <use class="hidden" href="#volume-mute"></use>
      <use class="hidden" href="#volume-low"></use>
      <use href="#volume-high"></use>
    </svg>
  </button>

  <input class="volume" id="volume" value="1" type="range" max="1" min="0" step="0.01">
</div>
. . .

существовать Приведенный выше фрагмент кодасередина,Вы можете найти все соответствующие элементы управления звуком из тегов в разделе «Приехать». у нас есть кнопка,Отображение на основе статуса видео и аудио,и Диапазон звукового контроляиз input элемент.

Прежде всего, когда #volume Когда значение элементаз меняется, нам нужно изменить размер видео и аудио. Мы также собираемся обновить видео, когда оно находится спереди из значка.

Как видите, звук из входного диапазона 0 приезжать 1,ик 0.01 из стоимости увеличивается. Он установлен таким образом, чтобы обеспечить соответствие значению свойства громкости видео, которое также варьируется от 0 приезжать 1,Чтосередина 0 это самый низкий объем,1 это самый высокий объём.

продолжать,Выбираем кнопку,значок и поле ввода,следующее index.js Показано:

Язык кода:javascript
копировать
// index.js
const volumeButton = document.getElementById('volume-button');
const volumeIcons = document.querySelectorAll('.volume-button use');
const volumeMute = document.querySelector('use[href="#volume-mute"]');
const volumeLow = document.querySelector('use[href="#volume-low"]');
const volumeHigh = document.querySelector('use[href="#volume-high"]');
const volume = document.getElementById('volume');

затем,создаватьновыйизимядля updateVolume Функция: при изменении значения поля аудиовхода эта функция обновляет значение видео-аудио:

Язык кода:javascript
копировать
// index.js
// updateVolume updates the video's volume
// and disables the muted state if active
function updateVolume() {
  if (video.muted) {
    video.muted = false;
  }

  video.volume = volume.value;
}

Затем,Воля Чтои volume Элементы связаны следующим образом:

Язык кода:javascript
копировать
// index.js
volume.addEventListener('input', updateVolume);

приезжатьздесь,Вы поймете, когда приехать, когда сдвинете поле ввода влево.,уменьшение объема,Наоборот, объем увеличивается.。мы Должны быть добавлены еще одна функция для обновления значка при изменении громкости:

Язык кода:javascript
копировать
// index.js
// updateVolumeIcon updates the volume icon so that it correctly reflects
// the volume of the video
function updateVolumeIcon() {
  volumeIcons.forEach(icon => {
    icon.classList.add('hidden');
  });

  volumeButton.setAttribute('data-title', 'Mute (m)')

  if (video.muted || video.volume === 0) {
    volumeMute.classList.remove('hidden');
    volumeButton.setAttribute('data-title', 'Unmute (m)')
  } else if (video.volume > 0 &amp;&amp; video.volume <= 0.5) {
    volumeLow.classList.remove('hidden');
  } else {
    volumeHigh.classList.remove('hidden');
  }
}

Когда эта функция выполняется,Все значки будут скрыты,Затембудет отображаться в зависимости от условий Чтосерединазначок。

Мы можем контролировать видео volumechange событие, существующее, запускается каждый раз при изменении громкости updateVolumeIcon функцию следующим образом:

Язык кода:javascript
копировать
// index.js
video.addEventListener('volumechange', updateVolumeIcon);

После добавления вышеуказанных изменений, которые вы просматриваете, вы можете увидеть эффект перемещения ниже:

мы Еще одно событие, добавленное пользователем «должениз», — это возможность нажать на значок громкости, чтобы отключить и включить звук видео. Мы создадим файл с именем toggleMute функция:

Язык кода:javascript
копировать
// index.js
// toggleMute mutes or unmutes the video when executed
// When the video is unmuted, the volume is returned to the value
// it was set to before the video was muted
function toggleMute() {
  video.muted = !video.muted;

  if (video.muted) {
    volume.setAttribute('data-volume', volume.value);
    volume.value = 0;
  } else {
    volume.value = volume.dataset.volume;
  }
}

когда volumeButton Запустите эту функцию после нажатия:

Язык кода:javascript
копировать
// index.js
volumeButton.addEventListener('click', toggleMute);

Эта функция переключает видео muted Атрибут статуса имеет значение true или false. когда видео отключено, значение звука будет сохранено volume элемент data-volume Атрибуты,Чтобы когда видео было включено,Мы можем восстановить состояние звука до его предыдущего значения.

Вот реальный эффект:

Нажмите на видео, чтобы воспроизвести или приостановить его.

существоватьмноговидеоплеерприложениесередина,Нажмите на само видео, чтобы быстро воспроизвести и приостановить его.,так,Наш существующий игрок середина также реализует это.

Что нам нужно сделать, так это следить video начальствоиз click Событие, запускается при возникновении события "когда" togglePlay функция:

Язык кода:javascript
копировать
// index.js
video.addEventListener('click', togglePlay);

Хотя это работает,Но давайте проведемсуществовать, чтобы сделать его более интересным, добавив обратную связь во время воспроизведения или паузы видео.,нравиться YouTube или Netflix То же, что и выше.

Это наша анимацияиз HTML

Язык кода:javascript
копировать
<!-- index.html -->
. . .
<div class="playback-animation" id="playback-animation">
  <svg class="playback-icons">
    <use class="hidden" href="#play-icon"></use>
    <use href="#pause"></use>
  </svg>
</div>
. . .

Следующее связано CSS

Язык кода:javascript
копировать
// style.css
.playback-animation {
  pointer-events: none;
  position: absolute;
  top: 50%;
  left: 50%;
  margin-left: -40px;
  margin-top: -40px;
  width: 80px;
  height: 80px;
  border-radius: 80px;
  background-color: rgba(0, 0, 0, 0.6);
  display: flex;
  justify-content: center;
  align-items: center;
  opacity: 0;
}

.playback-animation элементпроходить opacity Свойство, установите значение по умолчанию на прозрачный цвет. чтобы скопировать YouTube серединаиз анимации, мы будем использовать Web Animations API Добиться прозрачности элемента и эффекта масштабирования.

существовать index.js Сначала выберите серединаэтоэлемент в верхней части файла:

Язык кода:javascript
копировать
// index.js
const playbackAnimation = document.getElementById('playback-animation');

Затемсуществовать Чтоон Создать под функциейподизфункция:

Язык кода:javascript
копировать
// index.js
// animatePlayback displays an animation when
// the video is played or paused
function animatePlayback() {
  playbackAnimation.animate([
    {
      opacity: 1,
      transform: "scale(1)",
    },
    {
      opacity: 0,
      transform: "scale(1.3)",
    }], {
    duration: 500,
  });
}

animate Функция принимает массив объектов ключевых кадров и необязательный объект, управляющий временем анимации.

сейчассуществовать,для video элементдобавить второй click событие:

Язык кода:javascript
копировать
// index.js
video.addEventListener('click', animatePlayback);

Теперь, когда вы нажимаете кнопку воспроизведения и ставите видео на паузу, вы можете увидеть короткий анимационный эффект прибытия.

Видео на весь экран

Далее мы реализуем полноэкранную функциональную кнопку. Для того, чтобы сделать Видео на весь экран (включая контроллер), мы должнывыбирать .video-container элемент,Затем Попросите браузер разместить его в полноэкранном режиме.(и Чторебенокэлемент)。

существовать index.js Кнопка выбора файла середина и видеоконтейнер:

Язык кода:javascript
копировать
// index.js
const fullscreenButton = document.getElementById('fullscreen-button');
const videoContainer = document.getElementById('video-container');

Затемсоздаватьновыйизимядля toggleFullScreen функция:

Язык кода:javascript
копировать
// index.js
// toggleFullScreen toggles the full screen state of the video
// If the browser is currently in fullscreen mode,
// then it should exit and vice versa.
function toggleFullScreen() {
  if (document.fullscreenElement) {
    document.exitFullscreen();
  } else if (document.webkitFullscreenElement) {
    // Need this to support Safari
    document.webkitExitFullscreen();
  } else if (videoContainer.webkitRequestFullscreen) {
    // Need this to support Safari
    videoContainer.webkitRequestFullscreen();
  } else {
    videoContainer.requestFullscreen();
  }
}

Тогда для fullScreenButton элемент Добавить один click события, а именно:

Язык кода:javascript
копировать
// index.js
fullscreenButton.onclick = toggleFullScreen;

toggleFullScreen Функция сначала проверит document Является ли это полноэкранным режимом, если да, то выйдите из режима браузера. В противном случае это будет videoContainer элементместосуществоватьполноэкранный。

существовать Долженглава,Нам также необходимо сделать это, когда появляется кнопка наведения курсора мыши, чтобы обновить полноэкранное изображение и текст подсказки. первый,Выберите значок:

Язык кода:javascript
копировать
// index.js
const fullscreenIcons = fullscreenButton.querySelectorAll('use');

Затемсоздаватьфункция,когда videoContainer Кнопка обновления при входе в полноэкранный режим и выходе из полноэкранного режима:

Язык кода:javascript
копировать
// index.js
// updateFullscreenButton changes the icon of the full screen button
// and tooltip to reflect the current full screen state of the video
function updateFullscreenButton() {
  fullscreenIcons.forEach(icon => icon.classList.toggle('hidden'));

  if (document.fullscreenElement) {
    fullscreenButton.setAttribute('data-title', 'Exit full screen (f)')
  } else {
    fullscreenButton.setAttribute('data-title', 'Full screen (f)')
  }
}

Наконец, для videoContainer элементраспространять updateFullscreenButton функцияприезжать onfullscreenchange Обработчик событий:

Язык кода:javascript
копировать
// index.js
videoContainer.addEventListener('fullscreenchange', updateFullscreenButton);

Ну, это работает, как и ожидалось! Вы можете протестировать его в своем браузере или посмотреть ниже. GIF картина.

Добавлена ​​поддержка «картинка в картинке».

Picture-in-Picture(PiP) API Разрешить пользователям существование плавающих окон (где середина расположена над другими окнами) середина смотрят видео, чтобы они могли существовать, смотреть видео, одновременно сосредотачиваясь на существовании других сайтов или приложений.

приезжать Пока это API Поддерживается лишь несколькими браузерами, поэтому мы следует скрыть это для браузеров, которые не поддерживают PiP Кнопки, чтобы они не могли видеть, что функция «приехатьиспользовать» не видна.

пожалуйстассылка caniuse.com Получите самую свежую информацию о форме.

Следующий код может помочь нам реализовать эту функцию. Существуют Добавьте этот код под другими прослушивателями событий.

Язык кода:javascript
копировать
// index.js
document.addEventListener('DOMContentLoaded', () => {
  if (!('pictureInPictureEnabled' in document)) {
    pipButton.classList.add('hidden');
  }
});

Как и в этом уроке, нам сначала нужно выбрать середину, связанную с контроллером:

Язык кода:javascript
копировать
// index.js
const pipButton = document.getElementById('pip-button')

Затем создайте переключатель Picture-in-Picture Функция шаблона:

Язык кода:javascript
копировать
// index.js
// togglePip toggles Picture-in-Picture mode on the video
async function togglePip() {
  try {
    if (video !== document.pictureInPictureElement) {
      pipButton.disabled = true;
      await video.requestPictureInPicture();
    } else {
      await document.exitPictureInPicture();
    }
  } catch (error) {
    console.error(error)
  } finally {
    pipButton.disabled = false;
  }
}

Я создал файл под названием togglePip из асинхронных функций, чтобы мы могли существовать requestPictureInPicture() Перехватывать, когда метод отклоняетсяприезжатьошибка,Это может произойти по ряду причин. существуют в реальном времени из приложения середина,Возможно, вы захотите отобразить пользователю сообщение об ошибке.,Вместо печати приезжать на консоль.

затем,существовать pipButton элементначальстводобавить в click событие, а затем добавить togglePip Функция приезжать Это обработчик событий середина.

Язык кода:javascript
копировать
// index.js
pipButton.addEventListener('click', togglePip);

сейчассуществовать,добавить в pipButton Вам следует войти или выйти из режима рисования. Вы также можете нажать кнопку закрытия в правом верхнем углу (режим рисования середина), чтобы закрыть его. PiP окно.

Переключить элементы управления видео

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

Для достижения этой цели напишем две функции следующим образом:

Язык кода:javascript
копировать
// index.js
// hideControls hides the video controls when not in use
// if the video is paused, the controls must remain visible
function hideControls() {
  if (video.paused) {
    return;
  }

  videoControls.classList.add('hide');
}

// showControls displays the video controls
function showControls() {
  videoControls.classList.remove('hide');
}

Что мы хотим сделать здесь, так это,Когда элементы управления будут скрыты, когда мышь будет отведена от видео. Но когда видео перестает воспроизводиться из,Следим за тем, чтобы элемент управления всегда отображал из,таксуществовать hideControls() Добавьте в функцию условное суждение.

Для достижения этого мы будем существовать video элементи videoControls элементначальствоиспользовать onmouseenter и onmouseleave Обработчик событий, например:

Язык кода:javascript
копировать
// index.js
video.addEventListener('mouseenter', showControls);
video.addEventListener('mouseleave', hideControls);
videoControls.addEventListener('mouseenter', showControls);
videoControls.addEventListener('mouseleave', hideControls);

Добавьте сочетания клавиш

Последняя функция, которую мы добавим в приезжающий плеер, — это использование сочетаний клавиш для управления воспроизведением видео. на самом деле,То есть, когда мы нажимаем определенную клавишу,бегатьнасобозначение Функция изиметь значение。нас Воля实сейчасизбыстрая клавишаследующее:

  • k:игратьили Пауза видео
  • m:отключить видеоили Включить звук
  • f:выключательполноэкранный
  • p:переключить картинкусерединарежим рисования

здесь Что нам нужно сделать, так это следить document середина keyup Событие обнаруживает нажатие клавиши быстрого доступа и возвращает соответствующую функцию.

Язык кода:javascript
копировать
// index.js
// keyboardShortcuts executes the relevant functions for
// each supported shortcut key
function keyboardShortcuts(event) {
  const { key } = event;
  switch(key) {
    case 'k':
      togglePlay();
      animatePlayback();
      if (video.paused) {
        showControls();
      } else {
        setTimeout(() => {
          hideControls();
        }, 2000);
      }
      break;
    case 'm':
      toggleMute();
      break;
    case 'f':
      toggleFullScreen();
      break;
    case 'p':
      togglePip();
      break;
  }
}

Как и выше, один switch Этот оператор используется для определения того, какая клавиша быстрого доступа была нажата, а затем выполнения соответствующего кода. Звонок через две секунды hideControl Функция Причина – имитация YouTube Поведение на из, прииспользование сочетаний клавиш при воспроизведении видео,Контроль не исчезнет сразу,Вместо этого происходит небольшая задержка.

Язык кода:javascript
копировать
// index.js
document.addEventListener('keyup', keyboardShortcuts);

Подвести итог

Есть много способов улучшить видеоплеер.,Но этот урок уже очень длинный,так Мне пришлосьсуществоватьздесьостанавливаться。Если вас интересуют дополнительныеиз Особенности интереса,Вот несколько идей:

  • Добавлена ​​поддержка субтитров
  • Добавлена ​​поддержка скорости воспроизведения
  • Добавлены функции быстрой перемотки вперед и назад.
  • добавить ввыбиратьвидео分辨率(720p, 480p, 360p, 240p)из Функция

Я надеюсь, что этот урок был вам полезен. Связанный код GitHub

Thanks for reading, and happy coding!

ссылка

Исходный адрес - https://freshman.tech/custom-html5-video/

boy illustration
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
boy illustration
Копикодер: этот инструмент отлично работает с Cursor, Bolt и V0! Предоставьте более качественные подсказки для разработки интерфейса (создание навигационного веб-сайта с использованием искусственного интеллекта).
boy illustration
Новый бесплатный RooCline превосходит Cline v3.1? ! Быстрее, умнее и лучше вилка Cline! (Независимое программирование AI, порог 0)
boy illustration
Разработав более 10 проектов с помощью Cursor, я собрал 10 примеров и 60 подсказок.
boy illustration
Я потратил 72 часа на изучение курсорных агентов, и вот неоспоримые факты, которыми я должен поделиться!
boy illustration
Идеальная интеграция Cursor и DeepSeek API
boy illustration
DeepSeek V3 снижает затраты на обучение больших моделей
boy illustration
Артефакт, увеличивающий количество очков: на основе улучшения характеристик препятствия малым целям Yolov8 (SEAM, MultiSEAM).
boy illustration
DeepSeek V3 раскручивался уже три дня. Сегодня я попробовал самопровозглашенную модель «ChatGPT».
boy illustration
Open Devin — инженер-программист искусственного интеллекта с открытым исходным кодом, который меньше программирует и больше создает.
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | SPPF сочетается с воспринимаемой большой сверткой ядра UniRepLK, а свертка с большим ядром + без расширения улучшает восприимчивое поле
boy illustration
Популярное и подробное объяснение DeepSeek-V3: от его появления до преимуществ и сравнения с GPT-4o.
boy illustration
9 основных словесных инструкций по доработке академических работ с помощью ChatGPT, эффективных и практичных, которые стоит собрать
boy illustration
Вызовите deepseek в vscode для реализации программирования с помощью искусственного интеллекта.
boy illustration
Познакомьтесь с принципами сверточных нейронных сетей (CNN) в одной статье (суперподробно)
boy illustration
50,3 тыс. звезд! Immich: автономное решение для резервного копирования фотографий и видео, которое экономит деньги и избавляет от беспокойства.
boy illustration
Cloud Native|Практика: установка Dashbaord для K8s, графика неплохая
boy illustration
Краткий обзор статьи — использование синтетических данных при обучении больших моделей и оптимизации производительности
boy illustration
MiniPerplx: новая поисковая система искусственного интеллекта с открытым исходным кодом, спонсируемая xAI и Vercel.
boy illustration
Конструкция сервиса Synology Drive сочетает проникновение в интрасеть и синхронизацию папок заметок Obsidian в облаке.
boy illustration
Центр конфигурации————Накос
boy illustration
Начинаем с нуля при разработке в облаке Copilot: начать разработку с минимальным использованием кода стало проще
boy illustration
[Серия Docker] Docker создает мультиплатформенные образы: практика архитектуры Arm64
boy illustration
Обновление новых возможностей coze | Я использовал coze для создания апплета помощника по исправлению домашних заданий по математике
boy illustration
Советы по развертыванию Nginx: практическое создание статических веб-сайтов на облачных серверах
boy illustration
Feiniu fnos использует Docker для развертывания личного блокнота Notepad
boy illustration
Сверточная нейронная сеть VGG реализует классификацию изображений Cifar10 — практический опыт Pytorch
boy illustration
Начало работы с EdgeonePages — новым недорогим решением для хостинга веб-сайтов
boy illustration
[Зона легкого облачного игрового сервера] Управление игровыми архивами
boy illustration
Развертывание SpringCloud-проекта на базе Docker и Docker-Compose