51 votes

Comment recevoir NSNotifications de UIWebView intégré vidéo YouTube de lecture

Je n'ai pas reçu de notifications pour MPMoviePlayerController. Ce que je fais mal?

J'utilise la suite logique.

Je suis en commençant à lire des vidéos youtube en UIWebView. UIWebView des appels standard MPMoviePlayerController. Je n'ai pas de contrôle MPMoviePlayerController parce que je n'ai pas instancier MPMoviePlayerController.

Je run youtube du clip avec l'exécution automatique (1 seconde de retard):

[self performSelector:@selector(touchInView:) withObject:b afterDelay:1];

Mon code est:

- (void)viewDidLoad
{
    [super viewDidLoad];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(loadStateDidChange:) name:MPMoviePlayerLoadStateDidChangeNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackDidFinish:) name:MPMoviePlayerDidExitFullscreenNotification object:nil];

    [self embedYouTube];
}

- (void)loadStateDidChange:(NSNotification*)notification
{
    NSLog(@"________loadStateDidChange");
}

- (void)playbackDidFinish:(NSNotification*)notification
{
    NSLog(@"________DidExitFullscreenNotification");
}

- (void)embedYouTube
{
    CGRect frame = CGRectMake(25, 89, 161, 121);
    NSString *urlString = [NSString stringWithString:@"http://www.youtube.com/watch?v=sh29Pm1Rrc0"];

    NSString *embedHTML = @"<html><head>\
    <body style=\"margin:0\">\
    <embed id=\"yt\" src=\"%@\" type=\"application/x-shockwave-flash\" \
    width=\"%0.0f\" height=\"%0.0f\"></embed>\
    </body></html>";
    NSString *html = [NSString stringWithFormat:embedHTML, urlString, frame.size.width, frame.size.height];
    UIWebView *videoView = [[UIWebView alloc] initWithFrame:frame];
    videoView.delegate = self;

    for (id subview in videoView.subviews)
        if ([[subview class] isSubclassOfClass: [UIScrollView class]])
            ((UIScrollView *)subview).bounces = NO;

            [videoView loadHTMLString:html baseURL:nil];
    [self.view addSubview:videoView];
    [videoView release];
}

- (void)webViewDidFinishLoad:(UIWebView *)_webView 
{
    UIButton *b = [self findButtonInView:_webView];
    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(touchInView:) object:b];
    [self performSelector:@selector(touchInView:) withObject:b afterDelay:1];
}

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

- (void)touchInView:(UIButton*)b
{
    [b sendActionsForControlEvents:UIControlEventTouchUpInside];
}

Mise à JOUR: je suis en création d'application qui joue de la vidéo de youtube. Vous pouvez exécuter la liste de lecture et vous permettra de voir la première vidéo. Lors de la première vidéo est terminée, la seconde de la vidéo commence à jouer automatiquement et ainsi de suite.

J'ai besoin de soutien ios 4.1 et supérieur.

UPDATE2: @H2CO3 je suis en train d'utiliser votre url, mais il ne fonctionne pas. Délégué de la méthode n'a pas appelé à la sortie de l'événement. J'ai ajouté mon code html url pour vous connecter. C'est:

<html><head>    <body style="margin:0">    
<script>function endMovie() 
{document.location.href="somefakeurlscheme://video-ended";} 
 </script>      <embed id="yt" src="http://www.youtube.com/watch?v=sh29Pm1Rrc0"        
 onended="endMovie()" type="application/x-shockwave-flash"  
 width="161" height="121"></embed>  
 </body></html>

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
  if ([[[request URL] absoluteString] hasPrefix:@"somefakeurlscheme://video-ended"]) 
  {
    [self someMethodSupposedToDetectVideoEndedEvent];
    return NO; // prevent really loading the URL
   }
  return YES; // else load the URL as desired
}

UPDATE3 @Till, je cann pas pris UIMoviePlayerControllerDidExitFullscreennotification, mais j'ai trouvé MPAVControllerItemPlaybackDidEndnotification. MPAVControllerItemPlaybackDidEndnotification s'affiche lorsque la lecture de la vidéo est terminée.

Mais je ne comprends pas comment faire des captures onDone notifications?

64voto

Till Points 20820

Il n'y a pas documenté les notifications envoyées par l' UIWebView intégré de l'acteur de cinéma.

En fait, le clos de la mise en œuvre utilisés au sein de l' UIWebView ne diffèrent du public MPMoviePlayerController sur de nombreux aspects (par exemple, les DRM).

Les classes les plus importantes utilisées pour la lecture de contenu vidéo à l'intérieur de cette UIWebView sont appelés MPAVController et UIMoviePlayerController. La dernière rend le joueur apparaît comme l' MPMoviePlayerController plein écran de l'interface.

Dans le cas où vous osez le risque d'un rejet par Apple, il ya effectivement des façons de toujours obtenir ce que vous cherchez.

NOTE Ce n'est pas documentée et est soumis à la pause sur chaque nouvelle version d'iOS. Il ne fait toutefois travailler sur iOS4.3, de la 5.0 5.01, 5.1 et 6.0 et il peut travailler sur d'autres versions.

Je ne suis pas en mesure de tester cette solution sur iOS 4.1 et 4.2, donc c'est à vous de le faire. Je soupçonne fortement qu'il va travailler.


Fullscreen État

Si, par exemple vous avez l'intention de réagir à l'utilisateur appuyant sur le FAIT bouton, vous pourriez être en mesure de le faire de cette façon:

Mise à JOUR de L'ancienne version de cette réponse recommandé d'utiliser UIMoviePlayerControllerDidExitFullscreenNotification alors même que cette nouvelle version (mise à jour pour iOS6) recommande l'utilisation d' UIMoviePlayerControllerWillExitFullscreenNotification.

