Avatar ·

Как получить миниатюру видео YouTube через API на PHP? (curl, YouTube Data API)

Всем привет! Я начинающий PHP-разработчик, пытаюсь вывести на своём сайте превью (миниатюру) для видео с YouTube. Видео загружаются пользователями, и мне нужно динамически получать картинку по ID видео. Я слышал, что можно использовать YouTube Data API v3, но не могу разобраться с запросами. Пробовал парсить страницу видео через file_get_contents и регулярки, но это ненадёжно и часто ломается. Мой текущий код на PHP (не работает): ```php ``` Но вместо картинки получаю ошибку "Undefined index: items" или пустую страницу. API ключ я получил, но, возможно, я не включил нужные сервисы в консоли Google? Или проблема в curl? Также интересует: нужно ли всегда использовать API, или есть более простой способ получить стандартную миниатюру? Например, многие говорят про формат URL: https://img.youtube.com/vi/VIDEO_ID/maxresdefault.jpg — но это работает не для всех видео. Какой подход правильный для production-сайта? Заранее спасибо за помощь! <<>>

Проверка API-ключа и базовый запрос

Ваша проблема скорее всего связана с тем, что API-ключ не активирован для YouTube Data API v3. Убедитесь, что вы:

  1. Перешли в Google Cloud Console и включили "YouTube Data API v3" для вашего проекта.
  2. Создали API-ключ (Credentials → Create Credentials → API Key) и, желательно, ограничили его использование только этим API.
  3. Проверили, что квота не исчерпана (бесплатно 10 000 запросов в день).

После включения API ваш код заработает, но я рекомендую добавить обработку ошибок и проверку ответа:

<?php
$videoId = "dQw4w9WgXcQ";
$apiKey = "ВАШ_КЛЮЧ";

$url = "https://www.googleapis.com/youtube/v3/videos?id=" . urlencode($videoId) . "&part=snippet&key=" . $apiKey;

$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL => $url,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_SSL_VERIFYPEER => false, // для локальной разработки
    CURLOPT_TIMEOUT => 10
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($httpCode !== 200) {
    die("Ошибка API: HTTP $httpCode. Проверьте ключ и квоту.");
}

$data = json_decode($response, true);

if (empty($data['items'][0])) {
    die("Видео не найдено или недоступно.");
}

// Выбираем лучшее качество
$thumbnails = $data['items'][0]['snippet']['thumbnails'];

$bestQuality = 'default';
if (isset($thumbnails['maxres'])) $bestQuality = 'maxres';
elseif (isset($thumbnails['high'])) $bestQuality = 'high';
elseif (isset($thumbnails['medium'])) $bestQuality = 'medium';

echo "<img src='" . $thumbnails[$bestQuality]['url'] . "' alt='Миниатюра'>";
?>

Альтернативный метод без API (для простых случаев)

Если вам не нужно получать динамические данные (название, описание), и вы хотите просто показать миниатюру, используйте прямые URL YouTube. Они работают в 95% случаев:

  • https://img.youtube.com/vi/VIDEO_ID/maxresdefault.jpg — максимальное качество (1920x1080)
  • https://img.youtube.com/vi/VIDEO_ID/hqdefault.jpg — высокое качество (480x360)
  • https://img.youtube.com/vi/VIDEO_ID/mqdefault.jpg — среднее качество (320x180)
  • https://img.youtube.com/vi/VIDEO_ID/default.jpg — стандартное (120x90)

Но есть нюансы: maxresdefault.jpg существует не для всех видео (только для тех, где автор загрузил HD-превью). В таких случаях лучше использовать hqdefault.jpg — он есть всегда.

Гибридный подход для production

Рекомендую комбинировать методы: сначала пробуйте получить maxresdefault.jpg через проверку HTTP-заголовков (чтобы не нагружать API), и только если картинка недоступна — используйте API для получения точного URL миниатюры. Вот пример:

<?php
function getYoutubeThumbnail($videoId) {
    // Пробуем максимальное качество
    $url = "https://img.youtube.com/vi/{$videoId}/maxresdefault.jpg";
    $headers = @get_headers($url);
    
    if ($headers && strpos($headers[0], '200') !== false) {
        return $url;
    }
    
    // Если нет — используем API
    $apiKey = "ВАШ_КЛЮЧ";
    $apiUrl = "https://www.googleapis.com/youtube/v3/videos?id={$videoId}&part=snippet&key={$apiKey}";
    
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $apiUrl);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 5);
    $response = curl_exec($ch);
    curl_close($ch);
    
    $data = json_decode($response, true);
    
    if (isset($data['items'][0]['snippet']['thumbnails']['high']['url'])) {
        return $data['items'][0]['snippet']['thumbnails']['high']['url'];
    }
    
    // fallback
    return "https://img.youtube.com/vi/{$videoId}/hqdefault.jpg";
}

echo getYoutubeThumbnail("dQw4w9WgXcQ");
?>

Этот подход минимизирует запросы к API (экономит квоту) и гарантирует получение картинки даже для старых видео.

<<>>

Использование oEmbed API (без ключа)

Если вам не нужны все данные из YouTube Data API, а только миниатюра, можно использовать oEmbed — официальный, но менее известный метод. Он не требует API-ключа и возвращает базовую информацию о видео.

<?php
$videoId = "dQw4w9WgXcQ";
$url = "https://www.youtube.com/oembed?url=https://www.youtube.com/watch?v={$videoId}&format=json";

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);

$data = json_decode($response, true);
echo $data['thumbnail_url']; // Вернёт hqdefault.jpg
?>

Плюсы: бесплатно, без ограничений (кроме разумного использования), легко реализовать.
Минусы: возвращает только стандартную миниатюру (480x360), нельзя получить maxres. Подходит для простых блогов или новостных лент.

Советую комбинировать oEmbed с прямыми URL: сначала проверяйте maxresdefault.jpg, при неудаче — используйте oEmbed. Это будет самый быстрый и экономный вариант.