IMA always starts midrolls at index 1. So if there is no preroll ad,
the ad group index in AdPlaybackState is off by 1 all the time, and
may also lead to ArrayIndexOutOfBoundsExceptions when trying to access
the last midroll ad
Issue: androidx/media#1741
PiperOrigin-RevId: 682324368
All methods check if the player is currently handling the ad source
by calling isCurrentAdPlaying(). This method was missing a check
for empty timelines that throws an exception when trying to access
a non-existent period.
Also add this check to two methods that assume the current item
is the ads source, but didn't check it yet.
PiperOrigin-RevId: 653963557
This interface is not used in the library. Callers can use the
`Bundle toBundle()` and `static Foo fromBundle(Bundle)` methods
defined directly on each type instead.
PiperOrigin-RevId: 642271609
When the AdTagLoader is deactivated because of a player error, the
error callback is already pending on the app's main thread, but not
yet executed. This means the VideoAdPlayerCallback instances
registered in AdTagLoader won't receive this error event if the
Player.Listener is immediately removed from AdTagLoader.
This can be fixed by postponing the deregistration until after
already pending messages have been handled. As this means other
callbacks can be triggered now with player==null, this check needs
to be added to other callbacks to avoid handling stale events.
Issue: androidx/media#1334
PiperOrigin-RevId: 630068222
Many usages are needed to support other deprecations and some
can be replaced by the recommended direct alternative.
Also replace links to deprecated/redirected dev site
PiperOrigin-RevId: 601795998
This helps to play ads where the file extension is not sufficient
to deduce the correct source in DefaultMediaSourceFactory.
PiperOrigin-RevId: 582340114
Currently, ads are only defined by a single URL, which makes it
impossible to define additional fields needed to play ads correctly.
This can be fixed by using a full MediaItem in AdPlaybackState,
replacing the previous Uri field.
PiperOrigin-RevId: 582331588
Both interfaces are not really needed as the methods can be called
on the respective classes directly. This also avoid error-prone
situations where classes define to/fromBundle methods with parameters
that should be used instead of the parameter-less version.
Also deprecate all existing CREATOR static instances and make the
corresponding fromBundle method public where needed.
PiperOrigin-RevId: 579189766
The period index was calculated relative to the contentTimeline
of the DAI stream, but then used with the full timeline of the
player. This means it currently only works when the stream is the
only or first item in the playlist.
Issue: androidx/media#571
PiperOrigin-RevId: 560023412
Updates to the ad playback state are posted on the main handler,
so they may arrive after the source has already been released
(=the internal MediaSource is null). This can cause NPEs.
PiperOrigin-RevId: 555102426
This changes all MediaSources in our library to allow updates to
their MediaItems (if supported).
Issue: google/ExoPlayer#9978
Issue: androidx/media#33
PiperOrigin-RevId: 546808812
MP4 edit lists sometimes ask to start playback between two samples.
If this happens, we currently change the timestamp of the first
sample to zero to trim it (e.g. to display the first frame for a
slightly shorter period of time). However, we can't do this to audio
samples are they have an inherent duration and trimming them this
way is not possible.
#minor-release
PiperOrigin-RevId: 543420218
This change addresses the case when the user joins the live stream
on an ad period but the metadata for the ad period is not emitted.
This results in inserting a partial ad group.
In this case the ad group duration is longer than the partial ad
group. If now the partial ad group ends at the period before the
last period of the window (unknown duration), the splitting algorithm
didn't recognize that the ad group already ended and made the last
period wrongly an ad period.
This change handles this edge case by counting the mapped ads in
the partial ad group to detect this situation and stops splitting.
#minor-release
PiperOrigin-RevId: 539102785
Docs:
* https://developer.android.com/build/publish-library/configure-pub-variants#single-pub-var
* https://developer.android.com/reference/tools/gradle-api/8.0/com/android/build/api/dsl/PublishingOptions
This resolves the following warning from Android Gradle Plugin 7.2.2 and
helps unblock the upgrade to AGP 8.0.1:
> Software Components will not be created automatically for Maven
> publishing from Android Gradle Plugin 8.0. To opt-in to the future
> behavior, set the Gradle property
> `android.disableAutomaticComponentCreation=true` in the
> `gradle.properties` file or use the new publishing DSL.
>
> Affected Modules: `lib-cast`, `lib-common`, `lib-container`,
> `lib-database`, `lib-datasource`, `lib-datasource-cronet`,
> `lib-datasource-okhttp`, `lib-datasource-rtmp`, `lib-decoder`,
> `lib-effect`, `lib-exoplayer`, `lib-exoplayer-all (legacy)`,
> `lib-exoplayer-dash`, `lib-exoplayer-hls`, `lib-exoplayer-ima`,
> `lib-exoplayer-rtsp`, `lib-exoplayer-smoothstreaming`,
> `lib-exoplayer-workmanager`, `lib-extractor`, `lib-media2 (legacy)`,
> `lib-mediasession (legacy)`, `lib-muxer`, `lib-session`,
> `lib-transformer`, `lib-ui`, `lib-ui-leanback`, `test-utils`,
> `test-utils-robolectric`
Issue: androidx/media#409
PiperOrigin-RevId: 533464133
This is a pre-requisite for the Android Studio upgrade assistant to
upgrade from AGP 7.2.2 to 8.0.1, otherwise it fails and complains
this is missing.
Issue: androidx/media#409
PiperOrigin-RevId: 533463246
This change enables the IMA extension to play live DASH streams
with DAI support. Samples streams can be found and played in the
main demo app.
Issue: google/ExoPlayer#10912
#minor-release
PiperOrigin-RevId: 532407708
The only dependencies that are not updated are the ones that need
to be kept in sync with other system (like Android source tree) or
would require a Kotlin dependency in common or exoplayer modules.
As a side effect, some demo apps now need a Kotlin config and some
additional modules require desugaring/multidex logic. To simplify
the setup, the desugaring and multidex steps are added to the common
config.
PiperOrigin-RevId: 527243950
This change improves `ImaUtil.maybeCorrectPreviouslyUnknownAdDuration` to
handles the case when the timeline moves forward more than a single period
while an ad group with unknown period duration is being played.
PiperOrigin-RevId: 522292612
This includes:
- Add an ad for each LOADED event of the SDK by taking the duration
of the ad from the media structure to exactly match the start position
of ads and then use `addLiveAdBreak()` that is used for HLS live already.
- When the refreshed content timeline arrives, possibly correct
the duration of an ad that has been inserted while the period duration was
still unknown (last period of the live timeline).
- When an ad period is removed the ad group needs to be put into a condition
that allows continuing playback.
PiperOrigin-RevId: 520919236
Also fixed the javadoc link in devsite and removed javadoc links from decoder extensions as it is not published yet on developer.android.com.
#minor-release
PiperOrigin-RevId: 520636868
For multi-period live streams the content timeline for
which the global ad playback state has been split needs
to be kept together to not run into a race between
timeline refreshes and ad events.
PiperOrigin-RevId: 520358964
In multi-period live streams, we can't use the content timeline if we want to
lookup a period from the public timeline by index or uid because it may be
that the content timeline has already been refreshed in the
`ImaServerSideAdInsertionMediaSource` but hasn't yet arrived in `ExoPlayerImpl`.
This change is taking the current position that needs to be reported
to the SDK every 200ms is not relying on the content timeline.
PiperOrigin-RevId: 520328126
This change makes sure that live ad periods that are played are
skip when attempted to be added to the queue. To make this work
the existing filter logic had to be take into account the content
resume offset that live periods use.
PiperOrigin-RevId: 518068138
This change does basically three things in preparation of a follow
up CL that will insert ad breaks into multi-period live windows.
- Make sure that only `AdPlaybackState`s of multi-period streams
are passed to `ImaUtil.splitAdPlaybackStateForPeriods()` from
the media source.
- Enhance the splitting algorithm in ImaUtil to support live windows.
Roughly, this includes calculating the window start position in the
UNIX epoch context, handling the end period with an unknown duration
and taking the `adResumePosition` of an ad group into account that
affects the ad group start positions (`adGroup.timeUs`).
- Append a placeholder postroll ad group to the ad playback state of
each period in a live stream to allow immediate transition to an
ad that's inserted by an ad event from the SDK.
PiperOrigin-RevId: 516167958
The value returned by `player.getContentPosition()` is calculated
in the timeline based on the position of the first period in the
window. In a single period live stream this position is advanced
when the live window advances on timeline refresh.
This calculation has produced slightly varying values below 1000
us which are likely caused by us/ms truncations for public API
values that we use in the IMASSAIMediaSource.
However, `AdGroup.timeUs` is the (recorded) content position at the
moment when the first ad of the an ad group has been inserted. While
playing an ad, we can always use this value instead of
`getContentPosition()` to not require recalculation.
#minor-release
PiperOrigin-RevId: 515093177
This is a refactoring to separate and simplify the logic
of VOD and live streams when handling IMA ad events. An
additional listener will be required for DASH live stream
in a follow-up CL.
PiperOrigin-RevId: 507435741
ImaUtil calls VideoProgressUpdate.equals() which is annotated as hidden,
which causes lint errors with gradle.
#minor-release
PiperOrigin-RevId: 504306210