C-Niveau De Langue:

void PlayerWillExitFullscreen (CFNotificationCenterRef center,
                 void *observer,
                 CFStringRef name,
                 const void *object,
                 CFDictionaryRef userInfo)
{
    //do something...
}

CFNotificationCenterAddObserver(CFNotificationCenterGetLocalCenter(), 
    NULL, 
    PlayerWillExitFullscreen, 
    CFSTR("UIMoviePlayerControllerWillExitFullscreenNotification"), 
    NULL,  
    CFNotificationSuspensionBehaviorDeliverImmediately);

Objective-C Niveau:

- (void)playerWillExitFullscreen:(NSNotification *)notification
{
    //do something...
}

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(playerWillExitFullscreen:)
                                             name:@"UIMoviePlayerControllerWillExitFullscreenNotification" 
                                           object:nil];

Je ne projet de les deux, de Niveau C et Objective-C au Niveau des options, parce que la meilleure façon de savoir ce qu'il en est d'utiliser le C-Level (CoreFoundation) fonctions comme indiqué en fin de ma réponse. Si l'expéditeur d'une notification de ne pas utiliser Objective-C (NSNotifications), vous pouvez effectivement ne pas être en mesure de les piéger à l'aide de la NSNotification-mécanique.


L'État De Lecture

Pour l'examen de l'état de lecture, "MPAVControllerPlaybackStateChangedNotification" (tel que rédigé ci-dessus) et d'examiner l' userInfo qui peut ressembler à ceci:

{
    MPAVControllerNewStateParameter = 1;
    MPAVControllerOldStateParameter = 2;
}

En Outre, L'Ingénierie Inverse

La rétro-ingénierie et l'exploration de toutes les notifications envoyées, utilisez l'extrait de code suivant.

void MyCallBack (CFNotificationCenterRef center,
                 void *observer,
                 CFStringRef name,
                 const void *object,
                 CFDictionaryRef userInfo)
{
    NSLog(@"name: %@", name);
    NSLog(@"userinfo: %@", userInfo);
}

CFNotificationCenterAddObserver(CFNotificationCenterGetLocalCenter(), 
    NULL, 
    MyCallBack, 
    NULL, 
    NULL,  
    CFNotificationSuspensionBehaviorDeliverImmediately);

32voto

ChrisJP Points 610

Dans iOS 4.3+, vous pouvez utiliser l' UIMoviePlayerControllerDidEnterFullscreenNotification et UIMoviePlayerControllerDidExitFullscreenNotification notifications:

-(void)viewDidLoad
{

    ...

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(youTubeStarted:) name:@"UIMoviePlayerControllerDidEnterFullscreenNotification" object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(youTubeFinished:) name:@"UIMoviePlayerControllerDidExitFullscreenNotification" object:nil];
}

-(void)youTubeStarted:(NSNotification *)notification{
    // your code here
}

-(void)youTubeFinished:(NSNotification *)notification{
    // your code here
}

6voto

Fábio Oliveira Points 1599

Basé sur l' @H2CO3 réponse, mais avec l' iframe de l'API. C'était la seule façon que je pouvais le faire fonctionner.

Ce n'est pas l'utilisation privée de l'API qui le rend plus fiable pour l'avenir.

Voici le code pour intégrer votre vidéo sur Youtube. Vérifier l'API pour plus de façons de personnaliser cette.

<html>
  <body>
  <!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
  <div id="player"></div>

  <script>
  // 2. This code loads the IFrame Player API code asynchronously.
    var tag = document.createElement('script');

    tag.src = "https://www.youtube.com/iframe_api";
    var firstScriptTag = document.getElementsByTagName('script')[0];
    firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
    // 3. This function creates an <iframe> (and YouTube player)
    //    after the API code downloads.
    var player;
    function onYouTubeIframeAPIReady() {
      player = new YT.Player('player', {
        height: '480',
        width: '640',
        videoId: 'aiugvdk755f',
        events: {
          'onStateChange': onPlayerStateChange
        }
      });
    }
    // 5. The API calls this function when the player's state changes.
    function onPlayerStateChange(event) {
      if (event.data == YT.PlayerState.ENDED) {
        endedMovie();
      }
    }
    function endedMovie() {
      // detect the event here
      document.location.href="somefakeurlscheme://video-ended";
    }
  </script>
  </body>
</html>

Et ce est la façon dont vous êtes averti que la vidéo terminée (UIWebViewDelegate méthode).

- (BOOL) webView:(UIWebView *)wv shouldStartLoadWithRequest:(NSURLRequest *)req {
    if ([[[req URL] absoluteString] hasPrefix:@"somefakeurlscheme://video-ended"]) {
        [self someMethodSupposedToDetectVideoEndedEvent];
        return NO; // prevent really loading the URL
    }
    return YES; // else load the URL as desired
 }

5voto

Prabhu Natarajan Points 360

dans le ViewDidLoad ajoutez le code suivant

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(VideoExitFullScreen:) name:@"UIMoviePlayerControllerDidExitFullscreenNotification" object:nil];

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(VideoEnterFullScreen:) name:@"UIMoviePlayerControllerDidEnterFullscreenNotification" object:nil];

Les méthodes suivantes sont pour montrer le message/fonctions respectives processus d'entrée/sortie vers/à partir plein écran

- (void)VideoExitFullScreen:(id)sender{
// Your respective content/function for Exit from full screen
}

- (void)VideoEnterFullScreen:(id)sender{
// Your respective content/function for Enter to full screen
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X