2012-09-17 13 views
13

Nella mia app, ho un pulsante che, se premuto, consente di guardare un video di YouTube (un trailer di un film). All'interno dell'app, senza avviare il safari. Di seguito puoi vedere uno snippet di codice. Questo codice funziona perfettamente bene con iOS5. Tuttavia, in iOS 6, UIButton in findButtonInView è sempre nullo. Qualche idea quale potrebbe essere la ragione?Riproduzione video YouTube interrotta su iOS6 (funziona perfettamente su 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

Sto usando nuova API iFrame HTML (che è il modo consigliato da BTW) per incorporare i video di YouTube e questa tecnica di riproduzione automatica findButtonInView non ha mai funzionato per me (restituisce null). – msk

+0

@MSK hai un collegamento a un tutorial o uno snippet di codice sull'uso degli iframe? thx –

+0

Vedere la mia domanda e rispondere [qui] (http://stackoverflow.com/questions/10385791/youtube-video-autoplay-inside-uiwebview) – msk

risposta

11

Apple ha cambiato il modo in cui i video di YouTube vengono gestiti in iOS6. Stavo anche usando il metodo findButtonInView ma non funziona più.

Ho scoperto i seguenti sembra funzionare (non testata in 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

Questo non ha funzionato per me :( – asheinfeld

+0

Ho modificato il codice javascript per eseguire il polling dell'elemento finché non è disponibile prima di inviare l'evento click.Questo problema è stato risolto quando l'ho visto su alcuni dispositivi. Fatemi sapere se questo aiuta! – dharmabruce

+0

non funziona anche per me :(qualsiasi altra idea? – 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 usa il gesto per rilevare l'utente tocca ora, dopo aver rilevato il tocco, usa la riproduzione automatica html5. – Steve

+1

Non so se Apple approverà ancora questo, proverò a presentare una versione con questo codice oggi. Vi terremo aggiornati. – Steve

+0

Apple ha approvato la mia app – Steve

1

testato e non sono sicuro se questo è il problema qui, lo stavano ristrutturando non so l'URL stai usando. Ma ho inciampato sul seguente:

A partire da iOS 6, gli URL di YouTube incorporati nel formato http://www.youtube.com/watch?v=oHg5SJYRHA0 non funzioneranno più. Questi URL servono per visualizzare il video sul sito di YouTube, non per l'incorporamento nelle pagine web. Invece, il formato che dovrebbe essere utilizzato è descritto qui: https://developers.google.com/youtube/player_parameters.

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

0

sto lavorando su questo stesso problema generale e io condividere l'approccio che è venuta in mente. Ho alcuni restringimenti da risolvere per la mia situazione particolare, ma l'approccio generale potrebbe funzionare per te, a seconda dei tuoi requisiti di interfaccia utente.

Se si struttura il codice HTML incorporato in modo che il player di YouTube copra l'intero limite di UIWebView, UIWebView diventa effettivamente un grande pulsante di riproduzione: un tocco in qualsiasi punto della sua superficie renderà il lancio del video nel lettore multimediale nativo. Per creare il tuo pulsante, basta coprire UIWebView con un UIView che ha userInteractionEnabled impostato su NO. È importante quale sia la dimensione di UIWebView in questa situazione? Non proprio, dal momento che il video si aprirà comunque nel player nativo.

Se si desidera che l'utente percepisca un'area dell'interfaccia utente come "dove" il video sta per "essere riprodotto", è possibile prendere la miniatura per il video da YouTube e posizionarla ovunque. Se necessario, puoi mettere un secondo UIWebView dietro quella vista, quindi se l'utente tocca quella vista, il video potrebbe anche avviarsi - o semplicemente distribuire l'altra UIWebView in modo che sia "dietro" entrambe le visualizzazioni.

Se pubblichi uno screenshot della tua interfaccia utente, posso dare alcuni suggerimenti più specifici, ma l'idea di base è di trasformare UIWebView in un pulsante mettendo davanti una vista che ha l'interazione dell'utente disabilitata.

0

Ho trovato che il codice qui sotto funziona sia per iOS5 & iOS6. Nel mio esempio, ho un campo di testo che contiene l'url del video. Prima converto i formati nella stessa stringa di partenza "http: // m ...". Quindi controllo se il formato è il vecchio formato con "watch? V =" e poi lo sostituisco con il nuovo formato . ho provato questo su un iPhone con iOS5 e nei simulatori di 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

soluzione dharmabruce funziona alla grande su iOS 6, ma per farlo funzionare su iOS 5.1, ho dovuto sostituire il javascript click() con playVideo(), e ho dovuto impostare mediaPlaybackRequiresUserAction di UIWebView NO

Ecco il codice modificato:

- (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

Sta funzionando per la prima volta. Se voglio guardare un altro video, il codice sopra non funziona. Perché? – Dee

+0

@Dee se la mia risposta - risolve il problema .. –

0

Credo che il problema è che quando webViewDidFinishLoad era innescato, UIButton non è stato ancora aggiunto alla vista. Ho implementato un piccolo ritardo per trovare il pulsante dopo che è stato restituito il callback e funziona per me su ios5 e ios6. inconveniente è che non vi è alcuna garanzia che UIButton sia pronto per essere trovato dopo il ritardo.

- (void)autoplay { 
    UIButton *b = [self findButtonInView:webView]; 
    [b sendActionsForControlEvents:UIControlEventTouchUpInside]; } 

- (void)webViewDidFinishLoad:(UIWebView *)_webView { 
    [self performSelector:@selector(autoplay) withObject:nil afterDelay:0.3]; } 

ho dovuto usare l'url http://www.youtube.com/watch?v=videoid questo è l'unico modo in cui si lavorerà per me

3

ho risolto i problemi con dharmabruce e JimmY2K. soluzioni, con il fatto che funziona solo la prima volta che un video viene riprodotto, come detto da Dee

Ecco il codice (compreso evento quando un video si conclude):

- (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

Ha funzionato. Grazie. – Dee

+1

Per favore scrivi il tuo indirizzo, voglio mandarti un regalo! –

+0

non funziona qui. Ha funzionato una volta forse, ma per la somereason non funziona più. Ho il tuo codice esatto! ios 6.1.x provato in iphone e simulatore stessa cosa –

Problemi correlati