Android KotlinAndroid tutorial

Androidx Media3 ExoPlayer in Android with Example

Androidx Media3 ExoPlayer View is among the most frequently used UI components found in a variety of applications like YouTube, Netflix, and other online video streaming sites. ExoPlayerView can be used for audio and streaming video in Android applications.

A lot of Google applications use ExoPlayerView to play streaming videos and audio. ExoPlayer is an audio and media player library that allows you to play video and audio with a lot of flexibility in it. It’s a substitute that plays audio and videos in Android alongside MediaPlayer.

ExoPlayer is an app that is the best alternative to playing videos and audio on Android. The library can also assist users to personalize their media player to suit the needs of our users.

ExoPlayer is an app-level player that is that is built upon the low-level media APIs that are available in Android. The ExoPlayer project is an open-source project that is used by Google applications, such as YouTube as well as Google TV. ExoPlayer is extremely flexible and adaptable which makes it able of various advanced usage scenarios. It supports a range of formats for media that include adaptive formats like DASH, as well as smooth streaming.

Androidx Media3 ExoPlayer Prerequisites

  • A basic understanding of Android creation and Android Studio

Which will you do?

  • Set up your own ExoPlayer instance that creates and plays media from various sources.
  • Integration of ExoPlayer with the app’s lifecycle for activities to enable backgrounding, foregrounding, as well as playback resumption, in single or multi-window environments.
  • Make use of the MediaItems to build a playlist.
  • You can play adaptive streams of video that adjust the quality of the media to the bandwidth available.
  • Listeners can register to track playback status and demonstrate what listeners could be utilized to determine the quality of the playback.
  • Utilize the standard ExoPlayer components to create a UI. You can then personalize the components to fit your application’s design.

What do you require

  • The most recent stabile version of Android Studio, and the knowledge to make use of it. Check that you have Android Studio, Android SDK and Gradle plugins that are up-to current.
  • An Android device that runs JellyBean (4.1) or greater and Nougat (7.1) or greater as it allows multiple windows.

Androidx Media3 ExoPlayer in Android with Example

ExoPlayer Pros and pros and

ExoPlayer offers a variety of advantages over the built-in Android MediaPlayer. MediaPlayer:

  • There are fewer device-specific issues and less variations in behavior between different versions and devices of Android.
  • It is possible of updating your player the application. Since ExoPlayer functions as a program is integrated into the application’s apk file it is your choice the version you’re using, and can upgrade to a fresher version through an ongoing update to your application.
  • The capability to modify and expand the capabilities of the player to fit your needs situation. ExoPlayer is specifically designed to meet this need and permits many of the components to be changed with custom-designed implementations.
  • Help for playlists.
  • Assistance for DASH and SmoothStreaming SmoothStreaming, both of which is supported in MediaPlayer. Other formats are supported. Check out the supported formats page for more information.
  • Support for the most advanced HLS features, for example the correct handling of #EXT-X DISCONTINUITY tags.
  • The support for Widevine encryption common for Android 4.4 (API Level 19) and later.
  • The ability to integrate quickly with various other libraries with official extensions. For instance, that the IMA extension lets you earn money from your content using an Interactive Media Ads SDK.

It is important to remember that there are a few negatives

  • To playback audio only on certain gadgets, ExoPlayer may consume significantly more battery than MediaPlayer. Check out this battery consumption section for more details.
  • The inclusion of ExoPlayer within your application adds hundreds of kilobytes to your APK size. This is likely to be an issue for lightweight applications. Guidelines on shrinking ExoPlayer is available in page webpage for APK shrinking.

ExoPlayer in Android with Example

We are going to create an app that plays videos where we’ll be downloading a video from an URL and playing that video within our ExoPlayer. We use Kotlin to implement ExoPlayer on Android.

Step 1:  Create a New Android project Using Kotlin.

Start your android studio and create a new project with the Kotlin language and build it and adding the below dependencies

def mediaVersion = "1.0.0-alpha03"
dependencies {

    implementation 'androidx.core:core-ktx:1.7.0'
    implementation 'androidx.appcompat:appcompat:1.5.1'
    implementation 'com.google.android.material:material:1.7.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.4'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.0'
    implementation 'androidx.appcompat:appcompat:1.4.1'
    implementation "androidx.media3:media3-exoplayer:$mediaVersion"
    implementation "androidx.media3:media3-ui:$mediaVersion"
    implementation "androidx.media3:media3-exoplayer-dash:$mediaVersion"
}

