YouTube API: как создать видеогалерею на сайте
В этой статье мы разберём как на сайте сделать видеогалерею из 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».
Теперь все наши действия будут относится к данному проекту. Если у вас несколько проектов, то просто переключитесь на нужный, выбрав его из раскрывающего списка, расположенного вверху экрана.
Сейчас перейдём в раздел «APIs & Services». Здесь отображаются все подключенные к данному проекту API и сервисы. Для добавления нового нажмём на надпись «Enable APIs & services».
Здесь в поле поиска введём искомый API, то есть «YouTube Data API v3».
Далее кликнем на кнопку «Enable», чтобы подключить его.
В карточке этого API в верней его части отображается предупреждение. В нём говорится, что для использования этого API необходимо создать учётные записи. Чтобы это сделать нажмём на кнопку «Create credentials».
В этой форме необходимо для «YouTube Data API v3», который у нас уже по умолчанию отображается в раскрывающем списке, выбрать к каким данным нам нужен доступ. В данном случае нам будет достаточно иметь доступ к публичным данным («Public data»). После этого нажимаем на кнопку «Next».
Теперь копируем полученный API и нажимаем на кнопку «Done».
Посмотреть созданные ключи можно в таблице «API Keys» на вкладке «Credentials».
PHP-скрипт для получения информации об YouTube ролике
Перед тем как перейти к разработке YouTube видеогалереи, сначала напишем тестовый пример на PHP. В нём мы посмотрим, как по URL можно получить детальную информацию о видео, в том числе его обложку.
Начнём разработку примера с создания php-файла, который назовём, например, test.php
. В начале файла создадим переменную $url
и зададим ей в качестве значения URL-адрес видео, информацию о котором мы хотим получить.
<?php
$url = 'https://youtu.be/HggVMUQt4lU?si=hviCYcN8d78139Z9';
Затем создадим константу API_KEY
и присвоим её в качестве значения наш ключ API.
const API_KEY = 'BKl3DxC4ohjYusw6FdxGk1LNMSRs35Jq0KRe9_U';
Теперь нам нужно создать функцию, которая будет извлекать id-видео из URL:
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;
}
Теперь чтобы продемонстрировать как это работает, выведем просто полученную информацию о видео на страницу. Для этого добавим ещё в test.php
следующий код:
echo '<pre>';
print_r(getSnippet($url));
echo '</pre>';
Сейчас если открыть эту страницу (http://localhost/test.php
) в браузере, то увидим всю информацию об этом видео.
Создание видеогалереи из YouTube роликов
В этом разделе реализуем простую видеогалерею для сайта, которая будет состоять из двух частей:
- формы, с помощью которой мы будем добавлять новые ролики на страницу;
- галереи миниатюр (обложек) видео, при нажатии на каждую из которых уже будет, собственно говоря, открываться модальное окно с видеоплеером для его проигрывания.
Страница с видеогалереей будет иметь следующий вид:
При нажатии на изображение (обложку) видео будет открываться модальное окно. Оно будет содержать видеоплеер для его проигрывания. Дизайн модального окна будет таким:
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
:
<link rel="stylesheet" href="main.css">
Код на JavaScript и PHP можно условно разделить на 2 части. Первая из них будет использоваться для добавления новых видео в галерею. На сервере видео, а точнее их данные (уникальный идентификатор id
, заголовок title
, дата публикации publishedAt
и ссылка на обложку image
), будем хранить в файле videos.json
. А вторая часть для формирования галереи из видео, добавленных в неё, при открытии страницы.
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
:
<script src="main.js"></script>
Начнём написания кода, с того, который будет отвечать за формирования галереи из видео при открытии страницы:
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 на сервер:
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 код, который будет при клике по обложке видео открывать модальном окно с видеоплеером для его проигрывания. А также код, который будет закрывать модальное окно при клике по кнопке с крестиком, расположенной в правом верхнем углу страницы:
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
Еще один момент, только что увидел, после закрытия модального окна исчезает прокрутка страницы в браузере, пока не обновишь её.
Там был просто опечаток, исправил его.
Небольшие нюансы по видеогалерее.
1) Поскольку у меня PHP7.1 то в логе выпадает ошибка, ругается наarray_key_last()
которая доступна начиная с PHP7.3, устранил добавив вprocessing.php
небольшую функцию: 2) Еще мелкий нюансик. При открытии модального окна браузер блокирует видео, устранил - в файлеmain.js
- http меняем на https 3) Когда нажимаешь кнопку "Добавить", но при этом адрес URL пустой, то вvideos.json
сохраняются пустые значения: и соответственно в галерее надпись NULL и пустая картинка, как побороть не знаю.В остальном все хорошо
Все эти моменты поправил в коде на GitHub, кроме
array_key_last()
. Для использования того, чего нет в новых версиях, лучше не придумаешь.Спасибо Александр! Теперь все работает. Для сайта очень полезная вещь
Практически готовое решение для структурированных данных VideoObject, если видео размещенное на страницах сайта находится на YouTube. Отличная статья! Впрочем как и все материалы здесь
Спасибо за отзыв!