Adding this callback makes sense for completeness (we have similar callbacks
for all other playback state properties), and also to detect audio focus loss
while buffering which would currently trigger no callback because isPlaying
is still false.
Issue:#6203
PiperOrigin-RevId: 271347351
Inline invocations of these methods, which still leaks the MediaDrms.
However, it will be fixed once the DefaultDrmSessionManager API is finalized
and ExoMediaDrm.Providers are introduced.
Issue:#4721
PiperOrigin-RevId: 270681467
Remove the flag DataSpec.FLAG_ALLOW_ICY_METADATA. Instead, set the
header IcyHeaders.REQUEST_HEADER_ENABLE_METADATA_NAME in the DataSpec
httpRequestHeaders.
BUG:134034248
PiperOrigin-RevId: 270662676
This option allows to set the preferred text language and role flags based
on the user's accessiblity captioning settings.
Issue:#5749
PiperOrigin-RevId: 270233205
The player may suppress playback when waiting for audio focus even if the
state==Player.READY. There is currently no getter or callback to obtain this
piece of information for UI updates or analytics.
Also, it's a important derived state to know whether the playback position is
advancing. Add isPlaying and the corresponding callback to allow retrieving
this information more easily.
Issue:#6203
PiperOrigin-RevId: 268921721
This allows to uniquely identify a window within a Timeline. The value is set
correctly for all Window instances, but is not used anywhere yet.
PiperOrigin-RevId: 267556516
Include Dataspec.httpRequestHeaders in CronetDataSource,
and OkHttpDataSource. Updated documentation of
HttpDataSource.open() to suggest that it should set request
headers (in decreasing priority) from (1) the passed DataSpec,
(2) parameters set with setRequestProperty() and (3) default
parameters set in the HttpDataSource.Factory. No mechanism
has been put in place to enforce this.
PiperOrigin-RevId: 266895574
Sniffing is performed in ProgressiveMediaPeriod even if a single
extractor is provided. Skip it in that case to improve performances.
Issue:#6325
PiperOrigin-RevId: 266766373
- Surface information provided by methods isHardwareAccelerated,
isSoftwareOnly and isVendor added in Android Q in MediaCodecInfo
class.
- Estimate this information based on the codec name for earlier API
levels.
Issue:#5839
PiperOrigin-RevId: 266334850
The last selection criteria is the audio bitrate to prefer higher-quality
streams. We shouldn't apply this criterium though if the languages of the
tracks are different.
Issue:#6335
PiperOrigin-RevId: 265064756
This situation happens if the first chunk to load is already behind the end
of the stream. In this case, the preparation never completes because
HlsSampleStreamWrapper gets stuck in a prepared=false and loadingFinished=true
state.
Gracefully handle this situation by attempting to load the last chunk if still
unprepared to ensure that track information is obtained as far as possible.
Otherwise, it wouldn't be possible to play anything even when seeking back.
Issue:#6314
PiperOrigin-RevId: 264599465
Extract supplemental data from block additions in WebM/Matroska.
Allow storing supplemental data alongside samples in the SampleQueue and write
it as a separate field in DecoderInputBuffers.
Handle supplemental data in the VP9 extension by propagating it to the output
buffer.
Handle supplemental data for HDR10+ in MediaCodecVideoRenderer by passing it to
MediaCodec.setParameters, if supported by the component.
PiperOrigin-RevId: 264582805
There is no point in having this parameter as the tag should always be a single
immutable object instantiated at the time the Timeline is created or earlier.
So there is no preformance benefit and it's error-prone in case people
forget to set setTag=true.
PiperOrigin-RevId: 264117041
This solves various issues around event association for buffering and
error throwing around period discontinuities.
The main changes are:
- Logic around being "ready" at the end of a period no longer checks if the
next period is prepared.
- Advancing the playing period no longer checks if the next one is prepared.
- Prepare errors are always thrown for the playing period.
This changes the semantics and assumptions about the "playing" period:
1. The playing period can no longer assumed to be prepared.
2. We no longer have a case where the queue is non-empty and the playing or
reading periods are unassigned (=null).
Most other code changes ensure that these changed assumptions are handled.
Issue:#5407
PiperOrigin-RevId: 263776304
The current ExoPlayerFactory is growing too big and usage becomes increasingly
complicated because it's not possible to set individual components without
specifying many other defaults.
Adding new builder classes makes building easier and more future-proof.
PiperOrigin-RevId: 263339078
The current max video buffer is 13MB which is too small for high quality
streams and doesn't allow the DefaultLoadControl to buffer up to its default
max buffer time of 50 seconds.
Also move util method and constants only used by DefaultLoadControl into this
class.
PiperOrigin-RevId: 263328088
We already allow mixed mime type and mixed sample rate adaptation on request,
so for completeness, we can also allow mixed channel count adaptation.
Issue:#6257
PiperOrigin-RevId: 261930046
If we keep streams in chunk sources after selecting new tracks, we also keep
a reference to a stale disabled TrackSelection object. Fix this by updating
the TrackSelection object when keeping the stream. The static part of the
selection (i.e. the subset of selected tracks) stays the same in all cases.
Issue:#6256
PiperOrigin-RevId: 261696082
A previous change switched to calculation of the bitrate based on the
first MPEG audio header in the stream. This had the effect of fixing
seeking to be consistent with playing from the start for streams where
every frame has the same padding value, but broke streams where the
encoder (correctly) modifies the padding value to match the declared
bitrate in the header.
Issue: #6238
PiperOrigin-RevId: 261163904
This factory was only needed in the past when we didn't have
AnalyticsCollector.setPlayer. Code becomes easier to use without this factory.
PiperOrigin-RevId: 261081860
This changes the logic in the following ways:
- If no preferred language is matched, prefer better scores for the selected
audio language.
- If a preferred language is matched, always prefer the better match
irrespective of default or forced flags.
- If a preferred language score and the isForced flag is the same, prefer
tracks with a better selected audio language match.
PiperOrigin-RevId: 259707430
1. Using the Locale on API<21 doesn't make any sense because it's a no-op
anyway. Slightly restructured the code to avoid that.
2. API<21 often reports languages with non-standard underscores instead of
dashes. Normalize that too.
3. Some invalid language tags on API>21 get normalized to "und". Use original
tag in such a case.
Issue:#6153
PiperOrigin-RevId: 258773463
2-letter codes (ISO 639-1) are the standard Android normalization and thus we
should prefer them to 3-letter codes (although both are technically allowed
according the BCP47).
This helps in two ways:
1. It simplifies app interaction with our normalized language codes as the
Locale class makes it easy to convert a 2-letter to a 3-letter code but
not the other way round.
2. It better normalizes codes on API<21 where we previously had issues with
language+country codes (see tests).
3. It allows us to normalize both ISO 639-2/T and ISO 639-2/B codes to the same
language.
PiperOrigin-RevId: 258729728
If we use the default start position, we currently resolve it immediately
even if we need to play an ad first, and later try to project forward again
if we believe that the default start position should be used.
This causes problems if a specific start position is set and the later
projection after the preroll ad shouldn't take place.
The problem is solved by keeping the content position as TIME_UNSET (= default
position) if an ad needs to be played first. The content after the ad can
then be resolved to its current default position if needed.
PiperOrigin-RevId: 258583948
These methods helps to indicate that a media source isn't used to create new
periods in the immediate term and thus limited resources can be released.
PiperOrigin-RevId: 258373069
- Remove manifest argument from callbacks of Player.EventListener and
SourceInfoRefreshListener. Instead make it accessible through
Player.getCurrentManifest() and Timeline.Window.manifest.
- Fix all MediaSource implementation to include the manifest in the
Timeline instead of passing it to the SourceInfoRefreshListener.
- Refactor ExoPlayerTestRunner, FakeTimeline, FakeMediaSource to
reflect these changes and make tests pass.
PiperOrigin-RevId: 257359662
We currently handle most the control code logic after handling special
characters. This includes filtering out repeated control codes and checking
for the correct channel. As the special character sets are control codes as well,
these checks should happen before parsing the characters.
Issue:#6133
PiperOrigin-RevId: 256993672
Currently, we sometimes apply new playback parameters directly and sometimes
through the list of playbackParameterCheckpoints. Only when using the checkpoints,
we also reset the offset and corresponding position for speedup position
calculation. However, these offsets need to be changed in all cases to prevent
calculation errors during speedup calculation[1].
This change channels all playback parameters changes through the checkpoints to
ensure the offsets get updated accordingly. This fixes an issue introduced in
31911ca54a.
[1] - The speed up is calculated using the ratio of input and output bytes in
SonicAudioProcessor.scaleDurationForSpeedUp. Whenever we set new playback
parameters to the audio processor these two counts are reset. If we don't reset
the offsets too, the scaled timestamp can be a large value compared to the input
and output bytes causing massive inaccuracies (like the +20 seconds in the
linked issue).
Issue:#6117
PiperOrigin-RevId: 256533780
1. Only output video starting from a keyframe
2. When calculating the timestamp offset to adjust live streams to start
at t=0, use the timestamp of the first tag from which a sample is actually
output, rather than just the first audio/video tag. The test streams in
the referenced GitHub issue start with a video tag whose packet type is
AVC_PACKET_TYPE_SEQUENCE_HEADER (i.e. does not contain a sample) and whose
timestamp is set to 0 (i.e. isn't set). The timestamp is set correctly on
tags that from which a sample is actually output.
Issue: #6111
PiperOrigin-RevId: 256147747
We are currently queuing periods in a way such that the new start position
lines up with the end of the previous period (to ensure continuous playback).
However, if the start position of the new period is larger than the total of
all previously played period durations, we may end up with negative renderer
timestamps when seeking back to the beginning of this new period. Negative
timestamps should be avoided as most decoders have problems handling them
correctly.
This change forces a renderer reset if we detect such a seek to a negative
renderer time and also resets the renderer offset to 0 every time all
renderers are disabled, as this is the only time where we can savely change
the offset of an existing media period.
Also, if playback starts with an ad, we choose the content position as
renderer offset to prevent the whole issue from occurring for the seek-behind-
midroll case.
Issue:#6009
Issue:#5323
PiperOrigin-RevId: 253790054
This permission has normal access right and can't be revoked by the user.
However, an app can choose to revoke it when using ExoPlayer, e.g. if
no network is required and the app doesn't want to list this permission.
Support this use case by gracefully catching the exception in the relevant
places.
Issue:#6019
PiperOrigin-RevId: 253759332
We currently report MediaCodec exceptions as unexpected exceptions instead of
as renderer error. All such exceptions are now wrapped in a new DecoderException
to allow adding more details to the exception.
PiperOrigin-RevId: 252054486
We currently don't display the last frame because the seek time is behind the
last frame's timestamps and it's thus marked as decodeOnly.
This case can be detected by checking whether all data sent to the codec is
marked as decodeOnly at the time we read the end of stream signal. If so, we
can re-enable the last frame. This should work for almost all cases because the
end-of-stream signal is read in the same feedInputBuffer loop as the last
frame and we therefore haven't released the last frame buffer yet.
Issue:#2568
PiperOrigin-RevId: 251425870
Using parallel adaptation for Formats without bitrate information currently
causes an exception. Handle this gracefully and also cases where all formats
have the same bitrate.
Issue:#5971
PiperOrigin-RevId: 250682127
cache() opens all connections with unset length to avoid position errors.
This makes more data then needed to be downloading by the underlying
network stack.
This fix makes makes it open connections for only required length.
Issue:#5927
PiperOrigin-RevId: 250546175
This prevents further unexpected updates if the MediaSource happens to
finish its preparation at a later point.
Issue:#5915
PiperOrigin-RevId: 249439246
Adding an explicit option to clear all downloads prevents repeated database
access in a loop when trying to delete all downloads.
However, we still create an arbitrary number of parallel Task threads for this
and seperate callbacks for each download.
PiperOrigin-RevId: 247234181
Can happen if the load position falls behind in every playlist and
when we try to load the next segment, the adaptive selection logic
decides to change variant.
Issue:#5816
PiperOrigin-RevId: 245923006
We currently toggle the view in onTouchEvent ACTION_DOWN which is non-standard
and causes problems when used in a ViewGroup intercepting touch events.
Switch to standard Android click handling instead which is also what most
other player apps are doing.
Issue:#5784
PiperOrigin-RevId: 245219728
Experiments show this is beneficial for rebuffers with only minor impact
on battery usage.
Configurations which explicitly set a minimum buffer duration are unaffected.
Issue:#2083
PiperOrigin-RevId: 244823642
Before this change we'd release the audio track and create a new one as soon
as audio processors had drained when reconfiguring.
Fix this behavior by stop()ing the AudioTrack to play out all written data.
Issue: #2446
PiperOrigin-RevId: 244812402
Remove MediaCodecSelector.DEFAULT_WITH_FALLBACK, as codec selectors
will need to be able to return a list of decoder infos even when not
using fallback in a later change. Instead signal that fallback should
be used via a renderer constructor.
Fallback is always disabled for audio.
PiperOrigin-RevId: 242454172
The priority task manager only needs to listen to loading state changes and
is independent of the rest of DefaultLoadControl. This also fixes problems
where the player stops loading without consultin the LoadControl.
PiperOrigin-RevId: 242098374
If no track matches the preferred language or no preferred language is provided,
use the system Locale language as the next decision criterion.
PiperOrigin-RevId: 241322703
It's currently very difficult to actually set a reason for track selection
triggered by a SelectionOverride. It would require creating a new custom
TrackSelection.Factory where the reason gets injected somehow before the
override is specified on the player.
Simplify this whole procedure by allowing to set the reason directly and
forward this reason to all fixed selections created based on this override.
PiperOrigin-RevId: 240114942
This allows to distinguish between regional variants and scripts.
We still need to normalize the language code itself to make track selection
independent of the whether 2 or 3 letter codes are used.
PiperOrigin-RevId: 239783115
Any seek map with non-zero offsets breaks playback with ICY metadata as
the metadata is no longer read from the correct position.
Issue:#5658
PiperOrigin-RevId: 239605839
The flag in ExoPlayer.prepare is documented as keeping the current window
index and window position. We are currently using the current period UID and
period position instead. This causes problems when the media source is changed
but the position is not reset.
Using the initial seek position instead ensures we actually use the window
index and position.
Issue:#5520
PiperOrigin-RevId: 236101024
Adding new error types may cause issues when listeners assume a fixed set of
error types and don't handle arbitrary defaults.
Fixing error handling in one case and improving documentation to make people
aware of the issue.
PiperOrigin-RevId: 236093265
*** Reason for rollback ***
Reverting as this may break playback on other Amlogic devices and/or playback of non-interlaced content.
*** Original change description ***
Add max video size workaround for Amlogic decoder.
The Amlogic awesome decoder reduces the video size of interlaced videos by half
if the internal configuration isn't force reset with new maximum input size
values. The product of these new values must exceed 1920x1088 to force the
reset.
Issue:#5003
***
PiperOrigin-RevId: 234967314
HlsSampleStream#read should return end of stream when
there is no mapping for the sample stream, instead of
nothing read. This allows the player to transition to
ended.
Issue:#5524
PiperOrigin-RevId: 234764027
This bug affects any playlist that uses initialization segments. In practice,
almost exclusively fragmented mp4 segmented playlists are affected.
The bottom line is that extractors are chosen for reuse after the
initialization segment connection is open. However, reused extractors
do not need re-parsing the init segment, so loading the initialization is
wasteful.
PiperOrigin-RevId: 234479467
Previously we would get a new AudioTrack and flush all audio processors if any
AudioProcessor needed to be flushed on reconfiguration. This was problematic for
the case of TrimmingAudioProcessor because it could become active or inactive
due to transitioning to a period with gapless metadata or without it (we don't
keep it active all the time because it is wasteful to populate its end buffer
for content that is not gapless).
This change handles the case where we don't need an AudioTrack but
AudioProcessors do need to be flushed. In this case we drain all the audio
processors when next handling data then switch to the new configuration.
This avoids truncation when period transitions change whether
TrimmingAudioProcessor is active but don't require a new AudioTrack, and is also
a step towards draining the AudioTrack when transitioning between periods if we
do need a new AudioTrack.
To do this, it needs to be possible to drain any pending output data from an
AudioProcessor after it's configured to a new format, so this change makes sure
AudioProcessors allow calling playToEndOfStream and getOutput after
reconfiguration and before flush.
PiperOrigin-RevId: 234033552
Stop encoding/decoding presentation time as part of the message.
What's actually in emsg boxes is a presentation time delta,
which is why it's only 32 bits, and hence why it doesn't handle
large absolute timestamps. We were using this field to hold
absolute timestamps only for the purpose of passing presentation
times from DashManifestParser.parseEvent back to the calling
method. After this change, we return Pair<Long, EventMessage>
instead.
Issue: #5490
PiperOrigin-RevId: 233561731
Switch from passing an ad UI ViewGroup to passing an object that can also
provide information about controls overlays.
Also switch to using a dedicated overlay for ads instead of the overlay frame
layout, which apps have easy access to.
PiperOrigin-RevId: 233393500
Supporting multiple overrides allows to select tracks from multiple groups, if
enabled. As more options are added, the creation of the dialog is moved to a
separate builder class.
PiperOrigin-RevId: 233366282
Imported from GitHub PR https://github.com/google/ExoPlayer/pull/5438
Plus the following changes:
- Only support profile 5 (handling other profiles requires
backward-compatibility changes in the renderer which are left for a later
change.)
- Only add KEY_PROFILE to the codec configuration MediaFormat for Dolby Vision.
- In MediaCodecUtil support all DV profiles that Android has constants for. This
includes ones that are "not supported for new applications". Since we don't
extract these profiles, this is currently only for the benefit of custom
extractors.
- Misc code style fixes and reordering for consistency.
Merge 37878b975c2bc082b0568e21cbe62bfcef97c10d into 67be9e7783
PiperOrigin-RevId: 233066799
Given the change to require setPlayer on AdsLoaders, it seems like a good
opportunity to clean up deprecated ads-related symbols.
PiperOrigin-RevId: 233020171
When calling releaseSource(), all pending messages will be removed. That means
that all action-on-completion callbacks which are somewhere in flight are
just dropped without being called. This change adds code to keep track of the
current state of each callback to allow all of them being called when the
source is released.
Issue:#5464
PiperOrigin-RevId: 232312528
It better describes what the class does. More importantly, we've had
inconsistent class names since we added offline support, for which we
added ProgressiveDownloader ("ExtractorDownloader" doesn't make any
sense). We could really do with aligning the names for clarity.
(Sorry)
PiperOrigin-RevId: 231387268
The combination of pre-16 API levels accounting for ~0.5% of the device
population, and that the most important components in ExoPlayer (e.g.
the MediaCodec renderers) have always required API level 16, mean it's
very unlikely this will negatively impact on anyone.
PiperOrigin-RevId: 230701808
ExoPlaybackExceptions of type SOURCE are always associated with the loading
period and thus we can use the event time for the loading period in
onPlayerError. Renderer and unexpected exceptions are still associated with the
currently playing period.
Issue:#5407
PiperOrigin-RevId: 230216253
The Amlogic awesome decoder reduces the video size of interlaced videos by half
if the internal configuration isn't force reset with new maximum input size
values. The product of these new values must exceed 1920x1088 to force the
reset.
Issue:#5003
PiperOrigin-RevId: 230206675
That's the same position set in MediaPeriod.prepare (where it may be removed
in the future).
Having the position at an earlier point is necessary to fix an
issue with lazy preparation in ConcatenatingMediaSource where the prepare
position was assumed to be known but MediaPeriod.prepare hasn't been called
yet.
Issue:#5350
PiperOrigin-RevId: 229756637
The buffered position is currently based on the mimimum queued timestamp of
all AV tracks. If the tracks have unequal lengths, one track continues loading
without bounds as the "buffered position" will always stay at the shorter
track's duration.
This change adds an optional buffer flag to mark the last sample of the
stream. This is set in the Mp4Extractor only so far. ExtractorMediaSource
uses this flag to ignore AV streams in the buffered duration calculation if
they already finished loading.
Issue:#3670
PiperOrigin-RevId: 229359899
DataSpec.FLAG_ALLOW_CACHE_FRAGMENTATION is added to indicate to the
cache when fragmentation is allowed. This flag is set for progressive
requests only.
To avoid breaking changes, CacheDataSink defaults to ignoring the flag
(and enabling fragmentation) for now. Respecting the flag can be
enabled manually. DownloaderConstructorHelper enables respecting of
the flag.
Issue: #4253
PiperOrigin-RevId: 229176835
We currently forget whether a source is seekable at re-preparation. This was
implemented intentionally this way under the assumption that we really can't seek
until we have loaded the seek map again. However, seek operations are only
allowed after a media period is prepared. So there is no harm in remembering
whether a source is seekable.
This problem currently prevents reusing ClippingMediaSources with
ExtractorMediaSource and a non-zero start clip position.
Issue: #5351
PiperOrigin-RevId: 229169441
They are not longer needed anywhere, are error-prone (because of threading
requirements), and complicate testing and using MediaSources without a player.
PiperOrigin-RevId: 227871157
We currently either use the app thread returned by the player or the thread
the commands are called on depending on whether the media source is already
prepared or not.
This change lets the application decide which callback thread to use. As a
side effect, we also don't longer need access the player instance passed to
MediaSource.prepare.
PiperOrigin-RevId: 227871111
Also configure the FFmpeg context to ignore errors as far as possible (this
appears to have an effect only for certain decoders).
Issue: #5293
PiperOrigin-RevId: 227851397
Passing the player through MediaSource.prepare is only needed for the AdsLoader
and complicates other usages of MediaSource. Providing the player directly to
the AdsLoader is also in line with the usage pattern of PlayerView and other
components.
Also rename methods to start/stop to better reflect their usage.
PiperOrigin-RevId: 227682112
Made DownloadState top level class.
Replaced action field DownloadAction fields.
Added removing, removed and restarting states.
Renamed started state to downloading.
PiperOrigin-RevId: 227664735
ExoPlayer methods must not be called from any thread besides the specified
app thread. Therefore we shouldn't use them here. Using a regular Handler
instead is fully equivalent.
Issue:#5240
PiperOrigin-RevId: 227650489
We currently have two factory methods where it is completely unclear which one needs
to be overridden.
This change deprecates the old one, adds a Util method to easily map back from the new
to the old behaviour, and updates all implementations of the now deprecated method in
our code.
PiperOrigin-RevId: 224303560
We currently default to not caching data if the content length
cannot be resolved once the DataSource has been open. The
reason for this is to avoid caching progressive live streams.
By doing this we were accidentally not caching in other places
where caching is possible, such as DASH/SS/HLS segments during
playback if the server doesn't include a Content-Length header.
Also HLS encryption key chunks, which were very unlikely to be
cached during playback because we explicitly set FLAG_ALLOW_GZIP
(which normally stops content length from resolving) without
setting FLAG_ALLOW_CACHING_UNKNOWN_LENGTH.
It seems like a good idea to flip the default at this point,
and explicitly disable caching in the one case where we want
that to happen.
PiperOrigin-RevId: 223994110
- Increase the search window size to fix TS seeking for problematic
media we've had provided to us.
- As per my comments on the issue, we should look at doing more here
to better fix the problem. This will solve the worst of the
immediate problem, however.
- The memory usage is non-trivial, particularly with the increased
search window size. I've made the allocations only live whilst
determining duration and seeking to address this. I've done the same
for PS just for consistency.
Issue: #5097
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=221449988
The remaining work is to split Window.isDynamic so that it's
possible to represent a window that wont be appended to, but
may still be removed from.
Issue: #4780
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=221439220
This fixes an issue where disabling audio focus handling
while audio focus is held would not release audio focus.
A new test was added for this situation.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=220316866
This prevents leaving an inconsistent state after a EOF exception.
Issue:#5039
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=219785275
This seems to be more stable in case Bintray has issues updating the ExoPlayer
sources.
Issue:#4997
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=218327350
In ConcatenatingMediaSource, the source may be removed before it started
preparing (this may happen if lazyPreparation=true). In this case, we
shouldn't call releaseSource as the preparation didn't start.
Issue:#4986
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=218141658