将视频添加到 YouTube 上用户的收藏夹/点赞播放列表
Posted
技术标签:
【中文标题】将视频添加到 YouTube 上用户的收藏夹/点赞播放列表【英文标题】:Add video to user's Favorite/Like playlist on YouTube 【发布时间】:2017-08-30 23:00:16 【问题描述】:目的是使用 YouTube API 创建一个收藏/点赞按钮。当用户点击该按钮时,视频被保存到用户的收藏夹/点赞播放列表中。
就像您在自己的网站上实现 Facebook 点赞按钮时的工作原理一样。
这本质上是Bertrand Martel 在我之前的question 上发布的出色解决方案的后续问题,我们旨在将视频添加到“稍后观看”播放列表中。
这个特定功能的工作代码是:
<!-- 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://***.com/a/42561941/1649673
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 code samples。我们还有一些关于adding a video to playlist 的文档。
如何使用 PHP 或/和 javascript 来实现?
【问题讨论】:
【参考方案1】:您可以使用以下参数找到带有频道列表端点的 Like & Favorite 播放列表 ID(检查 this sample request):
mine: true,
part: 'contentDetails'
您将获得relatedPlaylists
中的播放列表列表,包括likes
、favorites
、uploads
、watch later
和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"
]
对于 WatchLater 和 WatchHistory,所有用户(分别为 WL 和 HL)的 playlistId 相同
您可以在 JavaScript 中使用 gapi.client.youtube.channels.list
调用频道列表端点,就像调用播放列表插入 API 一样。
然后,您可以使用 playlistId 将您的视频插入到另一个播放列表中,而不是稍后观看。
在以下代码中,您将找到 3 个按钮,用于将不同的视频添加到 Watch Later
播放列表、Like
播放列表和 Favorite
播放列表
Javascript
Here 是带有source code 的现场演示(如下)
Here 是一个小提琴。替换您的客户端 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>
用您自己的客户 ID 替换 OAUTH2_CLIENT_ID
在 API 响应中,会检查状态代码以防找不到视频 (404
)。如果视频已经在播放列表中,则返回409
状态代码,但仅用于稍后观看的播放列表(将现有视频添加到喜欢/收藏的播放列表不会改变任何内容)
PHP
和之前一样,基于google-api php sample:
安装作曲家:见instructions安装 google-api 客户端:
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 版本,请注意除了当前会话 $_SESSION["video"]
中的视频 id 之外,目标操作也存储在 $_SESSION["action"]
中,以便能够确定要使用哪个播放列表。使用$youtube->channels->listChannels
的频道列表端点检索播放列表。
请注意,视频可能需要一些时间才能出现在播放列表中(有时需要几秒钟)
【讨论】:
感谢您花时间拼凑起来,谢谢。这周我要测试一下。我有一个问题。是否可以同时将视频添加到多个播放列表?例如,在类型数据属性值中,我们添加一个类似data-type="WL, likes"
的数组,并将视频添加到这些播放列表中。不确定 YouTube 是否有某种形式的屏蔽。
我不这么认为,playlist insert endpoint 没有实现批量插入(playlistId
字段需要一个对象,使用数组时只考虑第一项) .您将需要进行 2 次连续的播放列表插入调用
非常感谢您的解释。过去几天我一直处于非活动状态,未能按时奖励这笔赏金。我已通过this meta thread 与社区联系,希望能为您获得剩余积分!另外,我应该注意,我没有在我的本地环境中测试过这段代码(本周晚些时候会这样做),但从你之前的回答来看,它肯定会相应地发挥作用。
别担心 :) 保持您的声誉,以备日后需要。如果您对此代码有任何问题,请告诉我
@BertrandMartel 您的代码中有错误。 else if (response.code == 409)
和其他仅适用于 WL
播放列表。它不适用于favorites
和likes
播放列表。因此,即使视频被添加到用户收藏的播放列表中,他们也会看到$(button).val('Video added');
。您可以在自己的demo 中轻松看到此问题,只需单击两次喜欢或收藏一个...您有解决此问题的方法吗?除了这个问题,这个答案是一个怪物。恭喜你把它放在一起。如果可以的话 +1000!以上是关于将视频添加到 YouTube 上用户的收藏夹/点赞播放列表的主要内容,如果未能解决你的问题,请参考以下文章
jScrollPane + 嵌入式 Youtube 视频悬停
将 onPause/onResume 添加到 Ionic 2 页面中的 Youtube 视频
允许用户使用 youtube API v3 将视频上传到我的频道
如何使用javascript(或jQuery)将youtube视频添加到iframe(基于Web的RTE)