13

私のアプリには、押すとYouTubeビデオ(映画の予告編)を見ることができるボタンがあります。アプリ内で、サファリを起動せずに。以下にコード スニペットを示します。このコードは、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;
}
4

8 に答える 8

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();\
     "];
}
于 2012-09-20T01:12:54.623 に答える
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();\
     "];
}
于 2012-11-05T15:24:23.770 に答える
3

dharmabruceJimmY2Kの問題を解決しました。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;
}
于 2013-03-08T13:00:14.147 に答える
1

あなたが使用している URL がわからないため、テストされておらず、それが問題かどうかはわかりません。しかし、私は次のことについて正しくつまずきました:

iOS 6 以降、埋め込みの YouTube URL は機能しhttp://www.youtube.com/watch?v=oHg5SJYRHA0なくなります。これらの URL は、YouTube サイトでビデオを表示するためのものであり、Web ページに埋め込むためのものではありません。代わりに、使用する必要がある形式については、https ://developers.google.com/youtube/player_parameters で説明されています。

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

于 2012-09-26T07:11:20.237 に答える
0

私はこれと同じ一般的な問題に取り組んでおり、私が思いついたアプローチを共有します。特定の状況で解決するためのいくつかの問題が残っていますが、UI要件によっては、一般的なアプローチでうまくいく場合があります。

YouTubeプレーヤーがUIWebViewの境界全体をカバーするように、HTML埋め込みコードを構造化すると、そのUIWebViewは事実上大きな再生ボタンになります。その表面のどこかにタッチすると、ネイティブメディアプレーヤーでビデオが起動します。ボタンを作成するには、userInteractionEnabledがNOに設定されているUIViewでUIWebViewをカバーするだけです。この状況でUIWebViewのサイズは重要ですか?とにかくビデオがネイティブプレーヤーに開かれるので、実際にはそうではありません。

UIの領域をビデオが「再生」される場所としてユーザーに認識させたい場合は、YouTubeからビデオのサムネイルを取得して、どこにでも配置できます。必要に応じて、2番目のUIWebViewをそのビューの後ろに配置して、ユーザーがそのビューに触れると、ビデオも起動します。または、他のUIWebViewを広げて、これらのビューの両方の「後ろ」に配置します。

UIのスクリーンショットを投稿すると、より具体的な提案をすることができますが、基本的な考え方は、UIWebViewの前に、ユーザー操作が無効になっているビューを配置することで、UIWebViewをボタンに変えることです。

于 2012-10-01T17:52:01.423 に答える
0

以下のコードは、iOS5 と iOS6 の両方で機能することがわかりました。私の例では、ビデオへの URL を含むテキスト フィールドがあります。最初にフォーマットを同じ開始文字列 '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];
}
于 2012-11-02T13:48:40.977 に答える
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を使用する必要がありました。これが唯一の方法です。

于 2012-12-20T04:46:32.057 に答える
-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];
}
于 2012-09-24T06:54:06.330 に答える