我正在尝试允许用户从我的网站上传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编码的值data
发送单个表单字段{"snippet":{"description":"Test video description","title":"Test Video Title"},"status":{"privacyStatus":"unlisted"}}
,但这也不起作用。
我总是从API获得成功的JSON响应,包含代码段和状态,并且视频已上传,但片段和状态尚未设置,它们是空值或默认值。有线索吗?
答案 0 :(得分:2)
如果要在单个POST中发送它,则需要在JSON blob对象(例如,通过JSON.stringify)中发送元数据(即片段和状态数组),基本上作为第二个文件上载。你可能也应该在标题中设置访问令牌(让它感到惊讶的是在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/
史蒂夫似乎已经通过检查ruby客户端库的输出来确定将元数据作为二进制对象发布的必要性。并根据这个stackoverflow帖子:Upload video on Youtube using curl and api v3
同样的事情可以通过两个帖子来实现(参见Chad Befus'答案),第一个包含元数据,第二个包含视频文件。我对这种方法没有经验。
答案 1 :(得分:1)
我最终只能通过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可能已有更新!