Issue: google/ExoPlayer#9775
We got a few issues for this on GH already. Some RTSP servers do not provide
track timing in PLAY responses, or the timings are invalid.
Missing timing means the RTSP stream is not seekable. Added method to
1. Update the timeline that seek is not possible
2. Report read discontinuity so that playback can start from the beginning.
PiperOrigin-RevId: 423281439
If the output sample MIME type is inferred from the input
but is not supported by the muxer, we fallback to transcoding
to a supported sample MIME type.
The audio and video renderers need to make sure not to select the PassthroughSamplePipeline for this case. Which sample MIME type
to choose is decided by the EncoderFactory.
PiperOrigin-RevId: 423272812
To avoid the `MediaPeriodQueue`to discard the reading period, we can set the next ad of an ad group early and then (possibly) only change it's duration once we receive the actual duration. This way we avoid a rebuffering as a result of the reading period being discarded.
The change also takes care to properly set ad break and their durations when we join the live stream at the moment when an ad is playing.
PiperOrigin-RevId: 423163467
We currently only end sessions on Timeline updates if the associated media
is no longer in the playlist. But we should also end all sessions that are
finished as a result of the timeline update (similar to how this is done for
discontinuities). This issue was introduced by 394ab7bcfd
PiperOrigin-RevId: 423075855
We currently don't check which session is causing a network transfer
(it could be a preloaded item in a playlist). To clearly associate
network transfer data with sessions, we need to keep track of
transferred bytes and transfer time per session.
PiperOrigin-RevId: 422867845
We may fall back to a different sample MIME type because
a) the sample MIME type inferred from the input is not supported
by the muxer or b) no encoders are available for the the requested
sample MIME type.
PiperOrigin-RevId: 422849036
With this change, the MediaCodecAudioRenderer configures the MediaCodec
to not downmix audio only if spatialization can be applied. This way,
decoders who are downmixing by default are left doing so when
spatialization cannot be applied. The renderer re-initializes the codec
when spatialization properties change mid-playback.
PiperOrigin-RevId: 422822952
TransformationRequest is otherwise immutable, so if we modify the
transformationMatrix in place (done before this cl) this may cause
confusing behaviour for apps when they reuse a TransformationRequest.
PiperOrigin-RevId: 422822916
Currently, we keep the values for dropped/played frames, audio underruns
and current formats from the last session, causing double reporting
of counters and wrong track change reasons for formats. All these
values should be reset when the active session is finished, so that the
new session can start from scratch.
PiperOrigin-RevId: 422798406
This change closes an edge case when an app is connecting a controller to a session that is already playing. In such a case `MediaControllerImplBase.getContentPosition()` keeps returning the first estimation for every call until `playWhenReady` changes for the first time.
Reproduction: Launch the demo-session app and start audio playback. Put the activity to the background and then to the foreground again. Go to the playlist view and `PlayerActivity` without interrupting playback and try to seek in the timebar. The position is stuck and snaps back.
PiperOrigin-RevId: 422795360
Currently, we always end the current session if onSessionFinished is
called. However, the finished session may not be the active one (for
example when discarding prebuffered items in a playlist). To make this
code more robust, we can save the active session id explicitly and only
end this session.
PiperOrigin-RevId: 422788542
After implementing fallback, it won't always be possible to
differentiate between muxer and encoder as the cause of an output
format not being supported.
PiperOrigin-RevId: 422780443
This change adds more standard metadata fields to Cast metadata including the artwork URL that makes the cast device show the artwork in the Cast route dialog (https://screenshot.googleplex.com/uj4n4Jqd7it9bob) and the Cast device.
This change also discriminates between media with an audio MIME type and others. For audio MIME type the Cast metadata is set to MEDIA_TYPE_MUSIC_TRACK which changes the layout and shows artwork and additional audio meta data to be displayed (https://screenshot.googleplex.com/ASy3KDcsTdJDM2T).
Issue: google/ExoPlayer#9663
PiperOrigin-RevId: 422589957
This change enables the ImaServerSideAdInsertionMediaSource for multi-period content. The global ad playback state is split into pieces for each period and the window and period durations are calculated accordingly in the ServerSideAdInsertionTimeline.
For multi-period live content (DASH), the ad playback state is not set with this change. This is deferred to a follow up CL. Splitting is very tricky. For each timeline update the windowStartTimeUs may vary for some milliseconds relative to the start of the period.positionInWindowUs. This requires to either introduce some fuzzy logic or to choose a different approach than for multi-period VOD. Because mistakes within the playback states of subsequent moving live windows produces crashes, it seems sensible to defer this for now and keep this change in a separate future CL (unblock further work, easy to rollback).
In this state, live DASH stream are working and the ad overlay is placed over the player correctly bu the SDK. However, ads are not reported by the position discontinuity event. Similarly, the player.isPlayingAd() does never returns true when a ad period is playing.
PiperOrigin-RevId: 422539770
This CL implements fixing the input format to the encoder spec. Fixed
parameters include:
- MIME type
- Profile & level
- Resolution
- frame rate, and
- bitrate
PiperOrigin-RevId: 422513738
The MediaMetricsListener currently just looks at the mime type and
doesn't use the inference based on the URI if no mime type is set.
Also change default type to OTHER to avoid classifying streams from
URLs without clear file extension as progressive.
PiperOrigin-RevId: 422373381
Adaptive video and audio selections will be limited to formats with
the same level of DecoderSupport and HardwareAccelatationSupport, unless
specifically allowed by new flags.
If different levels of decoder support are available, prefer primary
over fallback decoders and hardware-accelerated over software decoders
(in this order). For video, also prefer more efficient codecs, if both
are supported by hardware-accelerated primary decoders.
Issue: google/ExoPlayer#4835
Issue: google/ExoPlayer#9565
PiperOrigin-RevId: 422345048
MediaNotificationHandler tries to connect session in the same
process, so tests should be aware MediaControllers from the
MediaNotificationHandler.
PiperOrigin-RevId: 422330424
This change moves the video track selection to the generic
selection method introcuced for audio and text. This ensures
we can apply the same criteria for fixed and adaptive video
track selections. Implicitly, this reorders the preferences
for adaptive tracks to give non-quality preferences (like
preferred MIME type or preferred role flags) a higher priority
than number of tracks in the selection.
Issue: google/ExoPlayer#9519
PiperOrigin-RevId: 422310902
This does currently only happen by chance in replaceStream (called from
enable) if the stream previosly played read until C.TIME_END_OF_SOURCE.
enable already makes all changes done in resetPosition (except resetting
the reading position), so it's less error-prone and makes the intention
clearer if the same code is called from both enable and resetPosition.
The effect of this bug was quite limited because the numerical value
of readingPositionUs was only relevant for periods with changing
durations and server-side inserted ads.
PiperOrigin-RevId: 422300690
This is a small refactoring toward merging
MediaNotificationHandler and PlayerNotificationManager
In detail, this CL includes following changes:
- Use MediaController to dispatch commands to sessions in
MediaSessionService, rather than media key events.
- Use MediaController to monitor changes in MediaSession's
underlying Player, rather than ForegroundServiceEventCallback.
Removed the callback interface as well.
PiperOrigin-RevId: 422049265
The app will be notified about fallback using a callback on
Transformer.Listener. Fallback may be applied separately for
the audio and video options, so an intermediate internal
FallbackListener is needed to accumulate and merge the track-specific
changes to the TransformationRequest.
PiperOrigin-RevId: 421839991
We currently run (almost) the same code for all track types.
De-duplicate this by using a single method that takes functional
interfaces for track-type dependent logic.
This has the benefit that all track-type dependent logic is
contained within their subclasses and the generic logic doesn't
need to make any assumption about the eligibility of tracks for
selection or adaptation, and doesn't need to access Parameters.
Make this change for audio and text only for now. Video can
be updated in a subsequent change.
PiperOrigin-RevId: 421811411
Simplifying and clarifying variables, and adding comments.
Tested by confirming demo-gl and demo-transformer both
correctly display videos
PiperOrigin-RevId: 421792079
The existing wording would be correct if prefixed with
"Returns false if [...]", but it seems confusing to a document a boolean
method in terms the condition it returns false - so I reworded it in
terms of when it returns true.
#minor-release
PiperOrigin-RevId: 421682584
After this change exceptions throw by MediaCodec during
encoding/decoding will result in TransformationExceptions with
ERROR_CODE_ENCODING_FAILED/ERROR_CODE_DECODING_FAILED.
Before this change ERROR_CODE_FAILED_RUNTIME_CHECK was used.
PiperOrigin-RevId: 421560396
Expected images are taken on emulators, so a larger acceptable
difference from expected images must be accepted on physical devices.
PiperOrigin-RevId: 421543441
Live speed adjustment is used for all live playback at the moment,
but has no user visible effect if the media is not played with low
latency. To avoid unnecessary adjustment during playback without
benefit, this change restricts the live speed adjustment to cases
where either the user requested a speed value in the MediaItem or the
media specifically defined a low-latency stream.
Issue: google/ExoPlayer#9329
PiperOrigin-RevId: 421514283
This ensures we test the API level specific logic, in particular
around 5G-NSA detection.
Robolectric has a remaining bug that it doesn't support listening
to service state changes. Hence, we need to ignore some tests on
these API levels still until this is fixed.
PiperOrigin-RevId: 421505951
MediaController tries to release itself when the binder to the
session becomes unavailable. However, if such thing happens while
connecting in the constructor, it causes NPE when accessing
MediaControllerImpl which is only initialized after it's
connected.
This fixes random failures in existing tests.
PiperOrigin-RevId: 421423381
Codec and its factories can use MediaCodec directly as for API >= 21,
the SynchronousMediaCodecAdapter methods used in Codec just correspond
to a single MediaCodec call each so there is no reason to have another
wrapping layer.
PiperOrigin-RevId: 421041177
Exceptions thrown by MediaMuxer are converted MuxerExceptions
and later to TransformationExceptions with ERROR_CODE_MUXING_FAILED.
PiperOrigin-RevId: 421033721
The media codec renderers have fallback logic in getDecoderInfos
to assume that E-AC3 decoders can handle the 2D version of E-AC3-JOC and
that H264/H265 decoders can handle some base layer of Dolby Vision
content. Both fallbacks are useful if there is no decoder for the
enhanced Dolby formats.
Both fallbacks are not applied during track selection at the moment
because the separate MediaCodecInfo.isCodecSupported method verifies
that the mime type corresponding to format.codecs is the same as the
decoder mime type (which isn't true for the fallback case).
To fix the fallback logic, we can just completely remove this additional
check because it's not needed in the context of this method that is only
called after we already established that the decoder can handle the
format.sampleMimeType.
In addition, we need to map the Dolby Vision profiles to the equivalent
H264/H265 profile to make the codec profile comparison sensible again.
PiperOrigin-RevId: 420959104
SampleQueues may be released in the context of a finally block
after an out of memory error. Allocating in that scenario can
throw yet a new OutOfMemoryError. By safely releasing SampleQueue
memory, we increase the possibility of handling the error
gracefully.
PiperOrigin-RevId: 420859022
This method has been deprecated since 2.12.0 ([commit](d1bbd3507a)).
Also remove
DashMediaSource.Factory#setLivePresentationDelayMs(long, boolean), this
method has been deprecated since 2.13.0 ([commit](41b58d503a)).
PiperOrigin-RevId: 420719877
This class is already called StyledPlayerControlViewLayoutManager, it
seems unecessary to repeate the 'styled' word again in this context.
PiperOrigin-RevId: 420711161
These were missed in 9dae5fd2c0
These references will be re-written to PlayerView when exporting to
exoplayer2, so this commit results in some small reformatting changes.
Also fix a reference to LegacyPlayerControlView that should be
StyledPlayerControlView.
PiperOrigin-RevId: 420707706
The draw method was disabling vertex attrib arrays but not re-enabling them. Remove the call to disable the vertex attrib arrays so that then remain enabled after the program is created.
Manually verified by setting the surface type to spherical in the demo app and playing a spherical sample video.
Issue: google/ExoPlayer#9782
PiperOrigin-RevId: 420707503
The encoder and sonic are now set up in the constructor rather
than in a configuration method called from processData(). This
is more similar to VideoSamplePipeline and reduces null checks.
PiperOrigin-RevId: 420260526
When sending a MediaItem to a MediaSession with a Media3 MediaController important information is removed for privacy reason. To look up the fully populated MediaItem the mediaId is used as a key. Hence having the mediaId marhalled to the JSON representation that is sent to a Cast device enables app developers to use the same look up facilities.
#minor-release
PiperOrigin-RevId: 420022868
Only allowing TransformationExceptions to be created using the factory methods helps keeping error messages consistent. This is consistent with ExoPlaybackException.
PiperOrigin-RevId: 419841025
The common module now defines all other released targets as constraints,
which ensures they must have matching versions. As all other libraries
indirectly depend on the common module, this declaration is only needed
in here.
PiperOrigin-RevId: 419776578
A session may not notify its release back to the controller
when the controller is connecting while the session is releasing.
Here are issues in detail:
- MediaSession doesn't respond to controller's connection
request when it's released.
- MediaSession discards incoming connection requests when it's
released. The requests are only kept in the application
looper, but the looper is cleared when the session is
released.
This CL fixes the above issues, and fixes some flaky tests.
PiperOrigin-RevId: 419756158
The UI component will be switched over to use them in a
subsequent commit, once the translations have been
imported.
Issue: google/ExoPlayer#9811
PiperOrigin-RevId: 419632617
Compensate for aspect ratio of input frames, so that they're applied on
rectangular frames instead of square normalized-device-coordinate frames.
This fixes distortion most visible when rotating any GL video 45°
(non-rectangular frames) or 90° (stretched frames)
Tested by rotating several landscape/portrait demo videos.
(Automated tests will follow in <unknown commit>)
PiperOrigin-RevId: 419619743
* Move checking that the output format is supported by the muxer
from supportsFormat (which deals with the input format) to
ensureConfigured.
* Add maps for the supported MIME types so that the muxer can
return what MIME types it supports rather than just check a
MIME type.
PiperOrigin-RevId: 419578165
The `main` role distinguishes a track from an `alternate`, but unlike
`SELECTION_FLAG_DEFAULT` it doesn't imply the track should be selected
unless user preferences state otherwise. e.g. in the case of a text
track, the player shouldn't enable subtitle rendering just because a
`main` text track is present in the manifest.
The `main`/`alternate` distinction is still available through
`Format.roleFlags` and the `ROLE_FLAG_MAIN` and `ROLE_FLAG_ALTERNATE`
values.
This behaviour was originally [added in 2.2.0](7f967f3057),
however at the time the `C.RoleFlags` IntDef did not exist. The IntDef
was [added in 2.10.0](a86a9137be).
PiperOrigin-RevId: 418937747
* @Override is not a TYPE_USE annotation, so should appear before any modifiers and after Javadocs. @CryptoType is a TYPE_USE annotation, so should appear after modifiers and directly before the type.
PiperOrigin-RevId: 418811744
Before this change we checked whether the playback state and playWhenReady have changed when the state from the cast device arrived. If we detected such a change we called the listener callback `onIsPlayingChanged`. However, in the case when `setPlayWhenReady(boolean)` is called on 'CastPlayer', we mask the change in `playWhenReady`, then send the play/pause request to the cast device and when the state from the cast device arrives we never detect a change because we have already masked `playWhenReady`.
This change now moves the check for `isPlaying` to the same place where the state and playWhenReady is updated, so we call the `onIsPlayingChanged` callback in either case, when masking or when a changed state from the server arrives.
Issue: google/ExoPlayer#9792
PiperOrigin-RevId: 418483509
This is better than silently dropping tracks as done previously. Later,
we will implement fallback to transcoding to a supported MIME type.
PiperOrigin-RevId: 418006258
MediaController.getContentPosition() estimates the content position
based on the last position info sent by the player and the elapsed
real-time since the position info was received. After calling
MediaController's play/pause/setPlayWhenReady, the position estimation
logic is still applying, therefore advancing the position until the
underlying player's actual position is received. This can make the
MediaController's content position to be out of sync with player's
actual content position.
With this change, MediaController stops making content position
estimations after any of play/pause/setPlayWhenReady is called and
until a new position info is received from the underlying player.
Tested manually with the the session demo app, pausing/resuming content
from the UI.
PiperOrigin-RevId: 418000800
This more closely matches the pattern we have for all implementations
except DefaultMediaSourceFactory (e.g. ProgressiveMediaSource.Factory)
and other factory interfaces like (Http)DataSource.Factory.
PiperOrigin-RevId: 417826803
There's no need to extend this class. Factories for subclasses of
FakeMediaSource will need to re-implement createMediaSource, at which
point they basically need to re-implement the whole factory interface.
PiperOrigin-RevId: 417817499
This involves stabilising AdsLoader and ImaAdsLoader, as well
as (Default)MediaSourceFactory and the following methods on
ExoPlayer.Builder:
* setMediaSourceFactory
* setAdsLoaderProvider
* setAdViewProvider
Most of ImaAdsLoader.Builder and (Default)MediaSourceFactory remain
unstable for now.
PiperOrigin-RevId: 417814106
Switch to using sentence-case naming convention but with one character prefixes for different types.
This is a no-op change.
PiperOrigin-RevId: 417791624
Some have been deprecated since 2.13.0
([commit](5b9fa7d7d9)):
* `setDrmSessionManager(DrmSessionManager)`
* `setDrmHttpDataSourceFactory(HttpDataSource.Factory)`
* `setDrmUserAgent(String)`
And the rest have been deprecated since 2.12.0
([commit](d1bbd3507a)):
* `setStreamKeys(List<String>)`
* `createMediaSource(Uri)`
PiperOrigin-RevId: 417622794
Move static factories into a separate class and make it implement an interface
that will let tests customize encoder/decoder creation.
PiperOrigin-RevId: 417610825