YouTube上的video播放在iOS6上破解(在iOS5上正常工作)

在我的应用程序中,我有一个button,当按下它时,可以让您观看YouTubevideo(电影预告片)。 在应用程序内,不用启动Safari。 下面你可以看到一个代码片段。 这个代码可以在iOS5下正常工作。 但是,在iOS 6中,findButtonInView中的UIButton始终为零。 任何想法可能是什么原因?

youtubeWebView.delegate = self; youtubeWebView.backgroundColor = [UIColor clearColor]; NSString* embedHTML = @" <html><head> <style type=\"text/css\"> body {background-color: transparent; color: white; }</style></head><body style=\"margin:0\"><embed id=\"yt\" src=\"%@?version=3&app=youtube_gdata\" type=\"application/x-shockwave-flash\"width=\"%0.0f\" height=\"%0.0f\"></embed></body></html>"; NSURL *movieTrailer; if(tmdbMovie) movieTrailer = tmdbMovie.trailer; else movieTrailer = [NSURL URLWithString:movie.trailerURLString]; NSString *html = [NSString stringWithFormat:embedHTML, movieTrailer, youtubeWebView.frame.size.width, youtubeWebView.frame.size.height]; [youtubeWebView loadHTMLString:html baseURL:nil]; [self addSubview:youtubeWebView]; - (void)webViewDidFinishLoad:(UIWebView *)_webView { isWatchTrailerBusy = NO; [manager displayNetworkActivityIndicator:NO]; //stop the activity indicator and enable the button UIButton *b = [self findButtonInView:_webView]; //TODO this returns null in case of iOS 6, redirect to the youtube app if(b == nil) { NSURL *movieTrailer; if(tmdbMovie) { movieTrailer = tmdbMovie.trailer; } else { movieTrailer = [NSURL URLWithString:movie.trailerURLString]; } [[UIApplication sharedApplication] openURL:movieTrailer]; } else { [b sendActionsForControlEvents:UIControlEventTouchUpInside]; } } - (UIButton *)findButtonInView:(UIView *)view { UIButton *button = nil; if ([view isMemberOfClass:[UIButton class]]) { return (UIButton *)view; } if (view.subviews && [view.subviews count] > 0) { for (UIView *subview in view.subviews) { button = [self findButtonInView:subview]; if (button) return button; } } return button; } 

苹果改变了在iOS6中处理YouTubevideo的方式。 我也正在使用findButtonInView方法,但不再有效。

我发现以下似乎工作(未经testing在iOS <6):

 - (void)viewDidLoad { [super viewDidLoad]; self.webView.mediaPlaybackRequiresUserAction = NO; } - (void)playVideo { self.autoPlay = YES; // Replace @"y8Kyi0WNg40" with your YouTube video id [self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@%@", @"http://www.youtube.com/embed/", @"y8Kyi0WNg40"]]]]; } // UIWebView delegate - (void)webViewDidFinishLoad:(UIWebView *)webView { if (self.autoPlay) { self.autoPlay = NO; [self clickVideo]; } } - (void)clickVideo { [self.webView stringByEvaluatingJavaScriptFromString:@"\ function pollToPlay() {\ var vph5 = document.getElementById(\"video-player\");\ if (vph5) {\ vph5.playVideo();\ } else {\ setTimeout(pollToPlay, 100);\ }\ }\ pollToPlay();\ "]; } 

dharmabruce解决scheme在iOS 6上效果很好,但为了使它在iOS 5.1上工作,我必须用playVideo()replacejavascript click(),并且必须将UIWebView的mediaPlaybackRequiresUserAction设置为NO

这是修改的代码:

 - (void)viewDidLoad { [super viewDidLoad]; self.webView.mediaPlaybackRequiresUserAction = NO; } - (void)playVideo { self.autoPlay = YES; // Replace @"y8Kyi0WNg40" with your YouTube video id [self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@%@", @"http://www.youtube.com/embed/", @"y8Kyi0WNg40"]]]]; } // UIWebView delegate - (void)webViewDidFinishLoad:(UIWebView *)webView { if (self.autoPlay) { self.autoPlay = NO; [self clickVideo]; } } - (void)clickVideo { [self.webView stringByEvaluatingJavaScriptFromString:@"\ function pollToPlay() {\ var vph5 = document.getElementById(\"video-player-html5\");\ if (vph5) {\ vph5.playVideo();\ } else {\ setTimeout(pollToPlay, 100);\ }\ }\ pollToPlay();\ "]; } 

我已经用dharmabruceJimmY2K解决了这个问题。 解决scheme,事实上,只有在第一次播放video时,正如Dee所提到的

这里是代码(包括video结束时的事件):

 - (void)embedYouTube:(NSString *)urlString frame:(CGRect)frame { videoView = [[UIWebView alloc] init]; videoView.frame = frame; videoView.delegate = self; [videoView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:urlString]]];// this format: http://www.youtube.com/embed/xxxxxx [self.view addSubview:videoView]; //https://github.com/nst/iOS-Runtime-Headers/blob/master/Frameworks/MediaPlayer.framework/MPAVController.h [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackDidEnd:) name:@"MPAVControllerItemPlaybackDidEndNotification"//@"MPAVControllerPlaybackStateChangedNotification" object:nil]; } - (void)webViewDidFinishLoad:(UIWebView *)webView { //http://stackoverflow.com/a/12504918/860488 [videoView stringByEvaluatingJavaScriptFromString:@"\ var intervalId = setInterval(function() { \ var vph5 = document.getElementById(\"video-player\");\ if (vph5) {\ vph5.playVideo();\ clearInterval(intervalId);\ } \ }, 100);"]; } - (void)playbackDidEnd:(NSNotification *)note { [videoView removeFromSuperview]; videoView.delegate = nil; videoView = nil; } 

未经testing,不知道这是否是这里的问题,因为我不知道您使用的url。 但是我偶然发现以下几点:

从iOS 6开始,以http://www.youtube.com/watch?v=oHg5SJYRHA0格式embedded的YouTubeurl将不再有效。 这些url用于在YouTube网站上查看video,而不是embedded到网页中。 相反,应该使用的格式在这里描述: https : //developers.google.com/youtube/player_parameters 。

来自http://thetecherra.com/2012/09/12/ios-6-gm-released-full-changelog-inside/

我正在研究同样的一般问题,我将分享我提出的方法。 我还有一些问题可以解决我的具体情况,但是一般的方法可能适用于您,取决于您的UI要求。

如果您构buildHTMLembedded代码,以便YouTube播放器覆盖UIWebView的整个边界,则该UIWebView将有效地变成一个大型播放button – 在表面上的任何地方都可以将video发送到本机媒体播放器中。 要创build您的button,只需使用将UI设置为NO的UIView覆盖UIWebView即可。 在这种情况下,UIWebView的尺寸是多less? 不是,因为无论如何,video都会打开本地播放器。

如果您希望用户将video的某个区域视为video要“播放”的位置,则可以从YouTube获取video的缩略图,并将其放在任何位置。 如果需要的话,你可以在该视图后面放置第二个UIWebView,所以如果用户触摸该视图,video也将启动 – 或者仅仅传播另一个UIWebView,使其位于这两个视图的“后面”。

如果您发布了UI的屏幕截图,我可以提出一些更具体的build议,但基本的想法是将UIWebView变成一个button,方法是在用户交互禁用的前面放置一个视图。

我发现下面的代码适用于iOS5和iOS6。 在我的例子中,我有一个文本字段,其中包含video的url。 我首先将格式转换为相同的起始string“http:// m …”,然后检查格式是否为带有“watch?v =”的旧格式,然后将其replace为新格式我已经在iOS5的iPhone上和iOS5和iOS6的模拟器上testing过了:

 -(IBAction)loadVideoAction { [activityIndicator startAnimating]; NSString *urlString = textFieldView.text; urlString = [urlString stringByReplacingOccurrencesOfString:@"http://www.youtube" withString:@"http://m.youtube"]; urlString = [urlString stringByReplacingOccurrencesOfString:@"http://m.youtube.com/watch?v=" withString:@""]; urlString = [NSString stringWithFormat:@"%@%@", @"http://www.youtube.com/embed/", urlString]; [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:urlString]]]; } - (void)webViewDidFinishLoad:(UIWebView *)webView { [activityIndicator stopAnimating]; } 