Step 2: Adding Exoplayer layout in main_activity  XML file.

<?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"
    tools:context=".MainActivity">

    <FrameLayout 
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:background="#000000"
        tools:ignore="MissingConstraints">

        <androidx.media3.ui.PlayerView
            android:id="@+id/video_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

    </FrameLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

Step 3 Implement it on the Main Activity Kt file 

Implement the functionality of media3 Exoplayer like play, Push, forward-back, and Forward next for Media streaming with ExoPlayer.

package com.codeplayon.exoplayerexample

import android.annotation.SuppressLint
import android.content.ContentValues.TAG
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.WindowInsetsControllerCompat
import androidx.media3.common.MediaItem
import androidx.media3.common.MimeTypes
import androidx.media3.common.Player
import androidx.media3.common.util.Log
import androidx.media3.common.util.Util
import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.exoplayer.trackselection.DefaultTrackSelector
import androidx.media3.ui.PlayerView

class MainActivity : AppCompatActivity() {


    private val playbackStateListener: Player.Listener = playbackStateListener()
    private var player: ExoPlayer? = null

    private var playWhenReady = true
    private var currentItem = 0
    private var playbackPosition = 0L
    private lateinit var video_view : PlayerView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        video_view = findViewById(R.id.video_view)
    }
    public override fun onStart() {
        super.onStart()
        if (Util.SDK_INT > 23) {
            initializePlayer()
        }
    }

    public override fun onResume() {
        super.onResume()
        hideSystemUi()
        if (Util.SDK_INT <= 23 || player == null) {
            initializePlayer()
        }
    }

    public override fun onPause() {
        super.onPause()
        if (Util.SDK_INT <= 23) {
            releasePlayer()
        }
    }

    public override fun onStop() {
        super.onStop()
        if (Util.SDK_INT > 23) {
            releasePlayer()
        }
    }

    private fun initializePlayer() {
        val trackSelector = DefaultTrackSelector(this).apply {
            setParameters(buildUponParameters().setMaxVideoSizeSd())
        }
        player = ExoPlayer.Builder(this)
            .setTrackSelector(trackSelector)
            .build()
            .also { exoPlayer ->
                video_view.player = exoPlayer

                val mediaItem = MediaItem.Builder()
                    .setUri(getString(R.string.media_url_dash))
                    .setMimeType(MimeTypes.APPLICATION_MPD)
                    .build()
                exoPlayer.setMediaItem(mediaItem)
                exoPlayer.playWhenReady = playWhenReady
                exoPlayer.seekTo(currentItem, playbackPosition)
                exoPlayer.addListener(playbackStateListener)
                exoPlayer.prepare()
            }
    }

    private fun releasePlayer() {
        player?.let { exoPlayer ->
            playbackPosition = exoPlayer.currentPosition
            currentItem = exoPlayer.currentMediaItemIndex
            playWhenReady = exoPlayer.playWhenReady
            exoPlayer.removeListener(playbackStateListener)
            exoPlayer.release()
        }
        player = null
    }

    @SuppressLint("InlinedApi")
    private fun hideSystemUi() {
        WindowCompat.setDecorFitsSystemWindows(window, false)
        WindowInsetsControllerCompat(window, video_view).let { controller ->
            controller.hide(WindowInsetsCompat.Type.systemBars())
            controller.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
        }
    }
}

private fun playbackStateListener() = object : Player.Listener {
    override fun onPlaybackStateChanged(playbackState: Int) {
        val stateString: String = when (playbackState) {
            ExoPlayer.STATE_IDLE -> "ExoPlayer.STATE_IDLE      -"
            ExoPlayer.STATE_BUFFERING -> "ExoPlayer.STATE_BUFFERING -"
            ExoPlayer.STATE_READY -> "ExoPlayer.STATE_READY     -"
            ExoPlayer.STATE_ENDED -> "ExoPlayer.STATE_ENDED     -"
            else -> "UNKNOWN_STATE             -"
        }
        Log.d(TAG, "changed state to $stateString")
    }
}

 

Read More:-