ExoPlayer in Android Part-1 [kotlin]

Mehedi Hassan Piash
2 min readApr 1, 2022

Sometimes we need the player to play our media either video or audio. Exoplayer is the best choice to play our video and audio.

So what is Exoplayer? ExoPlayer is an application level media player for Android. It provides an alternative to Android’s MediaPlayer API for playing audio and video both locally and over the Internet. ExoPlayer supports features not currently supported by Android’s MediaPlayer API, including DASH and SmoothStreaming adaptive playbacks. Unlike the MediaPlayer API, ExoPlayer is easy to customize and extend, and can be updated through Play Store application updates.

Today we are going to learn how to implement Exoplayer. So let’s start step by step:

Step-1: Add gradle dependency to you build.gradle

implementation 'com.google.android.exoplayer:exoplayer:2.17.1'

Step-2: Add media URL to res/values/string.xml

<string name="media_url_mp3">https://storage.googleapis.com/exoplayer-test-media-0/Jazz_In_Paris.mp3</string>
<!-- Big Buck Bunny video provided by the Blender Foundation.
(c) copyright 2008, Blender Foundation / www.bigbuckbunny.org -->
<string name="media_url_mp4">https://storage.googleapis.com/exoplayer-test-media-0/BigBuckBunny_320x180.mp4</string>
<string name="media_url_dash"><![CDATA[https://www.youtube.com/api/manifest/dash/id/bf5bb2419360daf1/source/youtube?as=fmp4_audio_clear,fmp4_sd_hd_clear&sparams=ip,ipbits,expire,source,id,as&ip=0.0.0.0&ipbits=0&expire=19000000000&signature=51AF5F39AB0CEC3E5497CD9C900EBFEAECCCB5C7.8506521BFC350652163895D4C26DEE124209AA9E&key=ik0]]></string>
<string name="logo">Google logo</string>

Step-3: Add res/layout/fragment_exo_player.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black">

<com.google.android.exoplayer2.ui.PlayerView
android:id="@+id/video_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:show_buffering="when_playing" />

</FrameLayout>

Step-4: Add ExoPlayerFragment

import android.annotation.SuppressLint
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.google.android.exoplayer2.*
import com.google.android.exoplayer2.util.Util
import com.piashcse.experiment.mvvm_hilt.R
import com.piashcse.experiment.mvvm_hilt.databinding.FragmentExoPlayerBinding


class ExoPlayerFragment : Fragment() {
private var _binding: FragmentExoPlayerBinding? = null
private val binding get() = requireNotNull(_binding)

private var player: ExoPlayer? = null

private var playWhenReady = true
private var currentWindow = 0
private var playbackPosition = 0L

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
// Inflate the layout for this fragment
_binding = FragmentExoPlayerBinding.inflate(layoutInflater, container, false)
return binding.root
}

override fun onStart() {
super.onStart()
if (Util.SDK_INT > 23) {
initializePlayer()
}
}

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

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

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

private fun initializePlayer() {
player = ExoPlayer.Builder(requireContext())
.build()
.also { exoPlayer ->
binding.videoView.player = exoPlayer

val mediaItem = MediaItem.fromUri(getString(R.string.media_url_mp4))
exoPlayer.setMediaItem(mediaItem)
// val secondMediaItem = MediaItem.fromUri(getString(R.string.media_url_mp3))
// exoPlayer.addMediaItem(secondMediaItem)
exoPlayer.playWhenReady = playWhenReady
exoPlayer.seekTo(currentWindow, playbackPosition)
exoPlayer.prepare()
}
}

private fun releasePlayer() {
player?.run {
playbackPosition = this.currentPosition
currentWindow = this.currentMediaItemIndex
playWhenReady
= this.playWhenReady
release()
}
player = null
}

@SuppressLint("InlinedApi")
private fun hideSystemUi() {
binding.videoView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LOW_PROFILE
or View.SYSTEM_UI_FLAG_FULLSCREEN
or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION)
}
}

Ref:
Github: https://github.com/piashcse/blog_piashcse_code/blob/master/MVVM_Hilt/app/src/main/java/com/piashcse/experiment/mvvm_hilt/ui/exoplyer/ExoPlayerFragment.kt

Blog: http://piashcse.blogspot.com/2022/03/exoplayer-in-android-part-1kotlin.html

--

--

Mehedi Hassan Piash

Senior Software Engineer @Field Nation | Android | Kotlin | Compose | Kmp | React-Native