Добавить видео в список воспроизведения "Смотреть позже" на YouTube

Цель состоит в создании кнопки Watch Later с использованием API YouTube. Когда пользователь нажимает кнопку, видео сохраняется в списке воспроизведения Watch Watch. Подобно тому, как это работает, когда вы реализуете кнопку "Facebook" на своем собственном сайте.

До сих пор у нас есть две официальные записи в документах API:

И у нас есть несколько образцов кода PHP в документах API.

Как это можно достичь с помощью PHP или/или javascript?

Ответ 1

Плейлист "Watch Later" - это список воспроизведения с id WL. Вы можете добавить видео в этот плейлист так же, как и другие плейлисты Youtube.

Сначала вам нужно перейти в консоль разработчика Google:

  • включить API данных Youtube для вашего проекта.
  • сгенерируйте Oauth Client ID

Затем вы можете использовать приведенный ниже код, который будет аутентифицироваться, получить токен доступа с областью https://www.googleapis.com/auth/youtube, а затем добавить видео в список воспроизведения позже.

Для следующих образцов Javascript и PHP, когда нажата кнопка, он регистрирует пользователя, если он еще не прошел проверку подлинности, и добавляет видео в список воспроизведения позже, чем у аутентифицированного пользователя.


Javascript

Это основано на api-образцах, предоставленных Google здесь.

Здесь - живая демонстрация с исходным кодом (как показано ниже)

Здесь - скрипка. Замените идентификатор клиента и добавьте его как авторизованное начало JavaScript в консоли разработчика: 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>

Замените OAUTH2_CLIENT_ID на свой собственный идентификатор клиента

В ответе API я проверяю следующий код состояния:

  • 409: видео уже в списке воспроизведения
  • 404: видео не найдено.

PHP

На основе google-api php sample:

  • установить композитор: см. инструкции
  • установить клиент google-api:

    composer require google/apiclient:~2.0
    

PHP скрипт 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>

Замените $OAUTH2_CLIENT_ID и $OAUTH2_CLIENT_SECRET своим соответствующим значением. Кроме того, вы должны установить redirect_uri в консоли Google, здесь будет http://localhost/watchlater.php

В версии PHP вы можете увидеть, что я храню идентификатор видео в $_SESSION["video"], чтобы иметь возможность добавлять его немедленно, когда аутентификация Google переадресовывается на watchlater.php


Вот экран консоли Google Oauth Client ID для этого проекта (действительный для версии Javascript и PHP выше):

enter image description here

Обратите внимание, что:

  • для версии Javascript: вам нужно CLIENT_ID и установить Javascript Origin
  • для версии PHP: вам нужно CLIENT_ID, CLIENT_SECRET, установить Javascript Origin и установить URI перенаправления

Примечание для тестирования я заметил, что при удалении видео может потребоваться некоторое время, если вы захотите повторно добавить его снова

Ответ 2

Я не знаю, поможет ли это вам, поскольку я никогда не работал с Youtube API. Но посмотрите этот ответ на вопрос о том, как получить плейлист Watch Later с помощью Youtube API v3.

Затем вы можете посмотреть this из документов Youtube для вставки элемента в данный список воспроизведения.

ANYWAY Я не уверен, что это возможно больше (вы можете попробовать), так как 15 сентября 2016 г.:

Ссылаясь на пункт 2.2 в списке:

Содержимое ресурса каналаDetails.relatedPlaylists.watchHistory и contentDetails.relatedPlaylists.watchLater теперь содержат значения HL и WL, соответственно, для всех каналов.

Чтобы быть ясными, эти свойства видны только авторизованному пользователю, который получает данные о собственном канале пользователя. Свойства всегда содержат значения HL и WL, даже для авторизованного пользователя, получающего данные о собственном канале пользователя. Таким образом, история просмотра и просмотр последующих идентификаторов списков воспроизведения не могут быть получены через API.

Кроме того, запросы на получение сведений о плейлисте (playlists.list) или элементов списка воспроизведения (playlistItems.list) для истории просмотра канала или просмотра более позднего списка воспроизведения теперь возвращают пустые списки. Это верно для новых значений, HL и WL, а также для любой истории просмотра или просмотра более поздних идентификаторов списков воспроизведения, которые ваш клиент API уже мог сохранить.