Avatar ·

Как получить миниатюру видео YouTube через API на PHP: разбор методов

Всем привет. Я новичок в PHP и пытаюсь вывести на своём сайте превью (миниатюру) для видео с YouTube. Нашёл в документации YouTube Data API, что можно получить JSON с информацией о видео, но никак не могу разобраться, как правильно извлечь ссылку на картинку. Пробовал использовать file_get_contents() с ключом API, но получаю ошибку "403 Forbidden". Потом нашёл старый способ — просто брать ID видео и подставлять в URL вида http://img.youtube.com/vi/VIDEO_ID/default.jpg. Но это даёт только одно маленькое изображение, а мне нужно большое (максимальное качество). Вот мой текущий код, который не работает: ```php "; ?> ``` Выдаёт ошибку: "Undefined array key 'maxres'". Для некоторых видео это срабатывает, но не для всех. Как правильно получить миниатюру максимального качества для любого видео? И есть ли способ обойтись без API-ключа для базовых превью? Буду благодарен за подробное объяснение с рабочими примерами. <<>>

Проблема с ключом 'maxres'

Ошибка возникает потому, что YouTube не гарантирует наличие миниатюры максимального разрешения (maxres) для всех видео. Для старых или загруженных в низком качестве роликов этого ключа может не быть в ответе API. Вместо того чтобы хардкодить один размер, нужно использовать fallback-цепочку.

Решение 1: API YouTube Data v3 (рекомендуемый способ)

Этот метод требует ключ API, но даёт полный контроль и доступ ко всем размерам. Вот надёжная реализация с проверкой всех доступных размеров:

<?php
function getYoutubeThumbnail($video_id, $api_key) {
    $url = "https://www.googleapis.com/youtube/v3/videos?part=snippet&id={$video_id}&key={$api_key}";
    
    // Используем cURL для надёжности
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    $response = curl_exec($ch);
    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    
    if ($http_code !== 200) {
        return false;
    }
    
    $data = json_decode($response, true);
    
    // Проверяем, есть ли данные
    if (empty($data['items'][0]['snippet']['thumbnails'])) {
        return false;
    }
    
    $thumbnails = $data['items'][0]['snippet']['thumbnails'];
    
    // Цепочка приоритетов: maxres -> standard -> high -> medium -> default
    $sizes = ['maxres', 'standard', 'high', 'medium', 'default'];
    
    foreach ($sizes as $size) {
        if (isset($thumbnails[$size]['url'])) {
            return $thumbnails[$size]['url'];
        }
    }
    
    return false;
}

// Использование
$video_id = "dQw4w9WgXcQ";
$api_key = "ВАШ_КЛЮЧ_API";
$thumb_url = getYoutubeThumbnail($video_id, $api_key);

if ($thumb_url) {
    echo "<img src='{$thumb_url}' alt='Thumbnail'>";
} else {
    echo "Миниатюра не найдена";
}
?>

Решение 2: Без API (быстрый hack)

Если вам не нужно максимальное качество и вы готовы мириться с небольшим риском (YouTube может изменить формат URL), используйте прямой шаблон. Вот функция с выбором размера:

<?php
function getYoutubeThumbnailDirect($video_id, $quality = 'maxres') {
    // Доступные качества: default, mqdefault, hqdefault, sddefault, maxresdefault
    $valid_qualities = ['default', 'mqdefault', 'hqdefault', 'sddefault', 'maxresdefault'];
    
    if (!in_array($quality, $valid_qualities)) {
        $quality = 'hqdefault'; // fallback
    }
    
    $url = "https://img.youtube.com/vi/{$video_id}/{$quality}.jpg";
    
    // Проверяем, существует ли файл (не все качества доступны для всех видео)
    $headers = @get_headers($url);
    if ($headers && strpos($headers[0], '200') !== false) {
        return $url;
    }
    
    // Fallback: пробуем hqdefault
    $fallback_url = "https://img.youtube.com/vi/{$video_id}/hqdefault.jpg";
    $headers = @get_headers($fallback_url);
    if ($headers && strpos($headers[0], '200') !== false) {
        return $fallback_url;
    }
    
    // Последний шанс: default
    return "https://img.youtube.com/vi/{$video_id}/default.jpg";
}

// Примеры использования
echo "<img src='" . getYoutubeThumbnailDirect("dQw4w9WgXcQ", "maxresdefault") . "'>";
echo "<img src='" . getYoutubeThumbnailDirect("dQw4w9WgXcQ", "hqdefault") . "'>";
?>

Важные замечания

  • Кэширование: Не делайте API-запрос для каждого показа страницы. Сохраняйте URL миниатюры в базу данных или кэш на 24 часа.
  • Ошибка 403: Возникает, если у вас превышена квота API (по умолчанию 10 000 запросов в день). Решение — увеличить квоту в Google Cloud Console или использовать кэширование.
  • cURL vs file_get_contents: cURL предпочтительнее — он даёт больше контроля над ошибками и HTTP-кодами.

Для продакшена рекомендую комбинировать оба подхода: сначала пробовать API с fallback-цепочкой, а если API недоступен — использовать прямой URL. Это обеспечит максимальную надёжность.

<<>>

Альтернативный подход: использование библиотеки Google API Client для PHP

Если вы не хотите писать велосипед с cURL, используйте официальный клиент Google. Это упрощает работу с API и автоматически обрабатывает ошибки и квоты.

<?php
require_once 'vendor/autoload.php'; // Composer

$client = new Google_Client();
$client->setDeveloperKey('ВАШ_КЛЮЧ_API');

$youtube = new Google_Service_YouTube($client);

try {
    $video = $youtube->videos->listVideos('snippet', ['id' => 'dQw4w9WgXcQ']);
    $thumbnails = $video[0]['snippet']['thumbnails'];
    
    // Выбираем самое большое доступное
    $best = $thumbnails['maxres'] ?? $thumbnails['standard'] ?? $thumbnails['high'] ?? $thumbnails['medium'] ?? $thumbnails['default'];
    echo "<img src='{$best['url']}'>";
    
} catch (Exception $e) {
    echo "Ошибка: " . $e->getMessage();
}
?>

Плюсы: автоматическая обработка пагинации, кэширование токенов, поддержка всех методов API. Минус — нужно установить библиотеку через Composer. Для простых задач это может быть избыточно, но для серьёзных проектов — лучший выбор.