YouTube API: как создать видеогалерею на сайте

YouTube API: как создать видеогалерею на сайте
Содержание:
  1. Получение API-ключа YouTube
  2. PHP-скрипт для получения информации об YouTube ролике
  3. Создание видеогалереи из YouTube роликов
  4. Комментарии

В этой статье мы разберём как на сайте сделать видеогалерею из YouTube роликов. Для оптимизации быстродействия страницы сами видеоплееры мы не будем непосредственно размещать на ней, вместо них будем просто показывать обложки. Проигрывание видеороликов будем осуществлять в модальном окне. Его открытие будем осуществлять при нажатии на обложку. Для получения информации о видео будем использовать API-ключ YouTube.

Получение API-ключа YouTube

Работа с сервисом YouTube осуществляется через API. Этот интерфейс предоставляет нам функции, которые обычно выполняются на веб-сайте YouTube. Но также эти функции доступны нам. На своём сайте или веб-приложении мы их можем использовать для взаимодействия с YouTube.

В этой статье мы будем использовать YouTube Data API для получения данных о видео по URL.

Для того чтобы нам выполнить запрос к YouTube Data API нам нужен ключ. Его получение осуществляется на Google Cloud Console с использованием своего аккаунта Google. Если у вас ещё нет учетной записи Google, то её необходимо завести.

На открывшейся странице консоли необходимо создать новый проект, в рамках которого мы будем использовать YouTube Data API. Осуществляется это посредством нажатия на надпись «Create project». Так как применять этот API будем для сайта, который будем запускать только на локальном компьютере, то дадим ему соответствующее имя, например localhost. После ввода имени нажмём на кнопку «Create».

Создание нового проекта на Google Cloud

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

Стартовая страница созданного проекта на Google Cloud

Сейчас перейдём в раздел «APIs & Services». Здесь отображаются все подключенные к данному проекту API и сервисы. Для добавления нового нажмём на надпись «Enable APIs & services».

API и сервисы Google Cloud, подключенные к проекту

Здесь в поле поиска введём искомый API, то есть «YouTube Data API v3».

Поиск YouTube Data API v3

Далее кликнем на кнопку «Enable», чтобы подключить его.

Подключим YouTube Data API v3 к своему проекту

В карточке этого API в верней его части отображается предупреждение. В нём говорится, что для использования этого API необходимо создать учётные записи. Чтобы это сделать нажмём на кнопку «Create credentials».

Создание учетных записей для YouTube Data API v3

В этой форме необходимо для «YouTube Data API v3», который у нас уже по умолчанию отображается в раскрывающем списке, выбрать к каким данным нам нужен доступ. В данном случае нам будет достаточно иметь доступ к публичным данным («Public data»). После этого нажимаем на кнопку «Next».

Выбор данных, к которым мы хотим получить посредством YouTube Data API v3

Теперь копируем полученный API и нажимаем на кнопку «Done».

Ключ API YouTube

Посмотреть созданные ключи можно в таблице «API Keys» на вкладке «Credentials».

Список всех созданных ключей API на Google Cloud

PHP-скрипт для получения информации об YouTube ролике

Перед тем как перейти к разработке YouTube видеогалереи, сначала напишем тестовый пример на PHP. В нём мы посмотрим, как по URL можно получить детальную информацию о видео, в том числе его обложку.

Начнём разработку примера с создания php-файла, который назовём, например, test.php. В начале файла создадим переменную $url и зададим ей в качестве значения URL-адрес видео, информацию о котором мы хотим получить.

PHP
<?php

$url = 'https://youtu.be/HggVMUQt4lU?si=hviCYcN8d78139Z9';

Затем создадим константу API_KEY и присвоим её в качестве значения наш ключ API.

PHP
const API_KEY = 'BKl3DxC4ohjYusw6FdxGk1LNMSRs35Jq0KRe9_U';

Теперь нам нужно создать функцию, которая будет извлекать id-видео из URL:

PHP
function getId(string $url) : string
{
  if (filter_var($url, FILTER_VALIDATE_URL)) {
    $pattern = '%(?:youtube(?:-nocookie)?.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=|live/)|youtu.be/)([^"&?/ ]{11})%i';
    preg_match($pattern, $url, $match);
    return count($match) > 0 ? $match[1] : '';
  }
  return '';
}

И наконец функция для получения детальной информации о видео:

PHP
function getSnippet(string $url) : array
{
  $id = getId($url);
  $url = 'https://www.googleapis.com/youtube/v3/videos?id=' . $id . '&key=' . API_KEY . '&part=snippet';
  $curlSession = curl_init();
  curl_setopt($curlSession, CURLOPT_URL, $url);
  curl_setopt($curlSession, CURLOPT_RETURNTRANSFER, true);
  $result = json_decode(curl_exec($curlSession), true);
  curl_close($curlSession);
  return $result;
}

Теперь чтобы продемонстрировать как это работает, выведем просто полученную информацию о видео на страницу. Для этого добавим ещё в test.php следующий код:

PHP
echo '<pre>';
print_r(getSnippet($url));
echo '</pre>';

