<p>This post is about how to implement caching using ExoPlayer in Android. To learn about how to implement Exoplayer Library to play media files on Android visit <span style="color: #0000ff;"><strong><a style="color: #0000ff;" href="https://c1ctech.com/android-exoplayer-example-in-kotlin/">here</a></strong></span>.</p> 
 
 
 
<div class="wp-block-buttons is-content-justification-center is-layout-flex wp-block-buttons-is-layout-flex"> 
<div class="wp-block-button"><a class="wp-block-button__link has-background" style="background-color: #170675;" href="https://github.com/arunk7839/ExoplayerCachingExp"><strong>DOWNLOAD CODE</strong></a></div> 
</div> 
<div> </div> 
<div> 
<p><amp-youtube layout="responsive" width="1200" height="675" data-videoid="FSSZ6q-x0SU" title="Android Caching in ExoPlayer in kotlin"><a placeholder href="https://www.youtube.com/watch?v=FSSZ6q-x0SU"><img src="https://i.ytimg.com/vi/FSSZ6q-x0SU/hqdefault.jpg" layout="fill" object-fit="cover" alt="Android Caching in ExoPlayer in kotlin"></a></amp-youtube></p> 
<p>Let’s create a simple video player app in which we will be fetching a video from a URL and cache (inside device memory) and play that video inside our ExoPlayer. </p> 
<h3><span style="color: #000080;"><strong>Creating new Project</strong></span></h3> 
<p>1 . Create a new project by going to <span style="color: #008000;"><b>File </b><span class="s1"><b>⇒</b></span></span><b><span style="color: #008000;"> New Android Project</span>,</b> select <span style="color: #008000;"><strong>Empty Activity</strong></span>, provide <span style="color: #008000;"><strong>app name</strong></span>, select language to <strong><span style="color: #0000ff;">kotlin</span> </strong>and then finally click on <span style="color: #008000;"><strong>finish</strong></span>.</p> 
<p>2 . Open app-level <span style="color: #008000;"><strong>build.gradle</strong></span> file, add the dependency of<strong> <span style="color: #008000;">ExoPlayer</span></strong> in the dependencies section, and <span style="color: #008000;"><strong>sync</strong></span> the project.</p> 
<p><span style="color: #0000ff;"><strong>build.gradle</strong></span></p> 
<pre>dependencies {<br /> <span style="color: #008000;"><strong> //exoplayer dependency</strong></span><br /> implementation 'com.google.android.exoplayer:exoplayer:2.15.0'<br />}</pre> 
<p>3. Go to <span style="color: #008000;"><strong>AndroidManifest.xml</strong></span> and add the internet permission above <span style="color: #008000;"><strong><;application>;</strong></span> tag as shown below:</p> 
<p><span style="color: #0000ff;"><strong>AndroidManifest.xml</strong></span></p> 
<pre><;uses-permission android:name="android.permission.INTERNET"/>;</pre> 
<p>4. Open the layout file <strong><span style="color: #008000;">activity_main.xml</span> </strong>and add the <span style="color: #0000ff;"><strong>PlayerView</strong></span> as shown below:</p> 
<p><span style="color: #0000ff;"><strong>activity_main.xml</strong></span></p> 
<pre><;?xml version="1.0" encoding="utf-8"?>;<br /><;androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"<br /> xmlns:app="http://schemas.android.com/apk/res-auto"<br /> xmlns:tools="http://schemas.android.com/tools"<br /> android:layout_width="match_parent"<br /> android:layout_height="match_parent">;<br /><br /> <span style="color: #008000;"><strong> <;com.google.android.exoplayer2.ui.PlayerView</strong></span><br /><span style="color: #008000;"><strong> android:id="@+id/playerView"</strong></span><br /><span style="color: #008000;"><strong> android:layout_width="match_parent"</strong></span><br /><span style="color: #008000;"><strong> android:layout_height="match_parent" />;</strong></span><br /><br /><;/androidx.constraintlayout.widget.ConstraintLayout>;</pre> 
<p>5. Create a new kotlin class inside package folder, named it as <strong><span style="color: #008000;">MyApp.kt</span></strong> and add the below code:</p> 
<p><span style="color: #0000ff;"><strong>MyApp.kt</strong></span></p> 
<pre>package com.c1ctech.exoplayercachingexp<br /><br />import android.app.Application<br />import com.google.android.exoplayer2.database.ExoDatabaseProvider<br />import com.google.android.exoplayer2.upstream.cache.LeastRecentlyUsedCacheEvictor<br />import com.google.android.exoplayer2.upstream.cache.SimpleCache<br /><br />class MyApp : Application() {<br /><br /> companion object {<br /> lateinit var simpleCache: SimpleCache<br /> const val exoPlayerCacheSize: Long = 90 * 1024 * 1024<br /> lateinit var leastRecentlyUsedCacheEvictor: LeastRecentlyUsedCacheEvictor<br /> lateinit var exoDatabaseProvider: ExoDatabaseProvider<br /> }<br /><br /> override fun onCreate() {<br /> super.onCreate()<br /> leastRecentlyUsedCacheEvictor = LeastRecentlyUsedCacheEvictor(exoPlayerCacheSize)<br /> exoDatabaseProvider = ExoDatabaseProvider(this)<br /> simpleCache = SimpleCache(cacheDir, leastRecentlyUsedCacheEvictor, exoDatabaseProvider)<br /> }<br />}</pre> 
<p>In the above code,</p> 
<p><span style="color: #0000ff;"><strong>SimpleCache</strong></span>: Constructs the cache. It takes three parameters :</p> 
<ul> 
<li><span style="color: #008000;"><strong>cacheDir</strong></span> – A dedicated cache directory where we want to cache video.</li> 
<li><strong><span style="color: #008000;">LeastRecentlyUsedCacheEvictor</span></strong>– When the cache size is reached out, it will automatically find and remove files which least recently used.</li> 
<li><strong><span style="color: #008000;">databaseProvider</span></strong> – Provides the database in which the cache index is stored.</li> 
</ul> 
<p>6. Open <strong><span style="color: #008000;">AndroidManifest.xml</span></strong> file and define the Application class using the <span style="color: #008000;"><strong>name</strong></span> property inside <strong><span style="color: #008000;"><;application>;</span></strong> tag.</p>
<!-- WP QUADS Content Ad Plugin v. 2.0.98.1 -->
<div class="quads-location quads-ad2" id="quads-ad2" style="float:none;margin:0px;">

</div>
 
<pre><;application<br /> <span style="color: #0000ff;"><strong> android:name=".MyApp"</strong></span><br /> android:allowBackup="true"<br /> android:icon="@mipmap/ic_launcher"<br /> android:label="@string/app_name"<br /> android:roundIcon="@mipmap/ic_launcher_round"<br /> android:supportsRtl="true"<br /> android:theme="@style/Theme.ExoplayerCachingExp">;<br /> <;activity<br /> android:name=".MainActivity"<br /> android:exported="true">;<br /> <;intent-filter>;<br /> <;action android:name="android.intent.action.MAIN" />;<br /><br /> <;category android:name="android.intent.category.LAUNCHER" />;<br /> <;/intent-filter>;<br /> <;/activity>;<br /><;/application>;</pre> 
<p>7. Open <span style="color: #008000;"><strong>MainActivity.kt</strong></span> and add the below code:</p> 
<p><span style="color: #0000ff;"><strong>MainActivity.kt</strong></span></p> 
<pre>package com.c1ctech.exoplayercachingexp<br /><br />import android.net.Uri<br />import androidx.appcompat.app.AppCompatActivity<br />import android.os.Bundle<br />import com.google.android.exoplayer2.MediaItem<br />import com.google.android.exoplayer2.Player<br />import com.google.android.exoplayer2.SimpleExoPlayer<br />import com.google.android.exoplayer2.source.DefaultMediaSourceFactory<br />import com.google.android.exoplayer2.source.ProgressiveMediaSource<br />import com.google.android.exoplayer2.ui.PlayerView<br />import com.google.android.exoplayer2.upstream.DataSource<br />import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory<br />import com.google.android.exoplayer2.upstream.DefaultHttpDataSource<br />import com.google.android.exoplayer2.upstream.HttpDataSource<br />import com.google.android.exoplayer2.upstream.cache.CacheDataSource<br />import com.google.android.exoplayer2.upstream.cache.SimpleCache<br />import com.google.android.exoplayer2.util.Util<br /><br />class MainActivity : AppCompatActivity() {<br /><br /> private lateinit var httpDataSourceFactory: HttpDataSource.Factory<br /> private lateinit var defaultDataSourceFactory: DefaultDataSourceFactory<br /> private lateinit var cacheDataSourceFactory: DataSource.Factory<br /> private lateinit var simpleExoPlayer: SimpleExoPlayer<br /> private val simpleCache: SimpleCache = MyApp.simpleCache<br /><br /> private var mPlayer: SimpleExoPlayer? = null<br /> private lateinit var playerView: PlayerView<br /> private val videoURL = "https://sample-videos.com/video123/mp4/720/big_buck_bunny_720p_1mb.mp4"<br /><br /><br /> override fun onCreate(savedInstanceState: Bundle?) {<br /> super.onCreate(savedInstanceState)<br /> setContentView(R.layout.activity_main)<br /><br /> <strong><span style="color: #008000;">//get PlayerView by its id</span></strong><br /> playerView = findViewById(R.id.playerView)<br /> }<br /><br /> private fun initPlayer() {<br /><br /> httpDataSourceFactory = DefaultHttpDataSource.Factory()<br /> .setAllowCrossProtocolRedirects(true)<br /><br /> defaultDataSourceFactory = DefaultDataSourceFactory(<br /> applicationContext, httpDataSourceFactory<br /> )<br /><br /> <strong><span style="color: #008000;">//A DataSource that reads and writes a Cache.</span></strong><br /> cacheDataSourceFactory = CacheDataSource.Factory()<br /> .setCache(simpleCache)<br /> .setUpstreamDataSourceFactory(httpDataSourceFactory)<br /> .setFlags(CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR)<br /><br /><span style="color: #008000;"><strong> // Create a player instance and set mediaSourceFactory.</strong></span><br /> simpleExoPlayer = SimpleExoPlayer.Builder(this)<br /> .setMediaSourceFactory(DefaultMediaSourceFactory(cacheDataSourceFactory)).build()<br /><br /> val videoUri = Uri.parse(videoURL)<br /> val mediaItem = MediaItem.fromUri(videoUri)<br /> val mediaSource =<br /> ProgressiveMediaSource.Factory(cacheDataSourceFactory).createMediaSource(mediaItem)<br /><br /> <strong><span style="color: #008000;">// Bind the player to the view.</span></strong><br /> playerView.player = simpleExoPlayer<br /><br /> <strong><span style="color: #008000;">//setting exoplayer when it is ready.</span></strong><br /> simpleExoPlayer.playWhenReady = true<br /><br /><strong><span style="color: #008000;"> //Seeks to a position specified in milliseconds in the specified window.</span></strong><br /> simpleExoPlayer.seekTo(0, 0)<br /><br /><strong><span style="color: #008000;"> //set repeat mode.</span></strong><br /> simpleExoPlayer.repeatMode = Player.REPEAT_MODE_OFF<br /><br /><strong><span style="color: #008000;"> // Set the media source to be played.</span></strong><br /> simpleExoPlayer.setMediaSource(mediaSource, true)<br /><br /><strong><span style="color: #008000;"> // Prepare the player.</span></strong><br /> simpleExoPlayer.prepare()<br /> }<br /><br /><br /> override fun onStart() {<br /> super.onStart()<br /> if (Util.SDK_INT >;= 24) {<br /> initPlayer()<br /> }<br /> }<br /><br /> override fun onResume() {<br /> super.onResume()<br /> if (Util.SDK_INT <; 24 || mPlayer == null) {<br /> initPlayer()<br /> }<br /> }<br /><br /> override fun onPause() {<br /> super.onPause()<br /> if (Util.SDK_INT <; 24) {<br /> releasePlayer()<br /> }<br /> }<br /><br /> override fun onStop() {<br /> super.onStop()<br /> if (Util.SDK_INT >;= 24) {<br /> releasePlayer()<br /> }<br /> }<br /><br /> private fun releasePlayer() {<br /> if (mPlayer == null) {<br /> return<br /> }<br /><span style="color: #008000;"><strong> //release player when done</strong></span><br /> mPlayer!!.release()<br /> mPlayer = null<br /> }<br />}</pre> 
<p><span style="color: #0000ff;"><strong>CacheDataSourceFactory</strong></span> : Constructs a factory which creates <span style="color: #008000;"><strong>CacheDataSource</strong></span> instance for reading and writing the cache.</p> 
<pre>httpDataSourceFactory = DefaultHttpDataSource.Factory()<br /> .setAllowCrossProtocolRedirects(true)<br /><br />cacheDataSourceFactory = CacheDataSource.Factory()<br /> .setCache(simpleCache)<br /> .setUpstreamDataSourceFactory(httpDataSourceFactory)<br /> .setFlags(CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR)</pre> 
<p>When you run the app it will look like this as shown below:</p> 
<p><img class="wp-image-2808 aligncenter" src="https://c1ctech.com/wp-content/uploads/2021/09/Screenshot_20210928-152949_ExoplayerCachingExp-498x1024.jpg" alt="" width="310" height="637" /></p> 
</div> 