我相信问题是,当webViewDidFinishLoad被触发,UIButton没有被添加到视图呢。 callback回来后,我实现了一个小的延迟findbutton,它适用于我在ios5和ios6。 缺点是不能保证UIButton在延迟之后能够被发现。

 - (void)autoplay { UIButton *b = [self findButtonInView:webView]; [b sendActionsForControlEvents:UIControlEventTouchUpInside]; } - (void)webViewDidFinishLoad:(UIWebView *)_webView { [self performSelector:@selector(autoplay) withObject:nil afterDelay:0.3]; } 

我不得不使用urlhttp://www.youtube.com/watch?v=videoid这是唯一的方式,它会为我工作

 - (void) performTapInView: (UIView *) view { BOOL found = NO; if ([view gestureRecognizers] != nil) { for (UIGestureRecognizer *gesture in [view gestureRecognizers]) { if ([gesture isKindOfClass: [UITapGestureRecognizer class]]) { if ([gesture.view respondsToSelector: @selector(_singleTapRecognized:)]) { found = YES; [gesture.view performSelector: @selector(_singleTapRecognized:) withObject: gesture afterDelay: 0.07]; break; } } } } if (!found) { for (UIView *v in view.subviews) { [self performTapInView: v]; } } } #pragma mark - UIWebViewDelegate methods - (void) webViewDidFinishLoad: (UIWebView *) webView { if (findWorking) { return; } findWorking = YES; [self performTapInView: webView]; }