在YouTube上为用户的“稍后观看”播放列表添加视频

17

目标是使用YouTube API创建一个稍后观看按钮。当用户点击该按钮时,视频将保存到用户的“稍后观看”播放列表中。类似于在您自己的网站上实现Facebook点赞按钮的方式。

到目前为止,我们在API文档中有两个官方条目:

并且我们在API文档中有许多PHP代码示例

如何使用PHP或/和javascript实现这一目标?

3个回答

20
Watch Later 播放列表的 ID 为 WL。您可以像添加其他 YouTube 播放列表一样将视频添加到此播放列表中。
首先,您需要前往 Google 开发者控制台
  • 为您的项目启用 YouTube 数据 API
  • 生成一个 Oauth Client ID
然后,您可以使用下面的代码进行身份验证,检索具有 https://www.googleapis.com/auth/youtube 范围的访问令牌,然后将视频添加到您的稍后观看播放列表中。
对于以下 Javascript 和 PHP 示例,在按下按钮时,如果用户尚未经过身份验证,则会登录该用户,并将视频添加到已经身份验证的用户的稍后观看播放列表中。

Javascript

这是基于谷歌提供的API示例这里

这里是一个带有源代码的实时演示(如下所示)

这里是一个fiddle。将你的客户端ID替换并添加为开发者控制台中的已授权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替换为您自己的客户端ID。
在API响应中,我检查以下状态码:
  • 409:视频已在播放列表中
  • 404:找不到视频

PHP

基于 google-api php示例

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

    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为其相应的值。此外,您需要在Google控制台中设置一个redirect_uri,在这里它将是http://localhost/watchlater.php
在PHP版本中,您可以看到我将视频id存储在$_SESSION["video"]中,以便在Google身份验证重定向到watchlater.php时立即添加它。
这是 Google 控制台中的一个屏幕,用于显示此项目的 Oauth 客户端 ID(适用于上述 JavaScript 和 PHP 版本):

enter image description here

请注意:
  • 对于Javascript版本:您需要CLIENT_ID并设置Javascript Origin。
  • 对于PHP版本:您需要CLIENT_IDCLIENT_SECRET,设置Javascript Origin和设置Redirect URI。

测试时请注意,如果您想重新添加视频,则手动删除视频可能需要一些时间。


1
非常感谢您的回复。我正在jsbin上进行测试。您能否更新这个答案,提供一个单一按钮的示例(类似于Facebook的“赞”按钮),当用户点击它时,它会将特定的YouTube视频添加到“稍后观看”播放列表中。如果用户未登录,则会加载一个弹出窗口,允许用户登录;然后将其添加到他们的播放列表中。到目前为止,我的问题是如何流畅地完成登录过程。 - Henrik Petterson
2
Authorized redirect URIs is not needed as you don't want to redirect the user to another page when the authentication is succesfull. You have to specify one Authorized JavaScript origins with the base URI as in my case https://bertrandmartel.github.io for this demo. For the fiddle link above you can use https://fiddle.jshell.net - Bertrand Martel
1
使用$('#myButton').text('Video added')只会影响页面上的一个按钮,如果您有多个按钮,则无法正常工作。我已经创建了这个jsFiddle:https://jsfiddle.net/q3L8n347/ - 目标是更改响应部分,使其仅触发单击的按钮,而不是页面上的所有按钮(通过仅针对类进行定位)。因此,我们需要像$(this).find('ma_youtube_watch_later_text').text('Video added');这样的东西,而不是$('.ma_youtube_watch_later_text').text('Video added');... 我解释清楚了吗? - Gary Woods
2
你可以将点击的按钮的引用存储为全局变量或通过回调函数传递它。这里提供了一个使用全局变量解决方案的示例。 - Bertrand Martel
1
你可以用想要的播放列表ID替换“WL”。它必须是有效的播放列表ID。你可以通过频道列表端点使用mine: truepart: contentDetails来查找它们。你将在relatedPlaylists中获得播放列表的列表,包括likesfavoritesuploadswatch laterwatch history。请查看此示例请求 - Bertrand Martel
显示剩余21条评论

1

获取“稍后观看”播放列表:

正如其他人指出的那样,YouTube不再允许这样做。

将视频添加到同一列表中相当简单:

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

您可以在此处找到JavaScript代码片段和更多信息:https://developers.google.com/youtube/v3/docs/playlistItems/insert

enter image description here


0

我不确定这会对你有多大帮助,因为我从未使用过Youtube的API。但是请看一下this关于如何使用Youtube的API v3获取“稍后观看”播放列表的答案。

然后你可以查看Youtube文档中的this,了解如何将元素插入到给定的播放列表中。

无论如何,自2016年9月15日修订版以来,我不确定这是否还可能(你可以试试):

参考列表中的第2.2点:

频道资源的contentDetails.relatedPlaylists.watchHistory和contentDetails.relatedPlaylists.watchLater属性现在分别包含值HL和WL,适用于所有频道。
需要明确的是,这些属性仅对已授权的用户检索有关其自己频道的数据时可见。即使对于已授权的用户检索有关其自己频道的数据,这些属性始终包含值HL和WL。因此,无法通过API检索观看历史记录和稍后观看的播放列表ID。
此外,请求检索频道观看历史记录或稍后观看播放列表的播放列表详细信息(playlists.list)或播放列表项(playlistItems.list)现在返回空列表。这适用于新值HL和WL以及您的API客户端可能已经存储的任何观看历史记录或稍后观看的播放列表ID。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接