-
Notifications
You must be signed in to change notification settings - Fork 6k
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
Gapless audio playback on multi-period DASH source #4899
Comments
Thanks for the interesting manifest. Things we found:
A few observations about the manifest itself:
At a higher level, it's unclear what you're trying to achieve. There's no need to start a new period to accommodate different segment durations. Periods are typically for use when the content actually changes (e.g. transition from one song to another, or from content to an ad). I also don't understand why you're having to clip from the start and end of each segment. Why are they there in the first place? It's pretty common to have variable segment length AAC in DASH and I've never seen this being necessary before, so there's likely a shortcoming with how you're preparing the media. So TLDR - We'll fix the issues identified at the top. It'll make things a bit better, but there will still be an audible discontinuity. I think the real fix is to prepare the content in a better way. |
Thank you ojw28 for looking at this and the detailed response. I will continue to look at the encoding to handle this better. I was trimming the beginning and end of the segments to account for the encoder start-up delay (https://www2.iis.fraunhofer.de/AAC/gapless.html) but it looks like I was not calculating the trim values correctly. I'll also look at using the MPEG Edit List to trim the segments and then including the segments in a single Period with a SegmentList. In addition (not shown in this repro), I am also using the presentationTimeOffset of the first segment and Period duration of the last segment / MPD mediaPresentationDuration to allow the manifest to trim the beginning and end of the entire presentation to bounds that fall inside of segments. Is that affected by the issue (2) you brought up, and if so is there a better way to handle this? |
Re: my last paragraph - I see if I get my media presentation to a single period I can use the ClippingMediaSource. I wasn't using ClippingMediaSource because I was using the multiple periods to trim the segments. |
I still don't really understand what you're doing. Pretty much any DASH stream will segment AAC audio into multiple segments, and they wont ever put each segment in its own period or do anything special to deal with start-up delay and padding. |
This makes the following changes to improve consistency among the PlaybackInfo values: 1. Update buffered position and total buffered duration after loading period is set as both values are affected by a loading period update. 2. Add copyWithPosition to allow updating the position without resetting the loading period. 3. Forward the total buffered duration to playing position updates as it may have changed with the new playing position. Issue:#4899 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=215712328
- Always clip to period duration for the last chunk. We previously did this only when the last chunk explicitly exceeded the period end time. We now also do it when the chunk claims to end at the period boundary, but still contains samples that exceed it. - If pendingResetPositionUs == chunk.startTimeUs == 0 but the chunk still contains samples with negative timestamps, we now clip them by setting the decode only flag. Previously we only clipped such samples if the first chunk explicitly preceeded the start of the period. Issue: #4899 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=215763467
This makes the following changes to improve consistency among the PlaybackInfo values: 1. Update buffered position and total buffered duration after loading period is set as both values are affected by a loading period update. 2. Add copyWithPosition to allow updating the position without resetting the loading period. 3. Forward the total buffered duration to playing position updates as it may have changed with the new playing position. Issue:#4899 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=215712328
- Always clip to period duration for the last chunk. We previously did this only when the last chunk explicitly exceeded the period end time. We now also do it when the chunk claims to end at the period boundary, but still contains samples that exceed it. - If pendingResetPositionUs == chunk.startTimeUs == 0 but the chunk still contains samples with negative timestamps, we now clip them by setting the decode only flag. Previously we only clipped such samples if the first chunk explicitly preceeded the start of the period. Issue: #4899 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=215763467
Issue description
I am playing a custom created MPEG-DASH manifest that includes multiple periods. Each period contains a single FMP4 segment that was created from ffmpeg using the following command line:
ffmpeg -i - -f segment -segment_attclocktime 1 -strftime 1 -c:a libfdk_aac -b:a 32k -segment_format mp4 -segment_format_options movflags=empty_moov+default_base_moof+frag_keyframe ~/test/%FT%H-%M-%S%z.mp4
Each period contains a single segment, and uses the period duration along with the presentationTimeOffset to trim the first and last sample off of the period. The segments, and thus the period durations vary, which is why each segment is in its own period.
When playing back, there is an audible gap between each period. Because the period start-times are configured without a gap, I would expect the audio playback to be gapless.
Reproduction steps
A reproduction app is available at:
https://github.com/ghexoplayerquestion/Repro
with the relevant code in the Android activity at:
https://github.com/ghexoplayerquestion/Repro/blob/master/app/src/main/java/com/example/ghexoplayerquestion/repro/MainActivity.java
During playback, the following is output on the debug console:
Link to test content
The DASH manifest that reproduces this issue is:
Version of ExoPlayer being used
ExoPlayer version 2.9.0
Device(s) and version(s) of Android being used
Reproduces on Android emulator:
Nexus 5X, 5.2 1080x1920 xxhdpi
Android API 28 x86
A full bug report captured from the device
The bug report is attached.
bugreport.zip
The text was updated successfully, but these errors were encountered: