2012-09-17 32 views
13

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

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; 
} 
+1

HTML iframe API(这是BTW推荐的方式)嵌入YouTube视频和这种自动播放技术findButtonInView从来没有为我工作(返回null)。 – msk

+0

@MSK您是否有指向使用iframe的教程或代码片段的链接? thx –

+0

看到我的问题和答案[这里](http://stackoverflow.com/questions/10385791/youtube-video-autoplay-inside-uiwebview) – msk

回答

11

Apple改变了在iOS6中处理YouTube视频的方式。我也使用findButtonInView方法,但不再有效。

我发现下面似乎工作(未经测试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();\ 
    "]; 
} 
+0

这对我不起作用:( – asheinfeld

+0

我修改了javascript代码来查询元素,直到它在发送click事件之前都可用,这样就解决了我在某些设备上看到的问题,请让我知道这是否有帮助! – dharmabruce

+0

也不适用于我:(任何其他想法? – Piero

-1
- (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]; 
} 
+0

iOS 6.0使用手势检测用户点击现在,点击后检测到使用html5自动播放。 – Steve

+1

我不知道苹果是否会批准这个,但是今天会尝试使用此代码提交一个版本。会让你们张贴。 – Steve

+0

苹果认可我的应用 – Steve

1

未经测试,不知道是否是这里的问题是,becasue我不知道网址你正在使用。但我偶然发现以下内容:

从iOS 6开始,以http://www.youtube.com/watch?v=oHg5SJYRHA0的形式嵌入的YouTube网址将不再有效。这些网址用于在YouTube网站上查看视频,而不是嵌入到网页中。相反,应该使用的格式如下所示:https://developers.google.com/youtube/player_parameters

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

0

我工作的这个相同的一般问题,我将分享的方法,我想出来的。我还有一些问题可以解决我的具体情况,但一般方法可能适用于您,具体取决于您的UI要求。

如果您构建HTML嵌入代码以便YouTube播放器覆盖UIWebView的整个范围,则该UIWebView实际上会变成一个大型播放按钮 - 它表面上的任意位置的触摸都会使视频启动进入本地媒体播放器。要创建您的按钮,只需使用UIInViewView和一个UIView将userInteractionEnabled设置为NO。这与UIWebView在这种情况下的大小有什么关系?并非如此,因为视频无论如何都会打开本地播放器。

如果您希望用户将用户界面的某个区域视为视频将要“播放”的位置,那么您可以从YouTube获取视频的缩略图并将其放在任何位置。如果需要的话,您可以在该视图后面放置第二个UIWebView,因此如果用户触及该视图,视频也将启动 - 或者仅将其他UIWebView展开,以使其位于这两个视图的“后面”。

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

0

我发现下面的代码适用于iOS5 & iOS6。在我的示例中,我有一个文本字段,其中包含视频的网址。我首先将格式转换为相同的起始字符串'http:// m ...',然后检查格式是否为带'watch?v ='的旧格式,然后将其替换为新格式我测试过这对iOS5的iPhone手机,并在iOS5的& iOS6的模拟器:

-(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]; 
} 
8

dharmabruce解决方案在iOS 6上的伟大工程,但为了使其在iOS 5的工作。1,我不得不替代的JavaScript点击()的调用playVideo(),我只好一个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();\ 
    "]; 
} 
+1

这是第一次工作。如果我想观看另一个视频,上面的代码不起作用。为什么? – Dee

+0

@Dee我的答案 - 它解决了这个问题.. –

0

我相信问题是,当webViewDidFinishLoad是触发,UIButton尚未添加到视图中。在回调返回后,我实现了一个小的延迟来查找按钮,它适用于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]; } 

我不得不使用url http://www.youtube.com/watch?v=videoid这仅仅是它的工作对我来说

3

我已经解决了这个问题dharmabruceJimmY2K的方式。解决方案的事实,它只能在第一时间的视频播放,通过

这里提到的是代码(当影片结束,包括事件):我现在用新

- (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; 
} 
+0

它的工作。谢谢。 – Dee

+1

请写下你的地址,我想送你一份礼物! –

+0

在这里不起作用。 它曾经工作过一次,但因为某些原因,它不再有效。我有你的确切代码! ios 6.1.x尝试在iphone和模拟器相同的东西 –

相关问题