2014-09-04 3 views
1

Я использую v3 Google API для Youtube:Получить все видео YouTube из канала (некоторое видео отсутствует)

$url = 'https://www.googleapis.com/youtube/v3/search?part=id&channelId=' . $channelID . '&maxResults=50&order=date&key=' . $API_key; 

Я создал скрипт, который должен дать мне все видео из данных идентификатор канала. Для некоторых каналов я получаю все видеоролики, некоторые из них отсутствуют (по сравнению с количеством видеороликов, показанных непосредственно на Youtube), а для большего канала я получаю максимум. результат из 488 видео, несмотря на то, что их больше.

pageToken странно. Например, канал имеет 955 видео. Я получаю 18 страниц с 50 пунктами на страницу (это будет 900 видео). Некоторые из них - плейлисты, но если я вычту 23 плейлиста, у меня все еще есть 877 видео. Если я удалю дубликаты, у меня будет только 488 результатов! totalResults на выходе JSON показывает мне 975 результатов !?

Это моя рекурсивная функция:

function fetchAllVideos($parsed_json){ 
    $foundIds = array(); 
    if($parsed_json != ''){ 
     $foundIds = getVideoIds($parsed_json); 
     $nextPageToken = getNextPageToken($parsed_json); 
     $prevPageToken = getPrevPageToken($parsed_json); 

     if($nextPageToken != ''){ 
      $new_parsed_json = getNextPage($nextPageToken); 
      $foundIds = array_merge($foundIds, fetchAllVideos($new_parsed_json)); 
     } 
     if($prevPageToken != ''){ 
      $new_parsed_json = getNextPage($prevPageToken); 
      $foundIds = array_merge($foundIds, fetchAllVideos($new_parsed_json)); 
     } 
    } 

    return $foundIds; 
} 

Я называю это с $videoIds = fetchAllVideos($parsed_json); и $parsed_json является результатом первого URL, который я получить. Вы видите ошибку здесь?

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

ответ

2

https://gdata.youtube.com/feeds/api/users/USERNAME_HERE/uploads?max-results=50&alt=json&start-index=1 сделал трюк. Это фишка JSON, где вам нужно зацикливаться до тех пор, пока вы не получите менее 50 результатов.

Edit:

Это должно быть сценарий я использовал:

ini_set('max_execution_time', 900); 

function getVideos($channel){ 
    $ids = array(); 
    $start_index = 1; 
    $still_have_results = true; 

    if($channel == ""){ 
     return false; 
    } 

    $url = 'https://gdata.youtube.com/feeds/api/users/' . $channel . '/uploads?max-results=50&alt=json&start-index=' . $start_index; 
    $json = file_get_contents($url); 
    $obj = json_decode($json); 

    while($still_have_results){ 
     foreach($obj->feed->entry as $video){ 
      $video_url = $video->id->{'$t'}; 
      $last_pos = strrpos($video_url, '/'); 
      $video_id = substr($video_url, $last_pos+1, strlen($video_url) - $last_pos); 
      array_push($ids, $video_id); 
     } 
     $number_of_items = count($obj->feed->entry); 
     $start_index += count($obj->feed->entry); 
     if($number_of_items < 50) { 
      $still_have_results = false; 
     } 

     $url = 'https://gdata.youtube.com/feeds/api/users/' . $channel . '/uploads?max-results=50&alt=json&start-index=' . $start_index; 
     $json = file_get_contents($url); 
     $obj = json_decode($json); 
    } 

    return $ids;  
} 

$videoIds = getVideos('youtube'); 
echo '<pre>'; 
print_r($videoIds); 
echo '</pre>'; 

Теперь я сделал тест, но я не собрал 100% видео. Тем не менее, лучший вариант, который я придумал.

+0

Я дал вам ножки, но в любом случае вы должны опубликовать окончательный вариант. Вы не знаете, когда это может быть полезно кому-то. – Random

+0

@Random: Теперь я добавил скрипт, который использовал. – testing

1

Этот сценарий проходит через 60-дневный период за один раз и извлекает результаты для него, а затем добавляет его в существующий массив данных. Делая это, нет никаких ограничений на количество видеороликов, хотя может потребоваться некоторое время, чтобы тралить более крупные каналы YouTube с несколькими тысячами видеороликов. Убедитесь, что вы установили API_KEY, часовой пояс, имя пользователя, дату начала (должны начаться до первого видео на канале) и период (по умолчанию задано значение 60 * 60 * 24 * 60, что составляет 60 дней в секундах. быть ниже, если частота видеороликов превышает 50 в течение 60 дней.) (5184000 секунд).

* Все это прокомментировано в скрипте.

date_default_timezone_set("TIMEZONE"); 

//youtube api key 
$API_KEY = "YOUR API KEY"; 

function search($searchTerm,$url){ 
    $url = $url . urlencode($searchTerm); 

    $result = file_get_contents($url); 

    if($result !== false){ 
     return json_decode($result, true); 
    } 

    return false; 
} 

function get_user_channel_id($user){ 
    global $API_KEY; 
    $url = 'https://www.googleapis.com/youtube/v3/channels?key=' . $API_KEY . '&part=id&forUsername='; 
    return search($user,$url)['items'][0]['id']; 
} 

function push_data($searchResults){ 
    global $data; 
    foreach($searchResults['items'] as $item){ 
     $data[] = $item; 
    } 
    return $data; 
} 

function get_url_for_utc_period($channelId, $utc){ 
    //get the API_KEY 
    global $API_KEY; 
    //youtube specifies the DateTime to be formatted as RFC 3339 formatted date-time value (1970-01-01T00:00:00Z) 
    $publishedAfter = date("Y-m-d\TH:i:sP",strval($utc)); 
    //within a 60 day period 
    $publishedBefore_ = $utc + (60 * 60 * 24 * 60); 
    $publishedBefore = date("Y-m-d\TH:i:sP",$publishedBefore_); 
    //develop the URL with the API_KEY, channelId, and the time period specified by publishedBefore & publishedAfter 
    $url = 'https://www.googleapis.com/youtube/v3/search?part=snippet&type=video&key=' . $API_KEY . '&maxResults=50&channelId=' . $channelId . '&publishedAfter=' . urlencode($publishedAfter) . '&publishedBefore=' . urlencode($publishedBefore); 

    return array("url"=>$url,"utc"=>$publishedBefore_); 
} 
//the date that the loop will begin with, have this just before the first videos on the channel. 
//this is just an example date 
$start_date = "2013-1-1"; 
$utc = strtotime($start_date); 
$username = "CHANNEL USERNAME NOT CHANNEL ID"; 
//get the channel id for the username 
$channelId = get_user_channel_id($username); 

while($utc < time()){ 
    $url_utc = get_url_for_utc_period($channelId, $utc); 
    $searchResults = search("", $url_utc['url']); 
    $data = push_data($searchResults); 
    $utc += 60 * 60 * 24 * 60; 
} 
print "<pre>"; 
print_r($data); 
print "</pre>"; 

//check that all of the videos have been accounted for (cross-reference this with what it says on their youtube channel) 
print count($data); 
Смежные вопросы