I have an iOS(swift) app in which I can log in through my google account and get an access token.
After retrieving the access token I am making a post request to YouTube for uploading the video.
The error returned is as follows
{error =
{code = 400;
errors =({domain = global;
location = part;
locationType = parameter;
message = \"Required parameter: part\";
reason = required;});
message = \"Required parameter: part\";};}"
Following is the code that I am using to make a post request.
func postVideoToYouTube(token: String, callback: @escaping (Bool) -> Void){
if videoPath == nil {
return
}
var movieData: NSData?
do {
movieData = try NSData(contentsOfFile: (videoPath?.relativePath)!, options: NSData.ReadingOptions.alwaysMapped)
} catch _ {
movieData = nil
return
}
let headers = ["Authorization": "Bearer \(token)"]
let URL = try! URLRequest(url: "https://www.googleapis.com/upload/youtube/v3/videos", method: .post, headers: headers)
print("Video Data",movieData)
Alamofire.upload(multipartFormData: { multipartFormData in
multipartFormData.append(movieData as! Data, withName: "video", fileName: "video.mp4", mimeType: "application/octet-stream")
}, with: URL, encodingCompletion: {
encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.responseJSON { response in
debugPrint("SUCCESS RESPONSE1: \(response)")
}
case .failure(let encodingError):
print("ERROR RESPONSE: \(encodingError)")
}
})
}
Earlier the error was 403 forbidden , but I have added "https://www.googleapis.com/auth/youtube.force-ssl" to scope and now I am getting a 400.
Any help will be appreciated. Thank you.
This line in the return data is interesting:
Required parameter: part
It tells you that a parameter named part
is required, and you have not included that in your call so that is why you are getting an error.
If you look at the Youtube API description you can see a description of the part
parameter.
For instance
The part parameter serves two purposes in this operation. It identifies the properties that the write operation will set as well as the properties that the API response will include.
And
The following list contains the part names that you can include in the parameter value and the quota cost for each part:
contentDetails: 2
fileDetails: 1
id: 0
liveStreamingDetails: 2
localizations: 2
player: 0
processingDetails: 1
recordingDetails: 2
snippet: 2
statistics: 2
status: 2
suggestions: 1
topicDetails: 2
OK..that may not make a lot of sense but fortunately there are some examples as well.
Here is a link to an example using python.
If you look at that example the interesting part (no pun intended) is here:
# Call the API's videos.insert method to create and upload the video.
insert_request = youtube.videos().insert(
part=",".join(body.keys()),
OK, so we join the keys of something called body
and that ends out being the value of the part
parameter.
Next question...how is body
defined?
body=dict(
snippet=dict(
title=options.title,
description=options.description,
tags=tags,
categoryId=options.category
),
status=dict(
privacyStatus=options.privacyStatus
)
)
So...the keys of body
must be snippet
and status
. If you look at the valid values mentioned in the list described by "The following list contains the part names that you can include in the parameter value" above in my answer, you'll see both snippet
and status
there, so they seems valid.
So in short, you should add the part
parameter when you do a POST request to the YouTube API. The value of that parameter could be snippet, status
but you should probably read up on exactly what that means and whether you should use something else.
Hope that helps you.