Objective-c – Detecting UIWebView finish to play youtube video on iPad

ipadobjective cuiwebviewyoutube

I'm using UIWebView to play YouTube videos in an iPad.

How can I detect when a YouTube video is finished playing?
I see the play icon in the status bar and I tried to use MPMusicPlayerController notifications to detect playbackStateDidChange, but it didn't work.

Any ideas how to detect this event? Again, I'm talking about iPad not iPhone.

Thanks in advance.

Update:

If you use zero solution to detect the end of playing and also want the Youtube video to start automatically set the UIWebView to :

self.webView.mediaPlaybackRequiresUserAction = NO ;

I just want to clarify about the YouTube frame API:

"Important: This is an experimental feature, which means that it might
change unexpectedly" (08/05/2012)

Best Answer

No, there's no way to directly get web page event from UIWebView. But we can accomplish this by using Javascript.

  • First you use embed Javascript in your custom HTML, to detect video ending play event.
  • Then you try to load a scheme-customized request using JavaScript, and UIWebView could catch the request.

These links may help:

  1. Calling Objective-C from JavaScript in an iPhone UIWebView

  2. Javascript callback in Objective-C

  3. YouTube iFrame API

updated with an example:

in UIWebView's delegate, i put:

#pragma - mark WebView Delegate
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {


if ( [[[request URL] scheme] isEqualToString:@"callback"] ) {

    NSLog(@"get callback");

    return NO;
}

return YES;

}

the web page is load when viewDidLoad:

[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:[[NSBundle       mainBundle] pathForResource:@"youtube" ofType:@"html" ]]]];

and in youtube.html i put:

<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 = "http://www.youtube.com/player_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 onYouTubePlayerAPIReady() {
    player = new YT.Player('player', {
      height: '390',
      width: '640',
      videoId: 'u1zgFlCw8Aw',
      events: {
        'onReady': onPlayerReady,
        'onStateChange': onPlayerStateChange
      }
    });
  }

  // 4. The API will call this function when the video player is ready.
  function onPlayerReady(event) {
    event.target.playVideo();
  }

  // 5. The API calls this function when the player's state changes.
  //    The function indicates that when playing a video (state=1),
  //    the player should play for six seconds and then stop.
  var done = false;
  function onPlayerStateChange(event) {

    if (event.data == YT.PlayerState.PLAYING && !done) {
      setTimeout(stopVideo, 6000);
      done = true;
    }
    if (event.data == YT.PlayerState.ENDED) {
      window.location = "callback:anything"; //here's the key
    };
  }
  function stopVideo() {
    player.stopVideo();
  }
</script>
</body>
</html>

you can see i add

if (event.data == YT.PlayerState.ENDED) {
      window.location = "callback:anything";
    };

to YouTube's iFrame API demo, and it catches the player end playing event and try to load a request with scheme "callback", then the UIWebView Delegate could catch it.

You can use this method to trigger any event using JavaScript;

Related Topic