将视频添加到用户在YouTube上的“收藏/喜欢”播放列表中

13

旨在使用YouTube API创建一个收藏/喜欢的按钮。当用户点击按钮时,视频将保存到用户的收藏/喜欢播放列表中。

就像你在自己的网站上实现Facebook喜欢按钮一样。

这是对我之前的问题所提出的Bertrand Martel绝佳解决方案的跟进问题。

此特定功能的工作代码为:

<!-- button 1 -->
<button type="submit" data-youtube-video-id="EH3gqI2NAiE" value="Watch Later" class="ma_youtube_watch_later" name="send">
  <div class="ma_youtube_watch_later_text">Watch Later</div>
</button>

<!-- button 2 -->
<button type="submit" data-youtube-video-id="0EMmKIIF-zE" value="Watch Later" class="ma_youtube_watch_later" name="send">
  <div class="ma_youtube_watch_later_text">Watch Later</div>
</button>

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script>
  // By Bertrand Martel: https://dev59.com/W1gQ5IYBdhLWcg3wl1F3#42561941
  var OAUTH2_CLIENT_ID = '28993181493-c9o6hdll3di0ssvebfd4atf13edqfu9g.apps.googleusercontent.com';
  var OAUTH2_SCOPES = [
    'https://www.googleapis.com/auth/youtube'
  ];
  var init = false;
  var youtube_video_id = '';

  var button = null;

  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) {

    jQuery('.ma_youtube_watch_later').off('click');
    jQuery('.ma_youtube_watch_later').click(function(e) {

      button = this;

      var youtube_video_id = jQuery(this).attr("data-youtube-video-id");

      // Add a video ID specified in the form to the playlist.
      function addVideoToPlaylist() {
        //addToPlaylist(jQuery('#video-id').val());
        addToPlaylist(youtube_video_id);
      }

      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.
      jQuery('.pre-auth').hide();
      jQuery('.post-auth').show();
      loadAPIClientInterfaces();

      jQuery('#add_to_wl').click(function(e) {

        button = this;

        addVideoToPlaylist(self);
      });
    }
  }

  function loadAPIClientInterfaces() {
    gapi.client.load('youtube', 'v3', function() {
      if (init) {
        init = false;
        addVideoToPlaylist();
      }
    });
  }

  // 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) {
        //jQuery('#status').html('<pre>Succesfully added the video : ' + JSON.stringify(response.result) + '</pre>');

        // change button text
        $(button).text('Video added');

      } else if (response.code == 409) {

        //jQuery('#status').html('<p>Conflict : this video is already on your Watch Later playlist</p>');

        // change button text
        $(button).text('Already added');

      } else if (response.code == 404) {
        //jQuery('#status').html('<p>Not Found : this video hasnt been found</p>');

        // change button text
        $(button).text('Video not found');

      } else {
        //jQuery('#status').html('<p>Error : code ' + response.code + '</p>');

        // change button text
        $(button).text('Error: Try again');

      }
    });
  }

</script>
<script src="https://apis.google.com/js/client.js?onload=googleApiClientReady"></script>

我们在API文档中有一些PHP代码示例。我们还有一些有关向播放列表添加视频的文档。

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

1个回答

13

您可以使用以下参数在频道列表端点中查找喜欢和收藏的播放列表ID(请检查此示例请求):

{
    mine: true,
    part: 'contentDetails'
}

您将在relatedPlaylists中获得播放列表的列表,包括喜欢收藏上传稍后观看观看历史记录

{
    "kind": "youtube#channelListResponse",
    "etag": "\"m2yskBQFythfE4irbTIeOgYYfBU/S1x68O9aSpvmndklrnSwKw_yYdE\"",
    "pageInfo": {
        "totalResults": 1,
        "resultsPerPage": 1
    },
    "items": [{
        "kind": "youtube#channel",
        "etag": "\"m2yskBQFythfE4irbTIeOgYYfBU/ura_vsrPt5tCZkjjGbH3ihN3Bq4\"",
        "id": "UCnQt5EmYRfX1uVYtwPNj7Dg",
        "contentDetails": {
            "relatedPlaylists": {
                "likes": "LLnQt5EmYRfX1uVYtwPNj7Dg",
                "favorites": "FLnQt5EmYRfX1uVYtwPNj7Dg",
                "uploads": "UUnQt5EmYRfX1uVYtwPNj7Dg",
                "watchHistory": "HL",
                "watchLater": "WL"
            }
        }
    }]
}

