How to embed YouTube videos into your Android app using Kotlin

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.

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 questionsplease feel free to leave a comment below

Subscribe
Notify of
guest
24 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments