YouTube Videos in PHP: Categories, Search and Suggestions

Share this article

In the first part, we introduced the YouTube API and built a small demo to list the most popular videos on YouTube. In this part, we will extend our application to have search functionality, and we’ll also list the available categories on YouTube to let the user narrow down their area of interest. Let’s get started.

YouTube Logo

Listing Categories

YouTube videos are grouped by categories. We can retrieve the list of categories for a certain country using their ISO code. The result can also be localized using an optional parameter like en_US, fr_FR, etc. You can read more in the documentation.

// app/Http/routes.php

Route::get('/categories', ['uses' => 'YouTubeAPIController@categories']);
// app/Http/Controllers/YouTubeAPIController.php

public function categories()
{
  $youtube = \App::make('youtube');
  $categories = $youtube->videoCategories->listVideoCategories('snippet', ['regionCode' => 'MA']);

  dump($categories);
}

As before, the first parameter is the part, and I used my country code as a filter. The result looks like the following.

Categories

Back to our demo, we need to use the list of categories and give the user the ability to filter the list of videos.

// app/Http/Controllers/YouTubeAPIController.php

public function videos()
{
  $options = ['chart' => 'mostPopular', 'maxResults' => 16];
  $regionCode = 'MA';
  $selectedCategory = 0;

  if (\Input::has('page')) {
    $options['pageToken'] = \Input::get('page');
  }

  if (\Input::has('category')) {
    $selectedCategory = \Input::get('category');
    $options['videoCategoryId'] = $selectedCategory;
  }

  $youtube = \App::make('youtube');
  $categories = $youtube->videoCategories->listVideoCategories('snippet', ['regionCode' => $regionCode])->getItems();
  $videos = $youtube->videos->listVideos('id, snippet', $options);

  return view('videos', ['videos' => $videos, 'categories' => $categories, 'selectedCategory' => $selectedCategory]);
}

When the user selects a category, we pass the category ID as a parameter to the videos method. This should work fine with the pagination, so let’s see our view markup changes.

// resources/views/videos.blade.php

{!! Form::open(['route' => 'videos', 'name' => 'formCategory', 'class' => 'form-inline']) !!}
    <label for="category">Filter by category: </label>
    <select name="category" id="category" class="form-control" onchange="this.form.submit()">
        <option value="0">All</option>
        @foreach($categories as $category)
            <option value="{{ $category->getId() }}" @if($selectedCategory == $category->getId()) selected @endif>{{ $category['snippet']['title'] }}</option>
        @endforeach
    </select>
{!! Form::close() !!}

<!-- Pagination -->
<li @if($videos->getPrevPageToken() == null) class="disabled" @endif>
  <a href="/videos?page={{$videos->getPrevPageToken()}}&category={{ $selectedCategory }}" aria-label="Previous">
    <span aria-hidden="true">Previous &laquo;</span>
  </a>
</li>
<li @if($videos->getNextPageToken() == null) class="disabled" @endif>
  <a href="/videos?page={{$videos->getNextPageToken()}}&category={{ $selectedCategory }}" aria-label="Next">
    <span aria-hidden="true">Next &raquo;</span>
  </a>
</li>

The form is submitted on change event of the list of categories, and we make sure to pass the selected category along with the page token on the navigation. The zero category resets our filter.

Categories filter

Searching is an important aspect of the YouTube platform, and we need to have this functionality in our demo. The user can search and paginate through the list of results.

Search

// app/Http/routes.php

Route::any('/search', ['as' => 'search', 'uses' => 'YouTubeAPIController@search']);
// app/Http/Controllers/YouTubeAPIController.php

public function search()
{
  if (!\Input::has('query')) {
    return view("search");
  }

  $options = ['maxResults' => 16, 'q' => \Input::get("query")];
  if (\Input::has('page')) {
    $options['pageToken'] = \Input::get('page');
  }

  $youtube = \App::make('youtube');
  $videos = $youtube->search->listSearch("snippet", $options);

  return view("search", ['videos' => $videos, 'query' => \Input::get('query')]);
}

