Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Image is skipped when mixing image and video media items in a exoplayer playlist #1017

Open
1 task
kleiren opened this issue Jan 24, 2024 · 4 comments
Open
1 task
Assignees
Labels

Comments

@kleiren
Copy link

kleiren commented Jan 24, 2024

Version

Media3 pre-release (alpha, beta or RC not in this list)

More version details

1.3.0-alpha01

Devices that reproduce the issue

OnePlus Nord running Android 11
Emulator running Android 14
Emulator running Android 10

Devices that do not reproduce the issue

No response

Reproducible in the demo app?

Not tested

Reproduction steps

In a default exoplayer with a simple ImageOutput set, setting a playlist with multiple media items:
e.g.:
mediaItems.add(imageMediaItemBuilder1.setImageDurationMs(3000).build()) //[Image1]
mediaItems.add(imageMediaItemBuilder2.setImageDurationMs(3000).build()) //[Image2]
mediaItems.add(videoMediaItem) //[Video]
videoPlayer.setMediaItems(mediaItems)
videoPlayer.playWhenReady = true
videoPlayer.prepare()

Expected result

Image 1 is shown 3000 ms, Image 2 is shown 3000 ms, Video is played in its entirety.

Actual result

The image right before the video is shown just a few milliseconds, transitioning directly to the video. That is, Image1 is shown 3000 ms, Image2 is shown a few ms, Video is played in its entirety.

For some reason, it seems having a video next in the playlist "overrides" the current image.

When the media items are only images it works as expected (all images are shown the set ms) and with only video it works as expected

Media

Not applicable

Bug Report

  • You will email the zip file produced by adb bugreport to [email protected] after filing this issue.
@christosts christosts assigned microkatz and unassigned christosts Jan 24, 2024
copybara-service bot pushed a commit that referenced this issue Mar 6, 2024
Renderers may be enabled for subsequent media items as soon as the current media item's renderer's isEnded() returns true. When a renderer is being enabled and the player is 'playing', that renderer is also started. When playing a mixed playlist of images and content with audio & video, the player may skip some image items because the early-starting of the audio renderer causes a clock update.

A solution is to only start the "early-enabled" renderers at the point of media transition and add a condition on DefaultMediaClock to use the standalone clock when reading-ahead and the renderer clock source is not in a started state.

Issue: #1017
PiperOrigin-RevId: 613231227
copybara-service bot pushed a commit to google/ExoPlayer that referenced this issue Mar 6, 2024
Renderers may be enabled for subsequent media items as soon as the current media item's renderer's isEnded() returns true. When a renderer is being enabled and the player is 'playing', that renderer is also started. When playing a mixed playlist of images and content with audio & video, the player may skip some image items because the early-starting of the audio renderer causes a clock update.

A solution is to only start the "early-enabled" renderers at the point of media transition and add a condition on DefaultMediaClock to use the standalone clock when reading-ahead and the renderer clock source is not in a started state.

Issue: androidx/media#1017
PiperOrigin-RevId: 613231227
@pawaom
Copy link

pawaom commented Mar 7, 2024

How are you displaying image and video in playlist can you share some sample code

copybara-service bot pushed a commit that referenced this issue Mar 11, 2024
Renderers may be enabled for subsequent media items as soon as the current media item's renderer's isEnded() returns true. Currently, when a player is set to pause, it stops all renderers that are `STATE_STARTED`. When a player is set to play, it starts all renderers that are enabled. This would include renderers that were enabled early for the subsequent media item. The solution is to only start renderers that are enabled by the current playing period.

Issue: #1017
PiperOrigin-RevId: 614734437
copybara-service bot pushed a commit to google/ExoPlayer that referenced this issue Mar 12, 2024
Renderers may be enabled for subsequent media items as soon as the current media item's renderer's isEnded() returns true. Currently, when a player is set to pause, it stops all renderers that are `STATE_STARTED`. When a player is set to play, it starts all renderers that are enabled. This would include renderers that were enabled early for the subsequent media item. The solution is to only start renderers that are enabled by the current playing period.

Issue: androidx/media#1017
PiperOrigin-RevId: 614734437
@microkatz
Copy link
Contributor

Hello @kleiren,

Thank you for reporting your issue! We submitted some fixes that should address the problem. These commits, 8b219b0 and 638b2a3 were pushed into the androidx/media main branch. With the fixes, Images with set duration should not be skipped in the mixed video, image playlist.

Hopefully that helps!

SheenaChhabra pushed a commit that referenced this issue Apr 8, 2024
Renderers may be enabled for subsequent media items as soon as the current media item's renderer's isEnded() returns true. When a renderer is being enabled and the player is 'playing', that renderer is also started. When playing a mixed playlist of images and content with audio & video, the player may skip some image items because the early-starting of the audio renderer causes a clock update.

A solution is to only start the "early-enabled" renderers at the point of media transition and add a condition on DefaultMediaClock to use the standalone clock when reading-ahead and the renderer clock source is not in a started state.

Issue: #1017
PiperOrigin-RevId: 613231227
(cherry picked from commit 638b2a3)
SheenaChhabra pushed a commit that referenced this issue Apr 8, 2024
Renderers may be enabled for subsequent media items as soon as the current media item's renderer's isEnded() returns true. Currently, when a player is set to pause, it stops all renderers that are `STATE_STARTED`. When a player is set to play, it starts all renderers that are enabled. This would include renderers that were enabled early for the subsequent media item. The solution is to only start renderers that are enabled by the current playing period.

Issue: #1017
PiperOrigin-RevId: 614734437
(cherry picked from commit 8b219b0)
@kleiren
Copy link
Author

kleiren commented Apr 10, 2024

Hi @microkatz
Just tried version 1.3.1. It seems all images are being sent through the ImageOutput (inside onImageAvailable()).

However, ImageOutput.onDisabled() seems to be being called immediately after the last onImageAvailable().
In my case, I am using ImageOutput.onDisabled() to hide the view where the images are being shown, with the exoplayer view below showing the videos from the media sequence.

For example, for 2 images and a video in sequence. Image 1 is shown correctly, the second image is shown for a few millis instead of its full presentation time (as on disabled is immediately called, hiding the view and showing what's below) and then the video is shown in the exoplayer view.

Should I use something different than onDisabled() to know when the current image has to stop being shown?

Thanks for the work!

@microkatz
Copy link
Contributor

microkatz commented Apr 11, 2024

Hi @kleiren.

Glad that progress has been made. The original issue was addressed by the player not transitioning its clock to the subsequent media item until the item has started(aka the play time has reached the next start position). I see that there is still a prevailing issue of the ImageRenderer finishing its renderering duties as soon as it offers that last image.

Thank you for reporting this new issue. We will need a little time to figure out the best solution.

In the meantime, may I suggest using the onMediaItemTransition callback? Hopefully that will provide ample notification for when the playback transitions to an item that is video vs image for switching your UI views.

l1068 pushed a commit to l1068org/media that referenced this issue Apr 15, 2024
Renderers may be enabled for subsequent media items as soon as the current media item's renderer's isEnded() returns true. When a renderer is being enabled and the player is 'playing', that renderer is also started. When playing a mixed playlist of images and content with audio & video, the player may skip some image items because the early-starting of the audio renderer causes a clock update.

A solution is to only start the "early-enabled" renderers at the point of media transition and add a condition on DefaultMediaClock to use the standalone clock when reading-ahead and the renderer clock source is not in a started state.

Issue: androidx#1017
PiperOrigin-RevId: 613231227
(cherry picked from commit 638b2a3)
l1068 pushed a commit to l1068org/media that referenced this issue Apr 15, 2024
Renderers may be enabled for subsequent media items as soon as the current media item's renderer's isEnded() returns true. Currently, when a player is set to pause, it stops all renderers that are `STATE_STARTED`. When a player is set to play, it starts all renderers that are enabled. This would include renderers that were enabled early for the subsequent media item. The solution is to only start renderers that are enabled by the current playing period.

Issue: androidx#1017
PiperOrigin-RevId: 614734437
(cherry picked from commit 8b219b0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants