Thayne
Thayne

Reputation: 6992

Youtube iFrame API pauseVideo is undefined in UIWebView

I am developing an app for iPad which contains one or more youtube videos embedded in a UIWebView. I am using the Youtube iframe API. The video shows up fine and the user can use the normal controls fine. However, I want to pause the video when an external event happens.

I am attempting to do this by using stringByEvaluatingJavascripFromString with "player.pauseVideo()". However, on inspection it appears that player.pauseVideo is undefined.

Strangely this only appears to be a problem in the UIWebView (or possibly just iOS) If I load the same page in a desktop browser player.pauseVideo works fine. Furthermore when I inspect the player object in a browser, it says it is a "Y" object, but in the UIWebView it is an "S" object, and most of its methods have obfuscated names.

Any help would be appreciated.

UPDATE: I found a workaround where I use player.getIframe().contentDocument.querySelector('video').pause() but this is not ideal.

Upvotes: 2

Views: 1134

Answers (1)

Brian
Brian

Reputation: 301

I had some trouble with this also. After hunting around SO and re-reading the YouTube iFrame API a few times, here's what I came up with to pause a YouTube video loaded in an iFrame within a UIWebView.

I have a number of UIWebViews in a a paginated UIScrollView, so I have a method where I form an HTML string to be loaded in a UIWebView:

NSString *urlString = [NSString stringWithFormat:@"https://www.youtube.com/embed/%@",videoID];

preparedHTML = [NSString stringWithFormat:@"<html><body style='background:none; text-align:center;'><script type='text/javascript' src='http://www.youtube.com/iframe_api'></script><script type='text/javascript'>var player; function onYouTubeIframeAPIReady(){player=new YT.Player('player')}</script><iframe id='player' class='youtube-player' type='text/html' width='%f' height='%f' src='%@?rel=0&showinfo=0&enablejsapi=1' style='text-align:center; border: 6px solid; border-radius:5px; background-color:transparent;' rel=nofollow allowfullscreen></iframe></body></html>", 628.0f, 352.0f, urlString];

You can ignore the styling stuff in the preparedHTML string. The important aspects are:

  • Using the API to create the "YT.player" object. At one point, I only had the video in the iFrame tag and that prevented me from referencing the "player" object later with JS.
  • I've seen a few examples on the web where the first script tag (the one with the iframe_api src tag) is omitted, but I definitely needed that to get this working.
  • Creating the "player" variable at the beginning of the API script. I have also seen some examples that have omitted that line.
  • Adding an id tag to the iFrame to be referenced in the API script. I almost forgot that part.
  • Adding "enablejsapi=1" to the end of the iFrame src tag. That hung me up for a while, as I initially had it as an attribute of the iFrame tag, which does not work/did not work for me.

When I need to pause the video, I just run this:

[webView stringByEvaluatingJavaScriptFromString:@"player.pauseVideo();"];

I'm probably doing some things in there that are unneccessary, but this is what finally started working for me. Hope it helps!

Upvotes: 2

Related Questions