ExoPlayer icon indicating copy to clipboard operation
ExoPlayer copied to clipboard

Estimate duration of AAC file based on file length and bit rate

Open patrick131313 opened this issue 5 years ago • 6 comments

When I play an AAC File ExoPlayer getDuration() method returns -9223372036854775807

ExoPlayer version: 2.10.8

Device(s) and version(s) of Android being used Samsung Galaxy s8+ Android 8 Lg Q6 Android 8.1

I sent the AAC File on email at [email protected]

patrick131313 avatar Dec 10 '19 09:12 patrick131313

You should use getDuration after loaded file, Better time is after called "onTracksChanged"

saleh-gholamian avatar Dec 10 '19 10:12 saleh-gholamian

getDuration() returns -9223372036854775807 which is C#TIME_UNSET because the duration is unknown.

For .aac containers, ExoPlayer needs to download the entire file to be able to determine the duration of the audio because the container does not have such metadata in a header located in the beginning of the file. The player restricts how much data it downloads to preserve resources (memory, network, CPU), and downloads the file progressively and plays it in parallel. The duration will be available as soon as the file is fully downloaded. Using the default parameters for downloading/buffering, that will be about 60-30 seconds before the end of the file.

The recommendation is to use another container, such as mp4, which has duration in the file headers and the player can pick it up immediately.

Alternatively, you can tune the player's downloading/buffering behavior by passing a custom LoadControl when creating the player instance. For example, you can construct a DefaultLoadControl and tune its min and max buffers (duration and size) accordingly, to let the player download the entire file very quickly. That has 3 implications:

  1. you need to know the full duration of the audio and its size beforehand to tune the injected LoadControl behavior (or set the max values high enough for every audio?)
  2. The player will download entire .aac files (no matter how big) as soon as possible, so you need to keep an eye on memory.
  3. The duration of the file will not be available until the entire file is downloaded and, depending on the parameters tuned for buffering, playback might start before the file is fully downloaded. In which case, you will hear audio but not be able to display the duration yet. Keep this UX in mind.

On a last note, the specific .aac file sent, does not display the same duration between different players (I tried vlc, media player and chrome on a Linux machine).

christosts avatar Dec 10 '19 15:12 christosts

I am leaving the bug tag in case we add some additional logic for .aac files to make an estimation of the duration based on the file length and bit rate, but it is going to be low on priority.

christosts avatar Dec 10 '19 15:12 christosts

I checked again with the file that I've sent on email, the duration like you said is available from about 60-30 seconds before the end of the file. Even when duration is known the file is not seekable (FLAG_ENABLE_CONSTANT_BITRATE_SEEKING is enabled), it starts again from beginning. I tried also with larger files (about 30 minutes length) and the duration is known from beginning. I will send the files on email at [email protected]

patrick131313 avatar Dec 11 '19 08:12 patrick131313

All .aac files sent are variable bitrate HE-AAC audio put inside .aac. They should be packaged in a different container such as MP4. I also think they are not packaged properly: (i) several players have issue detecting the duration accurately, (ii) I tried to transcode them with ffmpeg and it raised parsing errors.

The recommendation is to switch to another container.

christosts avatar Dec 11 '19 14:12 christosts

I have the same problem, but the android.media.MediaPlayer has no problem,also can seekto the correct position

ExoPlayer version: 2.16.1

firsthubgit avatar Jan 16 '22 13:01 firsthubgit