Skip to content

Commit

Permalink
get video info via post request using innertube api key 0xced#545
Browse files Browse the repository at this point in the history
get video info via post request using innertube api key 0xced#545
  • Loading branch information
sixty8 committed Jul 27, 2021
1 parent b40ce84 commit ed6dcaa
Showing 1 changed file with 51 additions and 49 deletions.
100 changes: 51 additions & 49 deletions XCDYouTubeKit/XCDYouTubeVideoOperation.m
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#import "XCDYouTubeDashManifestXML.h"
#import "XCDYouTubePlayerScript.h"
#import "XCDYouTubeLogger+Private.h"
#import "XCDYouTubeClient.h"

typedef NS_ENUM(NSUInteger, XCDYouTubeRequestType) {
XCDYouTubeRequestTypeGetVideoInfo = 1,
Expand Down Expand Up @@ -146,13 +147,24 @@ - (void) startNextRequest
}
else
{
NSString *eventLabel = [self.eventLabels objectAtIndex:0];
[self.eventLabels removeObjectAtIndex:0];

NSDictionary *query = @{ @"video_id": self.videoIdentifier, @"hl": self.languageIdentifier, @"el": eventLabel, @"ps": @"default", @"html5" : @"1", @"eurl": [@"https://youtube.googleapis.com/v/" stringByAppendingString:self.videoIdentifier],@"c": @"TVHTML5", @"cver": @"6.20180913"};
NSString *queryString = XCDQueryStringWithDictionary(query);
NSURL *videoInfoURL = [NSURL URLWithString:[@"https://www.youtube.com/get_video_info?" stringByAppendingString:queryString]];
[self startRequestWithURL:videoInfoURL type:XCDYouTubeRequestTypeGetVideoInfo];
NSString *urlString = [NSString stringWithFormat:@"https://youtubei.googleapis.com/youtubei/v1/player?key=%@", XCDYouTubeClient.innertubeApiKey];
NSURL *url = [NSURL URLWithString:urlString];

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10];

[request setHTTPMethod:@"POST"];

NSString *string = [NSString stringWithFormat:@"{'context': {'client': {'hl': 'en','clientName': 'WEB','clientVersion': '2.20210721.00.00','mainAppWebInfo': {'graftUrl': '/watch?v=%@'}}},'videoId': '%@'}", self.videoIdentifier, self.videoIdentifier];

NSData *postData = [string dataUsingEncoding:NSASCIIStringEncoding];

[request setHTTPBody:postData];

[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];

[self startRequestWith:request type:XCDYouTubeRequestTypeGetVideoInfo];
}
}

Expand Down Expand Up @@ -206,6 +218,39 @@ - (void) startRequestWithURL:(NSURL *)url type:(XCDYouTubeRequestType)requestTyp
self.requestType = requestType;
}

- (void) startRequestWith:(NSMutableURLRequest *)request type:(XCDYouTubeRequestType)requestType
{
if (self.isCancelled)
return;

// Max (age-restricted VEVO) = 2×GetVideoInfo + 1×WatchPage + 2×EmbedPage + 1×JavaScriptPlayer + 1×GetVideoInfo + 1xDashManifest
if (++self.requestCount > 8)
{
// This condition should never happen but the request flow is quite complex so better abort here than go into an infinite loop of requests
[self finishWithError];
return;
}

XCDYouTubeLogDebug(@"Starting request: %@", [request URL]);

[request setValue:self.languageIdentifier forHTTPHeaderField:@"Accept-Language"];
[request setValue:[NSString stringWithFormat:@"https://youtube.com/watch?v=%@", self.videoIdentifier] forHTTPHeaderField:@"Referer"];

self.dataTask = [self.session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
{
if (self.isCancelled)
return;

if (error)
[self handleConnectionError:error requestType:requestType];
else
[self handleConnectionSuccessWithData:data response:response requestType:requestType];
}];
[self.dataTask resume];

self.requestType = requestType;
}

