Last updated on: May 27, 2023
In this tutorial, I’m going to show you how to embed a YouTube video in your android app with three different methods using the official library (YouTube Player API), a 3rd party library called Android YouTube Player, and WebView.
Contents
1st Method (YouTube Player API)
Pros
- The official library provided by YouTube
Cons
- Has bugs that haven’t been fixed since 2015
- Need an API KEY
- Doesn’t get updates anymore
YouTube Player API is the official way to embed a youtube video in your android app. The problem with this library is they don’t maintain it anymore, the latest update was in 2015 (1.2.2 version), but besides that, it’s a recommended method if you don’t want to display many videos in your app.
Get the API KEY from Google
First, we must get our API key from the Google Developers Console.
Let’s create a project by pressing the ‘CREATE‘ button:
In the new window, type a name for the project and press ‘CREATE‘:
Go back to the Dashboard and press the ‘ENABLE APIS AND SERVICES‘ button:
Now, we have to find the YouTube Data API v3, use the search bar at the top of the screen to find it quicker, and enable it:
Now, choose Credentials on the left sidebar and press Create credentials.
In the dropdown menu, choose API KEY:
Done! We have generated our API KEY, and it’s ready to use in our embedded YouTube Player later.
Add YouTube Player API to our app
First, we have to add the library to our project. Let’s go and download the jar file from here.
After downloading it, unzip it, go to the libs folder and copy the YouTubeAndroidPlayerApi.jar file.
Now go to our project and change from Android to Project in the dropdown menu, and paste the jar file like that:
Now, let’s insert the libs folder (if it does not already exist) in our project by adding the following line in our build.gradle file:
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
// ...
}
Code language: Kotlin (kotlin)
Because the YouTube Player API it’s old, it doesn’t have AndroidX support. But there is a fix for that!
Right-click on your project, choose New > Package, delete the name (e.g., com.johncodeos.youtubeexample), and type com.google.android.youtube.player:
After that, you will not see the package folder we created. To see it, go to the dropdown menu on the top left again, and change it from Android to Project
Next, right-click on the com.google.android.youtube.player folder, create a new Kotlin class file, name it YouTubePlayerSupportFragmentX and paste the following code inside :
package com.google.android.youtube.player
import android.os.Bundle
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.google.android.youtube.player.internal.ab
// source : https://gist.github.com/medyo/f226b967213c3b8ec6f6bebb5338a492#file-youtubeplayersupportfragmentx-java
open class YouTubePlayerSupportFragmentX : Fragment(), YouTubePlayer.Provider {
private val a: A = A()
private var b: Bundle? = null
private var c: YouTubePlayerView? = null
private var d: String? = null
private var e: YouTubePlayer.OnInitializedListener? = null
private val f = false
private fun a() {
if (c != null && e != null) {
c?.a(f)
c?.a(this.activity, this, d, e, b)
b = null
e = null
}
}
override fun initialize(p0: String?, p1: YouTubePlayer.OnInitializedListener?) {
this.d = ab.a(p0, "Developer key cannot be null or empty")
this.e = p1
this.a()
}
override fun onCreate(var1: Bundle?) {
super.onCreate(var1)
b = var1?.getBundle("YouTubePlayerSupportFragment.KEY_PLAYER_VIEW_STATE")
}
override fun onCreateView(var1: LayoutInflater, var2: ViewGroup?, var3: Bundle?): View? {
c = YouTubePlayerView(this.activity, null as AttributeSet?, 0, a)
this.a()
return c
}
override fun onStart() {
super.onStart()
c?.a()
}
override fun onResume() {
super.onResume()
c?.b()
}
override fun onPause() {
c?.c()
super.onPause()
}
override fun onSaveInstanceState(var1: Bundle) {
super.onSaveInstanceState(var1)
val var2 = if (c != null && c is YouTubePlayerView) {
(c as YouTubePlayerView).e()
} else b
var1.putBundle("YouTubePlayerSupportFragment.KEY_PLAYER_VIEW_STATE", var2)
}
override fun onStop() {
c?.d()
super.onStop()
}
override fun onDestroyView() {
this.activity?.let {
c?.c(it.isFinishing)
c = null
}
super.onDestroyView()
}
override fun onDestroy() {
if (c != null && c is YouTubePlayerView) {
val var1 = this.activity
(c as YouTubePlayerView).b(var1 == null || var1.isFinishing)
}
super.onDestroy()
}
companion object {
fun newInstance(): YouTubePlayerSupportFragmentX {
return YouTubePlayerSupportFragmentX()
}
}
private class A : YouTubePlayerView.b {
override fun a(
p0: YouTubePlayerView?,
p1: String?,
p2: YouTubePlayer.OnInitializedListener?
) {
val fragment = newInstance()
fragment.initialize(p1, fragment.e)
}
override fun a(p0: YouTubePlayerView?) {
// do nothing
}
}
}
Code language: Kotlin (kotlin)
Now it’s time to add the YouTube player view to our layout by adding it like that:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimary"
tools:context=".YouTubePlayerAPIActivity">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/youtube_player_view_layout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="@android:color/black"
app:layout_constraintDimensionRatio="H,16:9"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/official_player_view"
android:name="com.google.android.youtube.player.YouTubePlayerSupportFragmentX"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
Code language: HTML, XML (xml)
Let’s go to our Kotlin class with the YouTube view and add the following code:
class YouTubePlayerAPIActivity : AppCompatActivity(), YouTubePlayer.OnInitializedListener {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_youtube_player_api)
val youTubePlayerFragment =
supportFragmentManager.findFragmentById(R.id.official_player_view) as YouTubePlayerSupportFragmentX
youTubePlayerFragment.initialize("YOUR_API_KEY", this)
}
override fun onInitializationSuccess(
provider: YouTubePlayer.Provider,
youTubePlayer: YouTubePlayer,
wasRestored: Boolean
) {
if (!wasRestored) {
youTubePlayer.cueVideo("YE7VzlLtp-4")
}
}
override fun onInitializationFailure(
provider: YouTubePlayer.Provider,
youTubeInitializationResult: YouTubeInitializationResult
) {
if (youTubeInitializationResult.isUserRecoverableError) {
youTubeInitializationResult.getErrorDialog(this, RECOVERY_DIALOG_REQUEST).show()
} else {
val errorMessage = String.format(
"There was an error initializing the YouTubePlayer (%1\$s)",
youTubeInitializationResult.toString()
)
Toast.makeText(this, errorMessage, Toast.LENGTH_LONG).show()
}
}
companion object {
const val RECOVERY_DIALOG_REQUEST = 1
}
}
Code language: Kotlin (kotlin)
Next, replace YOUR_API_KEY with the API KEY we created before.
Run your project and see the results!
2nd Method (3rd Party Library Android YouTube Player)
Pros
- Highly customizable
- Gets updates
- It’s the fastest of the other two methods
- It doesn’t need an API KEY
- Plays also copyrighted videos (e.g., music videos)
Cons
- Some devs have reported that their app has been rejected from the Google Play Store. (It never happened to me)
In this method, we will use the 3rd party library Android YouTube Player, made by Pierfrancesco Soffritti, to embed our YouTube video into our app.
Add Android YouTube Player Library to our app
Let’s start by adding the library to the build.gradle file:
dependencies {
// ...
implementation 'com.pierfrancescosoffritti.androidyoutubeplayer:core:11.0.1'
// ...
}
Code language: Kotlin (kotlin)
Not let’s add our Youtube view to our layout like the following example:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimary"
tools:context=".AndroidYoutubePlayerActivity">
<com.pierfrancescosoffritti.androidyoutubeplayer.core.player.views.YouTubePlayerView
android:id="@+id/third_party_player_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
Code language: HTML, XML (xml)
Let’s go to our Kotlin class with the youtube view and add the following code:
class AndroidYoutubePlayerActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_android_youtube_player)
val thirdPartyYouTubePlayerView =
findViewById<YouTubePlayerView>(R.id.third_party_player_view)
thirdPartyYouTubePlayerView.enableAutomaticInitialization =
false // We set it to false because we init it manually
val listener: YouTubePlayerListener = object : AbstractYouTubePlayerListener() {
override fun onReady(youTubePlayer: YouTubePlayer) {
// We're using pre-made custom ui
val defaultPlayerUiController =
DefaultPlayerUiController(thirdPartyYouTubePlayerView, youTubePlayer)
defaultPlayerUiController.showFullscreenButton(true)
// When the video is in full-screen, cover the entire screen
defaultPlayerUiController.setFullScreenButtonClickListener {
if (thirdPartyYouTubePlayerView.isFullScreen()) {
thirdPartyYouTubePlayerView.exitFullScreen()
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE
// Show ActionBar
if (supportActionBar != null) {
supportActionBar!!.show()
}
} else {
thirdPartyYouTubePlayerView.enterFullScreen()
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_FULLSCREEN
// Hide ActionBar
if (supportActionBar != null) {
supportActionBar!!.hide()
}
}
}
thirdPartyYouTubePlayerView.setCustomPlayerUi(defaultPlayerUiController.rootView)
val videoId = "YE7VzlLtp-4"
youTubePlayer.cueVideo(videoId, 0f)
}
}
// Disable iFrame UI
val options: IFramePlayerOptions = IFramePlayerOptions.Builder().controls(0).build()
thirdPartyYouTubePlayerView.initialize(listener, options)
}
}
Code language: Kotlin (kotlin)
Here, we have a listener for the full-screen button. When the user opens the video in full-screen mode, we hide the ActionBar and the StatusBar (available only for Android 4.1 and above) and unhide them when we close it.
For more customization, check out the documentation here.
.. and done!
3rd Method(WebView)
Pros
- Very quick to setup
- Doesn’t need an API KEY.
- No need to install any library
Cons
- It doesn’t play copyrighted videos (It says ‘Video unavailable’)
- Poor performance
- Zero customization
Add YouTube Player with WebView into our app
First, let’s add a WebView into our layout like that:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimary"
tools:context=".WebViewActivity">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/youtube_player_view_layout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="@android:color/black"
app:layout_constraintDimensionRatio="H,16:9"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<WebView
android:id="@+id/webview_player_view"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
Code language: HTML, XML (xml)
Now, in our Kotlin class, let’s add the following code:
@SuppressLint("SetJavaScriptEnabled")
class WebViewActivity : AppCompatActivity() {
private lateinit var webView: WebView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_web_view)
webView = findViewById(R.id.webview_player_view)
webView.webViewClient = WebViewClient()
webView.webChromeClient = CustomChromeClient() // Full-screen support
val webSettings = webView.settings
webSettings.javaScriptEnabled = true
webSettings.allowFileAccess = true
if (savedInstanceState == null) {
webView.loadUrl("https://www.youtube.com/embed/YE7VzlLtp-4")
}
}
private inner class CustomChromeClient : WebChromeClient() {
private var mCustomView: View? = null
private var mCustomViewCallback: CustomViewCallback? = null
private var mOriginalOrientation = 0
private var mOriginalSystemUiVisibility = 0
override fun getDefaultVideoPoster(): Bitmap? {
return if (mCustomView == null) {
null
} else BitmapFactory.decodeResource(applicationContext.resources, 2130837573)
}
override fun onHideCustomView() {
(window.decorView as FrameLayout).removeView(mCustomView)
mCustomView = null
window.decorView.systemUiVisibility = mOriginalSystemUiVisibility
requestedOrientation = mOriginalOrientation
mCustomViewCallback!!.onCustomViewHidden()
mCustomViewCallback = null
}
override fun onShowCustomView(
paramView: View?,
paramCustomViewCallback: CustomViewCallback?
) {
if (mCustomView != null) {
onHideCustomView()
return
}
mCustomView = paramView
mOriginalSystemUiVisibility = window.decorView.systemUiVisibility
mOriginalOrientation = requestedOrientation
mCustomViewCallback = paramCustomViewCallback
(window.decorView as FrameLayout).addView(mCustomView, FrameLayout.LayoutParams(-1, -1))
window.decorView.systemUiVisibility = 3846 or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
}
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
webView.saveState(outState)
}
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
super.onRestoreInstanceState(savedInstanceState)
webView.restoreState(savedInstanceState)
}
}
Code language: Kotlin (kotlin)
We need to enable javascript in our WebView to play embedded YouTube videos.
Run it… and Voilà !
You can find the final project here
If you have any questions, please feel free to leave a comment below