Mehedi Hassan Piash [Sr. Software Engineer]

March 31, 2022

ExoPlayer in Android Part-1 [kotlin]

March 31, 2022 Posted by Piash , No comments

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

implementation 'com.google.android.exoplayer:exoplayer:2.17.1'
<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>
<?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>
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)
}
}