If the query parameter is not present, that means we need just to render an empty page with the search input, otherwise, we add the query parameter to the list of options and we see if we have a pagination parameter. The view is almost identical to the videos one.

// resources/views/search.blade.php

{!! Form::open(['route' => 'search', 'class' => 'form-inline']) !!}
    <input type="text" name="query" class="form-control" style="width: 50%;" autofocus="true" value="{{ $query }}"/>
    <input type="submit" class="btn btn-default" value="Search"/>
{!! Form::close() !!}

@if(isset($videos))
    <ul class="list-unstyled video-list-thumbs row">
    @foreach($videos as $video)
        <li class="col-lg-3 col-sm-4 col-xs-6">
            <a href="{{ URL::route('video', ['id' => $video->getId()->getVideoId()]) }}" title="{{ $video['snippet']['title'] }}" target="_blank">
                <img src="{{ $video['snippet']['thumbnails']['medium']['url'] }}" alt="{{ $video['snippet']['title'] }}" class="img-responsive" height="130px" />
                <h2 class="truncate">{{ $video['snippet']['title'] }}</h2>
                <span class="glyphicon glyphicon-play-circle"></span>
            </a>
        </li>
    @endforeach
    </ul>

    <nav class="text-center">
      <ul class="pagination pagination-lg">
        <li @if($videos->getPrevPageToken() == null) class="disabled" @endif>
          <a href="/search?page={{$videos->getPrevPageToken()}}&query={{ $query }}" aria-label="Previous">
            <span aria-hidden="true">Previous &laquo;</span>
          </a>
        </li>
        <li @if($videos->getNextPageToken() == null) class="disabled" @endif>
          <a href="/search?page={{$videos->getNextPageToken()}}&query={{ $query }}" aria-label="Next">
            <span aria-hidden="true">Next &raquo;</span>
          </a>
        </li>
      </ul>
    </nav>
@else
    <h2>No result.</h2>
@endif

You see that the videos result is identical to the video page, except that the $video->getId() method returns a resource, and you need to get the video ID using a chained call. YouTube API results have array access, so you can work with them as arrays instead of calling getter methods.
The response also contains information about the video channel, creation date, quality, etc. You may use them to enrich your page.

When you visit a single video page on YouTube, you see a list of suggestions based on your current video. The search endpoint offers this possibility through some options:

// app/Http/Controllers/YouTubeAPIController.php

public function video($id)
{
  $options = ['maxResults' => 1, 'id' => $id];

  $youtube = \App::make('youtube');
  $videos = $youtube->videos->listVideos('id, snippet, player, contentDetails, statistics, status', $options);
  $relatedVideos = $youtube->search->listSearch("snippet", ['maxResults' => 16, 'type' => 'video', 'relatedToVideoId' => $id]);

  if (count($videos->getItems()) == 0) {
    return redirect('404');
  }

  return view('video', ['video' => $videos[0], 'relatedVideos' => $relatedVideos]);
}

Suggestions

According to the documentation, you need to set the type parameter to video when you want to do a related video search. The search endpoint has a lot of options like restricting the search to a certain quality, a certain category or a certain channel, etc. Be sure to check the documentation for the list of available options.

Extending the Demo

Because we can’t cover everything in this tutorial, you can take the demo from here and start extending it with some new functionality. You can start by displaying video channel names and links under every video element, and when the user clicks on the link, redirect them to the /channel/channel_id route and only display the channel videos; you can group the video by playlists, etc.

Quotas & Caching

An important part of working with APIs are quotas. YouTube gives you 50,000,000 units/day, and as we said earlier, units are calculated per request and can be increased when you ask for more information. Some API calls cost more than others. For example, calls to the search endpoint cost 100 units. Apart from that, you are limited to 3000 requests/second/user.

Quotas

Etags Caching

If you’ve noticed in the previous screenshots, we have an Etag attribute which stamps the current state of the entity result. This attribute can be sent inside the HTTP headers as described on the HTTP spec page and if the entity has changed you’ll get a refreshed version, otherwise you get a 304 (not modified) response. You can read more about optimization and performance in the documentation.

Conclusion

In this article, we introduced the YouTube API v3 and built a demo along the way. The API offers a lot of features, like working with user activities, playlists, channels, subscriptions, etc. Be sure to check the getting started guide to familiarize yourself with the limits and possibilities.

You can check the final demo on Github, it includes an installation guide to get you started. If you have any comments or questions, don’t hesitate to post them below and I will do my best to answer them.

Frequently Asked Questions (FAQs) about YouTube Videos, PHP Categories, Search, and Suggestions

How can I categorize YouTube videos using PHP?

Categorizing YouTube videos using PHP involves using the YouTube Data API. This API allows you to fetch video details, including categories. You can make a GET request to the API endpoint and parse the response to get the category details. You can then use these details to categorize the videos on your website. Remember to replace ‘YOUR_API_KEY’ with your actual API key in the code.

How can I implement a search feature for YouTube videos on my website?

Implementing a search feature for YouTube videos on your website involves using the YouTube Data API’s search.list method. This method returns a collection of search results that match the query parameters specified in the API request. You can use these results to display a list of videos that match the user’s search query on your website.

How can I suggest YouTube videos to users based on their viewing history?

Suggesting YouTube videos to users based on their viewing history involves tracking the videos that users watch on your website and using this data to recommend similar videos. You can use the YouTube Data API’s related videos feature to fetch a list of videos that are similar to a specific video. You can then use this list to suggest videos to the user.

How can I handle errors when using the YouTube Data API?

Handling errors when using the YouTube Data API involves checking the response from the API for any error messages. If an error message is present, you can display a user-friendly message to the user and log the error for debugging purposes. You can also use try-catch blocks in your code to catch any exceptions that occur when making API requests.

How can I paginate results when using the YouTube Data API?

Paginating results when using the YouTube Data API involves using the pageToken parameter in your API requests. This parameter allows you to fetch a specific page of results. You can use the nextPageToken and prevPageToken values in the API response to fetch the next and previous pages of results, respectively.

How can I filter YouTube videos by category using PHP?

Filtering YouTube videos by category using PHP involves using the YouTube Data API’s videoCategory.list method. This method returns a list of video categories that match the query parameters specified in the API request. You can use these categories to filter the videos on your website.

How can I sort YouTube videos by popularity using PHP?

Sorting YouTube videos by popularity using PHP involves using the YouTube Data API’s video.list method with the ‘mostPopular’ chart parameter. This parameter returns a list of the most popular videos. You can use this list to display the most popular videos on your website.

How can I embed YouTube videos on my website using PHP?

Embedding YouTube videos on your website using PHP involves using the YouTube Data API’s videos.list method to fetch the video details and the embed code for the video. You can then use this embed code to display the video on your website.

How can I fetch video details from YouTube using PHP?

Fetching video details from YouTube using PHP involves using the YouTube Data API’s videos.list method. This method returns a list of video details that match the query parameters specified in the API request. You can use these details to display video information on your website.

How can I authenticate my application with the YouTube Data API?

Authenticating your application with the YouTube Data API involves creating a project in the Google Cloud Console, enabling the YouTube Data API, and creating credentials for your application. You can then use these credentials to authenticate your API requests.

Younes RafieYounes Rafie
View Author

Younes is a freelance web developer, technical writer and a blogger from Morocco. He's worked with JAVA, J2EE, JavaScript, etc., but his language of choice is PHP. You can learn more about him on his website.

apiBrunoSlaravelOOPHPPHPvideoYoutube
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week