对于WatchLater和WatchHistory,播放列表ID对于所有用户都相同(分别为WL和HL)。
您可以使用gapi.client.youtube.channels.list以与调用播放列表插入API相同的方式在Javascript中调用频道列表端点。
然后,使用播放列表ID,您可以将视频插入到不同于“稍后观看”的播放列表中。
在以下代码中,您将找到3个按钮,可将不同的视频添加到“稍后观看”播放列表、喜欢的播放列表和收藏的播放列表中。

Javascript

此处是一个带有源代码的实时演示(如下所示)。

这里是一个fiddle。 请替换您的客户端ID并将其添加为开发人员控制台中的已授权JavaScript来源:https://fiddle.jshell.net

<!doctype html>
<html>

<head>
    <title>Add to multiple playlists</title>
</head>

<body>
    <input type="submit" data-youtube-video-id="EH3gqI2NAiE" data-type="WL" value="Add to Watch Later playlist" class="yt_add_to_playlist" />
    <input type="submit" data-youtube-video-id="0EMmKIIF-z" data-type="likes" value="Add to Like playlist" class="yt_add_to_playlist" />
    <input type="submit" data-youtube-video-id="T4ZE2KtoFzs" data-type="favorites" value="Add to Favorite playlist" class="yt_add_to_playlist" />
    <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;
    var button = null;

    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) {

        jQuery('.yt_add_to_playlist').off('click');
        jQuery('.yt_add_to_playlist').click(function(e) {

            button = this;

            if (authResult && !authResult.error) {
                addToPlaylist($(this).attr("data-youtube-video-id"), $(this).attr("data-type"));
            } 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.
            jQuery('.pre-auth').hide();
            jQuery('.post-auth').show();
            loadAPIClientInterfaces();

            jQuery('#add_to_wl').click(function(e) {
                button = this;
                addToPlaylist($(this).attr("data-youtube-video-id"), $(this).attr("data-type"));
            });
        }
    }

    function loadAPIClientInterfaces() {
        gapi.client.load('youtube', 'v3', function() {
            if (init) {
                init = false;
                addToPlaylist($(button).attr("data-youtube-video-id"), $(button).attr("data-type"));
            }
        });
    }

    function addToPlaylist(videoId, playlistType) {

        console.log("add to playlist type : " + playlistType);

        if (playlistType != "WL" && playlistType != "HL") {

            var request = gapi.client.youtube.channels.list({
                mine: true,
                part: 'contentDetails'
            });

            request.execute(function(response) {
                var playlistId = response.result.items[0].contentDetails.relatedPlaylists[playlistType];

                if (typeof playlistId != 'undefined') {
                    console.log("found playlist id : " + playlistId);
                    insertToPlaylist(videoId, playlistId);
                } else {
                    console.log("playlist not found");
                }

            });

        } else {
            insertToPlaylist(videoId, playlistType);
        }
    }

    function insertToPlaylist(videoId, playlistId) {

        var details = {
            videoId: videoId,
            kind: 'youtube#video'
        };
        var request = gapi.client.youtube.playlistItems.insert({
            part: 'snippet',
            resource: {
                snippet: {
                    playlistId: playlistId,
                    resourceId: details
                }
            }
        });

        request.execute(function(response) {
            console.log(response);
            if (!response.code) {
                $(button).val('Video added');
            } else if (response.code == 409) {
                $(button).val('Already added');
            } else if (response.code == 404) {
                $(button).val('Video not found');
            } else {
                $(button).val('Error: Try again');
            }
        });
    }
    </script>
    <script src="https://apis.google.com/js/client.js?onload=googleApiClientReady"></script>
</body>

</html>

请将OAUTH2_CLIENT_ID替换为您自己的客户端ID。
在API响应中,如果视频未找到(404),则检查状态码。如果视频已在播放列表中,但仅适用于稍后观看播放列表,则返回409状态码(尽管将现有视频添加到喜欢/收藏播放列表中不会改变任何内容)。

PHP

与之前相同,基于google-api php示例
  • install composer : see instructions
  • install google-api client :

    composer require google/apiclient:~2.0
    

这个php脚本 multi-playlist.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($_GET['action'])){
      $action = $_GET['action'];
    }
    else if(isset($_SESSION['action'])){
      $action = $_SESSION['action'];
    }

    if(isset($videoId) && isset($action) && !isset($_GET['state'])) {

      file_put_contents('php://stderr', print_r("adding video to watch later playlist " . $videoId . "\n", TRUE));

      if ($action == "Add to Watch Later playlist") {
        $playlistId = "WL";
      }
      else {
          $listResponse = $youtube->channels->listChannels("contentDetails", array(
              'mine' => true
          ));

          if (!empty($listResponse)) {
            if ($action == "Add to Like playlist"){
              $playlistId = $listResponse['items'][0]['contentDetails']['relatedPlaylists']['likes'];
            }
            else if ($action == "Add to Favorite playlist"){
              $playlistId = $listResponse['items'][0]['contentDetails']['relatedPlaylists']['favorites'];
            }
          }
      }

      if (isset($playlistId)){

        // 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);
      }
      else{
        $response = "no playlist selected";
      }

      $_SESSION['video'] = "";
      $_SESSION["action"] = "";
  }
  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'];
    $_SESSION["action"] = $_GET['action'];

    // 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 playlists</title>
</head>
<body>
    <div>
        <form id="form" action="multi-playlist.php"">
            <input type="hidden"  name="video" value="EH3gqI2NAiE">
            <input name="action" type="submit" value="Add to Watch Later playlist" />
            <input name="action" type="submit" value="Add to Like playlist" />
            <input name="action" type="submit" value="Add to Favorite playlist" />
        </form>
        <div>
          <?php echo $response ?>
        </div>
    </div>
</body>
</html>

针对此PHP版本,需要注意的是除了当前会话中的视频ID $_SESSION["video"],目标操作也存储在 $_SESSION["action"] 中,以便确定使用哪个播放列表。使用$youtube->channels->listChannels终端节点检索播放列表。


请注意,视频出现在播放列表中可能需要一些时间(有时需要几秒钟)。


2
感谢您抽出时间来整理这个,非常感谢。我将在本周进行测试。我有一个问题。是否可以同时将视频添加到多个播放列表中?例如,在类型数据属性值中,我们添加一个类似于data-type="WL, likes"的数组,然后将视频添加到这些播放列表中。不确定YouTube是否会对此进行某种形式的阻止。 - Henrik Petterson
我认为不行,播放列表插入端点没有实现批量插入(当使用数组时,需要一个对象来填充playlistId字段,但它只考虑第一个项目)。您需要进行两次连续的播放列表插入调用。 - Bertrand Martel
1
不用担心 :) 保持你的声誉,以防以后需要。如果您对此代码有任何问题,请告诉我。 - Bertrand Martel
1
@BertrandMartel 你的代码有一个bug。else if (response.code == 409)和其他类似的代码只适用于“WL”播放列表,而不适用于“favorites”和“likes”播放列表。因此,即使视频已添加到用户的收藏夹播放列表中,他们仍将看到 $(button).val('Video added');。您可以在自己的演示中轻松看到这个问题,只需两次点击喜欢或收藏即可...您有解决这个问题的方法吗?除了这个问题,这个答案真是太棒了。如果可以的话,我会加1000分! - Christine Cooper
我已经提到过:如果视频已经在稍后观看的播放列表中,将返回409状态代码(尽管将现有视频添加到喜欢/收藏的播放列表中不会改变任何内容)。如果您想检查视频是否已经在播放列表中,您必须调用playlistItem.list,请参见此处的示例。如果请求返回404,则视频不在播放列表中。 - Bertrand Martel
显示剩余2条评论

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