Site icon C1CTech

ExoPlayer audio caching in Android

&NewLine;<p>This post is about how to implement caching using ExoPlayer in Android&period; To learn about how to implement Exoplayer Library to play media files on Android visit <span style&equals;"color&colon; &num;0000ff&semi;"><strong><a style&equals;"color&colon; &num;0000ff&semi;" href&equals;"https&colon;&sol;&sol;c1ctech&period;com&sol;android-exoplayer-example-in-kotlin&sol;">here<&sol;a><&sol;strong><&sol;span>&period;<&sol;p> &NewLine; &NewLine; &NewLine; &NewLine;<div class&equals;"wp-block-buttons is-content-justification-center is-layout-flex wp-block-buttons-is-layout-flex"> &NewLine;<div class&equals;"wp-block-button"><a class&equals;"wp-block-button&lowbar;&lowbar;link has-background" style&equals;"background-color&colon; &num;170675&semi;" href&equals;"https&colon;&sol;&sol;github&period;com&sol;arunk7839&sol;ExoplayerCachingExp"><strong>DOWNLOAD CODE<&sol;strong><&sol;a><&sol;div> &NewLine;<&sol;div> &NewLine;<div> <&sol;div> &NewLine;<div> &NewLine;<p><amp-youtube layout&equals;"responsive" width&equals;"1200" height&equals;"675" data-videoid&equals;"FSSZ6q-x0SU" title&equals;"Android Caching in ExoPlayer in kotlin"><a placeholder href&equals;"https&colon;&sol;&sol;www&period;youtube&period;com&sol;watch&quest;v&equals;FSSZ6q-x0SU"><img src&equals;"https&colon;&sol;&sol;i&period;ytimg&period;com&sol;vi&sol;FSSZ6q-x0SU&sol;hqdefault&period;jpg" layout&equals;"fill" object-fit&equals;"cover" alt&equals;"Android Caching in ExoPlayer in kotlin"><&sol;a><&sol;amp-youtube><&sol;p> &NewLine;<p>Let’s create a simple video player app in which we will be fetching a video from a URL and cache &lpar;inside device memory&rpar; and play that video inside our ExoPlayer&period; <&sol;p> &NewLine;<h3><span style&equals;"color&colon; &num;000080&semi;"><strong>Creating new Project<&sol;strong><&sol;span><&sol;h3> &NewLine;<p>1 &period; Create a new project by going to <span style&equals;"color&colon; &num;008000&semi;"><b>File <&sol;b><span class&equals;"s1"><b>&Implies;<&sol;b><&sol;span><&sol;span><b><span style&equals;"color&colon; &num;008000&semi;"> New Android Project<&sol;span>&comma;<&sol;b> select <span style&equals;"color&colon; &num;008000&semi;"><strong>Empty Activity<&sol;strong><&sol;span>&comma; provide <span style&equals;"color&colon; &num;008000&semi;"><strong>app name<&sol;strong><&sol;span>&comma; select language to <strong><span style&equals;"color&colon; &num;0000ff&semi;">kotlin<&sol;span> <&sol;strong>and then finally click on <span style&equals;"color&colon; &num;008000&semi;"><strong>finish<&sol;strong><&sol;span>&period;<&sol;p> &NewLine;<p>2 &period; Open app-level <span style&equals;"color&colon; &num;008000&semi;"><strong>build&period;gradle<&sol;strong><&sol;span> file&comma; add the dependency of<strong> <span style&equals;"color&colon; &num;008000&semi;">ExoPlayer<&sol;span><&sol;strong> in the dependencies section&comma; and <span style&equals;"color&colon; &num;008000&semi;"><strong>sync<&sol;strong><&sol;span> the project&period;<&sol;p> &NewLine;<p><span style&equals;"color&colon; &num;0000ff&semi;"><strong>build&period;gradle<&sol;strong><&sol;span><&sol;p> &NewLine;<pre>dependencies &lbrace;<br &sol;> <span style&equals;"color&colon; &num;008000&semi;"><strong> &sol;&sol;exoplayer dependency<&sol;strong><&sol;span><br &sol;> implementation 'com&period;google&period;android&period;exoplayer&colon;exoplayer&colon;2&period;15&period;0'<br &sol;>&rcub;<&sol;pre> &NewLine;<p>3&period; Go to <span style&equals;"color&colon; &num;008000&semi;"><strong>AndroidManifest&period;xml<&sol;strong><&sol;span> and add the internet permission above <span style&equals;"color&colon; &num;008000&semi;"><strong>&lt&semi;application&gt&semi;<&sol;strong><&sol;span> tag as shown below&colon;<&sol;p> &NewLine;<p><span style&equals;"color&colon; &num;0000ff&semi;"><strong>AndroidManifest&period;xml<&sol;strong><&sol;span><&sol;p> &NewLine;<pre>&lt&semi;uses-permission android&colon;name&equals;"android&period;permission&period;INTERNET"&sol;&gt&semi;<&sol;pre> &NewLine;<p>4&period; Open the layout file <strong><span style&equals;"color&colon; &num;008000&semi;">activity&lowbar;main&period;xml<&sol;span> <&sol;strong>and add the <span style&equals;"color&colon; &num;0000ff&semi;"><strong>PlayerView<&sol;strong><&sol;span> as shown below&colon;<&sol;p> &NewLine;<p><span style&equals;"color&colon; &num;0000ff&semi;"><strong>activity&lowbar;main&period;xml<&sol;strong><&sol;span><&sol;p> &NewLine;<pre>&lt&semi;&quest;xml version&equals;"1&period;0" encoding&equals;"utf-8"&quest;&gt&semi;<br &sol;>&lt&semi;androidx&period;constraintlayout&period;widget&period;ConstraintLayout xmlns&colon;android&equals;"http&colon;&sol;&sol;schemas&period;android&period;com&sol;apk&sol;res&sol;android"<br &sol;> xmlns&colon;app&equals;"http&colon;&sol;&sol;schemas&period;android&period;com&sol;apk&sol;res-auto"<br &sol;> xmlns&colon;tools&equals;"http&colon;&sol;&sol;schemas&period;android&period;com&sol;tools"<br &sol;> android&colon;layout&lowbar;width&equals;"match&lowbar;parent"<br &sol;> android&colon;layout&lowbar;height&equals;"match&lowbar;parent"&gt&semi;<br &sol;><br &sol;> <span style&equals;"color&colon; &num;008000&semi;"><strong> &lt&semi;com&period;google&period;android&period;exoplayer2&period;ui&period;PlayerView<&sol;strong><&sol;span><br &sol;><span style&equals;"color&colon; &num;008000&semi;"><strong> android&colon;id&equals;"&commat;&plus;id&sol;playerView"<&sol;strong><&sol;span><br &sol;><span style&equals;"color&colon; &num;008000&semi;"><strong> android&colon;layout&lowbar;width&equals;"match&lowbar;parent"<&sol;strong><&sol;span><br &sol;><span style&equals;"color&colon; &num;008000&semi;"><strong> android&colon;layout&lowbar;height&equals;"match&lowbar;parent" &sol;&gt&semi;<&sol;strong><&sol;span><br &sol;><br &sol;>&lt&semi;&sol;androidx&period;constraintlayout&period;widget&period;ConstraintLayout&gt&semi;<&sol;pre> &NewLine;<p>5&period; Create a new kotlin class inside package folder&comma; named it as <strong><span style&equals;"color&colon; &num;008000&semi;">MyApp&period;kt<&sol;span><&sol;strong> and add the below code&colon;<&sol;p> &NewLine;<p><span style&equals;"color&colon; &num;0000ff&semi;"><strong>MyApp&period;kt<&sol;strong><&sol;span><&sol;p> &NewLine;<pre>package com&period;c1ctech&period;exoplayercachingexp<br &sol;><br &sol;>import android&period;app&period;Application<br &sol;>import com&period;google&period;android&period;exoplayer2&period;database&period;ExoDatabaseProvider<br &sol;>import com&period;google&period;android&period;exoplayer2&period;upstream&period;cache&period;LeastRecentlyUsedCacheEvictor<br &sol;>import com&period;google&period;android&period;exoplayer2&period;upstream&period;cache&period;SimpleCache<br &sol;><br &sol;>class MyApp &colon; Application&lpar;&rpar; &lbrace;<br &sol;><br &sol;> companion object &lbrace;<br &sol;> lateinit var simpleCache&colon; SimpleCache<br &sol;> const val exoPlayerCacheSize&colon; Long &equals; 90 &ast; 1024 &ast; 1024<br &sol;> lateinit var leastRecentlyUsedCacheEvictor&colon; LeastRecentlyUsedCacheEvictor<br &sol;> lateinit var exoDatabaseProvider&colon; ExoDatabaseProvider<br &sol;> &rcub;<br &sol;><br &sol;> override fun onCreate&lpar;&rpar; &lbrace;<br &sol;> super&period;onCreate&lpar;&rpar;<br &sol;> leastRecentlyUsedCacheEvictor &equals; LeastRecentlyUsedCacheEvictor&lpar;exoPlayerCacheSize&rpar;<br &sol;> exoDatabaseProvider &equals; ExoDatabaseProvider&lpar;this&rpar;<br &sol;> simpleCache &equals; SimpleCache&lpar;cacheDir&comma; leastRecentlyUsedCacheEvictor&comma; exoDatabaseProvider&rpar;<br &sol;> &rcub;<br &sol;>&rcub;<&sol;pre> &NewLine;<p>In the above code&comma;<&sol;p> &NewLine;<p><span style&equals;"color&colon; &num;0000ff&semi;"><strong>SimpleCache<&sol;strong><&sol;span>&colon; Constructs the cache&period; It takes three parameters &colon;<&sol;p> &NewLine;<ul> &NewLine;<li><span style&equals;"color&colon; &num;008000&semi;"><strong>cacheDir<&sol;strong><&sol;span> – A dedicated cache directory where we want to cache video&period;<&sol;li> &NewLine;<li><strong><span style&equals;"color&colon; &num;008000&semi;">LeastRecentlyUsedCacheEvictor<&sol;span><&sol;strong>– When the cache size is reached out&comma; it will automatically find and remove files which least recently used&period;<&sol;li> &NewLine;<li><strong><span style&equals;"color&colon; &num;008000&semi;">databaseProvider<&sol;span><&sol;strong> – Provides the database in which the cache index is stored&period;<&sol;li> &NewLine;<&sol;ul> &NewLine;<p>6&period; Open <strong><span style&equals;"color&colon; &num;008000&semi;">AndroidManifest&period;xml<&sol;span><&sol;strong> file and define the Application class using the <span style&equals;"color&colon; &num;008000&semi;"><strong>name<&sol;strong><&sol;span> property inside <strong><span style&equals;"color&colon; &num;008000&semi;">&lt&semi;application&gt&semi;<&sol;span><&sol;strong> tag&period;<&sol;p>&NewLine;<&excl;-- WP QUADS Content Ad Plugin v&period; 2&period;0&period;98&period;1 -->&NewLine;<div class&equals;"quads-location quads-ad2" id&equals;"quads-ad2" style&equals;"float&colon;none&semi;margin&colon;0px&semi;">&NewLine;&NewLine;<&sol;div>&NewLine; &NewLine;<pre>&lt&semi;application<br &sol;> <span style&equals;"color&colon; &num;0000ff&semi;"><strong> android&colon;name&equals;"&period;MyApp"<&sol;strong><&sol;span><br &sol;> android&colon;allowBackup&equals;"true"<br &sol;> android&colon;icon&equals;"&commat;mipmap&sol;ic&lowbar;launcher"<br &sol;> android&colon;label&equals;"&commat;string&sol;app&lowbar;name"<br &sol;> android&colon;roundIcon&equals;"&commat;mipmap&sol;ic&lowbar;launcher&lowbar;round"<br &sol;> android&colon;supportsRtl&equals;"true"<br &sol;> android&colon;theme&equals;"&commat;style&sol;Theme&period;ExoplayerCachingExp"&gt&semi;<br &sol;> &lt&semi;activity<br &sol;> android&colon;name&equals;"&period;MainActivity"<br &sol;> android&colon;exported&equals;"true"&gt&semi;<br &sol;> &lt&semi;intent-filter&gt&semi;<br &sol;> &lt&semi;action android&colon;name&equals;"android&period;intent&period;action&period;MAIN" &sol;&gt&semi;<br &sol;><br &sol;> &lt&semi;category android&colon;name&equals;"android&period;intent&period;category&period;LAUNCHER" &sol;&gt&semi;<br &sol;> &lt&semi;&sol;intent-filter&gt&semi;<br &sol;> &lt&semi;&sol;activity&gt&semi;<br &sol;>&lt&semi;&sol;application&gt&semi;<&sol;pre> &NewLine;<p>7&period; Open <span style&equals;"color&colon; &num;008000&semi;"><strong>MainActivity&period;kt<&sol;strong><&sol;span> and add the below code&colon;<&sol;p> &NewLine;<p><span style&equals;"color&colon; &num;0000ff&semi;"><strong>MainActivity&period;kt<&sol;strong><&sol;span><&sol;p> &NewLine;<pre>package com&period;c1ctech&period;exoplayercachingexp<br &sol;><br &sol;>import android&period;net&period;Uri<br &sol;>import androidx&period;appcompat&period;app&period;AppCompatActivity<br &sol;>import android&period;os&period;Bundle<br &sol;>import com&period;google&period;android&period;exoplayer2&period;MediaItem<br &sol;>import com&period;google&period;android&period;exoplayer2&period;Player<br &sol;>import com&period;google&period;android&period;exoplayer2&period;SimpleExoPlayer<br &sol;>import com&period;google&period;android&period;exoplayer2&period;source&period;DefaultMediaSourceFactory<br &sol;>import com&period;google&period;android&period;exoplayer2&period;source&period;ProgressiveMediaSource<br &sol;>import com&period;google&period;android&period;exoplayer2&period;ui&period;PlayerView<br &sol;>import com&period;google&period;android&period;exoplayer2&period;upstream&period;DataSource<br &sol;>import com&period;google&period;android&period;exoplayer2&period;upstream&period;DefaultDataSourceFactory<br &sol;>import com&period;google&period;android&period;exoplayer2&period;upstream&period;DefaultHttpDataSource<br &sol;>import com&period;google&period;android&period;exoplayer2&period;upstream&period;HttpDataSource<br &sol;>import com&period;google&period;android&period;exoplayer2&period;upstream&period;cache&period;CacheDataSource<br &sol;>import com&period;google&period;android&period;exoplayer2&period;upstream&period;cache&period;SimpleCache<br &sol;>import com&period;google&period;android&period;exoplayer2&period;util&period;Util<br &sol;><br &sol;>class MainActivity &colon; AppCompatActivity&lpar;&rpar; &lbrace;<br &sol;><br &sol;> private lateinit var httpDataSourceFactory&colon; HttpDataSource&period;Factory<br &sol;> private lateinit var defaultDataSourceFactory&colon; DefaultDataSourceFactory<br &sol;> private lateinit var cacheDataSourceFactory&colon; DataSource&period;Factory<br &sol;> private lateinit var simpleExoPlayer&colon; SimpleExoPlayer<br &sol;> private val simpleCache&colon; SimpleCache &equals; MyApp&period;simpleCache<br &sol;><br &sol;> private var mPlayer&colon; SimpleExoPlayer&quest; &equals; null<br &sol;> private lateinit var playerView&colon; PlayerView<br &sol;> private val videoURL &equals; "https&colon;&sol;&sol;sample-videos&period;com&sol;video123&sol;mp4&sol;720&sol;big&lowbar;buck&lowbar;bunny&lowbar;720p&lowbar;1mb&period;mp4"<br &sol;><br &sol;><br &sol;> override fun onCreate&lpar;savedInstanceState&colon; Bundle&quest;&rpar; &lbrace;<br &sol;> super&period;onCreate&lpar;savedInstanceState&rpar;<br &sol;> setContentView&lpar;R&period;layout&period;activity&lowbar;main&rpar;<br &sol;><br &sol;> <strong><span style&equals;"color&colon; &num;008000&semi;">&sol;&sol;get PlayerView by its id<&sol;span><&sol;strong><br &sol;> playerView &equals; findViewById&lpar;R&period;id&period;playerView&rpar;<br &sol;> &rcub;<br &sol;><br &sol;> private fun initPlayer&lpar;&rpar; &lbrace;<br &sol;><br &sol;> httpDataSourceFactory &equals; DefaultHttpDataSource&period;Factory&lpar;&rpar;<br &sol;> &period;setAllowCrossProtocolRedirects&lpar;true&rpar;<br &sol;><br &sol;> defaultDataSourceFactory &equals; DefaultDataSourceFactory&lpar;<br &sol;> applicationContext&comma; httpDataSourceFactory<br &sol;> &rpar;<br &sol;><br &sol;> <strong><span style&equals;"color&colon; &num;008000&semi;">&sol;&sol;A DataSource that reads and writes a Cache&period;<&sol;span><&sol;strong><br &sol;> cacheDataSourceFactory &equals; CacheDataSource&period;Factory&lpar;&rpar;<br &sol;> &period;setCache&lpar;simpleCache&rpar;<br &sol;> &period;setUpstreamDataSourceFactory&lpar;httpDataSourceFactory&rpar;<br &sol;> &period;setFlags&lpar;CacheDataSource&period;FLAG&lowbar;IGNORE&lowbar;CACHE&lowbar;ON&lowbar;ERROR&rpar;<br &sol;><br &sol;><span style&equals;"color&colon; &num;008000&semi;"><strong> &sol;&sol; Create a player instance and set mediaSourceFactory&period;<&sol;strong><&sol;span><br &sol;> simpleExoPlayer &equals; SimpleExoPlayer&period;Builder&lpar;this&rpar;<br &sol;> &period;setMediaSourceFactory&lpar;DefaultMediaSourceFactory&lpar;cacheDataSourceFactory&rpar;&rpar;&period;build&lpar;&rpar;<br &sol;><br &sol;> val videoUri &equals; Uri&period;parse&lpar;videoURL&rpar;<br &sol;> val mediaItem &equals; MediaItem&period;fromUri&lpar;videoUri&rpar;<br &sol;> val mediaSource &equals;<br &sol;> ProgressiveMediaSource&period;Factory&lpar;cacheDataSourceFactory&rpar;&period;createMediaSource&lpar;mediaItem&rpar;<br &sol;><br &sol;> <strong><span style&equals;"color&colon; &num;008000&semi;">&sol;&sol; Bind the player to the view&period;<&sol;span><&sol;strong><br &sol;> playerView&period;player &equals; simpleExoPlayer<br &sol;><br &sol;> <strong><span style&equals;"color&colon; &num;008000&semi;">&sol;&sol;setting exoplayer when it is ready&period;<&sol;span><&sol;strong><br &sol;> simpleExoPlayer&period;playWhenReady &equals; true<br &sol;><br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol;Seeks to a position specified in milliseconds in the specified window&period;<&sol;span><&sol;strong><br &sol;> simpleExoPlayer&period;seekTo&lpar;0&comma; 0&rpar;<br &sol;><br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol;set repeat mode&period;<&sol;span><&sol;strong><br &sol;> simpleExoPlayer&period;repeatMode &equals; Player&period;REPEAT&lowbar;MODE&lowbar;OFF<br &sol;><br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol; Set the media source to be played&period;<&sol;span><&sol;strong><br &sol;> simpleExoPlayer&period;setMediaSource&lpar;mediaSource&comma; true&rpar;<br &sol;><br &sol;><strong><span style&equals;"color&colon; &num;008000&semi;"> &sol;&sol; Prepare the player&period;<&sol;span><&sol;strong><br &sol;> simpleExoPlayer&period;prepare&lpar;&rpar;<br &sol;> &rcub;<br &sol;><br &sol;><br &sol;> override fun onStart&lpar;&rpar; &lbrace;<br &sol;> super&period;onStart&lpar;&rpar;<br &sol;> if &lpar;Util&period;SDK&lowbar;INT &gt&semi;&equals; 24&rpar; &lbrace;<br &sol;> initPlayer&lpar;&rpar;<br &sol;> &rcub;<br &sol;> &rcub;<br &sol;><br &sol;> override fun onResume&lpar;&rpar; &lbrace;<br &sol;> super&period;onResume&lpar;&rpar;<br &sol;> if &lpar;Util&period;SDK&lowbar;INT &lt&semi; 24 &vert;&vert; mPlayer &equals;&equals; null&rpar; &lbrace;<br &sol;> initPlayer&lpar;&rpar;<br &sol;> &rcub;<br &sol;> &rcub;<br &sol;><br &sol;> override fun onPause&lpar;&rpar; &lbrace;<br &sol;> super&period;onPause&lpar;&rpar;<br &sol;> if &lpar;Util&period;SDK&lowbar;INT &lt&semi; 24&rpar; &lbrace;<br &sol;> releasePlayer&lpar;&rpar;<br &sol;> &rcub;<br &sol;> &rcub;<br &sol;><br &sol;> override fun onStop&lpar;&rpar; &lbrace;<br &sol;> super&period;onStop&lpar;&rpar;<br &sol;> if &lpar;Util&period;SDK&lowbar;INT &gt&semi;&equals; 24&rpar; &lbrace;<br &sol;> releasePlayer&lpar;&rpar;<br &sol;> &rcub;<br &sol;> &rcub;<br &sol;><br &sol;> private fun releasePlayer&lpar;&rpar; &lbrace;<br &sol;> if &lpar;mPlayer &equals;&equals; null&rpar; &lbrace;<br &sol;> return<br &sol;> &rcub;<br &sol;><span style&equals;"color&colon; &num;008000&semi;"><strong> &sol;&sol;release player when done<&sol;strong><&sol;span><br &sol;> mPlayer&excl;&excl;&period;release&lpar;&rpar;<br &sol;> mPlayer &equals; null<br &sol;> &rcub;<br &sol;>&rcub;<&sol;pre> &NewLine;<p><span style&equals;"color&colon; &num;0000ff&semi;"><strong>CacheDataSourceFactory<&sol;strong><&sol;span> &colon; Constructs a factory which creates <span style&equals;"color&colon; &num;008000&semi;"><strong>CacheDataSource<&sol;strong><&sol;span> instance for reading and writing the cache&period;<&sol;p> &NewLine;<pre>httpDataSourceFactory &equals; DefaultHttpDataSource&period;Factory&lpar;&rpar;<br &sol;> &period;setAllowCrossProtocolRedirects&lpar;true&rpar;<br &sol;><br &sol;>cacheDataSourceFactory &equals; CacheDataSource&period;Factory&lpar;&rpar;<br &sol;> &period;setCache&lpar;simpleCache&rpar;<br &sol;> &period;setUpstreamDataSourceFactory&lpar;httpDataSourceFactory&rpar;<br &sol;> &period;setFlags&lpar;CacheDataSource&period;FLAG&lowbar;IGNORE&lowbar;CACHE&lowbar;ON&lowbar;ERROR&rpar;<&sol;pre> &NewLine;<p>When you run the app it will look like this as shown below&colon;<&sol;p> &NewLine;<p><img class&equals;"wp-image-2808 aligncenter" src&equals;"https&colon;&sol;&sol;c1ctech&period;com&sol;wp-content&sol;uploads&sol;2021&sol;09&sol;Screenshot&lowbar;20210928-152949&lowbar;ExoplayerCachingExp-498x1024&period;jpg" alt&equals;"" width&equals;"310" height&equals;"637" &sol;><&sol;p> &NewLine;<&sol;div> &NewLine;&NewLine;

Exit mobile version