Артём Мáлков

Как получить продолжительность видео с YouTube на PHP+API?

21 апр39 комм

Итак, мы с вами уже научились получать API KEY сервиса YouTube для получения данных о видео, и сегодня мы рассмотрим первый и простой способ получения информации о нем, а именно – о продолжительности.

Напишем небольшую функцию, которая и будет возвращать нам необходимые данные:

function get_time_youtube($id_video) {

	$api_key = 'AIzaSyC-tRTwkGhKL4eegGg6utVtsN4lklTs8oU';
	$get_data = file_get_contents('https://www.googleapis.com/youtube/v3/videos?part=snippet,contentDetails,statistics&id='.$id_video.'&key='.$api_key);
	$get_data = json_decode($get_data, true);
	$result_time = $get_data['items']['0']['contentDetails']['duration'];

	$result_time = new \DateInterval($result_time);
	$total_sec = $result_time->days * 86400 + $result_time->h * 3600 + $result_time->i * 60 + $result_time->s;
	$total_time = new DateTime('@'.$total_sec);

	return $total_time->format('H:i:s');

}

А так будет выглядеть пример ее использования:

echo 'Длительность ролика: '.get_time_youtube('bhXZiG4bsjA');

На что тут стоит обратить внимание?

  1. $api_key – это ваш персональный ключ доступа. О том, как его получить, написано здесь.
  2. bhXZiG4bsjA – ID видео, узнать его можно по ссылке.

Например, в ссылке на видео https://www.youtube.com/watch?v=bhXZiG4bsjA – часть bhXZiG4bsjA и есть нужный вам ID.

Если что-то вам показалось непонятным – пишите об этом в комментариях.

Рекомендуем к просмотру
Как зациклить воспроизведение встроенного на сайт видео с YouTube
Статьи и советы
Как получить API KEY для работы с сервисом YouTube?
Статьи и советы
Как быстро и просто получить кадр из видеролика YouTube?
Статьи и советы
39
комментариев
Форма комментирования этого поста скрыта. Авторизуйтесь, чтобы расширить привилегии гостевого посещения и получить необходимую помощь от сообщества Pandoge.
    • 2
    1
      •  Пользователь
    10 мая в 04:33

    Артему большое спасибо!

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

    • 19
    1
      •  Пользователь
    20 апр в 04:53

    Добрый день, Артем. Подскажите пожайлуста правки кода, чтобы сделать вывод продолжительности как на YouTube. Например если ролик идет 00:27:14 отоброжалось без нулей - 27:14. В случае если продолжительность ролика более одного часа, автоматически добавляется переменная hours 01:27:14.

    Устроит также второй вариант. Чтобы отображалось без hours, 27:14 , 68:34 (минуты суммируются, если 60+ минут). Спасибо curly

      • 6
      1066
        •  Команда Pandoge
      изменено 21 апр в 13:56

      Dima Golovkov, здравствуйте!

      Первый вариант.

      Строку:

      return $total_time->format('H:i:s');

      замените на:

      $total_time_r = $total_time->format('i:s');
      
      if($total_time->format('H') != '00') {
      
      	$total_time_r = $total_time->format('H:').$total_time_r;
      
      }
       
      return $total_time_r;

      Второй вариант.

      Строку:

      return $total_time->format('H:i:s');

      замените на:

      $total_time_i = $total_time->format('i');
      $total_time_s = $total_time->format('s');
      
      $total_time_r = $total_time_i.':'.$total_time_s;
      
      if($total_time->format('H') != '00') {
      
      	$total_time_r = ($total_time->format('H') * 60 + $total_time_i).':'.$total_time_s;
      
      }
       
      return $total_time_r;
    • 11
    5
      •  Проверенный
    17 авг в 18:35

    Все отлично работает на DLE 13.2!

    Но есть вопрос: а как сделать еще и вывод количества просмотров видео?

    Это было бы просто бесценно!smiley

      • 2
      1066
        •  Команда Pandoge
      17 авг в 22:55

      Евгений, попробуйте так:

      function get_view_youtube($id_video) {
      
      	$api_key = 'AIzaSyC-tRTwkGhKL4eegGg6utVtsN4lklTs8oU';
      	$get_data = file_get_contents('https://www.googleapis.com/youtube/v3/videos?part=snippet,contentDetails,statistics&id='.$id_video.'&key='.$api_key);
      	$get_data = json_decode($get_data, true);
      	
      	return $result_view = $get_data['items']['0']['statistics']['viewCount'];
      
      }
      
      echo 'Количество просмотров: '.get_view_youtube('bhXZiG4bsjA');

      Если же Вы хотите получить одновременно и длительность и количество просмотров, то лучше объединить код из статьи и из комментария, чтобы получить необходимые данные о видео за 1 запрос.

      • 7
      5
        •  Проверенный
      18 авг в 13:11

      Артем Мáлков, огромное спасибо, это то, что нужно! wink

      • 16
      5
        •  Проверенный
      18 авг в 19:49

      Артем Мáлков, а вот интересно, к этой функции можно прикрутить склонение слов?

      Чтобы на выходе было примерно следующее:

      echo get_view_youtube($video_id, array('просмотр', 'просмотра', 'просмотров'));

      И еще такой вопрос - функция выдает например число просмотров 65999 или 444333 (без пробелов или запятых между тысячными). Есть вариант сделать вывод в формате 65 999 или 444,333 ?

      Заранее спасибо за ответ!

      • 13
      1066
        •  Команда Pandoge
      19 авг в 22:13

      Евгений, пробуйте:

      function declination($number, $titles) {
      	
      	$cases = array(2, 0, 1, 1, 1, 2);
      	
      	return number_format($number, 0, '', ' ').' '.$titles[($number%100>4 && $number%100<20) ? 2 : $cases[min($number%10, 5)]];
      	
      }
      
      
      function get_view_youtube($id_video) {
      
      	$api_key = 'AIzaSyC-tRTwkGhKL4eegGg6utVtsN4lklTs8oU';
      	$get_data = file_get_contents('https://www.googleapis.com/youtube/v3/videos?part=snippet,contentDetails,statistics&id='.$id_video.'&key='.$api_key);
      	$get_data = json_decode($get_data, true);
      
      	return $get_data['items']['0']['statistics']['viewCount'];
      
      }
      
      echo 'Количество просмотров: '.declination(get_view_youtube('bhXZiG4bsjA'), array('просмотр', 'просмотра', 'просмотров'));

      Подробнее о методах можете почитать тут:

      https://www.pandoge.com/stati_i_sovety/razbivaem-chisla-na-razryady-na-javascript-php

      https://www.pandoge.com/moduli_i_skripty/prostoe-sklonenie-chislitelnyh-na-php-javascript

      • 12
      5
        •  Проверенный
      20 авг в 00:58

      Артем Мáлков, ОГРОМНОЕ вам спасибо! Думаю код многим пригодится)

      Статьи обязательно прочту - интересно разобраться.

      Хотел еще спросить: этот код несет какую-нибудь существенную нагрузку?

      Я так понимаю он никак не кэшируется...

      (я в этих делах пока нуб smiley)

      • 6
      1066
        •  Команда Pandoge
      20 авг в 01:24

      Евгений, нет, не кешируется. Но можно сделать кеш с сохранением данных в базу или txt.

      • 1
      5
        •  Проверенный
      20 авг в 02:21

      Артем Мáлков, ну для меня сделать кэш этой функции в бд - это из разряда фантастики)))

      Есть еще такой вопрос - на самом ютубе в шортстори пишет например 233 тыс. просмотров или 1,7 млн. просмотров, а в когда открываешь видео - там 233 000 или 1 700 00...

      Т.е. по сути в шортстори каким-то образом обрезается до тыс. или млн. просмотров

      Вам случайно не известен подобный хак?

      • 4
      1066
        •  Команда Pandoge
      20 авг в 03:50

      Евгений, самое простое - это делить искомое число на разные классы чисел.

      Пример со своей функцией:

      <?php
      
      	function sort_number($numb) {
      		
      		if(($numb / 1000000000) > 1) { // Если при делении на миллиард получаем больше 1
      			
      			return round($numb / 1000000000, 1).' млрд';
      			
      		} elseif(($numb / 1000000) > 1) { // Если при делении на миллион получаем больше 1
      			
      			return round($numb / 1000000, 1).' млн';
      		
      		} elseif(($numb / 1000) > 1) { // Если при делении на тысячу получаем больше 1
      			
      			return round($numb / 1000, 1).' тыс';
      			
      		} else { // Все остальные маленькие числа
      			
      			return $numb;
      			
      		}
      		
      	}
      
      	$my_number = '1 500 000'; // Искомое число
      	$my_number = preg_replace("/[^0-9]/", '', $my_number); // Получаем чистое число, без знаков и пробелов.
      
      	echo sort_number($my_number); // Выводим результат.
      	
      ?>
    • 20
    9
      •  Пользователь
    8 июл в 12:44

    В коде есть ошибка. Минуты с секундами перепутаны.

    return date("H:i:s", mktime(0, 0, $totalSec));

    меняем на

    return date("H:s:i", mktime(0, 0, $totalSec));
      • 6
      9
        •  Пользователь
      8 июл в 14:09

      На DLE 13.2 в фуллстори всё работает. А в шортстори выходит ошибка:

      Fatal error: Cannot redeclare get_time_youtube() (previously declared in сайт/engine/modules/get_time_youtube.php:5) in /сайт/engine/modules/get_time_youtube.php on line 5

      Кучу информации перерыл про include и include_once (со вторым, кстати, ошибки нет, но не работает). Пробовал делать вторые файлы, переименовывать.. ничего не срабатывает. Может что-то не так делаю. Объясните, пожалуйста, нубу :)

      • 17
      1066
        •  Команда Pandoge
      8 июл в 14:40

      Сергей Янковский, спасибо за замечание - поправили.

      А что касается ошибки, сделайте так. Всю функцию из статьи замените на:

      if(!function_exists('get_time_youtube')) {
      
      	function get_time_youtube($id_video) {
      
      		$api_key = 'AIzaSyC-tRTwkGhKL4eegGg6utVtsN4lklTs8oU';
      		$get_data = file_get_contents('https://www.googleapis.com/youtube/v3/videos?part=snippet,contentDetails,statistics&id='.$id_video.'&key='.$api_key);
      		$get_data = json_decode($get_data, true);
      		$result_time = $get_data['items']['0']['contentDetails']['duration'];
      
      		$result_time = new \DateInterval($result_time);
      		$total_sec = $result_time->days * 86400 + $result_time->h * 3600 + $result_time->i * 60 + $result_time->s;
      		$total_time = new DateTime('@'.$total_sec);
      
      		return $total_time->format('H:i:s');
      
      	}
      
      }
      • 11
      9
        •  Пользователь
      9 июл в 10:27

      Добрый день. Это снова я :)

      Обнаружил такую штуку: если загрузить видео длинной в 5 секунд, то отображается 00:00:05. И если загрузить видео длинной 5 минут, то так же отображается 00:00:05. То есть секунды с минутами равнозначны. Попробовал поменять местами секунды с минутами на H:i:s и видео, которые идут от 1 минуты стали правильно отображаться, но те которые до 1 минуты (значения которых по идее должны отображаться в секундах - отображаются в минутах)

      Подскажите, пожалуйста, как поправить?

      • 1
      9
        •  Пользователь
      9 июл в 10:44

      И, соответственно, если добавить часовое видео, например на 3:49:40, то отображается как 00:03:49. Это. при значении "H:i:s"

      • 1
      1066
        •  Команда Pandoge
      9 июл в 14:52

      Сергей Янковский, врать не буду, но вроде YouTube изменил формат времени, которое отдается в API.

      Изменили функцию, сейчас должно работать - проверьте.

      • 11
      9
        •  Пользователь
      9 июл в 15:37

      Артем Мáлков, спасибо) Только не совсем пойму, как её в DLE вставить? До этого ваш код из предыдущих комментариев копировал, а код из самой статьи проверил, на DLE не работает

      • 10
      1066
        •  Команда Pandoge
      9 июл в 19:21

      Сергей Янковский, как и раньше через модуль:

      <?php
      	
      	if(!defined('DATALIFEENGINE')) {
      
      		die('Hacking attempt!');
      	
      	}
      
      	function get_time_youtube($id_video) {
      
      		$api_key = 'AIzaSyC-tRTwkGhKL4eegGg6utVtsN4lklTs8oU';
      		$get_data = file_get_contents('https://www.googleapis.com/youtube/v3/videos?part=snippet,contentDetails,statistics&id='.$id_video.'&key='.$api_key);
      		$get_data = json_decode($get_data, true);
      		$result_time = $get_data['items']['0']['contentDetails']['duration'];
      
      		$result_time = new \DateInterval($result_time);
      		$total_sec = $result_time->days * 86400 + $result_time->h * 3600 + $result_time->i * 60 + $result_time->s;
      		$total_time = new DateTime('@'.$total_sec);
      
      		return $total_time->format('H:i:s');
      
      	}
      
      	echo 'Длительность ролика: '.get_time_youtube($id_video);
      
      ?>
      • 9
      9
        •  Пользователь
      9 июл в 19:39

      Работает, спасибо большое!)

      • 8
      9
        •  Пользователь
      9 июл в 22:53

      Оооох. Это уже не смешно. Сначала всё хорошо работало. А потом вылетела ошибка. При том, что этот код уже вообще не трогал. Да и то, что трогал вернул в старое состояние, когда вылетела ошибка. И всё равно никуда она не уходит. Ошибка такого вида:

      Fatal error: Uncaught exception 'Exception' with message 'DateInterval::__construct(): Unknown or bad format ()' in /home/y/yankov7s/video.helpblogger.org/public_html/engine/modules/get_time_youtube.php:16 Stack trace: #0 сайт/public_html/engine/modules/get_time_youtube.php(16): DateInterval->__construct('') #1 сайт/public_html/engine/modules/get_time_youtube.php(26): get_time_youtube('MEBxC4_SxaM') #2 сайт/public_html/engine/classes/templates.class.php(330): include('/home/y/yankov7...') #3 [internal function]: dle_template->load_file(Array) #4 сайт/public_html/engine/classes/templates.class.php(1021): preg_replace_callback('#\\{include file...', Array, '

      • 8
      1066
        •  Команда Pandoge
      9 июл в 22:56

      Сергей Янковский, тут без FTP от сайта и админки уже не смогу помочь.

      • 12
      9
        •  Пользователь
      9 июл в 23:16

      У вас личка в вк закрыта :)

      • 12
      1066
        •  Команда Pandoge
      10 июл в 00:20

      Сергей Янковский, отправьте в группу или в комментариях.

      • 9
      9
        •  Пользователь
      10 июл в 14:41

      Артем Мáлков, отправил

      • 1
      2
        •  Проверенный
      17 мар в 11:49

      Сергей Янковский, а вы можете выложить как решили данную проблему "Артём Мáлкова". У меня такая-же ошибка. sad

      • 1
      1066
        •  Команда Pandoge
      20 мар в 00:39

      Владимир Атрошенко, пришлите на почту FTP от сайта, где наблюдается проблема - постараемся помочь и выложить решение.

    • 24
    3
      •  Пользователь
    3 мар в 15:14

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

    с моими размерами видео?

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

    А то так не удобно вставлять через редактор и каждый раз изменять размер

      • 6
      1066
        •  Команда Pandoge
      3 мар в 18:22

      Виктор Лобанов, про какой движок идет речь?

      • 1
      3
        •  Пользователь
      3 мар в 19:06

      Движок DLE 13.0

      • 6
      1066
        •  Команда Pandoge
      3 мар в 20:43

      Виктор Лобанов, а официальную документацию по движку не читали? Там хорошо все написано.

      [xfgiven_x]
      
      	<iframe width="560" height="315" src="[xfvalue_x]" frameborder="0" allowfullscreen></iframe>
      
      [/xfgiven_x]

      x три раза меняете на название вашего поля. В само поле пишите ссылки на видео с YouTube через embed. То есть, если видео имеет такой адрес:

      https://www.youtube.com/watch?v=bhXZiG4bsjA

      на сайте, в поле, Вы прописываете его так:

      https://www.youtube.com/embed/bhXZiG4bsjA
      • 12
      3
        •  Пользователь
      3 мар в 22:02

      Спасибо просто не так давно стал изучать DLE

      • 20
      1066
        •  Команда Pandoge
      3 мар в 22:46

      Виктор Лобанов, ааа... Тогда обращайтесь wink

    • 17
    766
      •  Гости
    8 апр в 15:39

    Странный у меня вопрос.. но как использовать эту функцию в dle? Что только не придумывал, не получается у меня вставить её в шаблон. Чувствую что это просто, и явно я просто вставляю echo как то не так. Артём, помогите пожалуйста))

      • 18
      1066
        •  Команда Pandoge
      8 апр в 16:36

      Scorp, исключительно для Вас.

      1. В шаблон полной или краткой новости вставляете:

      [xfgiven_xxx]
      
      	{include file="engine/modules/get_time_youtube.php?id_video=[xfvalue_xxx]"}
      
      [/xfgiven_xxx]

      xxx - название вашего поля, в котором храниться ID видео.

      2. Создаете файл get_time_youtube.php со следующим содержимым:

      <?php
      	
      	if(!defined('DATALIFEENGINE')) {
      
      		die('Hacking attempt!');
      	
      	}
      
      	function get_time_youtube($id_video) {
      
      		$api_key = 'AIzaSyC-tRTwkGhKL4eegGg6utVtsN4lklTs8oU';
      		$get_data = file_get_contents('https://www.googleapis.com/youtube/v3/videos?part=snippet,contentDetails,statistics&id='.$id_video.'&key='.$api_key);
      		$get_data = json_decode($get_data, true);
      		$result_time = $get_data['items']['0']['contentDetails']['duration'];
      
      		$result_time = new \DateInterval($result_time);
      		$total_sec = $result_time->days * 86400 + $result_time->h * 3600 + $result_time->i * 60 + $result_time->s;
      		$total_time = new DateTime('@'.$total_sec);
      
      		return $total_time->format('H:i:s');
      
      	}
      
      	echo 'Длительность ролика: '.get_time_youtube($id_video);
      
      ?>

      Его Вы загружаете в /engine/modules/

      3. Чистите кэш сайта. На этом должно быть все.

      • 11
      766
        •  Гости
      8 апр в 21:23

      Я благодарю Вас Артём за помощь!

      • 13
      1066
        •  Команда Pandoge
      8 апр в 21:53

      Scorp, не забудьте создать свой API KEY.

      • 9
      766
        •  Гости
      8 апр в 23:47

      Хм.. не всё так просто. Когда вставляешь в полную новость, то всё норм, но когда вставляешь в краткую новость, то ошибка в строке function get_time_youtube($id_video) {

      Далее я поставил я в краткую новость, но для раздела закладок и если 1 закладка, то работает, а если две и более закладки, то нет. В этом сумеете помочь? angel

Подняться наверх
«Pandoge» - помощник вебмастера