Add video to user's Favorite/Like playlist on YouTube

后端 未结 1 684
离开以前
离开以前 2021-02-04 09:43

The aim is to create a Favorite/Like button using the YouTube API. When a user clicks the button, the video is saved into the user\'s Favorite/Like playlist.

Just like

相关标签:
1条回答
  • 2021-02-04 10:00

    You can find Like & Favorite playlist ID with channel list endpoint with the following parameters (check this sample request) :

    {
        mine: true,
        part: 'contentDetails'
    }
    

    You will get the list of playlists in relatedPlaylists including likes, favorites, uploads, watch later and watch history.

    {
        "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"
                }
            }
        }]
    }
    

    For WatchLater & WatchHistory, the playlistId is the same for all users (respectively WL & HL)

    You can call channel list endpoint in Javascript with gapi.client.youtube.channels.list the same way as you've called the playlist insert API.

    Then with the playlistId you can insert your video to another playlist than Watch Later.

    In the following code, you will find 3 buttons to add different videos to Watch Later playlist, Like playlist & Favorite playlist


    Javascript

    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

    <!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>
    

    Replace OAUTH2_CLIENT_ID with your own client ID

    In the API response, the status code is checked in case the video is not found (404). The 409 status code is returned if the video is already in the playlist but only for watch later playlist (adding an existing video to like/favorite playlist will not changed anything though)


    PHP

    The same as before, based on google-api php sample :

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

      composer require google/apiclient:~2.0
      

    The php script 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>
    

    For this PHP version, note that in addition to the video id in the current session $_SESSION["video"], the target action is also stored in $_SESSION["action"] to be able to determine which playlist to use. Playlists are retrieved with channel list endpoint with $youtube->channels->listChannels.


    Note that it can take some time for the video to appear in the playlists (sometimes a few seconds)

    0 讨论(0)
提交回复
热议问题