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

OnTimelineChanged skips mediaItems and messes up video duration when using a concatenated mediaSource #1990

Open
1 task done
BrLudington opened this issue Dec 20, 2024 · 6 comments
Assignees

Comments

@BrLudington
Copy link

BrLudington commented Dec 20, 2024

Version

Media3 1.5.1

More version details

Bug is also reproducible in version 1.4.1

Devices that reproduce the issue

Any android device should be able to do so, however I used a Pixel 4a and RealMe devices to test.

Devices that do not reproduce the issue

No response

Reproducible in the demo app?

Not tested

Reproduction steps

In the code save the current position of the exoplayer on orientation change. When all the concatenated mediaSources are finished (Player.Listener's onTimeLineChanged gets called for each one added), we seekTo the position.
1.) Concatenate several video MediaSources together using ConcatenatingMediaSource2.Builder
2.) Set Exoplayer's MediaSource to the resulting concatenation above
2.5.) Keep doing this until the resulting video is at least twenty seconds long
3.) Scrub to near the end of the video.
4.) Rotate the device.

Expected result

Regardless of where the position was in the video, return to that position once the concatenated video is finished setting up in Exoplayer.

Actual result

When the position is early in the video everything works fine, but when near the end odd behavior happens. OnTimelineChanged doesn't get called for each video, only some of them. The video's duration ends up being shorter with the position being all the way at the end.

For example say two videos take up 25 seconds. Upon the bug happening the duration cuts to 16 seconds on the time bar.

Media

Link to my project example

Bug Report

  • You will email the zip file produced by adb bugreport to [email protected] after filing this issue.
@tianyif
Copy link
Contributor

tianyif commented Dec 23, 2024

Hi @BrLudington,

Thanks for the project example! When reproducing on your app, I saw that the player was re-initialized while rotating the orientation. Thus, the sources concatenated would be set to the new player, and player had to prepare the concatenated source again. All of these were due to the MainActivity was recreated when orientation changed.

Please checkout https://developer.android.com/guide/topics/resources/runtime-changes#restrict-activity if you want to avoid activity recreation upon rotating.

@jstock78
Copy link

Hi @tianyif, I'm working with @BrLudington on this issue. Changing the reconstruction options for the Activity is an option to workaround most instances of this issue, but recreating the video player is a good way to see the issue with OnTimelineChanged. Just to reiterate, we're sometimes only seeing 1-2 calls to OnTimelineChanged when loading 4+ videos via ConcatenatingMediaSource2. None of the calls to OnTimelineChanged contain all of the Timeline windows, so we're unable to predetermine the duration and setting the seek position towards the end of the video doesn't work.

How can we seek to the end of a video with multiple MediaSource loaded with ConcatenatingMediaSource2? Perhaps we have some method calls out of sequence in our sample?

@tianyif
Copy link
Contributor

tianyif commented Dec 24, 2024

@jstock78,

I tried your sample app again, with always adding 9 videos (duration adding up to 2 min 14s), and seeing these logs:

2024-12-24 06:46:41.536 11864-11864 github                  com.example.exoplayerbugdemo         E  add video: 9
2024-12-24 06:46:41.558 11864-11864 github                  com.example.exoplayerbugdemo         E  onTimelineChanged timeline duration: 72112
2024-12-24 06:47:03.660 11864-11864 github                  com.example.exoplayerbugdemo         E  onTimelineChanged timeline duration: 89317
2024-12-24 06:47:21.362 11864-11864 github                  com.example.exoplayerbugdemo         E  onTimelineChanged timeline duration: 96126
2024-12-24 06:47:27.706 11864-11864 github                  com.example.exoplayerbugdemo         E  onTimelineChanged timeline duration: 116766
2024-12-24 06:47:48.421 11864-11864 github                  com.example.exoplayerbugdemo         E  onTimelineChanged timeline duration: 133971

The onTimelineChanged were called for 5 times, and outstandingly the duration already began with a large non-default number. I think this was because that every time when the app added a new video, it cleared the sources from the player, and added to the player again with all the previous sources and the new one. It's possible that some of the previous sources had already been prepared, thus their durations were immediately available upon new preparation, and they were all delivered via the first onTimelineChanged call. And the following sources still needed time to prepare, then you can see that time consumed between each call. And it took 1 min to finally get the total duration.

May I know in which use case you want to seek to the end of all the videos when adding a new video? Also, do you have any reason of combining all the source into one single, rather than using the playlist APIs (the multiple sources remain as multiple though)?

@jstock78
Copy link

@tianyif

I'll be honest, I haven't looked at the test code that @BrLudington created, but I am very familiar with the production code. We regularly see the final duration not update if you change orientation a few times, especially if the video is playing at the time. It's concerning that it took a full minute for the final duration to appear in your example.

A little background on what we're trying to do, we're developing a video editing app that combines multiple smaller videos into a large video using FFMpeg. We need to use Exoplayer to "preview" the final video before encoding. In our other Exoplayer implementations we've had no issues when a single source is used changing orientations and resuming playback at the previous point. We were hoping to do the same when using ConcatenatingMediaSource2.

@tianyif
Copy link
Contributor

tianyif commented Jan 2, 2025

Hi @jstock78,

We have a backlog feature request to enable ConcatenatingMediaSource2 to provide the total duration early, however there haven't been a concrete schedule when to add such support. An unideal workaround before that feature comes is that you may want to estimate the duration of the media as close to the actual duration as possible, and pass the estimated duration as the placeholder duration.

As you mentioned that you're doing a video editing app, I just want to bring up that media3 does have libraries for video editing. Please checkout our official blog post for more details (which should contain the links to the developer guide), and see if anything from the editing libraries can better fit your case.

@jstock78
Copy link

jstock78 commented Jan 2, 2025

Hi @tianyif,

Thank you for the continued responses. It sounds like the backlog feature would help a lot and is what we expected the behavior to be. Perhaps if the feature is going to take a while a quick note in the docs would help other users understand the duration might not be available immediately.

Thank you for the link! The media3-muxer module sounds like exactly what we are using FFMpeg for, I'll have to check it out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants