Open th3hamm0r opened 6 years ago
My first thought was, that maybe there is a difference in how the codec is re-initialized, so I already tried to dig into the MediaCodecRenderer
/MediaCodecAudioRenderer
a bit to find some major differences. I failed, so I hope you can help here.
For reference, the streams are 1.ogg and 2.ogg.
Ogg containers have gapless playback information that I think we don't currently handle. There is some information about how this works here. To summarize, each Ogg page containing a completed Vorbis audio packet has a granule position that specifies the end PCM sample index of the last completed audio packet in the page. At the start of the stream, we may need to discard PCM audio samples that have an inferred position before 0. For trimming the end of the stream, the granule position in the last page may indicate a last PCM sample index that is before the last decoded PCM sample.
I'll mark this as an enhancement to provide support but it's unlikely we will get round to it soon: for other formats where we support gapless playback, we know the encoder delay/padding when we parse the header of the file, but it looks like we can't do this for Ogg so it may be difficult to implement. We do already support gapless playback of MP3 (based on Xing/ID3 headers) and MP4 (udta and edit lists) containers, so perhaps you can switch to use one of those. Also, I think opus bitstreams contain gapless playback information in the codec initialization data, so those should just work with both MediaCodecAudioRenderer
and the opus extension.
@andrewlewis Thanks for your quick response!
Would this be an enhancement of ExoPlayer's OggExtractor? If this is the case, do you think it would be possible to somehow use Android's MediaExtractor
feeding the ExoPlayer to fix this problem, till you fix this in the ExoPlayer?
Or can you think of another (quick-)fix to get a gapless playback of ogg/vorbis with the player?
Even with lame-mp3 encoded wav-segments we still have click sounds for some reason. Opus is nice, but encoding existing wav-segments is not as easy as with ogg/vorbis. Without a special handling (http://lists.xiph.org/pipermail/opus/2017-November/004031.html), those segments don't play gapless (tested with the ExoPlayer).
It's an enhancement to OggExtractor
, though might need changes elsewhere as well, unless we can find a way to get the encoder delay/padding before we first create the Format.
We used to provide a MediaExtractor
wrapper in v1 (FrameworkSampleSource) but there were fundamental issues with it.
I can't think of any quick fixes that do this properly. On the off chance you want gapless playback of some particular fixed files, you could do a hacky fix where you find out how many samples need to be trimmed (perhaps based on kKeyValidSamples in the MediaFormat? I'm not sure) then make a custom Extractor
wrapping OggExtractor
that provides the known values. But in that case you may as well change to another container/codec.
Gapless with MP3 should work fine. If you think it's a bug in ExoPlayer please file a separate issue and I'll take a look. Thanks.
Aside: I had a quick look at how the framework does this. It seems to append a number of valid samples to input buffers sent to the decoder.
@andrewlewis Again, thanks a lot for your quick reply and your help! I've created another issue for MP3 (#3475), it looks like it suffers from the same problem. Unfortunately mp3 is not an option for us, so I will try to find a (hacky) solution in the meantime, but I hope that the vorbis issue will be fixed in the future!
Issue description
We are facing problems with click noises when playing a sequence of ogg/vorbis files with the ExoPlayer. The interesting thing is, that I was able to create a quick&dirty player with Android's decoding-APIs where the playback is absolutely gapless. So what is the difference to the ExoPlayer and is there a way to avoid those clicking sounds? Eg. do I have to pass some configuration or override the
DynamicConcatenatingMediaSource
in a way to avoid this?Note: There are several issues, including https://github.com/google/ExoPlayer/issues/497 where I actually stated that the playback is gapless. Most of the time this is true, but in some cases the transition between files result in a click noise.
Reproduction steps
ExoPlayer
produced a click noise when transitioning (after 10s), theCustomPlayer
did not.Note: These two files also play gapless with several audio tools (Audacity, Aqualung player,...).
Link to test content
Note: The custom player is a quick&dirty solution created from several sources with some deprecated APIs and so on...
https://github.com/th3hamm0r/exoplayer-gapless-test
Version of ExoPlayer being used
2.5.4
Device(s) and version(s) of Android being used
Tested on multiple devices, eg. Nexus 5 (6.0.1), Nexus 5X (8.0), Nexus 9 (7.1.1), Nokia 6,...
A full bug report captured from the device
--