#pragma mark - Response Dispatch

- (void) handleConnectionSuccessWithData:(NSData *)data response:(NSURLResponse *)response requestType:(XCDYouTubeRequestType)requestType
Expand Down Expand Up @@ -270,49 +315,10 @@ - (void) handleConnectionError:(NSError *)connectionError requestType:(XCDYouTub

#pragma mark - Response Parsing

- (void) initializeConsentWithResponse:(NSURLResponse *)response {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
if (httpResponse && response.URL) {
NSArray <NSHTTPCookie *> *cookies = [NSHTTPCookie cookiesWithResponseHeaderFields:httpResponse.allHeaderFields forURL:(NSURL *_Nonnull)response.URL];

for (NSHTTPCookie *cookie in cookies) {
if ([cookie.name isEqualToString:@"__Secure-3PSID"]) return;
}

for (NSHTTPCookie *cookie in cookies) {
if ([cookie.name isEqualToString:@"CONSENT"]) {
if ([cookie.value isEqualToString:@"YES"]) return;

NSString *rawConsentID = [cookie.value stringByReplacingOccurrencesOfString:@"PENDING+" withString:@""];
int consentID = [rawConsentID intValue];

// generate random consent id, if doesn't match expected format
if (consentID < 100 || consentID > 999) {
consentID = 100 + (int)arc4random_uniform((uint32_t)(999 - 100 + 1));
}

NSString *cookieValue = [[NSString alloc] initWithFormat:@"YES+cb.20210328-17-p0.en+FX+%i", consentID];
NSHTTPCookie *consentCookie = [NSHTTPCookie cookieWithProperties:@{
NSHTTPCookiePath: @"/",
NSHTTPCookieName: @"CONSENT",
NSHTTPCookieValue: cookieValue,
NSHTTPCookieDomain:@".youtube.com",
NSHTTPCookieSecure:@"TRUE"
}];
[self.session.configuration.HTTPCookieStorage setCookie:consentCookie];
return;
}
}

}
}

- (void) handleVideoInfoResponseWithInfo:(NSDictionary *)info response:(NSURLResponse *)response
{
XCDYouTubeLogDebug(@"Handling video info response");

[self initializeConsentWithResponse:response];

NSError *error = nil;
XCDYouTubeVideo *video = [[XCDYouTubeVideo alloc] initWithIdentifier:self.videoIdentifier info:info playerScript:self.playerScript response:response error:&error];
if (video)
Expand Down Expand Up @@ -395,13 +401,9 @@ - (void) handleJavaScriptPlayerWithScript:(NSString *)script

if (self.webpage.isAgeRestricted && self.cookies.count == 0)
{
NSString *eventLabel = [self.eventLabels objectAtIndex:0];
[self.eventLabels removeObjectAtIndex:0];

NSString *eurl = [@"https://youtube.googleapis.com/v/" stringByAppendingString:self.videoIdentifier];
NSString *sts = self.embedWebpage.sts ?: self.webpage.sts ?: @"";
//NSDictionary *query = @{ @"video_id": self.videoIdentifier, @"hl": self.languageIdentifier, @"eurl": eurl, @"sts": sts};
NSDictionary *query = @{ @"video_id": self.videoIdentifier, @"hl": self.languageIdentifier, @"el": eventLabel, @"ps": @"default" , @"html5" : @1,@"html5" : @1, @"c":@"TVHTML5", @"cver":@6.20180913};
NSDictionary *query = @{ @"video_id": self.videoIdentifier, @"hl": self.languageIdentifier, @"eurl": eurl, @"sts": sts};
NSString *queryString = XCDQueryStringWithDictionary(query);
NSURL *videoInfoURL = [NSURL URLWithString:[@"https://www.youtube.com/get_video_info?" stringByAppendingString:queryString]];
[self startRequestWithURL:videoInfoURL type:XCDYouTubeRequestTypeGetVideoInfo];
Expand Down

0 comments on commit ed6dcaa

Please sign in to comment.