Skip to content

Commit

Permalink
Merge branch 'release/2.8.1'
Browse files Browse the repository at this point in the history
  • Loading branch information
SoneeJohn committed Sep 11, 2019
2 parents 8367211 + 58b8809 commit 7b4c57a
Show file tree
Hide file tree
Showing 18 changed files with 378 additions and 288 deletions.
4 changes: 2 additions & 2 deletions .jazzy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ source_directory: XCDYouTubeKit
framework_root: .
umbrella_header: XCDYouTubeKit/XCDYouTubeKit.h
module: XCDYouTubeKit
module_version: 2.8.0
module_version: 2.8.1

author: Cédric Luthi
author_url: https://twitter.com/0xced

readme: README.md
github_url: https://github.com/0xced/XCDYouTubeKit
github_file_prefix: https://github.com/0xced/XCDYouTubeKit/tree/2.8.0/XCDYouTubeKit
github_file_prefix: https://github.com/0xced/XCDYouTubeKit/tree/2.8.1/XCDYouTubeKit
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
#### Version 2.8.1

* Adaptation to YouTube API change. (#447, #448, #449)

#### Version 2.8.0

* Adaptation to YouTube API change.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -760,7 +760,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 2.8.0;
CURRENT_PROJECT_VERSION = 2.8.1;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
Expand Down Expand Up @@ -804,7 +804,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = YES;
CURRENT_PROJECT_VERSION = 2.8.0;
CURRENT_PROJECT_VERSION = 2.8.1;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion XCDYouTubeKit.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "XCDYouTubeKit"
s.version = "2.8.0"
s.version = "2.8.1"
s.summary = "YouTube video player for iOS and OS X."
s.homepage = "https://github.com/0xced/XCDYouTubeKit"
s.screenshot = "https://raw.github.com/0xced/XCDYouTubeKit/#{s.version}/Screenshots/XCDYouTubeVideoPlayerViewController.png"
Expand Down
8 changes: 4 additions & 4 deletions XCDYouTubeKit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -613,10 +613,10 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COMBINE_HIDPI_IMAGES = YES;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 39;
CURRENT_PROJECT_VERSION = 40;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 2.0.0;
DYLIB_CURRENT_VERSION = 2.8.0;
DYLIB_CURRENT_VERSION = 2.8.1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
Expand Down Expand Up @@ -691,10 +691,10 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COMBINE_HIDPI_IMAGES = YES;
COPY_PHASE_STRIP = YES;
CURRENT_PROJECT_VERSION = 39;
CURRENT_PROJECT_VERSION = 40;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 2.0.0;
DYLIB_CURRENT_VERSION = 2.8.0;
DYLIB_CURRENT_VERSION = 2.8.1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
Expand Down
1 change: 1 addition & 0 deletions XCDYouTubeKit/XCDYouTubeVideo+Private.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ extern NSArray *XCDCaptionArrayWithString(NSString *string);
extern NSArray *XCDThumnailArrayWithString(NSString *string);
extern NSString *XCDHTTPLiveStreamingStringWithString(NSString *string);
extern NSDictionary *XCDDictionaryWithString(NSString *string);
extern NSDictionary *XCDStreamingDataWithString(NSString *string);

@interface XCDYouTubeVideo ()

Expand Down
144 changes: 96 additions & 48 deletions XCDYouTubeKit/XCDYouTubeVideo.m
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
NSString *const XCDYouTubeVideoQualityHTTPLiveStreaming = @"HTTPLiveStreaming";


NSString *XCDHTTPLiveStreamingStringWithString(NSString *string)
NSDictionary *XCDStreamingDataWithString(NSString *string)
{
NSError *error = nil;
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
Expand All @@ -24,7 +24,12 @@

if (error) { return nil; }

NSDictionary *streamingData = JSON[@"streamingData"];
return JSON[@"streamingData"];
}

NSString *XCDHTTPLiveStreamingStringWithString(NSString *string)
{
NSDictionary *streamingData = XCDStreamingDataWithString(string);
NSString *manifestURL = streamingData[@"hlsManifestUrl"];
if (manifestURL.length == 0) { return nil; }

Expand Down Expand Up @@ -161,17 +166,22 @@ - (instancetype) initWithIdentifier:(NSString *)identifier info:(NSDictionary *)
return nil; // LCOV_EXCL_LINE

_identifier = identifier;

NSString *streamMap = info[@"url_encoded_fmt_stream_map"];

NSString *playerResponse = info[@"player_response"];
NSString *streamMap = info[@"url_encoded_fmt_stream_map"];
NSArray *alternativeStreamMap = XCDStreamingDataWithString(playerResponse)[@"formats"];
NSString *httpLiveStream = info[@"hlsvp"] ?: XCDHTTPLiveStreamingStringWithString(playerResponse);
NSString *adaptiveFormats = info[@"adaptive_fmts"];
NSArray *alternativeAdaptiveFormats = XCDStreamingDataWithString(playerResponse)[@"adaptiveFormats"];
NSDictionary *videoDetails = XCDDictionaryWithString(playerResponse)[@"videoDetails"];

NSMutableDictionary *userInfo = response.URL ? [@{ NSURLErrorKey: (id)response.URL } mutableCopy] : [NSMutableDictionary new];

if (streamMap.length > 0 || httpLiveStream.length > 0)
if (streamMap.length > 0 || httpLiveStream.length > 0 || alternativeStreamMap.count > 0 || alternativeAdaptiveFormats.count > 0)
{
NSMutableArray *alternativeStreamQueries = [alternativeStreamMap mutableCopy];
[alternativeStreamQueries addObjectsFromArray:alternativeAdaptiveFormats];

NSMutableArray *streamQueries = [[streamMap componentsSeparatedByString:@","] mutableCopy];
[streamQueries addObjectsFromArray:[adaptiveFormats componentsSeparatedByString:@","]];

Expand Down Expand Up @@ -239,51 +249,19 @@ - (instancetype) initWithIdentifier:(NSString *)identifier info:(NSDictionary *)
{
_autoGeneratedCaptionURLs = [autoGeneratedCaptionURLs copy];
}

for (NSString *streamQuery in streamQueries)

NSError *streamURLsError;
NSDictionary *mainStreamURLs = [self extractStreamURLsWithQuery:streamQueries.count == 0 ? alternativeStreamQueries : streamQueries playerScript:playerScript userInfo:userInfo error:&streamURLsError];
if (mainStreamURLs)
[streamURLs addEntriesFromDictionary:mainStreamURLs];

if (streamURLsError)
{
NSDictionary *stream = XCDDictionaryWithQueryString(streamQuery);

NSString *scrambledSignature = stream[@"s"];
NSString *spParam = stream[@"sp"];

if (scrambledSignature && !playerScript)
{
userInfo[XCDYouTubeNoStreamVideoUserInfoKey] = self;
if (error)
*error = [NSError errorWithDomain:XCDYouTubeVideoErrorDomain code:XCDYouTubeErrorUseCipherSignature userInfo:userInfo];

return nil;
}
NSString *signature = [playerScript unscrambleSignature:scrambledSignature];
if (playerScript && scrambledSignature && !signature)
continue;

NSString *urlString = stream[@"url"];
NSString *itag = stream[@"itag"];
if (urlString && itag)
{
NSURL *streamURL = [NSURL URLWithString:urlString];
if (!_expirationDate)
_expirationDate = ExpirationDate(streamURL);

if (signature)
{
NSString *escapedSignature = [signature stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];

if (spParam.length > 0)
{
streamURL = URLBySettingParameter(streamURL, spParam, escapedSignature);

} else
{
streamURL = URLBySettingParameter(streamURL, @"signature", escapedSignature);
}
}

streamURLs[@(itag.integerValue)] = URLBySettingParameter(streamURL, @"ratebypass", @"yes");
}
if (error)
*error = streamURLsError;
return nil;
}

_streamURLs = [streamURLs copy];

if (_streamURLs.count == 0)
Expand All @@ -294,6 +272,14 @@ - (instancetype) initWithIdentifier:(NSString *)identifier info:(NSDictionary *)
return nil;
}

for (NSURL *streamURL in _streamURLs.allValues)
{
if (!_expirationDate) {
_expirationDate = ExpirationDate(streamURL);
break;
}
}

return self;
}
else
Expand All @@ -318,6 +304,68 @@ - (instancetype) initWithIdentifier:(NSString *)identifier info:(NSDictionary *)
}
}

- (NSDictionary <id, NSURL *>*)extractStreamURLsWithQuery:(NSArray *)streamQueries playerScript:(XCDYouTubePlayerScript *)playerScript userInfo:(NSMutableDictionary *)userInfo error:(NSError *__autoreleasing *)error
{
NSMutableDictionary *streamURLs = [NSMutableDictionary new];

for (NSObject *streamQuery in streamQueries)
{
NSDictionary *stream;

//When using alternative streams the `streamQueries` is an array of NSDictionary's (which are streams)
if ([streamQuery isKindOfClass:[NSDictionary class]])
{
stream = (NSDictionary *)streamQuery;
}
else
{
stream = XCDDictionaryWithQueryString((NSString *)streamQuery);
}
NSDictionary *alternativeStreamInfo = XCDDictionaryWithQueryString(stream[@"cipher"]);
NSString *alternativeURLString = alternativeStreamInfo[@"url"];

NSString *scrambledSignature = stream[@"s"] == nil? alternativeStreamInfo[@"s"] : stream[@"s"];
NSString *spParam = stream[@"sp"] == nil ? alternativeStreamInfo[@"sp"] : stream[@"sp"];

if (scrambledSignature && !playerScript)
{
userInfo[XCDYouTubeNoStreamVideoUserInfoKey] = self;
if (error)
*error = [NSError errorWithDomain:XCDYouTubeVideoErrorDomain code:XCDYouTubeErrorUseCipherSignature userInfo:userInfo];

return nil;
}
NSString *signature = [playerScript unscrambleSignature:scrambledSignature];
if (playerScript && scrambledSignature && !signature)
continue;

NSString *urlString = stream[@"url"] == nil ? alternativeURLString : stream[@"url"];
NSString *itag = stream[@"itag"];
if (urlString && itag)
{
NSURL *streamURL = [NSURL URLWithString:urlString];

if (signature)
{
NSString *escapedSignature = [signature stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];

if (spParam.length > 0)
{
streamURL = URLBySettingParameter(streamURL, spParam, escapedSignature);

} else
{
streamURL = URLBySettingParameter(streamURL, @"signature", escapedSignature);
}
}

streamURLs[@(itag.integerValue)] = URLBySettingParameter(streamURL, @"ratebypass", @"yes");
}
}

return streamURLs.copy;
}

- (void) mergeVideo:(XCDYouTubeVideo *)video
{
unsigned int count;
Expand Down

0 comments on commit 7b4c57a

Please sign in to comment.