Search code examples
android-mediaplayerexoplayerandroid-media3exoplayer-media-item

Android Media3 (ExoPlayer): How to set defaultPositionUs of a Window in the Timeline?


I want to set default start positions of my playlist items (basically to resume from where the user left), to use when playlist item auto transitions to next item.

As per my understanding (I am not sure), the default start position is of the window in the timeline.

From Docs: Timeline.Window.defaultPositionUs. But, I can't find a way to set this defaultPositionUs parameter.

I use this function to set playlist items: setMediaItems. My playlist items are mp3 files (local and https source).


Solution

  • I got a solution: (See issue: androidx/media#1129)

    class MyMediaSource(mediaSource: MediaSource, private val startPositionMs: Long): WrappingMediaSource(mediaSource) {
        override fun onChildSourceInfoRefreshed(newTimeline: Timeline) {
            super.onChildSourceInfoRefreshed(MyTimeline(newTimeline, startPositionMs))
        }
    
        class MyTimeline(timeline: Timeline, private val startPositionMs: Long): ForwardingTimeline(timeline) {
            override fun getWindow(windowIndex: Int, window: Window, defaultPositionProjectionUs: Long): Window {
                return super.getWindow(windowIndex, window, defaultPositionProjectionUs).apply {
                    defaultPositionUs = Util.msToUs(startPositionMs)
                }
            }
        }
    }
    
    val defaultMediaSourceFactory = DefaultMediaSourceFactory(this)
    val mediaSourceFactory = object : MediaSource.Factory {
        override fun setDrmSessionManagerProvider(drmSessionManagerProvider: DrmSessionManagerProvider): MediaSource.Factory {
            return defaultMediaSourceFactory.setDrmSessionManagerProvider(drmSessionManagerProvider)
        }
    
        override fun setLoadErrorHandlingPolicy(loadErrorHandlingPolicy: LoadErrorHandlingPolicy): MediaSource.Factory {
            return defaultMediaSourceFactory.setLoadErrorHandlingPolicy(loadErrorHandlingPolicy)
        }
    
        override fun getSupportedTypes(): IntArray {
            return defaultMediaSourceFactory.supportedTypes
        }
    
        override fun createMediaSource(mediaItem: MediaItem): MediaSource {
            return MyMediaSource(
                defaultMediaSourceFactory.createMediaSource(mediaItem),
                mediaItem.mediaMetadata.extras?.getLong("startPositionMs") ?: 0,
            )
        }
    }
    
    player = ExoPlayer.Builder(this)
        .setMediaSourceFactory(mediaSourceFactory)
        .build()