YouTube API v3 over HTTP POST:上传视频时无法设置片段(标题最终为“未知”)
Posted
技术标签:
【中文标题】YouTube API v3 over HTTP POST:上传视频时无法设置片段(标题最终为“未知”)【英文标题】:YouTube API v3 over HTTP POST: can't set snippet while uploading a video (title ends up as "unknown") 【发布时间】:2014-10-25 02:20:51 【问题描述】:我正在尝试允许用户从我的网站上传 YouTube 视频,但我没有使用 javascript API,因为用户需要能够将内容上传到我的频道,而不是使用他们自己的帐户,而我不能弄清楚如何使用 JS API 做到这一点。
无论如何,最终结果是我有一个 html 元素发布视频。视频被上传,但标题为“未知”且没有描述等。不知道我做错了什么。这是发送到 https://www.googleapis.com/upload/youtube/v3/videos?part=snippet,status&access_token=[accesstoken] 的 HTTP POST(如 multipart/form-data
)的有效负载:
------WebKitFormBoundaryqKACn63lpjqwi0sA
Content-Disposition: form-data; name="status[privacyStatus]"
unlisted
------WebKitFormBoundaryqKACn63lpjqwi0sA
Content-Disposition: form-data; name="snippet[title]"
Test Video Title
------WebKitFormBoundaryqKACn63lpjqwi0sA
Content-Disposition: form-data; name="snippet[description]"
Test video description
------WebKitFormBoundaryqKACn63lpjqwi0sA
Content-Disposition: form-data; name="videoFile"; filename="test_vide_upload.mp4"
Content-Type: video/mp4
------WebKitFormBoundaryqKACn63lpjqwi0sA--
我假设snippet
和status
字段的表单名称是错误的,但我尝试了各种选项,但无法正常工作。我还尝试发送带有 JSON 编码值 "snippet":"description":"Test video description","title":"Test Video Title","status":"privacyStatus":"unlisted"
的单个表单字段 data
,但这也不起作用。
我总是从 API 获得成功的 JSON 响应,带有 sn-p 和状态,并且视频已上传,但尚未设置 sn-p 和状态,它们是空值或默认值。有什么线索吗?
【问题讨论】:
你有没有想过这个问题?我遇到了完全相同的问题.. 总是成功上传,但从不设置 sn-p 信息。 @user3344977 我最终确实弄清楚了。只需挖掘代码并将其发布为答案:***.com/a/36213106/458614 查看 Google 的客户端 API 库代码,似乎应该可以在一个请求中完成所有操作。应该有两部分,第一部分是 JSON。我没有为 Youtube 找到相同的规范,但 Drive API 文档中给出的多部分规范很可能也适用于 Youtube:developers.google.com/drive/api/v3/multipart-upload。不过这是否值得有些疑问,因为它看起来比仅仅发出两个单独的请求要复杂得多。 【参考方案1】:如果您想在单个 POST 中发送它,您需要在 JSON blob 对象(例如通过 JSON.stringify)中发送元数据(即 sn-p 和状态数组),基本上作为第二个文件上传。您可能还应该在标头中设置访问令牌(很惊讶它在 URL 中工作):
headers:
Authorization: 'Bearer ' + [accesstoken]
这里有一个很好的 JS/CORS 示例:
https://code.google.com/p/youtube-api-samples/source/browse/yt-upload-javascript/index.js
你可以去掉
window.oauth2Callback = function(authResult) ...
有点,因为您已经拥有所需的访问令牌,否则它应该对您有用(我有一个概念证明做完全相同的事情,从这段代码中大量借用)。
这里也有一些有用/相关的内容:
http://lithostech.com/2013/10/upload-google-youtube-api-v3-cors/
Steve 似乎通过检查 ruby 客户端库的输出发现了将元数据作为二进制对象发布的必要性。根据这个***帖子:
Upload video on Youtube using curl and api v3
同样的事情可以通过两个帖子完成(参见 Chad Befus 的回答),第一个包含元数据,第二个包含视频文件。我没有这种方法的经验。
【讨论】:
【参考方案2】:我最终只能通过调用 2 个 API 来完成这项工作 - 一个用于上传视频(作为 multipart/form-data
POST)并获取结果 ID,第二个通过该 ID 更新视频(作为 application/json
PUT 与 snippet
在正文中)。
我从一个这样的 HTML 表单开始:
<form id="upload-yt-video" action="https://www.googleapis.com/upload/youtube/v3/videos?part=snippet&access_token=YOUR_TOKEN_HERE" method="post" enctype="multipart/form-data">
<input type="text" name="title" placeholder="Video title">
<textarea name="description" placeholder="Video description"></textarea>
<input type="file" accept="video/*" name="videoFile">
<input type="submit" value="Upload Video">
</form>
该表单自己上传视频,然后在JS中你可以捕获表单提交结果来获取视频ID,然后在纯JS中进行第二次AJAX调用来更新它:
var YOUTUBE_API_TOKEN = 'YOUR_TOKEN_HERE';
var YOUTUBE_VID_CATEGORY_ID = 24; // "entertainment" as an example - note that a category ID is required
var YOUTUBE_VID_PRIVACY_STATUS = 'unlisted';
$('#upload-yt-video').ajaxForm(
success: function(res, status)
if (status !== 'success' || ! res.id)
console.error('problem uploading the video, response status:', status, 'response:', res);
return;
console.log('form submission successful, video uploaded to youtube! response:', res);
updateYouTubeVideo(
id: res.id,
token: YOUTUBE_API_TOKEN,
title: $('#upload-yt-video [name=title]').val(),
description: $('#upload-yt-video [name=description]').val()
, function(err, res)
if (err)
console.error('problem uploading the video - error while updating video attributes after upload:', err);
else
console.log('video updated! upload complete. response:', res);
);
,
error: function()
console.error('form submission failed', arguments);
);
function updateYouTubeVideo(args, cb)
if (!args || !args.id || !args.token)
console.error('missing args: must at least include id and token');
return;
var apiArgs =
id: args.id,
snippet:
description: args.description || '',
title: args.title || 'Video ' + new Date().toDateString(),
categoryId: YOUTUBE_VID_CATEGORY_ID
,
status:
privacyStatus: YOUTUBE_VID_PRIVACY_STATUS
;
$.ajax(
type: 'PUT',
url: 'https://www.googleapis.com/youtube/v3/videos?part=snippet,status',
contentType: 'application/json',
headers:
Authorization: 'Bearer ' + args.token
,
data: JSON.stringify(apiArgs),
dataType: 'text',
success: function(data)
if ($.type(data) === "string") data = JSON.parse(data);
cb(null, data);
,
error: function(request, err)
cb(err);
);
注意 #1 - 这使用 this jQuery plugin 来捕获初始表单提交。免责声明 #1 - 我从一个代码库中改编了这个我没有寿命更长,因此我无法对其进行测试,因此此处可能存在轻微的拼写错误或错误。免责声明 #2 - 这在 2014 年 9 月有效 - 可能已经更新从那时起的 API!
【讨论】:
以上是关于YouTube API v3 over HTTP POST:上传视频时无法设置片段(标题最终为“未知”)的主要内容,如果未能解决你的问题,请参考以下文章
无帐号的 Youtube 视频列表(使用新的 API v3)