在我的应用程序中,我有一个按钮,当按下该按钮时,可以让您观看YouTube视频(电影预告片)。在应用程序内,没有启动safari。您可以在下面看到代码段。这个代码在iOS5下运行正常。但是,在iOS 6中,findButtonInView中的UIButton始终为nil。任何想法可能是什么原因?
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;
}
答案 0 :(得分:11)
Apple改变了iOS6中YouTube视频的处理方式。我也使用了findButtonInView方法但不再有效。
我发现以下内容似乎有效(在iOS&lt; 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();\
"];
}
答案 1 :(得分:8)
dharmabruce解决方案在iOS 6上运行良好,但为了使其在iOS 5.1上运行,我不得不用javascript click()替换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();\
"];
}
答案 2 :(得分:3)
我已经解决了 dharmabruce 和 JimmY2K 的问题。解决方案,因为它只在第一次播放视频时才有效,如 Dee
所述以下是代码(包括视频结束时的事件):
- (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;
}
答案 3 :(得分:1)
未经测试且不确定这是否是问题,因为我不知道您正在使用的网址。但我偶然发现了以下情况:
从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/
答案 4 :(得分:0)
我正在研究这个同样的问题,我将分享我提出的方法。我有一些剩余的问题需要解决我的特定情况,但根据您的UI要求,一般方法可能对您有用。
如果您构建HTML嵌入代码以便YouTube播放器覆盖UIWebView的整个范围,那么UIWebView实际上会成为一个重要的播放按钮 - 触摸它表面上的任何位置都会使视频启动到本机媒体播放器中。要创建按钮,只需使用将userInteractionEnabled设置为NO的UIView覆盖UIWebView。 UIWebView在这种情况下的大小是否重要?不是真的,因为视频无论如何都会打开原生播放器。
如果您希望用户将您的UI区域视为视频将“播放”的位置,那么您可以从YouTube获取视频的缩略图并将其放置在任何位置。如果需要,您可以在该视图后面放置第二个UIWebView,因此如果用户触摸该视图,视频也会启动 - 或者只是将其他UIWebView传播出去,以便它们“落后”这两个视图。
如果您发布了UI的屏幕截图,我可以提出一些更具体的建议,但基本的想法是通过在其前面放置禁用了用户交互的视图将UIWebView转换为按钮。
答案 5 :(得分:0)
我发现下面的代码适用于iOS5和iOS iOS6的。在我的示例中,我有一个文本字段,其中包含视频的网址。我首先将格式转换为相同的起始字符串'http:// m ...“。然后我检查格式是否是带有'watch?v ='的旧格式,然后用新格式替换它我已经在iOS5的iOS和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];
}
答案 6 :(得分: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]; }
我必须使用网址http://www.youtube.com/watch?v=videoid这是它对我有用的唯一方式
答案 7 :(得分:-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];
}