How to embed a YouTube video in Android Studio | Jetpack Compose

Video thumbnail

I am going to show you the necessary steps to embed a YouTube video in your mobile application. Although I encountered some connection errors during the demo (possibly due to YouTube API restrictions or specific video permissions), the technical procedure is what I will explain below.

Previously we saw the use of the Accelerometer in Android Studio

1. Dependency Configuration (Gradle)

Embedding a YouTube player is not a native functionality of the Android core, so we need to install additional dependencies. For this project, I used the help of an AI to identify the most stable libraries.

You must go to the build.gradle file and add the necessary dependencies. It is very important that you check the versions; for example, I had version 2.1, but the system warned me that 13.0 was already available. I always recommend syncing your project with the most recent versions to avoid compatibility issues.

app/build.gradle.kts

Add and configure the package 


dependencies {
    implementation("com.pierfrancescosoffritti.androidyoutubeplayer:core:13.0.0")
   implementation("androidx.lifecycle:lifecycle-runtime-compose:2.10.0")
}

For a change, I made the modification using the Gemini AI integrated into Android Studio:

Okay, I'll help you with that. I will add and configure the necessary package to play YouTube videos in your Android application. First, I need to modify the build.gradle file.
Got it. Now I'll read the build.gradle.kts file to add the new dependency.
I've added the YouTube player dependency to your build.gradle.kts file. Now I will sync the project.
build.gradle.kts
+1
     implementation(libs.androidx.compose.ui.tooling.preview)
     implementation(libs.androidx.compose.material3)
    implementation("com.pierfrancescosoffritti.androidyoutubeplayer:core:13.0.0")
     implementation(libs.androidx.material3
Add YouTube in Android Studio

 

Just as we use packages from pub.dev in Flutter, in Android we turn to repositories like Maven to obtain these features that do not come by default in Material 3.

Although you can do it manually.

2. Internet Permissions and Manifest

Logically, to play YouTube content we need network access. You must open the AndroidManifest.xml file and add the following permission:

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

Unlike gallery or location permissions (which require runtime user approval since Android 8), the internet permission is configured basically in the manifest and is automatically granted when the app is installed.

3. Composable Implementation and Lifecycle

YouTube does not have an official native "Composable" for Jetpack Compose, so we must use a third-party library and wrap it in an AndroidView (a legacy scheme that allows using old views in Compose):

@Composable
fun YoutubeVideoPlayer(videoId: String) {
    val context = LocalContext.current
    val lifecycleOwner = LocalLifecycleOwner.current

    // Usamos remember para mantener la misma instancia de la vista
    val playerView = remember {
        YouTubePlayerView(context).apply {
            // Añadimos el observador del ciclo de vida
            lifecycleOwner.lifecycle.addObserver(this)

            addYouTubePlayerListener(object : AbstractYouTubePlayerListener() {
                override fun onReady(youTubePlayer: YouTubePlayer) {
                    // Cargamos el video inicial
                    youTubePlayer.loadVideo(videoId, 0f)
                }
            })
        }
    }

    // Limpieza: Cuando el composable sale de la pantalla, quitamos el observador
    DisposableEffect(lifecycleOwner) {
        onDispose {
            lifecycleOwner.lifecycle.removeObserver(playerView)
            playerView.release()
        }
    }

    AndroidView(
        modifier = Modifier
            .fillMaxWidth()
            .padding(8.dp)
            .clip(RoundedCornerShape(12.dp)),
        factory = { playerView }
    )
}

Key points of the code

  • Lifecycle Management: Being a "heavy" component (like the Media Player or the Accelerometer), it is crucial to manage the lifecycle. If the user switches applications or closes the screen, we must release the resources.
  • Remember: We use remember to prevent the player variable from resetting every time the Composable recomposes.
  • DisposableEffect: This is where the cleanup magic happens. When the component leaves the screen, we execute the release() method to stop the video and free up memory.
  • YouTubePlayerView: We configure the player by passing it the video ID (the alphanumeric code that appears in the YouTube URL).

Final Considerations

If the video does not load and shows an error on the screen (as happened to me initially), it may be because the video owner has disabled the "allow embedding" option on external sites.

Always make sure to use libraries that have active maintenance. If you see that a package has not been updated in years, it is better to look for an alternative to avoid failures when Google releases new versions of Android.

What is its main function?

In Android, the "Lifecycle" manages when a screen opens, pauses, or closes. Before this library, connecting Compose with the lifecycle was manual and error-prone (memory leaks).

The previous package introduces tools that allow your @Composable components to observe the application state (whether it is in the foreground or background) automatically.

By adding this dependency, you were able to use:

  • LocalLifecycleOwner.current: This is the line that lets you know which activity or fragment is holding your video at that moment. Without this library, sometimes the compiler does not recognize the reference or does not allow you to access .lifecycle.addObserver().
  • LifecycleResumeEffect / LifecycleEventEffect: (Optional) These are modern functions that replace DisposableEffect to execute code exactly when the user sees the app again or when they minimize it.

Next step, How to show web pages with WebView in Android?

How to embed YouTube videos in Android using Jetpack Compose. Learn how to set up dependencies, manage the lifecycle with DisposableEffect, and use AndroidView.

I agree to receive announcements of interest about this Blog.

Andrés Cruz

ES En español