PHP
Article

Building a Basic Video Search App with Vimeo’s API and Slim

By Wern Ancheta

Consuming Vimeo's API

In this tutorial, you’ll get to know the basics of the Vimeo API. With it, you can fetch information on a specific user or get information on the videos uploaded by the user. If the video is private, you can only get it from the API if the user has given permission to your app.

Vimeo Logo

Creating a New App

The first thing you’re going to need is a Vimeo account. Once you have one, go to developer.vimeo.com and click on My Apps. This will list out all the apps that you’ve created. Since it’s your first time, it should be empty. Click the create a new app button to start creating a new app. Enter the name, description, URL and callback URL of the app. For the URL and callback URL you can enter a URL on your development machine (like http://homestead.app).

vimeo new app

Click on the create app button once you’re done adding the details. You will be redirected to the app page where you can click the ‘authentication’ tab to reveal the tokens which you can use to interact with the API. We’ll need those later.

API Playground

Before you move on to coding a demo app, take a look at the API Playground. This is a tool provided by Vimeo so developers can play around with the API without having to code anything. It allows you to make calls to specific API endpoints, set custom values for the parameters that can be passed through those endpoints and see the actual result which is a JSON string.

Check the ‘Authenticate this call as {your user name}’ checkbox so that all API calls are performed on behalf of your Vimeo account. If you do not check this box, the API calls will be performed as an unauthenticated request. This means that it won’t be using your app credentials, nor a specific user to perform requests to the API. In effect, it’s then limited to only accessing publicly available information.

Going back to the API Playground, select the application which you’ve created earlier. You can click the make call button to perform the request. The default URL used in the playground is https://api.vimeo.com/ which just lists out all the endpoints which are available from the API. To change this, you can click on the (Empty…) link on the left side of the screen. From there, you can select the endpoint to which you want to send a request. You can try the users endpoint for starters. Once selected, it allows you to input the ID of a specific user and search for users by specifying a set of parameters.

api playground users

In the example above, you’re searching for a user named ‘ash ketchum’. You do this by specifying a value for the query parameter. You can also see which parameters are required and which ones are optional. The parameters that you can specify are pretty self-explanatory. Go ahead and play with different values to familiarize yourself with the API calls that you can make.

If you examine the results, it returns 25 rows per page by default. It also shows the total number of rows that the query returns. In this case, it’s 16. This is evident on the paging data as well: next has a value null so this means there’s no next page.

vimeo user

From the response above, all the user data is inside the data array. Each user is an object with the same set of properties in them. If you want to get more detailed information about a specific user, you can extract its ID from the value of the uri. In this case it’s /users/3151551 so the ID is 3151551. You can copy that and use it as a value for the {user_id} under the users endpoint to query that specific user.

"data": [
        {
            "uri": "/users/3151551",
            "name": "ash ketchum",
            "link": "https://vimeo.com/user3151551",
...

Do note that some endpoints require an authenticated user to perform the request. This means that you have to check the Authenticate this call as {your user name} checkbox to perform the request. An example of such an endpoint is the me endpoint. This specific endpoint allows your app to query data regarding the currently authenticated user.

Creating the Demo

Prerequisites

From this point forward, we’ll assume you’re using our Homestead Improved Vagrant box to follow along. It’s a virtual development environment tuned for common PHP applications, so that every reader has the same starting point.

For the demo, you will be using the Slim framework, Twig templating engine and the Vimeo PHP library. Let’s install them:

composer require slim/slim twig/twig slim/views vimeo/vimeo-api

Bootstrapping

In your working directory, create an index.php file, start the session, and include Composer’s autoloader:

<?php
session_start();
require_once 'vendor/autoload.php';

Define a constant for the client ID, client secret and redirect URI used by your app. Make sure the redirect URI which you have added in the details of your app matches the URL that you use in here.

define('CLIENT_ID', 'your vimeo client id');
define('CLIENT_SECRET', 'your vimeo client secret');
define('REDIRECT_URI', 'your vimeo redirect or callback url');

Create a new instance of the Slim app and pass in Twig for the view option. This allows you to use Twig for handling views. Also, set the parser options for the view.

$app = new \Slim\Slim(array(
    'view' => new \Slim\Views\Twig() //use twig for handling views
));

$view = $app->view();
$view->parserOptions = array(
    'debug' => true, //enable error reporting in the view
    'cache' => dirname(__FILE__) . '/cache' //set directory for caching views
);

Add the following to use the Vimeo library.

$vimeo = new \Vimeo\Vimeo(CLIENT_ID, CLIENT_SECRET);

Getting Unauthenticated Tokens

You can perform requests to the Vimeo API without having the user logged in and give permission to your app. You can do that by acquiring unauthenticated tokens using the clientCredentials method in the Vimeo library. This returns an access token which can be used for querying public data. The number of API endpoints which you can use with an unauthenticated token is fairly limited so you won’t be using it in this tutorial.

$app->get('/token', function() use ($app, $vimeo) {

    $token = $vimeo->clientCredentials();

    echo $token['body']['access_token'];

});

Logging In

Here’s the login route. This allows the user to give permission to your app so that the app can access the user’s private data and perform requests on behalf of the user.

$app->get('/login', function () use ($app, $vimeo) {

    if($app->request->get('code') && $app->request->get('state') == $_SESSION['state']){

        $code = $app->request->get('code');

        $token = $vimeo->accessToken($code, REDIRECT_URI);

        $access_token = $token['body']['access_token'];
        $vimeo->setToken($access_token);

        $_SESSION['user.access_token'] = $access_token;

        $page_data = array(
            'user' => $token['body']['user']
        );

    }else{

        $scopes = array('public', 'private');
        $state = substr(str_shuffle(md5(time())), 0, 10);
        $_SESSION['state'] = $state;

        $url = $vimeo->buildAuthorizationEndpoint(REDIRECT_URI, $scopes, $state);

        $page_data = array(
            'url' => $url
        );
    }

    $app->render('login.php', $page_data);

});

Breaking it down, you first check if the code and the state are passed along as query parameters. For added security, you also check if the state is the same as the state that was previously saved in the session.

if($app->request->get('code') && $app->request->get('state') == $_SESSION['state']){
    ...   
}

If the condition above returns true for both, proceed with exchanging the code and the redirect URI for the access token. You can do that by calling the accessToken method in the Vimeo library. Next, extract the access token from the result that was returned and then call the setToken method to set it as the access token. Also store the access token in the session so you can access it later. Lastly, create an array that stores the data which you will pass to the view later on. In this case, it’s the user details.

$code = $app->request->get('code');

$token = $vimeo->accessToken($code, REDIRECT_URI);

$access_token = $token['body']['access_token'];
$vimeo->setToken($access_token);

$_SESSION['user.access_token'] = $access_token;

$page_data = array(
    'user' => $token['body']['user']
);

If the condition returns false, construct the URL that will lead the user to the Vimeo page where they can give permission to the app to do specific tasks. In this case, you’re only specifying public and private for the scopes. This means that the app can only have access to public and private user data. There are also others such as upload which allows the app to upload videos to Vimeo, or the interact permission which allows the app to interact with a video on behalf of the user. Examples of such interactions includes liking, commenting or adding the video to the watch list.

Going back to the code, create the state whose primary purpose is to add a security layer on redirects. As you have seen earlier, this is used to check if the same state is present on the query parameters that is passed along in the redirect from Vimeo to the redirect URL that you specified. Just pass this URL as the data for the page.

$scopes = array('public', 'private');
$state = substr(str_shuffle(md5(time())), 0, 10);
$_SESSION['state'] = $state;

$url = $vimeo->buildAuthorizationEndpoint(REDIRECT_URI, $scopes, $state);

$page_data = array(
    'url' => $url
);

Finally, render the login view.

$app->render('login.php', $page_data);

Here’s the login view (templates/login.php):

{% if url %}
<a href="{{ url }}">login to vimeo</a>
{% else %}
<h1>Hello {{ user.name }}!</h1>
<h2>websites</h2>
<ul>
{% for website in user.websites %}
    <li>
        <a href="{{ website.link }}">{{ website.name }}</a>
    </li>
{% endfor %}
</ul>
{% endif %}

From the above code, you can see that we’re just checking if the URL exists. If so, then output the authorization link. If it doesn’t, then greet the user and list their websites. When the authorization link is clicked by the user, they will be redirected to a Vimeo page where they can check what specific scopes they wish to allow. After clicking on ‘allow’, the user will be redirected to the redirect URL that you specified. The unique code and state will be passed as a query parameter in that redirect URL which you can then exchange for an access token.

vimeo auth

Getting the User Feed

You can get the user feed by making a request to the /me/feed endpoint. You can also pass in an optional parameter named per_page. This allows you to control the number of rows returned in the response. If this parameter is not specified, it uses the default one which is 25. After that, extract the body of the response and set it as the data to be passed to the view.

$app->get('/me/feed', function () use ($app, $vimeo) {

    $vimeo->setToken($_SESSION['user.access_token']);
    $response = $vimeo->request('/me/feed', array('per_page' => 10));

    $page_data = $response['body'];

    $app->render('feed.php', $page_data);

});

Here’s the code for feed.php. What it does is loop through all the feed items and then shows a thumbnail image which represents the video, the link to the actual video on Vimeo, the description and the tags attached to that video.

<h1>User Feed</h1>
{% for feed in data %}
    <li>
        <img src="{{ feed.clip.pictures.sizes[0]['link'] }}" alt="{{ feed.clip.name }}">
        <div>
            <a href="{{ feed.clip.link }}">{{ feed.clip.name }}</a>
        </div>
        <p>
            {{ feed.clip.description }}
        </p>
        <div>
            {% for tag in feed.clip.tags %}
            <span>{{ tag.name }}</span>
            {% endfor %}
        </div>
    </li>
{% endfor %}

Searching for Videos

The Vimeo API also allows you to search for videos by using a query. In the code below, initialize the page data to an empty array. If a query is present as a query parameter in the request URL, use it as the query for the /videos endpoint. You then pass this query along with the API results as the data for the videos.php view.

$app->get('/videos', function () use ($app, $vimeo) {

    $page_data = array();

    if($app->request->get('query')){

        $vimeo->setToken($_SESSION['user.access_token']);
        $query = $app->request->get('query');
        $response = $vimeo->request('/videos', array('query' => $query));

        $page_data = array(
            'query' => $query,
            'results' => $response['body']
        );
    }

    $app->render('videos.php', $page_data);

});

For videos.php, create a form that has the text field that the user can use to enter their query, and a button for submitting the query.

<form>
    <input type="text" name="query" value="{{ query }}">
    <button type="submit">Search</button>
</form>

After that, output the search results. If there is a value in the results item in the page data that was passed in earlier, loop through it and show the thumbnail for the video. This is usually the first image in the array of pictures that the API returns. So accessing the image at index 0 and extracting its link allows you to get the first item. Next, output the link to the video, using the name of the video as the text. Finally output a link to the user who uploaded the video and show the video description. If the results variable isn’t available, then simply output that there are no results.

<h1>Search Results</h1>
<div>
{% if results %}
<ul>    
{% for row in results.data %}
    <li>
        <img src="{{ row.pictures.sizes[0]['link'] }}" alt="{{ row.name }}">
        <div>
            <a href="{{ row.link }}">{{ row.name }}</a>
        </div>
        <div>
            by: <a href="{{ row.user.link }}">{{ row.user.name }}</a>
        </div>
        <p>
            {{ row.description }}
        </p>
    </li>
{% endfor %}
</ul>
{% else %}
    No search results.
{% endif %} 
</div>

Conclusion

In this part, we used the Vimeo API to build a rudimentary video application with Silex and Twig. We added login and user feed functionality and wrapped it all up with a video searching feature. You can check out the code used in this article in this Github repo.

If your interest is piqued, consider joining us in the followup post which will expand upon the basics presented here and add in likes, watchlists, and video uploads. Stay tuned!

  • http://www.adriansandu.com Adrian SANDU

    It’s always nice to see new way to interact with various popular APIs. Good job!

Recommended

Learn Coding Online
Learn Web Development

Start learning web development and design for free with SitePoint Premium!

Get the latest in PHP, once a week, for free.