diff --git a/Plugin/English.lproj/WhitelistPanel.xib b/Plugin/English.lproj/WhitelistPanel.xib
index 74653e3b..5129ea2f 100755
--- a/Plugin/English.lproj/WhitelistPanel.xib
+++ b/Plugin/English.lproj/WhitelistPanel.xib
@@ -8,6 +8,7 @@
353.00
YES
@@ -1304,22 +1329,6 @@ dG8gdW5pbnN0YWxsIENsaWNrVG9GbGFzaC4
178
-
-
- value: values.useYouTubeH264
-
-
-
-
-
- value: values.useYouTubeH264
- value
- values.useYouTubeH264
- 2
-
-
- 179
-
value: values.autoLoadInvisibleViews
@@ -1452,6 +1461,38 @@ dG8gdW5pbnN0YWxsIENsaWNrVG9GbGFzaC4
239
+
+
+ value: values.useYouTubeHDH264
+
+
+
+
+
+ value: values.useYouTubeHDH264
+ value
+ values.useYouTubeHDH264
+ 2
+
+
+ 245
+
+
+
+ value: values.useYouTubeH264
+
+
+
+
+
+ value: values.useYouTubeH264
+ value
+ values.useYouTubeH264
+ 2
+
+
+ 251
+
@@ -1608,17 +1649,18 @@ dG8gdW5pbnN0YWxsIENsaWNrVG9GbGFzaC4
YES
-
-
-
+
+
+
+
+
-
+
-
+
-
@@ -2068,6 +2110,20 @@ dG8gdW5pbnN0YWxsIENsaWNrVG9GbGFzaC4
+
+ 240
+
+
+ YES
+
+
+
+
+
+ 241
+
+
+
@@ -2190,6 +2246,9 @@ dG8gdW5pbnN0YWxsIENsaWNrVG9GbGFzaC4
232.IBPluginDependency
233.IBPluginDependency
234.IBPluginDependency
+ 240.IBAttributePlaceholdersKey
+ 240.IBPluginDependency
+ 241.IBPluginDependency
31.IBPluginDependency
32.IBPluginDependency
36.IBAttributePlaceholdersKey
@@ -2208,9 +2267,9 @@ dG8gdW5pbnN0YWxsIENsaWNrVG9GbGFzaC4
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilderKit
com.apple.InterfaceBuilderKit
- {{12, 251}, {527, 494}}
-
- {{12, 251}, {527, 494}}
+ {{186, 118}, {527, 516}}
+
+ {{186, 118}, {527, 516}}
{196, 240}
{{202, 428}, {480, 270}}
@@ -2363,6 +2422,16 @@ dG8gdW5pbnN0YWxsIENsaWNrVG9GbGFzaC4
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
+
+ ToolTip
+
+ ToolTip
+
+ Loads HD versions of the movie, if possible.
+
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
@@ -2404,7 +2473,7 @@ dG8gdW5pbnN0YWxsIENsaWNrVG9GbGFzaC4
- 239
+ 251
diff --git a/Plugin/Plugin.h b/Plugin/Plugin.h
index c7ba6029..90fe9712 100755
--- a/Plugin/Plugin.h
+++ b/Plugin/Plugin.h
@@ -39,6 +39,8 @@ THE SOFTWARE.
BOOL mouseInside;
BOOL _isLoadingFromWhitelist;
BOOL _fromYouTube;
+ BOOL _hasH264Version;
+ BOOL _hasHDH264Version;
WebView *_webView;
NSUInteger _sifrVersion;
NSString *_baseURL;
diff --git a/Plugin/Plugin.m b/Plugin/Plugin.m
index 7ca7d9e6..f66afd3b 100755
--- a/Plugin/Plugin.m
+++ b/Plugin/Plugin.m
@@ -44,6 +44,7 @@ of this software and associated documentation files (the "Software"), to deal
// CTFUserDefaultsController keys
static NSString *sUseYouTubeH264DefaultsKey = @"useYouTubeH264";
+static NSString *sUseYouTubeHDH264DefaultsKey = @"useYouTubeHDH264";
static NSString *sAutoLoadInvisibleFlashViewsKey = @"autoLoadInvisibleViews";
static NSString *sPluginEnabled = @"pluginEnabled";
static NSString *sApplicationWhitelist = @"applicationWhitelist";
@@ -76,8 +77,11 @@ - (void) _loadContentForWindow: (NSNotification*) notification;
- (NSDictionary*) _flashVarDictionary: (NSString*) flashvarString;
- (NSDictionary*) _flashVarDictionaryFromYouTubePageHTML: (NSString*) youTubePageHTML;
- (NSString*) flashvarWithName: (NSString*) argName;
+- (void) _checkForH264VideoVariants;
- (BOOL) _hasH264Version;
- (BOOL) _useH264Version;
+- (BOOL) _hasHDH264Version;
+- (BOOL) _useHDH264Version;
- (NSString *)launchedAppBundleIdentifier;
@end
@@ -158,11 +162,6 @@ - (id) initWithArguments:(NSDictionary *)arguments
NSString* flashvars = [[self attributes] objectForKey: @"flashvars" ];
if( flashvars != nil )
_flashVars = [ [ self _flashVarDictionary: flashvars ] retain ];
-
-#if LOGGING_ENABLED
- NSLog( @"arguments = %@", arguments );
- NSLog( @"flashvars = %@", _flashVars );
-#endif
// check whether it's from YouTube and get the video_id
@@ -200,9 +199,17 @@ - (id) initWithArguments:(NSDictionary *)arguments
if (! pageSourceError) _flashVars = [[self _flashVarDictionaryFromYouTubePageHTML:pageSourceString] retain];
}
}
+
+ [self _checkForH264VideoVariants];
}
+#if LOGGING_ENABLED
+ NSLog( @"arguments = %@", arguments );
+ NSLog( @"flashvars = %@", _flashVars );
+#endif
+
+
// check whether plugin is disabled, load all content as normal if so
CTFUserDefaultsController *standardUserDefaults = [CTFUserDefaultsController standardUserDefaults];
@@ -653,6 +660,8 @@ - (void) _loadInvisibleContentForWindow: (NSNotification*) notification
- (NSString*) badgeLabelText
{
+ if( [ self _useHDH264Version ] )
+ return NSLocalizedString( @"HD H.264", @"HD H.264 badge text" );
if( [ self _useH264Version ] )
return NSLocalizedString( @"H.264", @"H.264 badge text" );
else if( [ self _hasH264Version ] )
@@ -1016,12 +1025,98 @@ - (NSString*) _videoHash
return [ self flashvarWithName: @"t" ];
}
+- (void) _checkForH264VideoVariants
+{
+ NSString* video_id = [self videoId];
+ NSString* video_hash = [ self _videoHash ];
+
+ NSString* src = [ NSString stringWithFormat: @"http://www.youtube.com/get_video?fmt=18&video_id=%@&t=%@",
+ video_id, video_hash ];
+ NSString* HDSrc = [ NSString stringWithFormat: @"http://www.youtube.com/get_video?fmt=22&video_id=%@&t=%@",
+ video_id, video_hash ];
+
+ NSMutableURLRequest *URLRequest = [[NSMutableURLRequest alloc] init];
+ [URLRequest setURL:[NSURL URLWithString:src]];
+
+
+ // this header is required, because otherwise the URLRequest will download
+ // the whole video before returning, which completely defeats the purpose
+ // of checking for the video variants in the first place
+
+ // this limits the download to the first 2 bytes of the video, which is
+ // sufficient to see if there is a video there or not.
+ [URLRequest setValue:@"bytes=0-1" forHTTPHeaderField:@"Range"];
+ NSError *requestError = nil;
+ NSHTTPURLResponse *requestResponse = nil;
+ NSData *returnedData = [NSURLConnection sendSynchronousRequest:URLRequest
+ returningResponse:&requestResponse
+ error:&requestError];
+ int statusCode = [requestResponse statusCode];
+
+ // 206 status code means partial content has been delivered, because of the
+ // range header
+ if (statusCode == 206) _hasH264Version = YES;
+
+ [URLRequest setURL:[NSURL URLWithString:HDSrc]];
+ returnedData = [NSURLConnection sendSynchronousRequest:URLRequest
+ returningResponse:&requestResponse
+ error:&requestError];
+
+ statusCode = [requestResponse statusCode];
+ if (statusCode == 206) _hasHDH264Version = YES;
+
+ [URLRequest release];
+}
+
+- (BOOL) _hasHDH264Version
+{
+ /*BOOL _hasHDH264Version = NO;
+ if (_fromYouTube) {
+ NSString *fmtMapString = [ self flashvarWithName: @"fmt_map" ];
+ NSArray *fmtMapArray = [fmtMapString componentsSeparatedByString:@","];
+
+ CTFForEachObject( NSString, currentMapString, fmtMapArray ) {
+ NSString *fmtQuality = [[currentMapString componentsSeparatedByString:@"/"] objectAtIndex:0];
+ if ([fmtQuality isEqualToString:@"22"]) {
+ _hasHDH264Version = YES;
+ break;
+ }
+ }
+ }*/
+
+ return (_fromYouTube && _hasHDH264Version);
+}
+
- (BOOL) _hasH264Version
{
- if( _fromYouTube )
- return [self videoId] != nil && [ self _videoHash ] != nil;
- else
- return NO;
+ /*BOOL _hasH264Version = NO;
+ if ( _fromYouTube ) {
+ NSString *fmtMapString = [ self flashvarWithName: @"fmt_map" ];
+ NSArray *fmtMapArray = [fmtMapString componentsSeparatedByString:@","];
+
+ CTFForEachObject( NSString, currentMapString, fmtMapArray ) {
+ NSString *fmtQuality = [[currentMapString componentsSeparatedByString:@"/"] objectAtIndex:0];
+ if ([fmtQuality isEqualToString:@"18"] || [fmtQuality isEqualToString:@"22"]) {
+ _hasH264Version = YES;
+ break;
+ }
+ }
+ }*/
+
+ return (_fromYouTube && _hasH264Version);
+
+ // sometimes, even though we have a videoId and a videoHash, the movie
+ // still doesn't have an H.264 version, so this logic is flawed
+
+ // return [self videoId] != nil && [ self _videoHash ] != nil;
+}
+
+- (BOOL) _useHDH264Version
+{
+ return [ self _hasHDH264Version ]
+ && [ [ CTFUserDefaultsController standardUserDefaults ] boolForKey: sUseYouTubeH264DefaultsKey ]
+ && [ [ CTFUserDefaultsController standardUserDefaults ] boolForKey: sUseYouTubeHDH264DefaultsKey ]
+ && [ [ CTFUserDefaultsController standardUserDefaults ] boolForKey: sPluginEnabled ];
}
- (BOOL) _useH264Version
@@ -1036,8 +1131,14 @@ - (void) _convertElementForMP4: (DOMElement*) element
NSString* video_id = [self videoId];
NSString* video_hash = [ self _videoHash ];
- NSString* src = [ NSString stringWithFormat: @"http://www.youtube.com/get_video?fmt=18&video_id=%@&t=%@",
- video_id, video_hash ];
+ NSString* src;
+ if ([self _hasHDH264Version]) {
+ src = [ NSString stringWithFormat: @"http://www.youtube.com/get_video?fmt=22&video_id=%@&t=%@",
+ video_id, video_hash ];
+ } else {
+ src = [ NSString stringWithFormat: @"http://www.youtube.com/get_video?fmt=18&video_id=%@&t=%@",
+ video_id, video_hash ];
+ }
[ element setAttribute: @"src" value: src ];
[ element setAttribute: @"type" value: @"video/mp4" ];