Сейчас если открыть эту страницу (http://localhost/test.php) в браузере, то увидим всю информацию об этом видео.

Получение подробной информации на сервере на языке PHP с использованием API-ключа YouTube

В этом разделе реализуем простую видеогалерею для сайта, которая будет состоять из двух частей:

  • формы, с помощью которой мы будем добавлять новые ролики на страницу;
  • галереи миниатюр (обложек) видео, при нажатии на каждую из которых уже будет, собственно говоря, открываться модальное окно с видеоплеером для его проигрывания.

Страница с видеогалереей будет иметь следующий вид:

Вид страницы с видеогалереей и формой для добавления в неё новых роликов

При нажатии на изображение (обложку) видео будет открываться модальное окно. Оно будет содержать видеоплеер для его проигрывания. Дизайн модального окна будет таким:

Вид модальное окно с видеоплеером, посредством которого будет осуществлять проигрывание роликов

HTML-код содержимого страницы:

HTML
<!-- Модальное окно -->
<div class="modal d-none">
  <!-- Кнопка для закрытия модального окна -->
  <button class="modal-close">
    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 16 16"><path d="M2.146 2.854a.5.5 0 1 1 .708-.708L8 7.293l5.146-5.147a.5.5 0 0 1 .708.708L8.707 8l5.147 5.146a.5.5 0 0 1-.708.708L8 8.707l-5.146 5.147a.5.5 0 0 1-.708-.708L7.293 8 2.146 2.854Z"></path></svg>
  </button>
  <div class="modal-body">
    <div class="modal-iframe">
      <!-- Элемент, с помощью которого встроим проигрыватель видео YouTube на сайт -->
      <iframe class="iframe" id="player" type="text/html" width="800" height="450" frameborder="0" allowfullscreen></iframe>
    </div>
  </div>
</div>

<!-- Форма, для добавления новых роликов в галерею -->
<form method="post" class="embed-video" action="processing.php">
  <label>
    <span>URL:</span>
    <input type="url" name="url" value="">
  </label>
  <button type="submit" name="submit">Добавить</button>
</form>

<!-- Форма, для добавления новых роликов в галерею -->
<div class="videos"></div>

В атрибуте action мы указываем путь до php-файла, который будет обрабатывать эту форму на сервере. В данном случае это будет файл processing.php.

Стили мы для оформления страницы напишем в файле main.css, который затем подключим к странице с помощью тега link:

HTML
<link rel="stylesheet" href="main.css">

Код на JavaScript и PHP можно условно разделить на 2 части. Первая из них будет использоваться для добавления новых видео в галерею. На сервере видео, а точнее их данные (уникальный идентификатор id, заголовок title, дата публикации publishedAt и ссылка на обложку image), будем хранить в файле videos.json. А вторая часть для формирования галереи из видео, добавленных в неё, при открытии страницы.

PHP-файл, выполняющий всю работу на сервере:

PHP
<?php

const PATH = 'videos.json';
const API_KEY = 'BKl3DxC4ohjYusw6FdxGk1LNMSRs35Jq0KRe9_U';

function getId(string $url) : string
{
  if (filter_var($url, FILTER_VALIDATE_URL)) {
    $pattern = '%(?:youtube(?:-nocookie)?.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=|live/)|youtu.be/)([^"&?/ ]{11})%i';
    preg_match($pattern, $url, $match);
    return count($match) > 0 ? $match[1] : '';
  }
  return '';
}

function getSnippet(string $url) : array
{
  $id = getId($url);
  $url = 'https://www.googleapis.com/youtube/v3/videos?id=' . $id . '&key=' . API_KEY . '&part=snippet';
  $curlSession = curl_init();
  curl_setopt($curlSession, CURLOPT_URL, $url);
  curl_setopt($curlSession, CURLOPT_RETURNTRANSFER, true);
  $result = json_decode(curl_exec($curlSession), true);
  curl_close($curlSession);
  return $result;
}

$method = $_SERVER['REQUEST_METHOD'];

// для получения всех видео, добавленных в галерею
if ($method === 'GET') {
  $data = '[]';
  if (file_exists(PATH)) {
    $data = file_get_contents(PATH);
  }
  $data = json_decode($data, true);
  echo json_encode($data);
  exit();
}

// для добавления нового видео в галерею
if ($method === 'POST') {
  $data = '[]';
  if (file_exists(PATH)) {
    $data = file_get_contents(PATH);
  }
  $data = json_decode($data, true);
  $result = getSnippet($_POST['url']);
  $result = $result['items'][0];
  $key = array_key_last($result['snippet']['thumbnails']);
  $data[$result['id']] = [
    'title' => $result['snippet']['title'],
    'publishedAt' => $result['snippet']['publishedAt'],
    'image' => $result['snippet']['thumbnails'][$key]['url'],
  ];
  file_put_contents(PATH, json_encode($data));
  echo json_encode([$result['id'] => $data[$result['id']]]);
  exit();
}

Весь создаваемый код JavaScript будем писать в файл main.js, который подключим к странице с помощью тега script:

JavaScript
<script src="main.js"></script>

Начнём написания кода, с того, который будет отвечать за формирования галереи из видео при открытии страницы:

PHP
const URL = 'processing.php';
const elVideos = document.querySelector('.videos');

const createCard = (id, src, title) => `<div class="video-item" data-id="${id}">
  <div class="video-wrapper">
    <img class="video-thumbnail" src="${src}">
    </div>
    <h3 class="video-title">${title}</h3>
  </div>`;

(async () => {
  try {
    const response = await fetch(URL);
    if (response.ok) {
      const result = await response.json();
      const html = [];
      Object.keys(result).forEach((key) => {
        const item = result[key];
        html.push(createCard(key, item.image, item.title));
      });
      elVideos.innerHTML = html.join('');
    }
  } catch (error) {
    console.log(error);
  }
})();

Затем добавим код JavaScript, с помощью которого будем добавлять видео в галерею, по указанному url. А точнее отправлять данные с указанным URL на сервер:

JavaScript
const form = document.querySelector('.embed-video');
const elVideos = document.querySelector('.videos');

form.addEventListener('submit', async (e) => {
  e.preventDefault();
  try {
    const response = await fetch(e.target.action, {
      method: 'post',
      body: new FormData(e.target)
    });
    if (response.ok) {
      const result = await response.json();
      const videoId = Object.keys(result)[0];
      if (elVideos.querySelector(`[data-id="${videoId}"]`)) {
        return;
      }
      const item = result[videoId];
      const html = createCard(videoId, item.image, item.title);
      elVideos.insertAdjacentHTML('beforeend', html);
      e.target.querySelector('input[name="url"]').value = '';
    }
  } catch (error) {
    console.log(error);
  }
});

В этом коде отправка сетевого запроса на сервер выполнятся с помощью метода fetch(). URL-адрес, на который нужно отправить данные формы для обработки их на сервере, устанавливается посредством атрибута action. После получения ответа от сервера JavaScript выводит данную информацию на страницу в виде карточки. Создание HTML-кода карточки осуществляем с помощью функции createCard(). Вставка на страницу HTML-текста, возвращаемого createCard(), выполнятся с помощью метода insertAdjacentHTML().

Сейчас нам осталось только добавить JavaScript код, который будет при клике по обложке видео открывать модальном окно с видеоплеером для его проигрывания. А также код, который будет закрывать модальное окно при клике по кнопке с крестиком, расположенной в правом верхнем углу страницы:

JavaScript
const elModal = document.querySelector('.modal');
const elIframe = elModal.querySelector('.iframe');

const createURL = (id) => `http://www.youtube.com/embed/${id}?enablejsapi=1&origin=${window.location.origin}`;

document.addEventListener('click', (e) => {
  if (e.target && e.target.closest('.video-item')) {
    e.preventDefault();
    const el = e.target.closest('.video-item');
    elIframe.src = createURL(el.dataset.id);
    elModal.classList.remove('d-none');
    document.body.style.overflow = 'hidden';
  }
  if (e.target && e.target.closest('.modal-close')) {
    e.preventDefault();
    elIframe.src = '';
    elModal.classList.add('d-none');
    document.body.style.overflow = 'hidden';
  }
});

В результате готовая видеогалерея будет состоять из следующих файлов:

Комментарии: 7

Nik
Nik

Еще один момент, только что увидел, после закрытия модального окна исчезает прокрутка страницы в браузере, пока не обновишь её.

Александр Мальцев
Александр Мальцев

Там был просто опечаток, исправил его.

Nik
Nik

Небольшие нюансы по видеогалерее.

1) Поскольку у меня PHP7.1 то в логе выпадает ошибка, ругается на array_key_last() которая доступна начиная с PHP7.3, устранил добавив в processing.php небольшую функцию:
function array_key_last( $array ) {
    $key = NULL;
    if ( is_array( $array ) ) {
        end( $array );
        $key = key( $array );
    }
    return $key;
}
2) Еще мелкий нюансик. При открытии модального окна браузер блокирует видео, устранил - в файле main.js - http меняем на https
const createURL = (id) => `http://www.youtube.com/embed/${id}?enablejsapi=1&origin=${window.location.origin}`;
3) Когда нажимаешь кнопку "Добавить", но при этом адрес URL пустой, то в videos.json сохраняются пустые значения:
"":{"title":null,"publishedAt":null,"image":null}}
и соответственно в галерее надпись NULL и пустая картинка, как побороть не знаю.

В остальном все хорошо

Александр Мальцев
Александр Мальцев

Все эти моменты поправил в коде на GitHub, кроме array_key_last(). Для использования того, чего нет в новых версиях, лучше не придумаешь.

Nik
Nik

Спасибо Александр! Теперь все работает. Для сайта очень полезная вещь

Nik
Nik

Практически готовое решение для структурированных данных VideoObject, если видео размещенное на страницах сайта находится на YouTube. Отличная статья! Впрочем как и все материалы здесь

Александр Мальцев
Александр Мальцев

Спасибо за отзыв!