Adding YouTube videos to your Android apps

December 20, 2013

So you want to add a YouTube video to your Android app? Let’s take a look at your options.

WebViews and Embedded YouTube Videos

Android has WebViews, views in which you can load up web pages or your own crafted HTML. You might try writing an HTML iframe and putting your video’s embedded URL in it, like this:

<iframe width="420" height="345" src="http://www.youtube.com/embed/dQw4w9WgXcQ" frameborder="0" allowfullscreen></iframe><br />

You’ll find that you also need to add a smattering of code to get the WebView to display in the iframe:

webView = (WebView) findViewById(R.id.webView);<br />
webView.setWebChromeClient(new WebChromeClient());<br />
webView.getSettings().setPluginState(WebSettings.PluginState.ON);<br />
webView.setWebViewClient(new WebViewClient());<br />
webView.setBackgroundColor(0x00000000);<br />
webView.getSettings().setBuiltInZoomControls(true);</p>
String html = "<iframe width='420' height='345' src='http://www.youtube.com/embed/dQw4w9WgXcQ' frameborder='0' allowfullscreen></iframe>";
webView.loadDataWithBaseURL(null, html, "text/html", "UTF-8", null);

Trying this, you’ll find that the video’s thumbnail appears with the red YouTube play icon and the tracking bar. Didn’t seem so hard, right?

But then you tried to click on the video to play it and it looks like it just keeps trying to load the video and the video never plays or maybe only the audio plays. There’s no fullscreen button, even though you explicitly specified that there be one in the HTML. Sometimes the behavior is different in subtle ways in different versions of Android and what works in one version doesn’t work in another. This doesn’t seem to be working the way you expected it to work.

Instead of an iframe, let’s try putting it in a video tag or an object tag. No improvements or it just got worse? When you try this method in an iOS app’s WebView, clicking on the video pops up a fullscreen video and plays it no problem in its native video player. Why can’t Android do this?

What’s worse is that when you write embedded HTML for your video, you must specify a width and height in pixels. Now you’ll have to go through the trouble of programmatically figuring out the size of the view in which you’re putting this and crafting the correct HTML parameters.

Maybe we’ll use the WebView’s functionality to catch the URL that the video is trying to load and send it through an Intent to the system. That seems to be working but it brought us to a browser or to the YouTube app and we’ve left our app, which makes for a slightly confusing and undesired user experience. What are we going to do?

The Android YouTube Player Library

Fortunately, Google has made a very nice, official YouTube player library that you can stick into your app. You have the option of putting a YouTubePlayerView into your Activity’s layout (but you’ll need to have your Activity extend YouTubeBaseActivity). If your code architecture won’t accommodate this, then you can put a YouTubePlayerFragment or YouTubePlayerSupportFragment (for pre-3.0 apps) into your layout, like so:

<fragment
 android:name="com.google.android.youtube.player.YouTubePlayerSupportFragment"
 android:id="@+id/youTubePlayerFragment"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"/>

If you want to use a fragment in your app, and your app is intended to work on Android versions that pre-dated fragments (version 3.0, API 11), you’ll need to use Android’s v7 support library.

After you go get a YouTube API key from Google, implement initialization of your YouTubePlayerFragment (or YouTubePlayerSupportFragment),

youTubePlayerFragment.initialize("YOUR_YOUTUBE_API_KEY", this);

provide YouTubePlayer.OnInitializedListener, YouTubePlayer.PlaybackEventListener, and YouTubePlayer.OnFullscreenListener implementations,

new YouTubePlayer.OnInitializedListener() {
	@Override
	public void onInitializationFailure(YouTubePlayer.Provider provider, YouTubeInitializationResult error) {
		if (error.isUserRecoverableError()) {
			error.getErrorDialog(this, YOUTUBE_PLAYER_ERROR_RECOVERY_DIALOG).show();
		} else {
			Toast.makeText(this, error.toString(), Toast.LENGTH_LONG).show();
		}
	}
	@Override
	public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer player, boolean wasRestored) {
		youTubePlayer = player;
		if (!wasRestored) {
			youTubePlayer.cueVideo(youTubeVideoId);
		}
		youTubePlayer.setPlaybackEventListener(new YouTubePlayer.PlaybackEventListener() {
			@Override
			public void onPlaying() {
			}
			@Override
			public void onPaused() {
			}
			@Override
			public void onStopped() {
			}
			@Override
			public void onBuffering(boolean isBuffering) {
			}
			@Override
			public void onSeekTo(int newPositionMillis) {
			}
		});
		youTubePlayer.setShowFullscreenButton(true);
		youTubePlayer.setOnFullscreenListener(new YouTubePlayer.OnFullscreenListener() {
			@Override
			public void onFullscreen(boolean isFullScreen) {
				youTubePlayerIsFullScreen = isFullScreen;
			}
		});
	}
}

and start up a video, now you can play videos in exactly the way you and your users would expect a video to behave. You can play the video in its own little view, or you can make it fullscreen. You’ve got a lot more control over the appearance and functionality of the player now, and you can react to events like the video playing or pausing.

Caveats

There’s a couple gotchas that you’ll have to watch out for, though. The YouTube player can detect when another view is overlapping it and it will play for 2 seconds, pause itself, and then tell you about it in LogCat with a message like:

"YouTube video playback stopped due to unauthorized overlay on top of player."

The same goes if you’ve put your player in a ScrollView and have scrolled part or all of the video off of the view. The player will also stop if it becomes smaller than 200 x 110 dp.

Use of the YouTube player also requires that the user have at least version 4.2.16 of the official YouTube app installed on their device. Fortunately, the library provides ways to prompt the user to go and do that easily. A small price to pay for the small size of the library and not having to write your own YouTube player.

Tips

When your video is in fullscreen mode, you would expect hitting the back button to take you out of fullscreen, but instead it’s treated like the back button was hit on your current activity, and exits out of it (or however the back button is handled for your activity). To handle this,

@Override
public void onBackPressed() {
 if (youTubePlayerIsFullScreen){
 youTubePlayer.pause();
 youTubePlayer.setFullscreen(false);
 }
 super.onBackPressed();
}

Speaking of fullscreen mode, YouTubePlayer.FULLSCREEN_FLAG_CONTROL_ORIENTATION is a bitwise flag used to control what happens when you rotate your device while the video is playing fullscreen. When it is on, videos will automatically switch to landscape while fullscreen, and when the device is rotated to portrait, the video will pop out of fullscreen. When it is off, the video will play fullscreen in either landscape or portrait, depending on how your device is rotated. Add this to your player initialization if you want the latter:

int fullScreenFlags = youTubePlayer.getFullscreenControlFlags();
 fullScreenFlags &= ~YouTubePlayer.FULLSCREEN_FLAG_CONTROL_ORIENTATION;
 youTubePlayer.setFullscreenControlFlags(fullScreenFlags);

Don’t forget to put this permission in your AndroidManifest.xml, otherwise none of this will work:

<uses-permission android:name="android.permission.INTERNET" />

In Conclusion

While a bit more work to get off the ground than a simple WebView, Android’s official YouTube player library provides a very nice, user-friendly, and multi-Android version way to play YouTube videos in your app.

Ready to get started?

Call us at 616-594-0269 or send us a note below.
Visit our office @ 452 Ada Drive SE Suite 300 Ada, Michigan 49301
Send us an e-mail @ info@michiganlabs.com