Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ExoPlayer, how to load bigger parts of remote audio files

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)

like image 957
Massimo Avatar asked Mar 07 '17 08:03

Massimo


People also ask

What is ExoPlayer and how to use?

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.

What is audio focus with ExoPlayer?

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.

What API level is ExoPlayer built on?

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.

What is the difference between ExoPlayer and Android mediaplayer?

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.


2 Answers

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.

like image 131
Massimo Avatar answered Sep 30 '22 19:09

Massimo


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
            )
like image 31
Vlad Avatar answered Sep 30 '22 21:09

Vlad