skip to Main Content

The aim is to create a Watch Later button using the YouTube API. When a user clicks the button, the video is saved into the user’s Watch Later playlist. Similar to how it works when you implement a Facebook like button on your own site.

So far, we have two official entries in the API documentations:

And we have a number of PHP code samples on the API docs.

How can this be achieved using either PHP or/and javascript?

3

Answers


  1. I don’t know if this will help you much since I never worked with Youtube’s API. But have a look at this answer on how to get the Watch Later playlist using Youtube’s API v3.

    Then you can take a look this, from Youtube docs, for inserting an element into a given playlist.

    ANYWAY I’m not sure this is possible anymore (you can give it a try) since September 15, 2016 revision:

    Referring to point 2.2 in the list:

    The channel resource’s contentDetails.relatedPlaylists.watchHistory and contentDetails.relatedPlaylists.watchLater properties now contain values of HL and WL, respectively, for all channels.

    To be clear, these properties are only visible to an authorized user retrieving data about the user’s own channel. The properties always contain the values HL and WL, even for an authorized user retrieving data about the user’s own channel. Thus, the watch history and watch later playlist IDs cannot be retrieved via the API.

    In addition, requests to retrieve playlist details (playlists.list) or playlist items (playlistItems.list) for a channel’s watch history or watch later playlist now return empty lists. This behavior is true for the new values, HL and WL, as well as for any watch history or watch later playlist IDs that your API Client may have already stored.

    Login or Signup to reply.
  2. The Watch Later playlist is the playlist with id WL. You can add a video to this playlist the same way as the other Youtube playlists.

    You will first need to go to your Google developer console :

    • enable Youtube Data API for your project
    • generate an Oauth Client ID

    Then you can use the code below which will authenticate, retrieve an access token with https://www.googleapis.com/auth/youtube scope and then add a video to your watch later playlist.

    For the following Javascript & PHP samples, when a button is pressed, it logs-in the user if not already authenticated and add the video to the watch later playlist of the authenticated user.


    Javascript

    This is based on api-samples provided by Google here.

    Here is a live demo with the source code (as below)

    Here is a fiddle. Replace your client id and add as Authorized JavaScript origins in developer console : https://fiddle.jshell.net

    index.html :

    <!doctype html>
    <html>
    
    <head>
        <title>Add to Watch Later playlist</title>
        <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
        <style>
        .btn-tech {
            color: #2c3e50;
            border: solid 2px #2c3e50;
            background: transparent;
            transition: all 0.3s ease-in-out;
            margin: 20px;
            border-radius: 20% 20% 20% 20%;
        }
    
        .btn-tech:hover,
        .btn-tech:active,
        .btn-tech.active {
            color: #FFFFFF;
            background: #2c3e50;
            cursor: pointer;
        }
        </style>
    </head>
    
    <body>
        <div id="watch_later">
            <div id="buttons">
                <label>Enter Video ID you want to add to Watch Later playlist :
                    <input id="video-id" value='T4ZE2KtoFzs' type="text" />
                </label>
            </div>
            <div class="like">
                <a id="fb-link">
                    <span class="btn-tech fa-stack fa-3x">
                      <i class="fa fa-thumbs-up fa-stack-1x"></i>
                    </span>
                </a>
            </div>
            <div id="playlist-container">
                <span id="status"></span>
            </div>
            <p>
                <a href="https://www.youtube.com/playlist?list=WL">check your watch later playlist</a>
            </p>
        </div>
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
        <script>
        var OAUTH2_CLIENT_ID = '28993181493-c9o6hdll3di0ssvebfd4atf13edqfu9g.apps.googleusercontent.com';
        var OAUTH2_SCOPES = [
            'https://www.googleapis.com/auth/youtube'
        ];
        var init = false;
        googleApiClientReady = function() {
            gapi.auth.init(function() {
                window.setTimeout(checkAuth, 1);
            });
        }
    
        function checkAuth() {
            gapi.auth.authorize({
                client_id: OAUTH2_CLIENT_ID,
                scope: OAUTH2_SCOPES,
                immediate: true
            }, handleAuthResult);
        }
        // Handle the result of a gapi.auth.authorize() call.
        function handleAuthResult(authResult) {
    
            $('.like').off('click');
            $('.like').click(function(e) {
                if (authResult && !authResult.error) {
                    addVideoToPlaylist();
                } else {
                    init = true;
                    gapi.auth.authorize({
                        client_id: OAUTH2_CLIENT_ID,
                        scope: OAUTH2_SCOPES,
                        immediate: false
                    }, handleAuthResult);
                }
                return false;
            });
    
            if (authResult && !authResult.error) {
                // Authorization was successful. Hide authorization prompts and show
                // content that should be visible after authorization succeeds.
                $('.pre-auth').hide();
                $('.post-auth').show();
                loadAPIClientInterfaces();
    
                $('#add_to_wl').click(function(e) {
                    addVideoToPlaylist();
                });
            }
        }
    
        function loadAPIClientInterfaces() {
            gapi.client.load('youtube', 'v3', function() {
                if (init) {
                    init = false;
                    addVideoToPlaylist();
                }
            });
        }
        // Add a video ID specified in the form to the playlist.
        function addVideoToPlaylist() {
            addToPlaylist($('#video-id').val());
        }
        // Add a video to a playlist. The "startPos" and "endPos" values let you
        // start and stop the video at specific times when the video is played as
        // part of the playlist. However, these values are not set in this example.
        function addToPlaylist(id, startPos, endPos) {
            var details = {
                videoId: id,
                kind: 'youtube#video'
            }
            if (startPos != undefined) {
                details['startAt'] = startPos;
            }
            if (endPos != undefined) {
                details['endAt'] = endPos;
            }
            var request = gapi.client.youtube.playlistItems.insert({
                part: 'snippet',
                resource: {
                    snippet: {
                        playlistId: "WL",
                        resourceId: details
                    }
                }
            });
            request.execute(function(response) {
                console.log(response);
                if (!response.code) {
                    $('#status').html('<pre>Succesfully added the video : ' + JSON.stringify(response.result) + '</pre>');
                } else if (response.code == 409) {
                    $('#status').html('<p>Conflict : this video is already on your Watch Later playlist</p>');
                } else if (response.code == 404) {
                    $('#status').html('<p>Not Found : this video hasnt been found</p>');
                } else {
                    $('#status').html('<p>Error : code ' + response.code + '</p>');
                }
            });
        }
        </script>
        <script src="https://apis.google.com/js/client.js?onload=googleApiClientReady"></script>
    </body>
    
    </html>
    

    Replace OAUTH2_CLIENT_ID with your own client ID

    In the API response, I check the following status code :

    • 409 : the video already on playlist
    • 404 : the video isn’t found

    PHP

    Based on google-api php sample :

    • install composer : see instructions
    • install google-api client :

      composer require google/apiclient:~2.0
      

    The php script watchlater.php :

    <?php
    /**
     * Library Requirements
     *
     * 1. Install composer (https://getcomposer.org)
     * 2. On the command line, change to this directory (api-samples/php)
     * 3. Require the google/apiclient library
     *    $ composer require google/apiclient:~2.0
     */
    if (!file_exists(__DIR__ . '/vendor/autoload.php')) {
      throw new Exception('please run "composer require google/apiclient:~2.0" in "' . __DIR__ .'"');
    }
    require_once __DIR__ . '/vendor/autoload.php';
    session_start();
    
    $response = "";
    
    /*
     * You can acquire an OAuth 2.0 client ID and client secret from the
     * {{ Google Cloud Console }} <{{ https://cloud.google.com/console }}>
     * For more information about using OAuth 2.0 to access Google APIs, please see:
     * <https://developers.google.com/youtube/v3/guides/authentication>
     * Please ensure that you have enabled the YouTube Data API for your project.
     */
    $OAUTH2_CLIENT_ID = 'YOUR_CLIENT_ID';
    $OAUTH2_CLIENT_SECRET = 'YOUR_CLIENT_SECRET';
    
    $client = new Google_Client();
    $client->setClientId($OAUTH2_CLIENT_ID);
    $client->setClientSecret($OAUTH2_CLIENT_SECRET);
    $client->setScopes('https://www.googleapis.com/auth/youtube');
    
    $redirect = filter_var('http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'],
        FILTER_SANITIZE_URL);
    
    $client->setRedirectUri($redirect);
    // Define an object that will be used to make all API requests.
    $youtube = new Google_Service_YouTube($client);
    // Check if an auth token exists for the required scopes
    $tokenSessionKey = 'token-' . $client->prepareScopes();
    if (isset($_GET['code'])) {
      if (strval($_SESSION['state']) !== strval($_GET['state'])) {
        die('The session state did not match.');
      }
      $client->authenticate($_GET['code']);
      $_SESSION[$tokenSessionKey] = $client->getAccessToken();
      header('Location: ' . $redirect);
    }
    if (isset($_SESSION[$tokenSessionKey])) {
      $client->setAccessToken($_SESSION[$tokenSessionKey]);
    }
    // Check to ensure that the access token was successfully acquired.
    
    if ($client->getAccessToken()) {
      try {
    
        $videoId = "";
    
        if (isset($_GET['video'])){
        $videoId = $_GET['video'];
        }
        else if(isset($_SESSION['video'])){
          $videoId = $_SESSION['video'];
        }
    
        if(isset($videoId) && !isset($_GET['state'])) {
    
          file_put_contents('php://stderr', print_r("adding video to watch later playlist " . $videoId . "n", TRUE));
    
          $playlistId = "WL";
          // 5. Add a video to the playlist. First, define the resource being added
          // to the playlist by setting its video ID and kind.
          $resourceId = new Google_Service_YouTube_ResourceId();
          $resourceId->setVideoId($videoId);
          $resourceId->setKind('youtube#video');
    
          // Then define a snippet for the playlist item. Set the playlist item's
          // title if you want to display a different value than the title of the
          // video being added. Add the resource ID and the playlist ID retrieved
          // in step 4 to the snippet as well.
          $playlistItemSnippet = new Google_Service_YouTube_PlaylistItemSnippet();
          $playlistItemSnippet->setTitle('First video in the test playlist');
          $playlistItemSnippet->setPlaylistId($playlistId);
          $playlistItemSnippet->setResourceId($resourceId);
          // Finally, create a playlistItem resource and add the snippet to the
          // resource, then call the playlistItems.insert method to add the playlist
          // item.
          $playlistItem = new Google_Service_YouTube_PlaylistItem();
          $playlistItem->setSnippet($playlistItemSnippet);
    
          $playlistItemResponse = $youtube->playlistItems->insert(
              'snippet,contentDetails', $playlistItem, array());
    
          $response = json_encode($playlistItem);
    
          $_SESSION['video'] = "";
      }
      else{
        file_put_contents('php://stderr', print_r("no video was specified", TRUE));
      }
    
      } catch (Google_Service_Exception $e) {
        $response = htmlspecialchars($e->getMessage());
      } catch (Google_Exception $e) {
        $response = htmlspecialchars($e->getMessage());
      }
      $_SESSION[$tokenSessionKey] = $client->getAccessToken();
    } else {
    
      if(isset($_GET['video'])){
    
        $_SESSION["video"] = $_GET['video'];
    
        // If the user hasn't authorized the app, initiate the OAuth flow
        $state = mt_rand();
        $client->setState($state);
        $_SESSION['state'] = $state;
        $authUrl = $client->createAuthUrl();
        header('Location: ' . $authUrl);
      }
    }
    ?>
    
    <!doctype html>
    <html>
    <head>
     <title>Add to Watch Later playlist</title>
        <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
        <style>
        .btn-tech {
            color: #2c3e50;
            border: solid 2px #2c3e50;
            background: transparent;
            transition: all 0.3s ease-in-out;
            margin: 20px;
            border-radius: 20% 20% 20% 20%;
        }
    
        .btn-tech:hover,
        .btn-tech:active,
        .btn-tech.active {
            color: #FFFFFF;
            background: #2c3e50;
            cursor: pointer;
        }
        </style>
    </head>
    <body>
       <div id="watch_later">
            <form id="form" action="watchlater.php"">
    
              <label>Enter Video ID you want to add to Watch Later playlist :
                    <input id="video-id" name="video" value='T4ZE2KtoFzs' type="text" />
              </label>
    
              <div>
                  <span class="btn-tech fa-stack fa-3x" onclick="javascript:document.getElementById('form').submit();">
                    <i class="fa fa-thumbs-up fa-stack-1x"></i>
                  </span>
              </div>
            </form>
            <div id="playlist-container">
              <?php echo $response ?>
            </div>
            <p>
                <a href="https://www.youtube.com/playlist?list=WL">check your watch later playlist</a>
            </p>
        </div>
    </body>
    </html>
    

    Replace $OAUTH2_CLIENT_ID and $OAUTH2_CLIENT_SECRET with their respective value. Also, you have to set a redirect_uri in google console, here it will be http://localhost/watchlater.php

    In the PHP version, you can see that I store video id in $_SESSION["video"] to be able to add it immediately when google authentication redirect to watchlater.php


    Here is a screen of google console Oauth Client ID for this project (valid for the Javascript & PHP version above) :

    enter image description here

    Note that :

    • for the Javascript version : you need CLIENT_ID and set Javascript Origin
    • for the PHP version : you need CLIENT_ID, CLIENT_SECRET, set Javascript Origin and set Redirect URI

    Note for testing, I noticed that it can take some time to delete the video when doing it manually if you want to re-add it again

    Login or Signup to reply.
  3. Retrieving "Watch Later" playlist:

    As pointed out by others, YouTube no longer allow this

    Adding a video to that same list is rather straight forward though:

    curl --request POST 
      'https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&key=[YOUR_API_KEY]' 
      --header 'Authorization: Bearer [YOUR_ACCESS_TOKEN]' 
      --header 'Accept: application/json' 
      --header 'Content-Type: application/json' 
      --data '{"snippet":{"playlistId":"WL","position":0,"resourceId":{"kind":"youtube#video","videoId":"M7FIvfx5J10"}}}' 
      --compressed
    

    You can find Javascript code snippet and more here: https://developers.google.com/youtube/v3/docs/playlistItems/insert

    enter image description here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search