Search code examples
objective-ciosyoutubeyoutube-apigdata

Trying to direct upload via Youtube API and getting Invalid Request (NSURLErrorDomain error 400.)


I'm trying to direct upload a video to Youtube via the Youtube API. I can't figure out where the problem is...is it my request URL syntax? Is there something wrong with the way I'm adding the video file to the body? (I'm using MKNetworkkit as my request engine.)

Here is my code:

    //*********************************************************
    //* Setup the request URL and params
    //*********************************************************

    NSString *baseUrl = @"http://uploads.gdata.youtube.com/feeds/api/users/default/uploads";
    NSString *_accessToken = // the google API access token
    NSString *xml = 
    @"<?xml version='1.0'>"
    "<entry xmlns='http://www.w3.org/2005/Atom'"
    "xmlns:media='http://search.yahoo.com/mrss/'"
    "xmlns:yt='http://gdata.youtube.com/schemas/2007'/>"
      "<media:group>"
        "<media:title type='plain'>My Video Title</media:title>"
        "<media:description type='plain'>"
        "This is a test video. Hopefully it'll upload to Youtube succesfully."
        "</media:description>"
        "<media:category"
        "scheme='http://gdata.youtube.com/schemas/2007/categories.cat'>People"
        "</media:category>"
        "<media:keywords>test, video</media:keywords>"
      "</media:group>"
    "</entry>";
    NSMutableDictionary *params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                   _accessToken, @"access_token",
                                   myYouTubeDeveloperKey, @"DEVELOPER_KEY",
                                   @"vid1.mp4", @"VIDEO_FILENAME",
                                   xml, @"API_XML_Request",
                                   nil];

    //*********************************************************
    //* Configure the request
    //*********************************************************
    MKNetworkOperation *op = [globalMKNetworkEngine operationWithURLString:baseUrl params:params httpMethod:@"POST"];
    [op addFile:[[self getVideoFileURL] absoluteString] forKey:@"Binary File Data"];
    [op onUploadProgressChanged:^(double progress) {
        NSLog(@"progress: %@", progress);
        [uploadProgressBar setProgress:progress animated:YES];
    }];
    [op onCompletion:^(MKNetworkOperation *operation) {

        //*********************************************************
        //* On success, do this
        //*********************************************************

        dispatch_async(dispatch_get_main_queue(), ^{
           NSLog(@"Success!");
        });


    } onError:^(NSError *error) {
        DLog(@"%@", [error localizedDescription]);
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Uh oh..." message:@"There was a network error. Please try again later." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alert show];
    }];
    [globalMKNetworkEngine enqueueOperation:op];

Here is the response as reported by MKNetworkKit:

 Danceplanet[16449:707] -[MKNetworkOperation     operationFailedWithError:]
Request
-------
curl -X POST "http://uploads.gdata.youtube.com/feeds/api/users/default/uploads" \
-F     "VIDEO_FILENAME=vid1" -F "DEVELOPER_KEY=(the developer key is here)" \
-F "access_token=(an access token)" -F "API_XML_Request=<?xml version='1.0'>\
<entry xmlns='http://www.w3.org/2005/Atom'xmlns:media='http://search.yahoo.com/mrss/'xmlns:yt='http://gdata.youtube.com/schemas/2007'/>\
<media:group>\
<media:title type='plain'>My Video Title</media:title>\
<media:description type='plain'>This is a test video. Hopefully it'll upload to Youtube succesfully.</media:description>\
<media:categoryscheme='http://gdata.youtube.com/schemas/2007/categories.cat'>People</media:category>\
<media:keywords>test, video</media:keywords>\
</media:group>\
</entry>" \
-F "Binary File Data=@file://localhost/var/mobile/Applications/BBD79FFD-01D5-402C-995A-D9F9CE61F312/Documents/savedVideos/vid1.mp4;type=application/octet-stream"

--------
Response
--------
Invalid Request
, [The operation couldn’t be completed. (NSURLErrorDomain error 400.)]
 Danceplanet[16449:707] __block_global_3 [Line 167] The operation     couldn’t be completed. (NSURLErrorDomain error 400.)
 Danceplanet[16449:707] -[MKNetworkOperation operationFailedWithError:]     [Line 1283] State: 0`

Solution

  • I've given up on this approach and am now using the Google obj-c client library instead.