我有兴趣将视频上传到youtube以及标题,说明和关键字。下面的代码将视频上传到youtube,没有任何属性:
func postVideoToYouTube(token: String, callback: Bool -> Void){
let headers = ["Authorization": "Bearer \(token)"]
let urlYoutube = "https://www.googleapis.com/upload/youtube/v3/videos?part=id"
let path = NSBundle.mainBundle().pathForResource("video", ofType: "mp4")
let videodata: NSData = NSData.dataWithContentsOfMappedFile(path!)! as! NSData
upload(
.POST,
urlYoutube,
headers: headers,
multipartFormData: { multipartFormData in
multipartFormData.appendBodyPart(data: videodata, name: "video", fileName: "video.mp4", mimeType: "application/octet-stream")
},
encodingCompletion: { encodingResult in
switch encodingResult {
case .Success(let upload, _, _):
upload.responseJSON { request, response, error in
print(response)
callback(true)
}
case .Failure(_):
callback(false)
}
})
}
我一直试图修改urlYoutube以包含必要的代码段信息无效:
let snippetTitle = "The Best Video Ever"
let snippetDesc = "first video upload with title"
let snippetTags = "best,video,ever,snoopy,monkey,charlie"
let urlYoutube = "https://www.googleapis.com/upload/youtube/v3/videos?part=id&snippet.title=%@&snippet.description=%@&snippet.keywords=%@", snippetTitle, snippetDesc, snippetTags)"
我尝试的另一种方法(感谢@adjuremods建议)是使用基于Youtube-API的Request Body来编辑之前上传的视频。所以,首先,我定义了一个视频资源:
let parms = [
"kind": "youtube#video",
"id" : returnedId,
"snippet.title" : "summer vacation cali",
"snippet.description" : "had fun in the sun",
"snippet.tags" : ["surf","fun","sun"],
"snippet.categoryId" : "1"
]
并将其作为PUT请求发送,如下所示:
do {
let parmsJson = try NSJSONSerialization.dataWithJSONObject(parameters, options: .PrettyPrinted)
let putURL = NSURL(string: "https://www.googleapis.com/upload/youtube/v3/videos")!
let request = NSMutableURLRequest(URL: putURL)
request.HTTPMethod = "PUT"
request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
request.setValue("application/json; charset=UTF-8", forHTTPHeaderField: "Content-Type")
request.HTTPBody = parmsJson
let task = NSURLSession.sharedSession().dataTaskWithRequest(request){ data, response, error in
if error != nil{
print("Error -> \(error)")
return
}
do {
let result = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? [String:AnyObject]
print("Result -> \(result)")
} catch {
print("Error -> \(error)")
}
}
task.resume()
//return task
} catch {
print ("...could not accomplish put request")
}
不幸的是,无论我如何修改视频资源,我得到的结果总是一样的:
Result -> Optional(["error": {
code = 400;
errors = (
{
domain = global;
message = "Unsupported content with type: application/json; charset=UTF-8";
reason = badContent;
}
);
message = "Unsupported content with type: application/json; charset=UTF-8";
有人可以建议我可能出错吗?我不清楚如何设置API定义的这些参数:
https://developers.google.com/youtube/v3/docs/videos/insert#parameters
答案 0 :(得分:5)
在multipartFormData块中为参数值添加一行,如下所示(将代码放在视频项之前 - 并且 - 根据隐含结构添加任何其他片段属性值):
var originalValues;
$('#industrySelect').change(function() {
if (!originalValues) {
originalValues = {};
$('#verticalMarketSelect').children().each(function() {
var industryValue = $(this).attr('industryValue');
if(!(industryValue in originalValues)){
originalValues[industryValue] = [];
}
originalValues[industryValue].push([$(this).val(), $(this).html()]);
});
}
$('#verticalMarketSelect').empty();
for(var x in originalValues[$('#industrySelect').val()]){
var v = originalValues[$('#industrySelect').val()][x];
$('#verticalMarketSelect').append('<option value="'+v[0]+'">' + v[1] + '</option>');
}
});
邮政网址也应更改为part = snippet
multipartFormData.appendBodyPart(data:"{'snippet':{'title' : 'TITLE_TEXT', 'description': 'DESCRIPTION_TEXT'}}".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!, name :"snippet", mimeType: "application/json")
即
https://www.googleapis.com/upload/youtube/v3/videos?part=snippet
答案 1 :(得分:0)
设置标题,说明,标签等将要求您使用基于API的Request Body。查看此issue raised here,了解如何在Swift中设置请求正文。
let json = [ "title":"ABC" , "dict": mapDict ]
let jsonData = NSJSONSerialization.dataWithJSONObject(json, options: .PrettyPrinted, error: nil)
// insert json data to the request
request.HTTPBody = jsonData
请记住,请求正文应该是Video
的资源表示答案 2 :(得分:0)
哦,男孩......结果证明这是个谜题。从之前的YouTube回答中可以看出,上传带有片段元数据的视频的唯一方法是通过POST和PUT请求的组合......然而,让这些工作变得非常困难。我在学习过程中学到的一个非常有用的事情是Alamofire在发出可用于解决cURL会话故障的请求时返回一个对象:
let putRequest = request(.PUT, "https://www.googleapis.com/youtube/v3/videos?part=snippet&key=\(ios_key)", parameters: dictionaryParameters, encoding: .JSON , headers: headers)
debugPrint(putRequest)
这会返回如下输出:
$ curl -i \
-X PUT \
-H "Authorization: Bearer ##########################" \
-H "Content-Type: application/json" \
-H "Accept-Language: en-US;q=1.0" \
-H "Accept-Encoding: gzip;q=1.0, compress;q=0.5" \
-H "User-Agent: testVideoApp/com.thinkforward.testVideoApp (1; OS Version 9.2 (Build 13C75))" \
-d "{\"id\":\"###########\",\"snippet\":{\"title\":\"something in the way\",\"tags\":[\"whisky\",\"tango\",\"fox\"],\"description\":\"is this finally gonna work?\"}}" \
啊哈!现在我们有一个cURL命令,我们可以使用独立的Alamofire进行测试。一旦我开始工作,剩下的就是对命令进行逆向工程以确保我将正确的参数传递给Alamofire ...这就是我发现Alamofire希望参数以非常特定的方式传递的方式:
parameters: <[String : AnyObject]?>
有了这个英特尔,我重建了我的词典如下:
let dictionarySnippet :Dictionary<String, AnyObject> = [
"title" : "something in the way",
"description" : "is this finally gonna work?",
"tags" : ["whisky","tango","fox"],
"categoryId" : "1"
]
let dictionaryParameters :Dictionary<String, AnyObject> = [
"id" : "\(returnedId)",
"snippet" : dictionarySnippet,
]
接下来,我发现发出PUT请求,实际上需要的范围与我用于POST的范围不同。由于我需要提出两种类型的请求,因此我必须更新我的范围变量,如下所示:
let scope = "https://www.googleapis.com/auth/youtube+https://www.googleapis.com/auth/youtube.upload"
同样,POST和PUT请求需要单独的URL:
https://www.googleapis.com/upload/youtube/v3/videos?part=snippet for POST
https://www.googleapis.com/youtube/v3/videos?part=snippet&key=\(ios_key) for PUT
随着这些变化,我的问题中发布的代码就像一个魅力。它不是很优雅,但它完成了工作。