androidx / androidx/media

CompositionPlayer: StuckPlayerException

Open
#3,019 2 comments 2 reactions 1 assignee View on GitHub

@kggibson is already working on this.

Since Jan 20, 2026.

bug editing preview
Dominant language
Java
Stars
3k
Forks
955
Avg merge
12d 14h
Merged PRs (30d)
2

Description

version ; 1.9.0 latest and last 1.9.0-rc-1

`//////CREATE-COMPOSITION//////

fun createComposition():Composition{
val editedMediaItemsList = mutableListOf()

filteredSelectionModels.forEachIndexed { index, mediaItem ->
log("Composition_LOG", "MEDIA->$index" + mediaItem.toString())

// Handle non-grid items
val selectionModel = mediaItem.clips?.first()?.file
selectionModel?.let { selectedFile ->
	val durationSec = mediaItem.duration ?: 1.0
	val imageDurationUs =
		((durationSec * 1_000_000).toLong()).coerceAtLeast(100_000L)

	val originalDurationUs = (selectedFile.uriDuration.times(1000000)).toLong()
	val startTime = (selectedFile.uriStartTime * 1000L).toLong()
	val clipDuration = (mediaItem.duration?.times(1000) ?: 1000).toLong()
	val endTime = (startTime + clipDuration)

	val filePath = selectedFile.trimPath ?: selectedFile.path

	log(
		"Composition_LOG",
		"Composition->$index fileType:${selectedFile.fileType}, " +
				"originalDur:${originalDurationUs}, " + "startTime:$startTime, " +
				"clipDuration:${clipDuration}, endTime:${endTime},\n" + 
				"important videoSeqDuration:${videoSequenceDurationUs} "
	)

	val editedMediaItem = when (selectedFile.fileType) {
		"Video" -> {
			EditedMediaItem.Builder(
				MediaItem.Builder().setUri(filePath).setClippingConfiguration(
					ClippingConfiguration.Builder()
						.setStartPositionMs(startTime).setEndPositionMs(endTime)
						.build()
				).build()
			).apply {
				setRemoveAudio(true)
				setDurationUs(originalDurationUs.toLong())
				setFrameRate(30)
				setEffects(Effects(listOf(pitchChanger), listOf()))
			}.build()
		}

		else -> {
			EditedMediaItem.Builder(
				MediaItem.Builder().setUri(filePath)
					.setImageDurationMs((imageDurationUs / 1000)).build()
			).apply {
				setDurationUs(imageDurationUs)
				setFrameRate(30)
				setEffects(Effects(listOf(pitchChanger), listOf()))
			}.build()
		}
	}

	editedMediaItemsList.add(editedMediaItem)
	videoSequenceDurationUs += clipDuration
}
}

// Create the final video sequences list
val videoImageSequences = mutableListOf()

// Create ONE main video sequence with all items
val mainVideoSequence =
EditedMediaItemSequence.Builder().addItems(editedMediaItemsList).build()

videoImageSequences.add(mainVideoSequence)

try {
val composition = Composition.Builder(videoImageSequences)
.setEffects(Effects(listOf(), videoEffects)).setTransmuxVideo(true).build()
compositionDeferred.complete(composition)
} catch (e: Exception) {
e.printStackTrace()
log("Composition_LOG", "composition is null with ${e.message}")
compositionDeferred.complete(null)
}
}
`

/////////// I'm creating composition with above code and playing it with compositionPlayer.
I've multiple success scenarios and then FAILURE with exception.

If I select one file witn 100ms results success in playing.
If I select two files with 100ms for each file it still plays the composition.

FAILURE:
When I include three files with 100ms for each it fails to play COMPOSITION.
Until unless I update first file of duration to atleast 300ms. same behavior for more entries.

//////////Here's my logs for Composition and CompositionPlayer:

