Skip to content

Commit 0b17a67

Browse files
tianyifcopybara-github
authored andcommitted
Use pre-caching feature of DefaultPreloadManager in demo-shortform app
PiperOrigin-RevId: 786250445
1 parent 4771273 commit 0b17a67

File tree

4 files changed

+90
-6
lines changed

4 files changed

+90
-6
lines changed

RELEASENOTES.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
`DefaultPreloadManager.PreloadStatus.specifiedRangeCached(durationMs)`
3131
via `TargetPreloadStatusControl.getTargetPreloadStatus(T rankingData)`
3232
to indicate that a media item needs to be pre-cached.
33+
* Use pre-caching functionality of `DefaultPreloadManager` in shortform
34+
demo app.
3335
* Transformer:
3436
* Track Selection:
3537
* Add `TrackSelectionParameters.selectTextByDefault` to prefer the
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Copyright 2025 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package androidx.media3.demo.shortform
17+
18+
import android.content.Context
19+
import androidx.annotation.OptIn
20+
import androidx.media3.common.util.UnstableApi
21+
import androidx.media3.database.DatabaseProvider
22+
import androidx.media3.database.StandaloneDatabaseProvider
23+
import androidx.media3.datasource.cache.Cache
24+
import androidx.media3.datasource.cache.NoOpCacheEvictor
25+
import androidx.media3.datasource.cache.SimpleCache
26+
import java.io.File
27+
28+
@OptIn(UnstableApi::class)
29+
object DemoUtil {
30+
31+
private const val PRECACHE_CONTENT_DIRECTORY = "precache"
32+
33+
private lateinit var databaseProvider: DatabaseProvider
34+
35+
private lateinit var downloadDirectory: File
36+
37+
private lateinit var downloadCache: Cache
38+
39+
@Synchronized
40+
fun getDownloadCache(context: Context): Cache {
41+
if (!::downloadCache.isInitialized) {
42+
val downloadContentDirectory = File(getDownloadDirectory(context), PRECACHE_CONTENT_DIRECTORY)
43+
downloadCache =
44+
SimpleCache(downloadContentDirectory, NoOpCacheEvictor(), getDatabaseProvider(context))
45+
}
46+
return downloadCache
47+
}
48+
49+
@Synchronized
50+
private fun getDatabaseProvider(context: Context): DatabaseProvider {
51+
if (!::databaseProvider.isInitialized) {
52+
databaseProvider = StandaloneDatabaseProvider(context)
53+
}
54+
return databaseProvider
55+
}
56+
57+
@Synchronized
58+
private fun getDownloadDirectory(context: Context): File {
59+
if (!::databaseProvider.isInitialized) {
60+
val externalFilesDir = context.getExternalFilesDir(/* type= */ null)
61+
downloadDirectory = externalFilesDir ?: context.filesDir
62+
}
63+
return downloadDirectory
64+
}
65+
}

demos/shortform/src/main/java/androidx/media3/demo/shortform/MediaItemDatabase.kt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,11 @@
1515
*/
1616
package androidx.media3.demo.shortform
1717

18+
import androidx.annotation.OptIn
1819
import androidx.media3.common.MediaItem
20+
import androidx.media3.common.util.UnstableApi
1921

22+
@OptIn(UnstableApi::class)
2023
class MediaItemDatabase {
2124

2225
private val mediaUris =
@@ -30,6 +33,10 @@ class MediaItemDatabase {
3033

3134
fun get(index: Int): MediaItem {
3235
val uri = mediaUris[index.mod(mediaUris.size)]
33-
return MediaItem.Builder().setUri(uri).setMediaId(index.toString()).build()
36+
return MediaItem.Builder()
37+
.setUri(uri)
38+
.setMediaId(index.toString())
39+
.setCustomCacheKey(index.toString())
40+
.build()
3441
}
3542
}

demos/shortform/src/main/java/androidx/media3/demo/shortform/viewpager/ViewPagerMediaAdapter.kt

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,13 @@ import androidx.media3.common.C
2323
import androidx.media3.common.MediaItem
2424
import androidx.media3.common.util.Log
2525
import androidx.media3.common.util.UnstableApi
26+
import androidx.media3.demo.shortform.DemoUtil
2627
import androidx.media3.demo.shortform.MediaItemDatabase
2728
import androidx.media3.demo.shortform.PlayerPool
2829
import androidx.media3.demo.shortform.R
2930
import androidx.media3.exoplayer.DefaultLoadControl
3031
import androidx.media3.exoplayer.source.preload.DefaultPreloadManager
32+
import androidx.media3.exoplayer.source.preload.PreloadManagerListener
3133
import androidx.media3.exoplayer.source.preload.TargetPreloadStatusControl
3234
import androidx.recyclerview.widget.RecyclerView
3335
import kotlin.math.abs
@@ -49,7 +51,7 @@ class ViewPagerMediaAdapter(
4951
private const val LOAD_CONTROL_MIN_BUFFER_MS = 5_000
5052
private const val LOAD_CONTROL_MAX_BUFFER_MS = 20_000
5153
private const val LOAD_CONTROL_BUFFER_FOR_PLAYBACK_MS = 500
52-
private const val MANAGED_ITEM_COUNT = 10
54+
private const val MANAGED_ITEM_COUNT = 20
5355
private const val ITEM_ADD_REMOVE_COUNT = 4
5456
}
5557

@@ -68,9 +70,11 @@ class ViewPagerMediaAdapter(
6870
val preloadManagerBuilder =
6971
DefaultPreloadManager.Builder(context.applicationContext, targetPreloadStatusControl)
7072
.setLoadControl(loadControl)
73+
.setCache(DemoUtil.getDownloadCache(context.applicationContext))
7174
playerPool = PlayerPool(numberOfPlayers, preloadManagerBuilder)
7275
holderMap = mutableMapOf()
7376
preloadManager = preloadManagerBuilder.build()
77+
preloadManager.addListener(DefaultPreloadManagerListener())
7478
for (i in 0 until MANAGED_ITEM_COUNT) {
7579
addMediaItem(index = i, isAddingToRightEnd = true)
7680
}
@@ -175,12 +179,18 @@ class ViewPagerMediaAdapter(
175179
TargetPreloadStatusControl<Int, DefaultPreloadManager.PreloadStatus> {
176180

177181
override fun getTargetPreloadStatus(rankingData: Int): DefaultPreloadManager.PreloadStatus {
178-
if (abs(rankingData - currentPlayingIndex) == 2) {
179-
return DefaultPreloadManager.PreloadStatus.specifiedRangeLoaded(/* durationMs= */ 500L)
180-
} else if (abs(rankingData - currentPlayingIndex) == 1) {
182+
if (abs(rankingData - currentPlayingIndex) == 1) {
183+
return DefaultPreloadManager.PreloadStatus.specifiedRangeLoaded(/* durationMs= */ 1000L)
184+
} else if (abs(rankingData - currentPlayingIndex) <= 3) {
181185
return DefaultPreloadManager.PreloadStatus.specifiedRangeLoaded(/* durationMs= */ 1000L)
182186
}
183-
return DefaultPreloadManager.PreloadStatus.PRELOAD_STATUS_NOT_PRELOADED
187+
return DefaultPreloadManager.PreloadStatus.specifiedRangeCached(5000L)
188+
}
189+
}
190+
191+
inner class DefaultPreloadManagerListener : PreloadManagerListener {
192+
override fun onCompleted(mediaItem: MediaItem) {
193+
Log.w(TAG, "onCompleted: " + mediaItem.mediaId)
184194
}
185195
}
186196
}

0 commit comments

Comments
 (0)