I'm using ExoPlayer 2 to play remote tracks. By default the player loads tracks piece by piece (i.e. about 20 seconds, then other 20 seconds while the track is playing).
Since tracks are loaded from a remote server, it happens that if connection goes down, the player is not able to load anymore. Is there a way to say to ExoPlayer to load bigger parts of the audio file (also the full track at once)?
I tried to see around ExtractorMediaSource
, DataSource.Factory
and DefaultExtractorsFactory
but I've found nothing to solve my problem.
val audioSource = ExtractorMediaSource(
Uri.parse(videoUrl),
mDataSourceFactory, // DataSource.Factory
mExtractor, // DefaultExtractorsFactory
null,
null
)
mExoPlayer.prepare(audioSource)
mExoPlayer.playWhenReady = true
(it is Kotlin, but it seems to be understandable also by Java programmers)
Refer to official website for more demonstration on ExoPlayer: E xoPlayer 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.
Easy Audio Focus with ExoPlayer. Managing audio focus is a vital part of… | by Nicole Borrelli | google-exoplayer | Medium Managing audio focus is a vital part of being a good citizen in the Android media ecosystem. What is audio focus? The docs describe it like this: Two or more Android apps can play audio to the same output stream simultaneously.
ExoPlayer’s standard audio and video components are built on Android’s MediaCodec API, which was released in Android 4.1 (API level 16). Because ExoPlayer is a library, you can easily take advantage of new features as they become available by updating your app.
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.
I've found the solution. Since I'm not finding other related questions, I'll answer to my question (I hope someone will need it in the future):
The right object to configure is the LoadControl
passed to the ExoPlayerFactory
when creating the ExoPlayer
object:
Original answer (deprecated):
val loadControl = DefaultLoadControl(
DefaultAllocator(true, C.DEFAULT_BUFFER_SEGMENT_SIZE),
5 * 60 * 1000, // this is it!
10 * 60 * 1000,
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_MS.toLong(),
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS.toLong()
)
exoPlayer = ExoPlayerFactory.newSimpleInstance(this, trackSelector, loadControl)
The updated answer:
val bandwidthMeter = DefaultBandwidthMeter.Builder(context).build()
val trackSelectionFactory = AdaptiveTrackSelection.Factory()
val trackSelector = DefaultTrackSelector(trackSelectionFactory)
val loadControl = DefaultLoadControl.Builder()
.setAllocator(DefaultAllocator(true, C.DEFAULT_BUFFER_SEGMENT_SIZE))
.setBufferDurationsMs(
5 * 60 * 1000, // this is it!
10 * 60 * 1000,
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_MS,
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS
)
.setTargetBufferBytes(DefaultLoadControl.DEFAULT_TARGET_BUFFER_BYTES)
.setPrioritizeTimeOverSizeThresholds(DefaultLoadControl.DEFAULT_PRIORITIZE_TIME_OVER_SIZE_THRESHOLDS)
.createDefaultLoadControl()
exoPlayer = ExoPlayerFactory.newSimpleInstance(
context,
DefaultRenderersFactory(context),
trackSelector,
loadControl,
null,
bandwidthMeter)
The doc where it is explained.
Answer of @Massimo is correct but the way is deprecated
use something like this
DefaultLoadControl.Builder()
.setBufferDurationsMs(
DefaultLoadControl.DEFAULT_MIN_BUFFER_MS,
30_000,
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_MS,
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With