`1- With only one File:
E previewComposition: creating new composition
Composition_LOG MEDIA->0start_time=0.0, end_time=0.1, duration=0.1, videoCount=1, uriTime=0.0, fileDur=3.0,)
Composition->0 fileType:Video, originalDur:3000000, startTime:0, clipDuration:100, endTime:100,important videoSeqDuration:0
Player ready: duration=100ms (0s), state=2, sequences=1
New composition player created successfully

2- With two Files:
E previewComposition: creating new composition
MEDIA->0 start_time=0.0, end_time=0.1, duration=0.1, videoCount=1, uriTime=0.0, fileDur=3.0,)
Composition->0 fileType:Video, originalDur:3000000, startTime:0, clipDuration:100, endTime:100, important videoSeqDuration:0
MEDIA->1 start_time=0.1, end_time=0.2, duration=0.1, videoCount=1, uriTime=0.0, fileDur=17.0,)
Composition->1 fileType:Video, originalDur:17000000, startTime:0, clipDuration:100, endTime:100, important videoSeqDuration:100
Player ready: duration=200ms (0s), state=2, sequences=1
New composition player created successfully

3-A With three Files (SUCCESS):

3-B With three Files (FAILURE):
E previewComposition: creating new composition
MEDIA->0start_time=0.0, end_time=0.1, duration=0.1, videoCount=1, uriTime=0.0, fileDur=3.0,)
Composition->0 fileType:Video, originalDur:3000000, startTime:0, clipDuration:100, endTime:100, important videoSeqDuration:0
MEDIA->1start_time=0.1, end_time=0.2, duration=0.1, videoCount=1, uriTime=0.0, fileDur=17.0,)
Composition->1 fileType:Video, originalDur:17000000, startTime:0, clipDuration:100, endTime:100, important videoSeqDuration:100
MEDIA->2start_time=0.2, end_time=5.333, duration=5.133, videoCount=1,uriTime=0.0, fileDur=5.133,)
Composition->2 fileType:Video, originalDur:5133000, startTime:0, clipDuration:5133, endTime:5133, important videoSeqDuration:200
Player ready: duration=5333ms (5s), state=2, sequences=1
New composition player created successfully

From Library::
CompositionPlayer-0
E playerFailed [eventTime=10.16, mediaPos=0.01, window=0, period=0, errorCode=ERROR_CODE_TIMEOUT (Ask Gemini)
androidx.media3.exoplayer.ExoPlaybackException: Unexpected runtime error
at androidx.media3.exoplayer.ExoPlayerImpl$ComponentListener.onStuckPlayerDetected(ExoPlayerImpl.java:3606)
at androidx.media3.common.util.StuckPlayerDetector$StuckPlayingDetector.update(StuckPlayerDetector.java:256)
at androidx.media3.common.util.StuckPlayerDetector.handleMessage(StuckPlayerDetector.java:130)
at androidx.media3.common.util.StuckPlayerDetector.$r8$lambda$O20OfWQe0IImnmxCKXMyVoyaxfk(Unknown Source:0)
at androidx.media3.common.util.StuckPlayerDetector$$ExternalSyntheticLambda0.handleMessage(D8$$SyntheticClass:0)
at android.os.Handler.dispatchMessage(Handler.java:128)
at android.os.Looper.dispatchMessage(Looper.java:333)
at android.os.Looper.loopOnce(Looper.java:263)
at android.os.Looper.loop(Looper.java:367)
at android.app.ActivityThread.main(ActivityThread.java:9287)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:566)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:929)
Caused by: androidx.media3.common.util.StuckPlayerException: Player stuck playing with no progress for 10000 ms
... 12 more
]

***More crashes when using all images files:

ExoPlayerImplInternal E Playback error
androidx.media3.exoplayer.ExoPlaybackException: Source error
at androidx.media3.exoplayer.ExoPlayerImplInternal.handleIoException(ExoPlayerImplInternal.java:937)
at androidx.media3.exoplayer.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:907)
at android.os.Handler.dispatchMessage(Handler.java:128)
at android.os.Looper.dispatchMessage(Looper.java:333)
at android.os.Looper.loopOnce(Looper.java:263)
at android.os.Looper.loop(Looper.java:367)
at android.os.HandlerThread.run(HandlerThread.java:139)
Caused by: androidx.media3.exoplayer.source.UnrecognizedInputFormatException: None of the available extractors (JpegExtractor, FlvExtractor, FlacExtractor, WavExtractor, FragmentedMp4Extractor, Mp4Extractor, AmrExtractor, PsExtractor, OggExtractor, TsExtractor, MatroskaExtractor, AdtsExtractor, Ac3Extractor, Ac4Extractor, Mp3Extractor, AviExtractor, PngExtractor, WebpExtractor, BmpExtractor, HeifExtractor, AvifExtractor) could read the stream. {contentIsMalformed=false, dataType=1}
sniff failures: [NoDeclaredBrand, NoDeclaredBrand]
at androidx.media3.exoplayer.source.BundledExtractorsAdapter.init(BundledExtractorsAdapter.java:110)
at androidx.media3.exoplayer.source.ProgressiveMediaPeriod$ExtractingLoadable.load(ProgressiveMediaPeriod.java:1169)
at androidx.media3.exoplayer.upstream.Loader$LoadTask.run(Loader.java:453)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1154)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:652)
at java.lang.Thread.run(Thread.java:1563)

MessageQueue W Handler (android.os.Handler) {792f255} sending message to a Handler on a dead thread (Ask Gemini)
java.lang.IllegalStateException: Handler (android.os.Handler) {792f255} sending message to a Handler on a dead thread
at android.os.MessageQueue.logDeadThread(MessageQueue.java:1452)
at android.os.MessageQueue.enqueueMessageLegacy(MessageQueue.java:1465)
at android.os.MessageQueue.enqueueMessage(MessageQueue.java:1539)
at android.os.Handler.enqueueMessage(Handler.java:829)
at android.os.Handler.sendMessageAtTime(Handler.java:771)
at android.os.Handler.sendMessageDelayed(Handler.java:741)
at android.os.Handler.post(Handler.java:461)
at androidx.media3.exoplayer.audio.AudioTrackAudioOutput.lambda$releaseAudioTrackAsync$1(AudioTrackAudioOutput.java:468)
at androidx.media3.exoplayer.audio.AudioTrackAudioOutput$$ExternalSyntheticLambda3.run(D8$$SyntheticClass:0)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:520)
at java.util.concurrent.FutureTask.run(FutureTask.java:317)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:348)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1154)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:652)
at java.lang.Thread.run(Thread.java:1563)

From LOCAL:
E playerFailed [eventTime=10.18, mediaPos=0.01, window=0, errorCode=ERROR_CODE_TIMEOUT (Ask Gemini)
androidx.media3.common.PlaybackException: error from player 0
at androidx.media3.transformer.CompositionPlayer.maybeUpdatePlaybackError(CompositionPlayer.java:1721)
at androidx.media3.transformer.CompositionPlayer.access$2700(CompositionPlayer.java:149)
at androidx.media3.transformer.CompositionPlayer$PlayerListener.onPlayerError(CompositionPlayer.java:2036)
at androidx.media3.exoplayer.ExoPlayerImpl.lambda$updatePlaybackInfo$21(ExoPlayerImpl.java:2342)
at androidx.media3.exoplayer.ExoPlayerImpl$$ExternalSyntheticLambda34.invoke(D8$$SyntheticClass:0)
at androidx.media3.common.util.ListenerSet$ListenerHolder.invoke(ListenerSet.java:458)
at androidx.media3.common.util.ListenerSet.lambda$queueEvent$0(ListenerSet.java:326)
at androidx.media3.common.util.ListenerSet$$ExternalSyntheticLambda1.run(D8$$SyntheticClass:0)
at androidx.media3.common.util.ListenerSet.flushEvents(ListenerSet.java:350)
at androidx.media3.exoplayer.ExoPlayerImpl.updatePlaybackInfo(ExoPlayerImpl.java:2405)
at androidx.media3.exoplayer.ExoPlayerImpl.stopInternal(ExoPlayerImpl.java:2139)
at androidx.media3.exoplayer.ExoPlayerImpl.access$3500(ExoPlayerImpl.java:144)
at androidx.media3.exoplayer.ExoPlayerImpl$ComponentListener.onStuckPlayerDetected(ExoPlayerImpl.java:3605)
at androidx.media3.common.util.StuckPlayerDetector$StuckPlayingDetector.update(StuckPlayerDetector.java:256)
at androidx.media3.common.util.StuckPlayerDetector.handleMessage(StuckPlayerDetector.java:130)
at androidx.media3.common.util.StuckPlayerDetector.$r8$lambda$O20OfWQe0IImnmxCKXMyVoyaxfk(Unknown Source:0)
at androidx.media3.common.util.StuckPlayerDetector$$ExternalSyntheticLambda0.handleMessage(D8$$SyntheticClass:0)
at android.os.Handler.dispatchMessage(Handler.java:128)
at android.os.Looper.dispatchMessage(Looper.java:333)
at android.os.Looper.loopOnce(Looper.java:263)
at android.os.Looper.loop(Looper.java:367)
at android.app.ActivityThread.main(ActivityThread.java:9287)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:566)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:929)
Caused by: androidx.media3.exoplayer.ExoPlaybackException: Unexpected runtime error
at androidx.media3.exoplayer.ExoPlayerImpl$ComponentListener.onStuckPlayerDetected(ExoPlayerImpl.java:3606)
... 12 more
Caused by: androidx.media3.common.util.StuckPlayerException: Player stuck playing with no progress for 10000 ms
... 12 more
]

`

E Player timeout detected (likely due to short 100ms clips). Attempting restart...

`Final previewComposition Player:

fun previewComposition( composition: Composition, pauseCallback: () -> Unit){

try {
    val player = CompositionPlayer.Builder(context).build()
    compositionPlayer = player
    playerView.setPlayer(player)
    playerView.useController = false
    playerView.setKeepContentOnPlayerReset(true)
    playerView.resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FILL

    // Duration will be logged after prepare() when it's actually available

    player.addListener(object : Player.Listener {

        override fun onPlayerError(error: PlaybackException) {
            pauseCallback.invoke()

            log(
                "PLAYER_LOG",
                "Preview error: code=${error.errorCode}, name=${error.errorCodeName}, " +
                        "msg=${error.message}, cause=${error.cause}"
            )

            when {
                error.errorCode == PlaybackException.ERROR_CODE_TIMEOUT -> {
                    log("PLAYER_LOG", "Player timeout detected (likely due to short 100ms clips). Attempting restart...")
                    try {
                    } catch (e: Exception) {
                        log("PLAYER_LOG", "Failed to restart player after timeout: ${e.message}")
                    }
                }
			}
		}
	}
		
}catch ( e: StuckPlayerException){
    log("Composition_LOG", "Player stuck: ${e.message}")
} catch (e: Exception) {
    log("Composition_LOG", "Preview creation error: ${e.message}")
    pauseCallback.invoke()
    uiStateViewModel.isCreatingComposition.value = false
}

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.