Merge pull request #11034 from google/release-v2-r2.18.4

r2.18.4
This commit is contained in:
tonihei 2023-03-03 10:01:45 +00:00 committed by GitHub
commit bc3537260b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
248 changed files with 66506 additions and 3133 deletions

View file

@ -18,6 +18,7 @@ body:
label: ExoPlayer Version
description: What version of ExoPlayer are you using?
options:
- 2.18.4
- 2.18.3
- 2.18.2
- 2.18.1

View file

@ -1,5 +1,46 @@
# Release notes
### 2.18.4 (2023-03-02)
This release corresponds to the
[AndroidX Media3 1.0.0-rc02 release](https://github.com/androidx/media/releases/tag/1.0.0-rc02).
* Core library:
* Fix network type detection on API 33
([#10970](https://github.com/google/ExoPlayer/issues/10970)).
* Fix `NullPointerException` when calling `ExoPlayer.isTunnelingEnabled`
([#10977](https://github.com/google/ExoPlayer/issues/10977)).
* Downloads:
* Make the maximum difference of the start time of two segments to be
merged configurable in `SegmentDownloader` and subclasses
([#248](https://github.com/androidx/media/pull/248)).
* Audio:
* Fix broken gapless MP3 playback on Samsung devices
([#8594](https://github.com/google/ExoPlayer/issues/8594)).
* Fix bug where playback speeds set immediately after disabling audio may
be overridden by a previous speed change
([#10882](https://github.com/google/ExoPlayer/issues/10882)).
* Video:
* Map HEVC HDR10 format to `HEVCProfileMain10HDR10` instead of
`HEVCProfileMain10`.
* Add workaround for a device issue on Chromecast with Google TV and
Lenovo M10 FHD Plus that causes 60fps AVC streams to be marked as
unsupported
([#10898](https://github.com/google/ExoPlayer/issues/10898)).
* Fix frame release performance issues when playing media with a frame
rate far higher than the screen refresh rate.
* Cast:
* Fix transient `STATE_IDLE` when transitioning between media items
([#245](https://github.com/androidx/media/issues/245)).
* RTSP:
* Catch the IllegalArgumentException thrown in parsing of invalid RTSP
Describe response messages
([#10971](https://github.com/google/ExoPlayer/issues/10971)).
* IMA extension:
* Fix a bug which prevented DAI streams without any ads from starting
because the first (and in the case without ads the only) `LOADED` event
wasn't received.
### 2.18.3 (2023-02-16)
This release corresponds to the

View file

@ -13,8 +13,8 @@
// limitations under the License.
project.ext {
// ExoPlayer version and version code.
releaseVersion = '2.18.3'
releaseVersionCode = 2_018_003
releaseVersion = '2.18.4'
releaseVersionCode = 2_018_004
minSdkVersion = 16
appTargetSdkVersion = 33
// API version before restricting local file access.

View file

@ -1,282 +0,0 @@
/*
* Copyright 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer2.transformerdemo;
import static com.google.android.exoplayer2.util.Assertions.checkArgument;
import static com.google.android.exoplayer2.util.Assertions.checkState;
import static com.google.android.exoplayer2.util.Assertions.checkStateNotNull;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import android.content.Context;
import android.opengl.EGL14;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.effect.GlTextureProcessor;
import com.google.android.exoplayer2.effect.TextureInfo;
import com.google.android.exoplayer2.util.FrameProcessingException;
import com.google.android.exoplayer2.util.LibraryLoader;
import com.google.android.exoplayer2.util.Util;
import com.google.mediapipe.components.FrameProcessor;
import com.google.mediapipe.framework.AppTextureFrame;
import com.google.mediapipe.framework.TextureFrame;
import com.google.mediapipe.glutil.EglManager;
import java.util.ArrayDeque;
import java.util.Queue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
/** Runs a MediaPipe graph on input frames. */
/* package */ final class MediaPipeProcessor implements GlTextureProcessor {
private static final String THREAD_NAME = "Demo:MediaPipeProcessor";
private static final long RELEASE_WAIT_TIME_MS = 100;
private static final long RETRY_WAIT_TIME_MS = 1;
private static final LibraryLoader LOADER =
new LibraryLoader("mediapipe_jni") {
@Override
protected void loadLibrary(String name) {
System.loadLibrary(name);
}
};
static {
// Not all build configurations require OpenCV to be loaded separately, so attempt to load the
// library but ignore the error if it's not present.
try {
System.loadLibrary("opencv_java3");
} catch (UnsatisfiedLinkError e) {
// Do nothing.
}
}
private final FrameProcessor frameProcessor;
private final ConcurrentHashMap<TextureInfo, TextureFrame> outputFrames;
private final boolean isSingleFrameGraph;
@Nullable private final ExecutorService singleThreadExecutorService;
private final Queue<Future<?>> futures;
private InputListener inputListener;
private OutputListener outputListener;
private ErrorListener errorListener;
private boolean acceptedFrame;
/**
* Creates a new texture processor that wraps a MediaPipe graph.
*
* <p>If {@code isSingleFrameGraph} is {@code false}, the {@code MediaPipeProcessor} may waste CPU
* time by continuously attempting to queue input frames to MediaPipe until they are accepted or
* waste memory if MediaPipe accepts and stores many frames internally.
*
* @param context The {@link Context}.
* @param useHdr Whether input textures come from an HDR source. If {@code true}, colors will be
* in linear RGB BT.2020. If {@code false}, colors will be in linear RGB BT.709.
* @param graphName Name of a MediaPipe graph asset to load.
* @param isSingleFrameGraph Whether the MediaPipe graph will eventually produce one output frame
* each time an input frame (and no other input) has been queued.
* @param inputStreamName Name of the input video stream in the graph.
* @param outputStreamName Name of the input video stream in the graph.
*/
public MediaPipeProcessor(
Context context,
boolean useHdr,
String graphName,
boolean isSingleFrameGraph,
String inputStreamName,
String outputStreamName) {
checkState(LOADER.isAvailable());
// TODO(b/227624622): Confirm whether MediaPipeProcessor could support HDR colors.
checkArgument(!useHdr, "MediaPipeProcessor does not support HDR colors.");
this.isSingleFrameGraph = isSingleFrameGraph;
singleThreadExecutorService =
isSingleFrameGraph ? null : Util.newSingleThreadExecutor(THREAD_NAME);
futures = new ArrayDeque<>();
inputListener = new InputListener() {};
outputListener = new OutputListener() {};
errorListener = (frameProcessingException) -> {};
EglManager eglManager = new EglManager(EGL14.eglGetCurrentContext());
frameProcessor =
new FrameProcessor(
context, eglManager.getNativeContext(), graphName, inputStreamName, outputStreamName);
outputFrames = new ConcurrentHashMap<>();
// OnWillAddFrameListener is called on the same thread as frameProcessor.onNewFrame(...), so no
// synchronization is needed for acceptedFrame.
frameProcessor.setOnWillAddFrameListener((long timestamp) -> acceptedFrame = true);
}
@Override
public void setInputListener(InputListener inputListener) {
this.inputListener = inputListener;
if (!isSingleFrameGraph || outputFrames.isEmpty()) {
inputListener.onReadyToAcceptInputFrame();
}
}
@Override
public void setOutputListener(OutputListener outputListener) {
this.outputListener = outputListener;
frameProcessor.setConsumer(
frame -> {
TextureInfo texture =
new TextureInfo(
frame.getTextureName(),
/* fboId= */ C.INDEX_UNSET,
frame.getWidth(),
frame.getHeight());
outputFrames.put(texture, frame);
outputListener.onOutputFrameAvailable(texture, frame.getTimestamp());
});
}
@Override
public void setErrorListener(ErrorListener errorListener) {
this.errorListener = errorListener;
frameProcessor.setAsynchronousErrorListener(
error -> errorListener.onFrameProcessingError(new FrameProcessingException(error)));
}
@Override
public void queueInputFrame(TextureInfo inputTexture, long presentationTimeUs) {
AppTextureFrame appTextureFrame =
new AppTextureFrame(inputTexture.texId, inputTexture.width, inputTexture.height);
// TODO(b/238302213): Handle timestamps restarting from 0 when applying effects to a playlist.
// MediaPipe will fail if the timestamps are not monotonically increasing.
// Also make sure that a MediaPipe graph producing additional frames only starts producing
// frames for the next MediaItem after receiving the first frame of that MediaItem as input
// to avoid MediaPipe producing extra frames after the last MediaItem has ended.
appTextureFrame.setTimestamp(presentationTimeUs);
if (isSingleFrameGraph) {
boolean acceptedFrame = maybeQueueInputFrameSynchronous(appTextureFrame, inputTexture);
checkState(
acceptedFrame,
"queueInputFrame must only be called when a new input frame can be accepted");
return;
}
// TODO(b/241782273): Avoid retrying continuously until the frame is accepted by using a
// currently non-existent MediaPipe API to be notified when MediaPipe has capacity to accept a
// new frame.
queueInputFrameAsynchronous(appTextureFrame, inputTexture);
}
private boolean maybeQueueInputFrameSynchronous(
AppTextureFrame appTextureFrame, TextureInfo inputTexture) {
acceptedFrame = false;
frameProcessor.onNewFrame(appTextureFrame);
try {
appTextureFrame.waitUntilReleasedWithGpuSync();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
errorListener.onFrameProcessingError(new FrameProcessingException(e));
}
if (acceptedFrame) {
inputListener.onInputFrameProcessed(inputTexture);
}
return acceptedFrame;
}
private void queueInputFrameAsynchronous(
AppTextureFrame appTextureFrame, TextureInfo inputTexture) {
removeFinishedFutures();
futures.add(
checkStateNotNull(singleThreadExecutorService)
.submit(
() -> {
while (!maybeQueueInputFrameSynchronous(appTextureFrame, inputTexture)) {
try {
Thread.sleep(RETRY_WAIT_TIME_MS);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
if (errorListener != null) {
errorListener.onFrameProcessingError(new FrameProcessingException(e));
}
}
}
inputListener.onReadyToAcceptInputFrame();
}));
}
@Override
public void releaseOutputFrame(TextureInfo outputTexture) {
checkStateNotNull(outputFrames.get(outputTexture)).release();
if (isSingleFrameGraph) {
inputListener.onReadyToAcceptInputFrame();
}
}
@Override
public void release() {
if (isSingleFrameGraph) {
frameProcessor.close();
return;
}
Queue<Future<?>> futures = checkStateNotNull(this.futures);
while (!futures.isEmpty()) {
futures.remove().cancel(/* mayInterruptIfRunning= */ false);
}
ExecutorService singleThreadExecutorService =
checkStateNotNull(this.singleThreadExecutorService);
singleThreadExecutorService.shutdown();
try {
if (!singleThreadExecutorService.awaitTermination(RELEASE_WAIT_TIME_MS, MILLISECONDS)) {
errorListener.onFrameProcessingError(new FrameProcessingException("Release timed out"));
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
errorListener.onFrameProcessingError(new FrameProcessingException(e));
}
frameProcessor.close();
}
@Override
public final void signalEndOfCurrentInputStream() {
if (isSingleFrameGraph) {
frameProcessor.waitUntilIdle();
outputListener.onCurrentOutputStreamEnded();
return;
}
removeFinishedFutures();
futures.add(
checkStateNotNull(singleThreadExecutorService)
.submit(
() -> {
frameProcessor.waitUntilIdle();
outputListener.onCurrentOutputStreamEnded();
}));
}
private void removeFinishedFutures() {
while (!futures.isEmpty()) {
if (!futures.element().isDone()) {
return;
}
try {
futures.remove().get();
} catch (ExecutionException e) {
errorListener.onFrameProcessingError(new FrameProcessingException(e));
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
errorListener.onFrameProcessingError(new FrameProcessingException(e));
}
}
}
}

View file

@ -16,7 +16,8 @@ as described
| CEA-608 | YES ||
| WebVTT | YES ||
| **Metadata** |||
| ID3 metadata | YES ||
| ID3 | YES ||
| SCTE-35 | NO ||
| **Content protection** |||
| AES-128 | YES ||
| Sample AES-128 | NO ||

View file

@ -225,14 +225,20 @@ the following:
When overriding `ForwardingPlayer` methods it's important to ensure the
implementation remains self-consistent and compliant with the `Player`
interface, especially when dealing with methods that are intended to have
identical or related behavior. For example, if you want to override every 'play'
operation, you need to override both `ForwardingPlayer.play` and
`ForwardingPlayer.setPlayWhenReady`, because a caller will expect the behavior
of these methdods to be identical when `playWhenReady = true`. Similarly, if you
want to change the seek-forward increment you need to override both
`ForwardingPlayer.seekForward` to perform a seek with your customized increment,
and `ForwardingPlayer.getSeekForwardIncrement` in order to report the correct
customized increment back to the caller.
identical or related behavior. For example:
* If you want to override every 'play' operation, you need to override both
`ForwardingPlayer.play` and `ForwardingPlayer.setPlayWhenReady`, because a
caller will expect the behavior of these methods to be identical when
`playWhenReady = true`.
* If you want to change the seek-forward increment you need to override both
`ForwardingPlayer.seekForward` to perform a seek with your customized
increment, and `ForwardingPlayer.getSeekForwardIncrement` in order to report
the correct customized increment back to the caller.
* If you want to control what `Player.Commands` are advertised by a player
instance, you must override `Player.getAvailableCommands()`,
`Player.isCommandAvailable()` and also listen to the
`Player.Listener.onAvailableCommandsChanged()` callback to get notified of
changes coming from the underlying player.
## MediaSource customization ##

View file

@ -3657,7 +3657,7 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
<tr id="i580" class="altColor">
<td class="colFirst"><a href="com/google/android/exoplayer2/ForwardingPlayer.html" title="class in com.google.android.exoplayer2">ForwardingPlayer</a></td>
<th class="colLast" scope="row">
<div class="block">A <a href="com/google/android/exoplayer2/Player.html" title="interface in com.google.android.exoplayer2"><code>Player</code></a> that forwards operations to another <a href="com/google/android/exoplayer2/Player.html" title="interface in com.google.android.exoplayer2"><code>Player</code></a>.</div>
<div class="block">A <a href="com/google/android/exoplayer2/Player.html" title="interface in com.google.android.exoplayer2"><code>Player</code></a> that forwards method calls to another <a href="com/google/android/exoplayer2/Player.html" title="interface in com.google.android.exoplayer2"><code>Player</code></a>.</div>
</th>
</tr>
<tr id="i581" class="rowColor">
@ -7767,7 +7767,7 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
<tr id="i1256" class="altColor">
<td class="colFirst"><a href="com/google/android/exoplayer2/text/webvtt/WebvttCssStyle.html" title="class in com.google.android.exoplayer2.text.webvtt">WebvttCssStyle</a></td>
<th class="colLast" scope="row">
<div class="block">Style object of a Css style block in a Webvtt file.</div>
<div class="block">Style object of a CSS style block in a WebVTT file.</div>
</th>
</tr>
<tr id="i1257" class="rowColor">

View file

@ -117,7 +117,7 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
<a href="https://developer.android.com/reference/java/lang/annotation/Retention.html" title="class or interface in java.lang.annotation" class="externalLink">@Retention</a>(<a href="https://developer.android.com/reference/java/lang/annotation/RetentionPolicy.html?is-external=true#SOURCE" title="class or interface in java.lang.annotation" class="externalLink" target="_top">SOURCE</a>)
<a href="https://developer.android.com/reference/java/lang/annotation/Target.html" title="class or interface in java.lang.annotation" class="externalLink">@Target</a>(<a href="https://developer.android.com/reference/java/lang/annotation/ElementType.html?is-external=true#TYPE_USE" title="class or interface in java.lang.annotation" class="externalLink" target="_top">TYPE_USE</a>)
public static @interface <span class="memberNameLabel">C.SpatializationBehavior</span></pre>
<div class="block">Represents the behavior affecting whether spatialization will be used.</div>
<div class="block">Represents the behavior affecting whether spatialization will be used. One of <a href="C.html#SPATIALIZATION_BEHAVIOR_AUTO"><code>C.SPATIALIZATION_BEHAVIOR_AUTO</code></a> or <a href="C.html#SPATIALIZATION_BEHAVIOR_NEVER"><code>C.SPATIALIZATION_BEHAVIOR_NEVER</code></a>.</div>
</li>
</ul>
</div>

View file

@ -136,7 +136,7 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
<pre>public class <span class="typeNameLabel">ForwardingPlayer</span>
extends <a href="https://developer.android.com/reference/java/lang/Object.html" title="class or interface in java.lang" class="externalLink" target="_top">Object</a>
implements <a href="Player.html" title="interface in com.google.android.exoplayer2">Player</a></pre>
<div class="block">A <a href="Player.html" title="interface in com.google.android.exoplayer2"><code>Player</code></a> that forwards operations to another <a href="Player.html" title="interface in com.google.android.exoplayer2"><code>Player</code></a>. Applications can use this
<div class="block">A <a href="Player.html" title="interface in com.google.android.exoplayer2"><code>Player</code></a> that forwards method calls to another <a href="Player.html" title="interface in com.google.android.exoplayer2"><code>Player</code></a>. Applications can use this
class to suppress or modify specific operations, by overriding the respective methods.</div>
</li>
</ul>

View file

@ -131,18 +131,20 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
<hr>
<pre>public final class <span class="typeNameLabel">FlacStreamMetadata</span>
extends <a href="https://developer.android.com/reference/java/lang/Object.html" title="class or interface in java.lang" class="externalLink" target="_top">Object</a></pre>
<div class="block">Holder for FLAC metadata.</div>
<dl>
<dt><span class="seeLabel">See Also:</span></dt>
<dd><a href="https://xiph.org/flac/format.html#metadata_block_streaminfo">FLAC format
METADATA_BLOCK_STREAMINFO</a>,
<a href="https://xiph.org/flac/format.html#metadata_block_seektable">FLAC format
METADATA_BLOCK_SEEKTABLE</a>,
<a href="https://xiph.org/flac/format.html#metadata_block_vorbis_comment">FLAC format
METADATA_BLOCK_VORBIS_COMMENT</a>,
<a href="https://xiph.org/flac/format.html#metadata_block_picture">FLAC format
METADATA_BLOCK_PICTURE</a></dd>
</dl>
<div class="block">Holder for FLAC metadata.
<p>See the following spec references:
<ul>
<li><a href="https://xiph.org/flac/format.html#metadata_block_streaminfo">FLAC format
METADATA_BLOCK_STREAMINFO</a>
<li><a href="https://xiph.org/flac/format.html#metadata_block_seektable">FLAC format
METADATA_BLOCK_SEEKTABLE</a>
<li><a href="https://xiph.org/flac/format.html#metadata_block_vorbis_comment">FLAC format
METADATA_BLOCK_VORBIS_COMMENT</a>
<li><a href="https://xiph.org/flac/format.html#metadata_block_picture">FLAC format
METADATA_BLOCK_PICTURE</a>
</ul></div>
</li>
</ul>
</div>

View file

@ -131,12 +131,10 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
<hr>
<pre>public final class <span class="typeNameLabel">VorbisBitArray</span>
extends <a href="https://developer.android.com/reference/java/lang/Object.html" title="class or interface in java.lang" class="externalLink" target="_top">Object</a></pre>
<div class="block">Wraps a byte array, providing methods that allow it to be read as a Vorbis bitstream.</div>
<dl>
<dt><span class="seeLabel">See Also:</span></dt>
<dd><a href="https://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-360002">Vorbis bitpacking
specification</a></dd>
</dl>
<div class="block">Wraps a byte array, providing methods that allow it to be read as a Vorbis bitstream.
<p>See the <a href="https://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-360002">Vorbis
bitpacking specification</a></div>
</li>
</ul>
</div>

View file

@ -129,12 +129,10 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
<hr>
<pre>public static final class <span class="typeNameLabel">VorbisUtil.VorbisIdHeader</span>
extends <a href="https://developer.android.com/reference/java/lang/Object.html" title="class or interface in java.lang" class="externalLink" target="_top">Object</a></pre>
<div class="block">Vorbis identification header.</div>
<dl>
<dt><span class="seeLabel">See Also:</span></dt>
<dd><a href="https://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-630004.2.2">Vorbis
spec/Identification header</a></dd>
</dl>
<div class="block">Vorbis identification header.
<p>See the <a href="https://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-630004.2.2">Vorbis
spec/Identification header</a></div>
</li>
</ul>
</div>

View file

@ -277,15 +277,15 @@ extends <a href="https://developer.android.com/reference/java/lang/Object.html"
<li class="blockList">
<h4>iLog</h4>
<pre class="methodSignature">public static&nbsp;int&nbsp;iLog&#8203;(int&nbsp;x)</pre>
<div class="block">Returns ilog(x), which is the index of the highest set bit in <code>x</code>.</div>
<div class="block">Returns ilog(x), which is the index of the highest set bit in <code>x</code>.
<p>See the <a href="https://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-1190009.2.1">Vorbis
spec</a></div>
<dl>
<dt><span class="paramLabel">Parameters:</span></dt>
<dd><code>x</code> - the value of which the ilog should be calculated.</dd>
<dt><span class="returnLabel">Returns:</span></dt>
<dd>ilog(x)</dd>
<dt><span class="seeLabel">See Also:</span></dt>
<dd><a href="https://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-1190009.2.1">Vorbis
spec</a></dd>
</dl>
</li>
</ul>
@ -297,7 +297,10 @@ extends <a href="https://developer.android.com/reference/java/lang/Object.html"
<h4>readVorbisIdentificationHeader</h4>
<pre class="methodSignature">public static&nbsp;<a href="VorbisUtil.VorbisIdHeader.html" title="class in com.google.android.exoplayer2.extractor">VorbisUtil.VorbisIdHeader</a>&nbsp;readVorbisIdentificationHeader&#8203;(<a href="../util/ParsableByteArray.html" title="class in com.google.android.exoplayer2.util">ParsableByteArray</a>&nbsp;headerData)
throws <a href="../ParserException.html" title="class in com.google.android.exoplayer2">ParserException</a></pre>
<div class="block">Reads a Vorbis identification header from <code>headerData</code>.</div>
<div class="block">Reads a Vorbis identification header from <code>headerData</code>.
<p>See the <a href="https://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-630004.2.2">Vorbis
spec/Identification header</a></div>
<dl>
<dt><span class="paramLabel">Parameters:</span></dt>
<dd><code>headerData</code> - a <a href="../util/ParsableByteArray.html" title="class in com.google.android.exoplayer2.util"><code>ParsableByteArray</code></a> wrapping the header data.</dd>
@ -305,9 +308,6 @@ extends <a href="https://developer.android.com/reference/java/lang/Object.html"
<dd>a <a href="VorbisUtil.VorbisIdHeader.html" title="class in com.google.android.exoplayer2.extractor"><code>VorbisUtil.VorbisIdHeader</code></a> with meta data.</dd>
<dt><span class="throwsLabel">Throws:</span></dt>
<dd><code><a href="../ParserException.html" title="class in com.google.android.exoplayer2">ParserException</a></code> - thrown if invalid capture pattern is detected.</dd>
<dt><span class="seeLabel">See Also:</span></dt>
<dd><a href="https://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-630004.2.2">Vorbis
spec/Identification header</a></dd>
</dl>
</li>
</ul>
@ -319,7 +319,10 @@ extends <a href="https://developer.android.com/reference/java/lang/Object.html"
<h4>readVorbisCommentHeader</h4>
<pre class="methodSignature">public static&nbsp;<a href="VorbisUtil.CommentHeader.html" title="class in com.google.android.exoplayer2.extractor">VorbisUtil.CommentHeader</a>&nbsp;readVorbisCommentHeader&#8203;(<a href="../util/ParsableByteArray.html" title="class in com.google.android.exoplayer2.util">ParsableByteArray</a>&nbsp;headerData)
throws <a href="../ParserException.html" title="class in com.google.android.exoplayer2">ParserException</a></pre>
<div class="block">Reads a Vorbis comment header.</div>
<div class="block">Reads a Vorbis comment header.
<p>See the <a href="https://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-640004.2.3">Vorbis
spec/Comment header</a></div>
<dl>
<dt><span class="paramLabel">Parameters:</span></dt>
<dd><code>headerData</code> - A <a href="../util/ParsableByteArray.html" title="class in com.google.android.exoplayer2.util"><code>ParsableByteArray</code></a> wrapping the header data.</dd>
@ -327,9 +330,6 @@ extends <a href="https://developer.android.com/reference/java/lang/Object.html"
<dd>A <a href="VorbisUtil.CommentHeader.html" title="class in com.google.android.exoplayer2.extractor"><code>VorbisUtil.CommentHeader</code></a> with all the comments.</dd>
<dt><span class="throwsLabel">Throws:</span></dt>
<dd><code><a href="../ParserException.html" title="class in com.google.android.exoplayer2">ParserException</a></code> - If an error occurs parsing the comment header.</dd>
<dt><span class="seeLabel">See Also:</span></dt>
<dd><a href="https://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-640004.2.3">Vorbis
spec/Comment header</a></dd>
</dl>
</li>
</ul>
@ -345,7 +345,10 @@ extends <a href="https://developer.android.com/reference/java/lang/Object.html"
throws <a href="../ParserException.html" title="class in com.google.android.exoplayer2">ParserException</a></pre>
<div class="block">Reads a Vorbis comment header.
<p>The data provided may not contain the Vorbis metadata common header and the framing bit.</div>
<p>The data provided may not contain the Vorbis metadata common header and the framing bit.
<p>See the <a href="https://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-640004.2.3">Vorbis
spec/Comment header</a></div>
<dl>
<dt><span class="paramLabel">Parameters:</span></dt>
<dd><code>headerData</code> - A <a href="../util/ParsableByteArray.html" title="class in com.google.android.exoplayer2.util"><code>ParsableByteArray</code></a> wrapping the header data.</dd>
@ -356,9 +359,6 @@ extends <a href="https://developer.android.com/reference/java/lang/Object.html"
<dd>A <a href="VorbisUtil.CommentHeader.html" title="class in com.google.android.exoplayer2.extractor"><code>VorbisUtil.CommentHeader</code></a> with all the comments.</dd>
<dt><span class="throwsLabel">Throws:</span></dt>
<dd><code><a href="../ParserException.html" title="class in com.google.android.exoplayer2">ParserException</a></code> - If an error occurs parsing the comment header.</dd>
<dt><span class="seeLabel">See Also:</span></dt>
<dd><a href="https://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-640004.2.3">Vorbis
spec/Comment header</a></dd>
</dl>
</li>
</ul>
@ -417,7 +417,10 @@ public static&nbsp;<a href="../metadata/Metadata.html" title="class in com.googl
throws <a href="../ParserException.html" title="class in com.google.android.exoplayer2">ParserException</a></pre>
<div class="block">This method reads the modes which are located at the very end of the Vorbis setup header.
That's why we need to partially decode or at least read the entire setup header to know where
to start reading the modes.</div>
to start reading the modes.
<p>See the <a href="https://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-650004.2.4">Vorbis
spec/Setup header</a></div>
<dl>
<dt><span class="paramLabel">Parameters:</span></dt>
<dd><code>headerData</code> - a <a href="../util/ParsableByteArray.html" title="class in com.google.android.exoplayer2.util"><code>ParsableByteArray</code></a> containing setup header data.</dd>
@ -426,9 +429,6 @@ public static&nbsp;<a href="../metadata/Metadata.html" title="class in com.googl
<dd>an array of <a href="VorbisUtil.Mode.html" title="class in com.google.android.exoplayer2.extractor"><code>VorbisUtil.Mode</code></a>s.</dd>
<dt><span class="throwsLabel">Throws:</span></dt>
<dd><code><a href="../ParserException.html" title="class in com.google.android.exoplayer2">ParserException</a></code> - thrown if bit stream is invalid.</dd>
<dt><span class="seeLabel">See Also:</span></dt>
<dd><a href="https://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-650004.2.4">Vorbis
spec/Setup header</a></dd>
</dl>
</li>
</ul>

View file

@ -87,13 +87,13 @@ loadScripts(document, 'script');</script>
<ul class="subNavList">
<li>Summary:&nbsp;</li>
<li><a href="#nested.class.summary">Nested</a>&nbsp;|&nbsp;</li>
<li>Field&nbsp;|&nbsp;</li>
<li><a href="#field.summary">Field</a>&nbsp;|&nbsp;</li>
<li><a href="#constructor.summary">Constr</a>&nbsp;|&nbsp;</li>
<li><a href="#method.summary">Method</a></li>
</ul>
<ul class="subNavList">
<li>Detail:&nbsp;</li>
<li>Field&nbsp;|&nbsp;</li>
<li><a href="#field.detail">Field</a>&nbsp;|&nbsp;</li>
<li><a href="#constructor.detail">Constr</a>&nbsp;|&nbsp;</li>
<li><a href="#method.detail">Method</a></li>
</ul>
@ -183,6 +183,29 @@ implements <a href="Downloader.html" title="interface in com.google.android.exop
</li>
</ul>
</section>
<!-- =========== FIELD SUMMARY =========== -->
<section role="region">
<ul class="blockList">
<li class="blockList"><a id="field.summary">
<!-- -->
</a>
<h3>Field Summary</h3>
<table class="memberSummary">
<caption><span>Fields</span><span class="tabEnd">&nbsp;</span></caption>
<tr>
<th class="colFirst" scope="col">Modifier and Type</th>
<th class="colSecond" scope="col">Field</th>
<th class="colLast" scope="col">Description</th>
</tr>
<tr class="altColor">
<td class="colFirst"><code>static long</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#DEFAULT_MAX_MERGED_SEGMENT_START_TIME_DIFF_MS">DEFAULT_MAX_MERGED_SEGMENT_START_TIME_DIFF_MS</a></span></code></th>
<td class="colLast">&nbsp;</td>
</tr>
</table>
</li>
</ul>
</section>
<!-- ======== CONSTRUCTOR SUMMARY ======== -->
<section role="region">
<ul class="blockList">
@ -201,6 +224,19 @@ implements <a href="Downloader.html" title="interface in com.google.android.exop
<a href="../upstream/ParsingLoadable.Parser.html" title="interface in com.google.android.exoplayer2.upstream">ParsingLoadable.Parser</a>&lt;<a href="SegmentDownloader.html" title="type parameter in SegmentDownloader">M</a>&gt;&nbsp;manifestParser,
<a href="../upstream/cache/CacheDataSource.Factory.html" title="class in com.google.android.exoplayer2.upstream.cache">CacheDataSource.Factory</a>&nbsp;cacheDataSourceFactory,
<a href="https://developer.android.com/reference/java/util/concurrent/Executor.html" title="class or interface in java.util.concurrent" class="externalLink" target="_top">Executor</a>&nbsp;executor)</code></th>
<td class="colLast">
<div class="block"><span class="deprecatedLabel">Deprecated.</span>
<div class="deprecationComment">Use <a href="#%3Cinit%3E(com.google.android.exoplayer2.MediaItem,com.google.android.exoplayer2.upstream.ParsingLoadable.Parser,com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory,java.util.concurrent.Executor,long)"><code>SegmentDownloader(MediaItem, Parser,
CacheDataSource.Factory, Executor, long)</code></a> instead.</div>
</div>
</td>
</tr>
<tr class="rowColor">
<th class="colConstructorName" scope="row"><code><span class="memberNameLink"><a href="#%3Cinit%3E(com.google.android.exoplayer2.MediaItem,com.google.android.exoplayer2.upstream.ParsingLoadable.Parser,com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory,java.util.concurrent.Executor,long)">SegmentDownloader</a></span>&#8203;(<a href="../MediaItem.html" title="class in com.google.android.exoplayer2">MediaItem</a>&nbsp;mediaItem,
<a href="../upstream/ParsingLoadable.Parser.html" title="interface in com.google.android.exoplayer2.upstream">ParsingLoadable.Parser</a>&lt;<a href="SegmentDownloader.html" title="type parameter in SegmentDownloader">M</a>&gt;&nbsp;manifestParser,
<a href="../upstream/cache/CacheDataSource.Factory.html" title="class in com.google.android.exoplayer2.upstream.cache">CacheDataSource.Factory</a>&nbsp;cacheDataSourceFactory,
<a href="https://developer.android.com/reference/java/util/concurrent/Executor.html" title="class or interface in java.util.concurrent" class="externalLink" target="_top">Executor</a>&nbsp;executor,
long&nbsp;maxMergedSegmentStartTimeDiffMs)</code></th>
<td class="colLast">&nbsp;</td>
</tr>
</table>
@ -290,6 +326,29 @@ implements <a href="Downloader.html" title="interface in com.google.android.exop
<div class="details">
<ul class="blockList">
<li class="blockList">
<!-- ============ FIELD DETAIL =========== -->
<section role="region">
<ul class="blockList">
<li class="blockList"><a id="field.detail">
<!-- -->
</a>
<h3>Field Detail</h3>
<a id="DEFAULT_MAX_MERGED_SEGMENT_START_TIME_DIFF_MS">
<!-- -->
</a>
<ul class="blockListLast">
<li class="blockList">
<h4>DEFAULT_MAX_MERGED_SEGMENT_START_TIME_DIFF_MS</h4>
<pre>public static final&nbsp;long DEFAULT_MAX_MERGED_SEGMENT_START_TIME_DIFF_MS</pre>
<dl>
<dt><span class="seeLabel">See Also:</span></dt>
<dd><a href="../../../../../constant-values.html#com.google.android.exoplayer2.offline.SegmentDownloader.DEFAULT_MAX_MERGED_SEGMENT_START_TIME_DIFF_MS">Constant Field Values</a></dd>
</dl>
</li>
</ul>
</li>
</ul>
</section>
<!-- ========= CONSTRUCTOR DETAIL ======== -->
<section role="region">
<ul class="blockList">
@ -300,13 +359,31 @@ implements <a href="Downloader.html" title="interface in com.google.android.exop
<a id="&lt;init&gt;(com.google.android.exoplayer2.MediaItem,com.google.android.exoplayer2.upstream.ParsingLoadable.Parser,com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory,java.util.concurrent.Executor)">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>SegmentDownloader</h4>
<pre><a href="https://developer.android.com/reference/java/lang/Deprecated.html" title="class or interface in java.lang" class="externalLink" target="_top">@Deprecated</a>
public&nbsp;SegmentDownloader&#8203;(<a href="../MediaItem.html" title="class in com.google.android.exoplayer2">MediaItem</a>&nbsp;mediaItem,
<a href="../upstream/ParsingLoadable.Parser.html" title="interface in com.google.android.exoplayer2.upstream">ParsingLoadable.Parser</a>&lt;<a href="SegmentDownloader.html" title="type parameter in SegmentDownloader">M</a>&gt;&nbsp;manifestParser,
<a href="../upstream/cache/CacheDataSource.Factory.html" title="class in com.google.android.exoplayer2.upstream.cache">CacheDataSource.Factory</a>&nbsp;cacheDataSourceFactory,
<a href="https://developer.android.com/reference/java/util/concurrent/Executor.html" title="class or interface in java.util.concurrent" class="externalLink" target="_top">Executor</a>&nbsp;executor)</pre>
<div class="deprecationBlock"><span class="deprecatedLabel">Deprecated.</span>
<div class="deprecationComment">Use <a href="#%3Cinit%3E(com.google.android.exoplayer2.MediaItem,com.google.android.exoplayer2.upstream.ParsingLoadable.Parser,com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory,java.util.concurrent.Executor,long)"><code>SegmentDownloader(MediaItem, Parser,
CacheDataSource.Factory, Executor, long)</code></a> instead.</div>
</div>
</li>
</ul>
<a id="&lt;init&gt;(com.google.android.exoplayer2.MediaItem,com.google.android.exoplayer2.upstream.ParsingLoadable.Parser,com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory,java.util.concurrent.Executor,long)">
<!-- -->
</a>
<ul class="blockListLast">
<li class="blockList">
<h4>SegmentDownloader</h4>
<pre>public&nbsp;SegmentDownloader&#8203;(<a href="../MediaItem.html" title="class in com.google.android.exoplayer2">MediaItem</a>&nbsp;mediaItem,
<a href="../upstream/ParsingLoadable.Parser.html" title="interface in com.google.android.exoplayer2.upstream">ParsingLoadable.Parser</a>&lt;<a href="SegmentDownloader.html" title="type parameter in SegmentDownloader">M</a>&gt;&nbsp;manifestParser,
<a href="../upstream/cache/CacheDataSource.Factory.html" title="class in com.google.android.exoplayer2.upstream.cache">CacheDataSource.Factory</a>&nbsp;cacheDataSourceFactory,
<a href="https://developer.android.com/reference/java/util/concurrent/Executor.html" title="class or interface in java.util.concurrent" class="externalLink" target="_top">Executor</a>&nbsp;executor)</pre>
<a href="https://developer.android.com/reference/java/util/concurrent/Executor.html" title="class or interface in java.util.concurrent" class="externalLink" target="_top">Executor</a>&nbsp;executor,
long&nbsp;maxMergedSegmentStartTimeDiffMs)</pre>
<dl>
<dt><span class="paramLabel">Parameters:</span></dt>
<dd><code>mediaItem</code> - The <a href="../MediaItem.html" title="class in com.google.android.exoplayer2"><code>MediaItem</code></a> to be downloaded.</dd>
@ -316,6 +393,9 @@ implements <a href="Downloader.html" title="interface in com.google.android.exop
<dd><code>executor</code> - An <a href="https://developer.android.com/reference/java/util/concurrent/Executor.html" title="class or interface in java.util.concurrent" class="externalLink" target="_top"><code>Executor</code></a> used to make requests for the media being downloaded.
Providing an <a href="https://developer.android.com/reference/java/util/concurrent/Executor.html" title="class or interface in java.util.concurrent" class="externalLink" target="_top"><code>Executor</code></a> that uses multiple threads will speed up the download by
allowing parts of it to be executed in parallel.</dd>
<dd><code>maxMergedSegmentStartTimeDiffMs</code> - The maximum difference of the start time of two
segments, up to which the segments (of the same URI) should be merged into a single
download segment, in milliseconds.</dd>
</dl>
</li>
</ul>
@ -534,13 +614,13 @@ implements <a href="Downloader.html" title="interface in com.google.android.exop
<ul class="subNavList">
<li>Summary:&nbsp;</li>
<li><a href="#nested.class.summary">Nested</a>&nbsp;|&nbsp;</li>
<li>Field&nbsp;|&nbsp;</li>
<li><a href="#field.summary">Field</a>&nbsp;|&nbsp;</li>
<li><a href="#constructor.summary">Constr</a>&nbsp;|&nbsp;</li>
<li><a href="#method.summary">Method</a></li>
</ul>
<ul class="subNavList">
<li>Detail:&nbsp;</li>
<li>Field&nbsp;|&nbsp;</li>
<li><a href="#field.detail">Field</a>&nbsp;|&nbsp;</li>
<li><a href="#constructor.detail">Constr</a>&nbsp;|&nbsp;</li>
<li><a href="#method.detail">Method</a></li>
</ul>

View file

@ -337,7 +337,7 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
<tr class="altColor">
<th class="colFirst" scope="row"><a href="ForwardingPlayer.html" title="class in com.google.android.exoplayer2">ForwardingPlayer</a></th>
<td class="colLast">
<div class="block">A <a href="Player.html" title="interface in com.google.android.exoplayer2"><code>Player</code></a> that forwards operations to another <a href="Player.html" title="interface in com.google.android.exoplayer2"><code>Player</code></a>.</div>
<div class="block">A <a href="Player.html" title="interface in com.google.android.exoplayer2"><code>Player</code></a> that forwards method calls to another <a href="Player.html" title="interface in com.google.android.exoplayer2"><code>Player</code></a>.</div>
</td>
</tr>
<tr class="rowColor">

View file

@ -87,7 +87,7 @@ loadScripts(document, 'script');</script>
<ul class="subNavList">
<li>Summary:&nbsp;</li>
<li><a href="#nested.class.summary">Nested</a>&nbsp;|&nbsp;</li>
<li>Field&nbsp;|&nbsp;</li>
<li><a href="#field.summary">Field</a>&nbsp;|&nbsp;</li>
<li><a href="#constructor.summary">Constr</a>&nbsp;|&nbsp;</li>
<li><a href="#method.summary">Method</a></li>
</ul>
@ -195,6 +195,23 @@ extends <a href="../../../offline/SegmentDownloader.html" title="class in com.go
</li>
</ul>
</section>
<!-- =========== FIELD SUMMARY =========== -->
<section role="region">
<ul class="blockList">
<li class="blockList"><a id="field.summary">
<!-- -->
</a>
<h3>Field Summary</h3>
<ul class="blockList">
<li class="blockList"><a id="fields.inherited.from.class.com.google.android.exoplayer2.offline.SegmentDownloader">
<!-- -->
</a>
<h3>Fields inherited from class&nbsp;com.google.android.exoplayer2.offline.<a href="../../../offline/SegmentDownloader.html" title="class in com.google.android.exoplayer2.offline">SegmentDownloader</a></h3>
<code><a href="../../../offline/SegmentDownloader.html#DEFAULT_MAX_MERGED_SEGMENT_START_TIME_DIFF_MS">DEFAULT_MAX_MERGED_SEGMENT_START_TIME_DIFF_MS</a></code></li>
</ul>
</li>
</ul>
</section>
<!-- ======== CONSTRUCTOR SUMMARY ======== -->
<section role="region">
<ul class="blockList">
@ -229,6 +246,19 @@ extends <a href="../../../offline/SegmentDownloader.html" title="class in com.go
<a href="../../../upstream/cache/CacheDataSource.Factory.html" title="class in com.google.android.exoplayer2.upstream.cache">CacheDataSource.Factory</a>&nbsp;cacheDataSourceFactory,
<a href="https://developer.android.com/reference/java/util/concurrent/Executor.html" title="class or interface in java.util.concurrent" class="externalLink" target="_top">Executor</a>&nbsp;executor)</code></th>
<td class="colLast">
<div class="block"><span class="deprecatedLabel">Deprecated.</span>
<div class="deprecationComment">Use <a href="#%3Cinit%3E(com.google.android.exoplayer2.MediaItem,com.google.android.exoplayer2.upstream.ParsingLoadable.Parser,com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory,java.util.concurrent.Executor,long)"><code>DashDownloader(MediaItem, Parser,
CacheDataSource.Factory, Executor, long)</code></a> instead.</div>
</div>
</td>
</tr>
<tr class="rowColor">
<th class="colConstructorName" scope="row"><code><span class="memberNameLink"><a href="#%3Cinit%3E(com.google.android.exoplayer2.MediaItem,com.google.android.exoplayer2.upstream.ParsingLoadable.Parser,com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory,java.util.concurrent.Executor,long)">DashDownloader</a></span>&#8203;(<a href="../../../MediaItem.html" title="class in com.google.android.exoplayer2">MediaItem</a>&nbsp;mediaItem,
<a href="../../../upstream/ParsingLoadable.Parser.html" title="interface in com.google.android.exoplayer2.upstream">ParsingLoadable.Parser</a>&lt;<a href="../manifest/DashManifest.html" title="class in com.google.android.exoplayer2.source.dash.manifest">DashManifest</a>&gt;&nbsp;manifestParser,
<a href="../../../upstream/cache/CacheDataSource.Factory.html" title="class in com.google.android.exoplayer2.upstream.cache">CacheDataSource.Factory</a>&nbsp;cacheDataSourceFactory,
<a href="https://developer.android.com/reference/java/util/concurrent/Executor.html" title="class or interface in java.util.concurrent" class="externalLink" target="_top">Executor</a>&nbsp;executor,
long&nbsp;maxMergedSegmentStartTimeDiffMs)</code></th>
<td class="colLast">
<div class="block">Creates a new instance.</div>
</td>
</tr>
@ -331,13 +361,31 @@ extends <a href="../../../offline/SegmentDownloader.html" title="class in com.go
<a id="&lt;init&gt;(com.google.android.exoplayer2.MediaItem,com.google.android.exoplayer2.upstream.ParsingLoadable.Parser,com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory,java.util.concurrent.Executor)">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>DashDownloader</h4>
<pre><a href="https://developer.android.com/reference/java/lang/Deprecated.html" title="class or interface in java.lang" class="externalLink" target="_top">@Deprecated</a>
public&nbsp;DashDownloader&#8203;(<a href="../../../MediaItem.html" title="class in com.google.android.exoplayer2">MediaItem</a>&nbsp;mediaItem,
<a href="../../../upstream/ParsingLoadable.Parser.html" title="interface in com.google.android.exoplayer2.upstream">ParsingLoadable.Parser</a>&lt;<a href="../manifest/DashManifest.html" title="class in com.google.android.exoplayer2.source.dash.manifest">DashManifest</a>&gt;&nbsp;manifestParser,
<a href="../../../upstream/cache/CacheDataSource.Factory.html" title="class in com.google.android.exoplayer2.upstream.cache">CacheDataSource.Factory</a>&nbsp;cacheDataSourceFactory,
<a href="https://developer.android.com/reference/java/util/concurrent/Executor.html" title="class or interface in java.util.concurrent" class="externalLink" target="_top">Executor</a>&nbsp;executor)</pre>
<div class="deprecationBlock"><span class="deprecatedLabel">Deprecated.</span>
<div class="deprecationComment">Use <a href="#%3Cinit%3E(com.google.android.exoplayer2.MediaItem,com.google.android.exoplayer2.upstream.ParsingLoadable.Parser,com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory,java.util.concurrent.Executor,long)"><code>DashDownloader(MediaItem, Parser,
CacheDataSource.Factory, Executor, long)</code></a> instead.</div>
</div>
</li>
</ul>
<a id="&lt;init&gt;(com.google.android.exoplayer2.MediaItem,com.google.android.exoplayer2.upstream.ParsingLoadable.Parser,com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory,java.util.concurrent.Executor,long)">
<!-- -->
</a>
<ul class="blockListLast">
<li class="blockList">
<h4>DashDownloader</h4>
<pre>public&nbsp;DashDownloader&#8203;(<a href="../../../MediaItem.html" title="class in com.google.android.exoplayer2">MediaItem</a>&nbsp;mediaItem,
<a href="../../../upstream/ParsingLoadable.Parser.html" title="interface in com.google.android.exoplayer2.upstream">ParsingLoadable.Parser</a>&lt;<a href="../manifest/DashManifest.html" title="class in com.google.android.exoplayer2.source.dash.manifest">DashManifest</a>&gt;&nbsp;manifestParser,
<a href="../../../upstream/cache/CacheDataSource.Factory.html" title="class in com.google.android.exoplayer2.upstream.cache">CacheDataSource.Factory</a>&nbsp;cacheDataSourceFactory,
<a href="https://developer.android.com/reference/java/util/concurrent/Executor.html" title="class or interface in java.util.concurrent" class="externalLink" target="_top">Executor</a>&nbsp;executor)</pre>
<a href="https://developer.android.com/reference/java/util/concurrent/Executor.html" title="class or interface in java.util.concurrent" class="externalLink" target="_top">Executor</a>&nbsp;executor,
long&nbsp;maxMergedSegmentStartTimeDiffMs)</pre>
<div class="block">Creates a new instance.</div>
<dl>
<dt><span class="paramLabel">Parameters:</span></dt>
@ -348,6 +396,9 @@ extends <a href="../../../offline/SegmentDownloader.html" title="class in com.go
<dd><code>executor</code> - An <a href="https://developer.android.com/reference/java/util/concurrent/Executor.html" title="class or interface in java.util.concurrent" class="externalLink" target="_top"><code>Executor</code></a> used to make requests for the media being downloaded.
Providing an <a href="https://developer.android.com/reference/java/util/concurrent/Executor.html" title="class or interface in java.util.concurrent" class="externalLink" target="_top"><code>Executor</code></a> that uses multiple threads will speed up the download by
allowing parts of it to be executed in parallel.</dd>
<dd><code>maxMergedSegmentStartTimeDiffMs</code> - The maximum difference of the start time of two
segments, up to which the segments (of the same URI) should be merged into a single
download segment, in milliseconds.</dd>
</dl>
</li>
</ul>
@ -445,7 +496,7 @@ extends <a href="../../../offline/SegmentDownloader.html" title="class in com.go
<ul class="subNavList">
<li>Summary:&nbsp;</li>
<li><a href="#nested.class.summary">Nested</a>&nbsp;|&nbsp;</li>
<li>Field&nbsp;|&nbsp;</li>
<li><a href="#field.summary">Field</a>&nbsp;|&nbsp;</li>
<li><a href="#constructor.summary">Constr</a>&nbsp;|&nbsp;</li>
<li><a href="#method.summary">Method</a></li>
</ul>

View file

@ -87,7 +87,7 @@ loadScripts(document, 'script');</script>
<ul class="subNavList">
<li>Summary:&nbsp;</li>
<li><a href="#nested.class.summary">Nested</a>&nbsp;|&nbsp;</li>
<li>Field&nbsp;|&nbsp;</li>
<li><a href="#field.summary">Field</a>&nbsp;|&nbsp;</li>
<li><a href="#constructor.summary">Constr</a>&nbsp;|&nbsp;</li>
<li><a href="#method.summary">Method</a></li>
</ul>
@ -196,6 +196,23 @@ extends <a href="../../../offline/SegmentDownloader.html" title="class in com.go
</li>
</ul>
</section>
<!-- =========== FIELD SUMMARY =========== -->
<section role="region">
<ul class="blockList">
<li class="blockList"><a id="field.summary">
<!-- -->
</a>
<h3>Field Summary</h3>
<ul class="blockList">
<li class="blockList"><a id="fields.inherited.from.class.com.google.android.exoplayer2.offline.SegmentDownloader">
<!-- -->
</a>
<h3>Fields inherited from class&nbsp;com.google.android.exoplayer2.offline.<a href="../../../offline/SegmentDownloader.html" title="class in com.google.android.exoplayer2.offline">SegmentDownloader</a></h3>
<code><a href="../../../offline/SegmentDownloader.html#DEFAULT_MAX_MERGED_SEGMENT_START_TIME_DIFF_MS">DEFAULT_MAX_MERGED_SEGMENT_START_TIME_DIFF_MS</a></code></li>
</ul>
</li>
</ul>
</section>
<!-- ======== CONSTRUCTOR SUMMARY ======== -->
<section role="region">
<ul class="blockList">
@ -230,6 +247,19 @@ extends <a href="../../../offline/SegmentDownloader.html" title="class in com.go
<a href="../../../upstream/cache/CacheDataSource.Factory.html" title="class in com.google.android.exoplayer2.upstream.cache">CacheDataSource.Factory</a>&nbsp;cacheDataSourceFactory,
<a href="https://developer.android.com/reference/java/util/concurrent/Executor.html" title="class or interface in java.util.concurrent" class="externalLink" target="_top">Executor</a>&nbsp;executor)</code></th>
<td class="colLast">
<div class="block"><span class="deprecatedLabel">Deprecated.</span>
<div class="deprecationComment">Use <a href="#%3Cinit%3E(com.google.android.exoplayer2.MediaItem,com.google.android.exoplayer2.upstream.ParsingLoadable.Parser,com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory,java.util.concurrent.Executor,long)"><code>HlsDownloader(MediaItem, Parser, CacheDataSource.Factory,
Executor, long)</code></a> instead.</div>
</div>
</td>
</tr>
<tr class="rowColor">
<th class="colConstructorName" scope="row"><code><span class="memberNameLink"><a href="#%3Cinit%3E(com.google.android.exoplayer2.MediaItem,com.google.android.exoplayer2.upstream.ParsingLoadable.Parser,com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory,java.util.concurrent.Executor,long)">HlsDownloader</a></span>&#8203;(<a href="../../../MediaItem.html" title="class in com.google.android.exoplayer2">MediaItem</a>&nbsp;mediaItem,
<a href="../../../upstream/ParsingLoadable.Parser.html" title="interface in com.google.android.exoplayer2.upstream">ParsingLoadable.Parser</a>&lt;<a href="../playlist/HlsPlaylist.html" title="class in com.google.android.exoplayer2.source.hls.playlist">HlsPlaylist</a>&gt;&nbsp;manifestParser,
<a href="../../../upstream/cache/CacheDataSource.Factory.html" title="class in com.google.android.exoplayer2.upstream.cache">CacheDataSource.Factory</a>&nbsp;cacheDataSourceFactory,
<a href="https://developer.android.com/reference/java/util/concurrent/Executor.html" title="class or interface in java.util.concurrent" class="externalLink" target="_top">Executor</a>&nbsp;executor,
long&nbsp;maxMergedSegmentStartTimeDiffMs)</code></th>
<td class="colLast">
<div class="block">Creates a new instance.</div>
</td>
</tr>
@ -332,13 +362,31 @@ extends <a href="../../../offline/SegmentDownloader.html" title="class in com.go
<a id="&lt;init&gt;(com.google.android.exoplayer2.MediaItem,com.google.android.exoplayer2.upstream.ParsingLoadable.Parser,com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory,java.util.concurrent.Executor)">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>HlsDownloader</h4>
<pre><a href="https://developer.android.com/reference/java/lang/Deprecated.html" title="class or interface in java.lang" class="externalLink" target="_top">@Deprecated</a>
public&nbsp;HlsDownloader&#8203;(<a href="../../../MediaItem.html" title="class in com.google.android.exoplayer2">MediaItem</a>&nbsp;mediaItem,
<a href="../../../upstream/ParsingLoadable.Parser.html" title="interface in com.google.android.exoplayer2.upstream">ParsingLoadable.Parser</a>&lt;<a href="../playlist/HlsPlaylist.html" title="class in com.google.android.exoplayer2.source.hls.playlist">HlsPlaylist</a>&gt;&nbsp;manifestParser,
<a href="../../../upstream/cache/CacheDataSource.Factory.html" title="class in com.google.android.exoplayer2.upstream.cache">CacheDataSource.Factory</a>&nbsp;cacheDataSourceFactory,
<a href="https://developer.android.com/reference/java/util/concurrent/Executor.html" title="class or interface in java.util.concurrent" class="externalLink" target="_top">Executor</a>&nbsp;executor)</pre>
<div class="deprecationBlock"><span class="deprecatedLabel">Deprecated.</span>
<div class="deprecationComment">Use <a href="#%3Cinit%3E(com.google.android.exoplayer2.MediaItem,com.google.android.exoplayer2.upstream.ParsingLoadable.Parser,com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory,java.util.concurrent.Executor,long)"><code>HlsDownloader(MediaItem, Parser, CacheDataSource.Factory,
Executor, long)</code></a> instead.</div>
</div>
</li>
</ul>
<a id="&lt;init&gt;(com.google.android.exoplayer2.MediaItem,com.google.android.exoplayer2.upstream.ParsingLoadable.Parser,com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory,java.util.concurrent.Executor,long)">
<!-- -->
</a>
<ul class="blockListLast">
<li class="blockList">
<h4>HlsDownloader</h4>
<pre>public&nbsp;HlsDownloader&#8203;(<a href="../../../MediaItem.html" title="class in com.google.android.exoplayer2">MediaItem</a>&nbsp;mediaItem,
<a href="../../../upstream/ParsingLoadable.Parser.html" title="interface in com.google.android.exoplayer2.upstream">ParsingLoadable.Parser</a>&lt;<a href="../playlist/HlsPlaylist.html" title="class in com.google.android.exoplayer2.source.hls.playlist">HlsPlaylist</a>&gt;&nbsp;manifestParser,
<a href="../../../upstream/cache/CacheDataSource.Factory.html" title="class in com.google.android.exoplayer2.upstream.cache">CacheDataSource.Factory</a>&nbsp;cacheDataSourceFactory,
<a href="https://developer.android.com/reference/java/util/concurrent/Executor.html" title="class or interface in java.util.concurrent" class="externalLink" target="_top">Executor</a>&nbsp;executor)</pre>
<a href="https://developer.android.com/reference/java/util/concurrent/Executor.html" title="class or interface in java.util.concurrent" class="externalLink" target="_top">Executor</a>&nbsp;executor,
long&nbsp;maxMergedSegmentStartTimeDiffMs)</pre>
<div class="block">Creates a new instance.</div>
<dl>
<dt><span class="paramLabel">Parameters:</span></dt>
@ -349,6 +397,9 @@ extends <a href="../../../offline/SegmentDownloader.html" title="class in com.go
<dd><code>executor</code> - An <a href="https://developer.android.com/reference/java/util/concurrent/Executor.html" title="class or interface in java.util.concurrent" class="externalLink" target="_top"><code>Executor</code></a> used to make requests for the media being downloaded.
Providing an <a href="https://developer.android.com/reference/java/util/concurrent/Executor.html" title="class or interface in java.util.concurrent" class="externalLink" target="_top"><code>Executor</code></a> that uses multiple threads will speed up the download by
allowing parts of it to be executed in parallel.</dd>
<dd><code>maxMergedSegmentStartTimeDiffMs</code> - The maximum difference of the start time of two
segments, up to which the segments (of the same URI) should be merged into a single
download segment, in milliseconds.</dd>
</dl>
</li>
</ul>
@ -446,7 +497,7 @@ extends <a href="../../../offline/SegmentDownloader.html" title="class in com.go
<ul class="subNavList">
<li>Summary:&nbsp;</li>
<li><a href="#nested.class.summary">Nested</a>&nbsp;|&nbsp;</li>
<li>Field&nbsp;|&nbsp;</li>
<li><a href="#field.summary">Field</a>&nbsp;|&nbsp;</li>
<li><a href="#constructor.summary">Constr</a>&nbsp;|&nbsp;</li>
<li><a href="#method.summary">Method</a></li>
</ul>

View file

@ -136,12 +136,10 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
<pre>public class <span class="typeNameLabel">SsManifest</span>
extends <a href="https://developer.android.com/reference/java/lang/Object.html" title="class or interface in java.lang" class="externalLink" target="_top">Object</a>
implements <a href="../../../offline/FilterableManifest.html" title="interface in com.google.android.exoplayer2.offline">FilterableManifest</a>&lt;<a href="SsManifest.html" title="class in com.google.android.exoplayer2.source.smoothstreaming.manifest">SsManifest</a>&gt;</pre>
<div class="block">Represents a SmoothStreaming manifest.</div>
<dl>
<dt><span class="seeLabel">See Also:</span></dt>
<dd><a href="http://msdn.microsoft.com/en-us/library/ee673436(v=vs.90).aspx">IIS Smooth
Streaming Client Manifest Format</a></dd>
</dl>
<div class="block">Represents a SmoothStreaming manifest.
<p>See the <a href="http://msdn.microsoft.com/en-us/library/ee673436(v=vs.90).aspx">IIS Smooth
Streaming Client Manifest Format</a></div>
</li>
</ul>
</div>

View file

@ -136,12 +136,10 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
<pre>public class <span class="typeNameLabel">SsManifestParser</span>
extends <a href="https://developer.android.com/reference/java/lang/Object.html" title="class or interface in java.lang" class="externalLink" target="_top">Object</a>
implements <a href="../../../upstream/ParsingLoadable.Parser.html" title="interface in com.google.android.exoplayer2.upstream">ParsingLoadable.Parser</a>&lt;<a href="SsManifest.html" title="class in com.google.android.exoplayer2.source.smoothstreaming.manifest">SsManifest</a>&gt;</pre>
<div class="block">Parses SmoothStreaming client manifests.</div>
<dl>
<dt><span class="seeLabel">See Also:</span></dt>
<dd><a href="http://msdn.microsoft.com/en-us/library/ee673436(v=vs.90).aspx">IIS Smooth
Streaming Client Manifest Format</a></dd>
</dl>
<div class="block">Parses SmoothStreaming client manifests.
<p>See the <a href="http://msdn.microsoft.com/en-us/library/ee673436(v=vs.90).aspx">IIS Smooth
Streaming Client Manifest Format</a></div>
</li>
</ul>
</div>

View file

@ -87,7 +87,7 @@ loadScripts(document, 'script');</script>
<ul class="subNavList">
<li>Summary:&nbsp;</li>
<li><a href="#nested.class.summary">Nested</a>&nbsp;|&nbsp;</li>
<li>Field&nbsp;|&nbsp;</li>
<li><a href="#field.summary">Field</a>&nbsp;|&nbsp;</li>
<li><a href="#constructor.summary">Constr</a>&nbsp;|&nbsp;</li>
<li><a href="#method.summary">Method</a></li>
</ul>
@ -194,6 +194,23 @@ extends <a href="../../../offline/SegmentDownloader.html" title="class in com.go
</li>
</ul>
</section>
<!-- =========== FIELD SUMMARY =========== -->
<section role="region">
<ul class="blockList">
<li class="blockList"><a id="field.summary">
<!-- -->
</a>
<h3>Field Summary</h3>
<ul class="blockList">
<li class="blockList"><a id="fields.inherited.from.class.com.google.android.exoplayer2.offline.SegmentDownloader">
<!-- -->
</a>
<h3>Fields inherited from class&nbsp;com.google.android.exoplayer2.offline.<a href="../../../offline/SegmentDownloader.html" title="class in com.google.android.exoplayer2.offline">SegmentDownloader</a></h3>
<code><a href="../../../offline/SegmentDownloader.html#DEFAULT_MAX_MERGED_SEGMENT_START_TIME_DIFF_MS">DEFAULT_MAX_MERGED_SEGMENT_START_TIME_DIFF_MS</a></code></li>
</ul>
</li>
</ul>
</section>
<!-- ======== CONSTRUCTOR SUMMARY ======== -->
<section role="region">
<ul class="blockList">
@ -228,6 +245,19 @@ extends <a href="../../../offline/SegmentDownloader.html" title="class in com.go
<a href="../../../upstream/cache/CacheDataSource.Factory.html" title="class in com.google.android.exoplayer2.upstream.cache">CacheDataSource.Factory</a>&nbsp;cacheDataSourceFactory,
<a href="https://developer.android.com/reference/java/util/concurrent/Executor.html" title="class or interface in java.util.concurrent" class="externalLink" target="_top">Executor</a>&nbsp;executor)</code></th>
<td class="colLast">
<div class="block"><span class="deprecatedLabel">Deprecated.</span>
<div class="deprecationComment">Use <a href="#%3Cinit%3E(com.google.android.exoplayer2.MediaItem,com.google.android.exoplayer2.upstream.ParsingLoadable.Parser,com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory,java.util.concurrent.Executor,long)"><code>SsDownloader(MediaItem, Parser, CacheDataSource.Factory,
Executor, long)</code></a> instead.</div>
</div>
</td>
</tr>
<tr class="rowColor">
<th class="colConstructorName" scope="row"><code><span class="memberNameLink"><a href="#%3Cinit%3E(com.google.android.exoplayer2.MediaItem,com.google.android.exoplayer2.upstream.ParsingLoadable.Parser,com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory,java.util.concurrent.Executor,long)">SsDownloader</a></span>&#8203;(<a href="../../../MediaItem.html" title="class in com.google.android.exoplayer2">MediaItem</a>&nbsp;mediaItem,
<a href="../../../upstream/ParsingLoadable.Parser.html" title="interface in com.google.android.exoplayer2.upstream">ParsingLoadable.Parser</a>&lt;<a href="../manifest/SsManifest.html" title="class in com.google.android.exoplayer2.source.smoothstreaming.manifest">SsManifest</a>&gt;&nbsp;manifestParser,
<a href="../../../upstream/cache/CacheDataSource.Factory.html" title="class in com.google.android.exoplayer2.upstream.cache">CacheDataSource.Factory</a>&nbsp;cacheDataSourceFactory,
<a href="https://developer.android.com/reference/java/util/concurrent/Executor.html" title="class or interface in java.util.concurrent" class="externalLink" target="_top">Executor</a>&nbsp;executor,
long&nbsp;maxMergedSegmentStartTimeDiffMs)</code></th>
<td class="colLast">
<div class="block">Creates a new instance.</div>
</td>
</tr>
@ -330,13 +360,31 @@ extends <a href="../../../offline/SegmentDownloader.html" title="class in com.go
<a id="&lt;init&gt;(com.google.android.exoplayer2.MediaItem,com.google.android.exoplayer2.upstream.ParsingLoadable.Parser,com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory,java.util.concurrent.Executor)">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>SsDownloader</h4>
<pre><a href="https://developer.android.com/reference/java/lang/Deprecated.html" title="class or interface in java.lang" class="externalLink" target="_top">@Deprecated</a>
public&nbsp;SsDownloader&#8203;(<a href="../../../MediaItem.html" title="class in com.google.android.exoplayer2">MediaItem</a>&nbsp;mediaItem,
<a href="../../../upstream/ParsingLoadable.Parser.html" title="interface in com.google.android.exoplayer2.upstream">ParsingLoadable.Parser</a>&lt;<a href="../manifest/SsManifest.html" title="class in com.google.android.exoplayer2.source.smoothstreaming.manifest">SsManifest</a>&gt;&nbsp;manifestParser,
<a href="../../../upstream/cache/CacheDataSource.Factory.html" title="class in com.google.android.exoplayer2.upstream.cache">CacheDataSource.Factory</a>&nbsp;cacheDataSourceFactory,
<a href="https://developer.android.com/reference/java/util/concurrent/Executor.html" title="class or interface in java.util.concurrent" class="externalLink" target="_top">Executor</a>&nbsp;executor)</pre>
<div class="deprecationBlock"><span class="deprecatedLabel">Deprecated.</span>
<div class="deprecationComment">Use <a href="#%3Cinit%3E(com.google.android.exoplayer2.MediaItem,com.google.android.exoplayer2.upstream.ParsingLoadable.Parser,com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory,java.util.concurrent.Executor,long)"><code>SsDownloader(MediaItem, Parser, CacheDataSource.Factory,
Executor, long)</code></a> instead.</div>
</div>
</li>
</ul>
<a id="&lt;init&gt;(com.google.android.exoplayer2.MediaItem,com.google.android.exoplayer2.upstream.ParsingLoadable.Parser,com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory,java.util.concurrent.Executor,long)">
<!-- -->
</a>
<ul class="blockListLast">
<li class="blockList">
<h4>SsDownloader</h4>
<pre>public&nbsp;SsDownloader&#8203;(<a href="../../../MediaItem.html" title="class in com.google.android.exoplayer2">MediaItem</a>&nbsp;mediaItem,
<a href="../../../upstream/ParsingLoadable.Parser.html" title="interface in com.google.android.exoplayer2.upstream">ParsingLoadable.Parser</a>&lt;<a href="../manifest/SsManifest.html" title="class in com.google.android.exoplayer2.source.smoothstreaming.manifest">SsManifest</a>&gt;&nbsp;manifestParser,
<a href="../../../upstream/cache/CacheDataSource.Factory.html" title="class in com.google.android.exoplayer2.upstream.cache">CacheDataSource.Factory</a>&nbsp;cacheDataSourceFactory,
<a href="https://developer.android.com/reference/java/util/concurrent/Executor.html" title="class or interface in java.util.concurrent" class="externalLink" target="_top">Executor</a>&nbsp;executor)</pre>
<a href="https://developer.android.com/reference/java/util/concurrent/Executor.html" title="class or interface in java.util.concurrent" class="externalLink" target="_top">Executor</a>&nbsp;executor,
long&nbsp;maxMergedSegmentStartTimeDiffMs)</pre>
<div class="block">Creates a new instance.</div>
<dl>
<dt><span class="paramLabel">Parameters:</span></dt>
@ -347,6 +395,9 @@ extends <a href="../../../offline/SegmentDownloader.html" title="class in com.go
<dd><code>executor</code> - An <a href="https://developer.android.com/reference/java/util/concurrent/Executor.html" title="class or interface in java.util.concurrent" class="externalLink" target="_top"><code>Executor</code></a> used to make requests for the media being downloaded.
Providing an <a href="https://developer.android.com/reference/java/util/concurrent/Executor.html" title="class or interface in java.util.concurrent" class="externalLink" target="_top"><code>Executor</code></a> that uses multiple threads will speed up the download by
allowing parts of it to be executed in parallel.</dd>
<dd><code>maxMergedSegmentStartTimeDiffMs</code> - The maximum difference of the start time of two
segments, up to which the segments (of the same URI) should be merged into a single
download segment, in milliseconds.</dd>
</dl>
</li>
</ul>
@ -438,7 +489,7 @@ extends <a href="../../../offline/SegmentDownloader.html" title="class in com.go
<ul class="subNavList">
<li>Summary:&nbsp;</li>
<li><a href="#nested.class.summary">Nested</a>&nbsp;|&nbsp;</li>
<li>Field&nbsp;|&nbsp;</li>
<li><a href="#field.summary">Field</a>&nbsp;|&nbsp;</li>
<li><a href="#constructor.summary">Constr</a>&nbsp;|&nbsp;</li>
<li><a href="#method.summary">Method</a></li>
</ul>

View file

@ -162,11 +162,9 @@ extends <a href="../SimpleSubtitleDecoder.html" title="class in com.google.andro
<li>time-offset-with-frames
<li>time-offset-with-ticks
<li>cell-resolution
</ul></div>
<dl>
<dt><span class="seeLabel">See Also:</span></dt>
<dd><a href="http://www.w3.org/TR/ttaf1-dfxp/">TTML specification</a></dd>
</dl>
</ul>
<p>See the <a href="http://www.w3.org/TR/ttaf1-dfxp/">TTML specification</a></div>
</li>
</ul>
</div>

View file

@ -131,12 +131,10 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
<hr>
<pre>public final class <span class="typeNameLabel">WebvttCssStyle</span>
extends <a href="https://developer.android.com/reference/java/lang/Object.html" title="class or interface in java.lang" class="externalLink" target="_top">Object</a></pre>
<div class="block">Style object of a Css style block in a Webvtt file.</div>
<dl>
<dt><span class="seeLabel">See Also:</span></dt>
<dd><a href="https://w3c.github.io/webvtt/#applying-css-properties">W3C specification - Apply
CSS properties</a></dd>
</dl>
<div class="block">Style object of a CSS style block in a WebVTT file.
<p>See the <a href="https://w3c.github.io/webvtt/#applying-css-properties">Apply CSS properties
section of the W3C specification</a></div>
</li>
</ul>
</div>

View file

@ -145,11 +145,9 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
<hr>
<pre>public final class <span class="typeNameLabel">WebvttDecoder</span>
extends <a href="../SimpleSubtitleDecoder.html" title="class in com.google.android.exoplayer2.text">SimpleSubtitleDecoder</a></pre>
<div class="block">A <a href="../SimpleSubtitleDecoder.html" title="class in com.google.android.exoplayer2.text"><code>SimpleSubtitleDecoder</code></a> for WebVTT.</div>
<dl>
<dt><span class="seeLabel">See Also:</span></dt>
<dd><a href="http://dev.w3.org/html5/webvtt">WebVTT specification</a></dd>
</dl>
<div class="block">A <a href="../SimpleSubtitleDecoder.html" title="class in com.google.android.exoplayer2.text"><code>SimpleSubtitleDecoder</code></a> for WebVTT.
<p>See the <a href="http://dev.w3.org/html5/webvtt">WebVTT specification</a>.</div>
</li>
</ul>
</div>

View file

@ -112,7 +112,7 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
<tr class="rowColor">
<th class="colFirst" scope="row"><a href="WebvttCssStyle.html" title="class in com.google.android.exoplayer2.text.webvtt">WebvttCssStyle</a></th>
<td class="colLast">
<div class="block">Style object of a Css style block in a Webvtt file.</div>
<div class="block">Style object of a CSS style block in a WebVTT file.</div>
</td>
</tr>
<tr class="altColor">

View file

@ -138,12 +138,14 @@ extends <a href="https://developer.android.com/reference/java/lang/Object.html"
<p>This class can be used for bandwidth estimation based on a sliding window of past transfer
rate observations. This is an alternative to sliding mean and exponential averaging which suffer
from susceptibility to outliers and slow adaptation to step functions.</div>
<dl>
<dt><span class="seeLabel">See Also:</span></dt>
<dd><a href="http://en.wikipedia.org/wiki/Moving_average">Wiki: Moving average</a>,
<a href="http://en.wikipedia.org/wiki/Selection_algorithm">Wiki: Selection algorithm</a></dd>
</dl>
from susceptibility to outliers and slow adaptation to step functions.
<p>See the following Wikipedia articles:
<ul>
<li><a href="http://en.wikipedia.org/wiki/Moving_average">Moving average</a>
<li><a href="http://en.wikipedia.org/wiki/Selection_algorithm">Selection algorithm</a>
</ul></div>
</li>
</ul>
</div>

View file

@ -131,12 +131,14 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
<hr>
<pre>public final class <span class="typeNameLabel">ColorParser</span>
extends <a href="https://developer.android.com/reference/java/lang/Object.html" title="class or interface in java.lang" class="externalLink" target="_top">Object</a></pre>
<div class="block">Parser for color expressions found in styling formats, e.g. TTML and CSS.</div>
<dl>
<dt><span class="seeLabel">See Also:</span></dt>
<dd><a href="https://w3c.github.io/webvtt/#styling">WebVTT CSS Styling</a>,
<a href="https://www.w3.org/TR/ttml2/">Timed Text Markup Language 2 (TTML2) - 10.3.5</a></dd>
</dl>
<div class="block">Parser for color expressions found in styling formats, e.g. TTML and CSS.
<p>See also:
<ul>
<li><a href="https://w3c.github.io/webvtt/#styling">WebVTT CSS Styling</a>
<li><a href="https://www.w3.org/TR/ttml2/">Timed Text Markup Language 2 (TTML2) - 10.3.5</a>
</ul></div>
</li>
</ul>
</div>

View file

@ -25,7 +25,7 @@
catch(err) {
}
//-->
var data = {"i0":9,"i1":9,"i2":9,"i3":9,"i4":9,"i5":9,"i6":9,"i7":9,"i8":9,"i9":9,"i10":9,"i11":9,"i12":9,"i13":9,"i14":9,"i15":9,"i16":9,"i17":9,"i18":9,"i19":9,"i20":9,"i21":9,"i22":9,"i23":9,"i24":9,"i25":9,"i26":9,"i27":9,"i28":9,"i29":9,"i30":9,"i31":9,"i32":9,"i33":9,"i34":9,"i35":9,"i36":9,"i37":9,"i38":9,"i39":9,"i40":9,"i41":9,"i42":9,"i43":9,"i44":9,"i45":9,"i46":9,"i47":9,"i48":9,"i49":9,"i50":9,"i51":9,"i52":9,"i53":9,"i54":9,"i55":9,"i56":9,"i57":9,"i58":9,"i59":9,"i60":9,"i61":9,"i62":9,"i63":9,"i64":9,"i65":9,"i66":9,"i67":9,"i68":9,"i69":9,"i70":9,"i71":9,"i72":41,"i73":41,"i74":9,"i75":9,"i76":9,"i77":9,"i78":9,"i79":9,"i80":9,"i81":9,"i82":9,"i83":9,"i84":9,"i85":9,"i86":9,"i87":9,"i88":9,"i89":9,"i90":9,"i91":9,"i92":9,"i93":9,"i94":9,"i95":9,"i96":9,"i97":9,"i98":9,"i99":9,"i100":9,"i101":9,"i102":9,"i103":9,"i104":9,"i105":9,"i106":9,"i107":9,"i108":9,"i109":9,"i110":9,"i111":9,"i112":9,"i113":9,"i114":9,"i115":9,"i116":9,"i117":9,"i118":9,"i119":9,"i120":9,"i121":9,"i122":9,"i123":9,"i124":9,"i125":9,"i126":9,"i127":9};
var data = {"i0":9,"i1":9,"i2":9,"i3":9,"i4":9,"i5":9,"i6":9,"i7":9,"i8":9,"i9":9,"i10":9,"i11":9,"i12":9,"i13":9,"i14":9,"i15":9,"i16":9,"i17":9,"i18":9,"i19":9,"i20":9,"i21":9,"i22":9,"i23":9,"i24":9,"i25":9,"i26":9,"i27":9,"i28":9,"i29":9,"i30":9,"i31":9,"i32":9,"i33":9,"i34":9,"i35":9,"i36":9,"i37":9,"i38":9,"i39":9,"i40":9,"i41":9,"i42":9,"i43":9,"i44":9,"i45":9,"i46":9,"i47":9,"i48":9,"i49":9,"i50":9,"i51":9,"i52":9,"i53":9,"i54":9,"i55":9,"i56":9,"i57":9,"i58":9,"i59":9,"i60":9,"i61":9,"i62":9,"i63":9,"i64":9,"i65":9,"i66":9,"i67":9,"i68":9,"i69":9,"i70":9,"i71":9,"i72":41,"i73":41,"i74":9,"i75":9,"i76":9,"i77":9,"i78":9,"i79":9,"i80":9,"i81":9,"i82":9,"i83":9,"i84":9,"i85":9,"i86":9,"i87":9,"i88":9,"i89":9,"i90":9,"i91":9,"i92":9,"i93":9,"i94":9,"i95":9,"i96":9,"i97":9,"i98":9,"i99":9,"i100":9,"i101":9,"i102":9,"i103":9,"i104":9,"i105":9,"i106":9,"i107":9,"i108":9,"i109":9,"i110":9,"i111":9,"i112":9,"i113":9,"i114":9,"i115":9,"i116":9,"i117":9,"i118":9,"i119":9,"i120":9,"i121":9,"i122":9,"i123":9,"i124":9,"i125":9,"i126":9};
var tabs = {65535:["t0","All Methods"],1:["t1","Static Methods"],8:["t4","Concrete Methods"],32:["t6","Deprecated Methods"]};
var altColor = "altColor";
var rowColor = "rowColor";
@ -1076,17 +1076,6 @@ extends <a href="https://developer.android.com/reference/java/lang/Object.html"
</td>
</tr>
<tr id="i106" class="altColor">
<td class="colFirst"><code>static <a href="https://developer.android.com/reference/android/content/Intent.html" title="class or interface in android.content" class="externalLink" target="_top">Intent</a></code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#registerReceiverNotExported(android.content.Context,android.content.BroadcastReceiver,android.content.IntentFilter,android.os.Handler)">registerReceiverNotExported</a></span>&#8203;(<a href="https://developer.android.com/reference/android/content/Context.html" title="class or interface in android.content" class="externalLink" target="_top">Context</a>&nbsp;context,
<a href="https://developer.android.com/reference/android/content/BroadcastReceiver.html" title="class or interface in android.content" class="externalLink" target="_top">BroadcastReceiver</a>&nbsp;receiver,
<a href="https://developer.android.com/reference/android/content/IntentFilter.html" title="class or interface in android.content" class="externalLink" target="_top">IntentFilter</a>&nbsp;filter,
<a href="https://developer.android.com/reference/android/os/Handler.html" title="class or interface in android.os" class="externalLink" target="_top">Handler</a>&nbsp;handler)</code></th>
<td class="colLast">
<div class="block">Registers a <a href="https://developer.android.com/reference/android/content/BroadcastReceiver.html" title="class or interface in android.content" class="externalLink" target="_top"><code>BroadcastReceiver</code></a> that's not intended to receive broadcasts from other
apps.</div>
</td>
</tr>
<tr id="i107" class="rowColor">
<td class="colFirst"><code>static &lt;T&gt;&nbsp;void</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#removeRange(java.util.List,int,int)">removeRange</a></span>&#8203;(<a href="https://developer.android.com/reference/java/util/List.html" title="class or interface in java.util" class="externalLink" target="_top">List</a>&lt;T&gt;&nbsp;list,
int&nbsp;fromIndex,
@ -1095,7 +1084,7 @@ extends <a href="https://developer.android.com/reference/java/lang/Object.html"
<div class="block">Removes an indexed range from a List.</div>
</td>
</tr>
<tr id="i108" class="altColor">
<tr id="i107" class="rowColor">
<td class="colFirst"><code>static long</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#scaleLargeTimestamp(long,long,long)">scaleLargeTimestamp</a></span>&#8203;(long&nbsp;timestamp,
long&nbsp;multiplier,
@ -1104,7 +1093,7 @@ extends <a href="https://developer.android.com/reference/java/lang/Object.html"
<div class="block">Scales a large timestamp.</div>
</td>
</tr>
<tr id="i109" class="rowColor">
<tr id="i108" class="altColor">
<td class="colFirst"><code>static long[]</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#scaleLargeTimestamps(java.util.List,long,long)">scaleLargeTimestamps</a></span>&#8203;(<a href="https://developer.android.com/reference/java/util/List.html" title="class or interface in java.util" class="externalLink">List</a>&lt;<a href="https://developer.android.com/reference/java/lang/Long.html?is-external=true" title="class or interface in java.lang" class="externalLink" target="_top">Long</a>&gt;&nbsp;timestamps,
long&nbsp;multiplier,
@ -1113,7 +1102,7 @@ extends <a href="https://developer.android.com/reference/java/lang/Object.html"
<div class="block">Applies <a href="#scaleLargeTimestamp(long,long,long)"><code>scaleLargeTimestamp(long, long, long)</code></a> to a list of unscaled timestamps.</div>
</td>
</tr>
<tr id="i110" class="altColor">
<tr id="i109" class="rowColor">
<td class="colFirst"><code>static void</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#scaleLargeTimestampsInPlace(long%5B%5D,long,long)">scaleLargeTimestampsInPlace</a></span>&#8203;(long[]&nbsp;timestamps,
long&nbsp;multiplier,
@ -1122,7 +1111,7 @@ extends <a href="https://developer.android.com/reference/java/lang/Object.html"
<div class="block">Applies <a href="#scaleLargeTimestamp(long,long,long)"><code>scaleLargeTimestamp(long, long, long)</code></a> to an array of unscaled timestamps.</div>
</td>
</tr>
<tr id="i111" class="rowColor">
<tr id="i110" class="altColor">
<td class="colFirst"><code>static void</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#sneakyThrow(java.lang.Throwable)">sneakyThrow</a></span>&#8203;(<a href="https://developer.android.com/reference/java/lang/Throwable.html" title="class or interface in java.lang" class="externalLink" target="_top">Throwable</a>&nbsp;t)</code></th>
<td class="colLast">
@ -1130,7 +1119,7 @@ extends <a href="https://developer.android.com/reference/java/lang/Object.html"
not declared to be thrown.</div>
</td>
</tr>
<tr id="i112" class="altColor">
<tr id="i111" class="rowColor">
<td class="colFirst"><code>static <a href="https://developer.android.com/reference/java/lang/String.html" title="class or interface in java.lang" class="externalLink" target="_top">String</a>[]</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#split(java.lang.String,java.lang.String)">split</a></span>&#8203;(<a href="https://developer.android.com/reference/java/lang/String.html" title="class or interface in java.lang" class="externalLink" target="_top">String</a>&nbsp;value,
<a href="https://developer.android.com/reference/java/lang/String.html" title="class or interface in java.lang" class="externalLink" target="_top">String</a>&nbsp;regex)</code></th>
@ -1138,7 +1127,7 @@ extends <a href="https://developer.android.com/reference/java/lang/Object.html"
<div class="block">Splits a string using <code>value.split(regex, -1</code>).</div>
</td>
</tr>
<tr id="i113" class="rowColor">
<tr id="i112" class="altColor">
<td class="colFirst"><code>static <a href="https://developer.android.com/reference/java/lang/String.html" title="class or interface in java.lang" class="externalLink" target="_top">String</a>[]</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#splitAtFirst(java.lang.String,java.lang.String)">splitAtFirst</a></span>&#8203;(<a href="https://developer.android.com/reference/java/lang/String.html" title="class or interface in java.lang" class="externalLink" target="_top">String</a>&nbsp;value,
<a href="https://developer.android.com/reference/java/lang/String.html" title="class or interface in java.lang" class="externalLink" target="_top">String</a>&nbsp;regex)</code></th>
@ -1146,14 +1135,14 @@ extends <a href="https://developer.android.com/reference/java/lang/Object.html"
<div class="block">Splits the string at the first occurrence of the delimiter <code>regex</code>.</div>
</td>
</tr>
<tr id="i114" class="altColor">
<tr id="i113" class="rowColor">
<td class="colFirst"><code>static <a href="https://developer.android.com/reference/java/lang/String.html" title="class or interface in java.lang" class="externalLink" target="_top">String</a>[]</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#splitCodecs(java.lang.String)">splitCodecs</a></span>&#8203;(<a href="https://developer.android.com/reference/java/lang/String.html" title="class or interface in java.lang" class="externalLink" target="_top">String</a>&nbsp;codecs)</code></th>
<td class="colLast">
<div class="block">Splits a codecs sequence string, as defined in RFC 6381, into individual codec strings.</div>
</td>
</tr>
<tr id="i115" class="rowColor">
<tr id="i114" class="altColor">
<td class="colFirst"><code>static <a href="https://developer.android.com/reference/android/content/ComponentName.html" title="class or interface in android.content" class="externalLink" target="_top">ComponentName</a></code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#startForegroundService(android.content.Context,android.content.Intent)">startForegroundService</a></span>&#8203;(<a href="https://developer.android.com/reference/android/content/Context.html" title="class or interface in android.content" class="externalLink" target="_top">Context</a>&nbsp;context,
<a href="https://developer.android.com/reference/android/content/Intent.html" title="class or interface in android.content" class="externalLink" target="_top">Intent</a>&nbsp;intent)</code></th>
@ -1162,7 +1151,7 @@ extends <a href="https://developer.android.com/reference/java/lang/Object.html"
<a href="https://developer.android.com/reference/android/content/Context.html#startService(android.content.Intent)" title="class or interface in android.content" class="externalLink" target="_top"><code>Context.startService(Intent)</code></a> otherwise.</div>
</td>
</tr>
<tr id="i116" class="altColor">
<tr id="i115" class="rowColor">
<td class="colFirst"><code>static long</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#subtractWithOverflowDefault(long,long,long)">subtractWithOverflowDefault</a></span>&#8203;(long&nbsp;x,
long&nbsp;y,
@ -1171,14 +1160,14 @@ extends <a href="https://developer.android.com/reference/java/lang/Object.html"
<div class="block">Returns the difference between two arguments, or a third argument if the result overflows.</div>
</td>
</tr>
<tr id="i117" class="rowColor">
<tr id="i116" class="altColor">
<td class="colFirst"><code>static long</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#sum(long...)">sum</a></span>&#8203;(long...&nbsp;summands)</code></th>
<td class="colLast">
<div class="block">Returns the sum of all summands of the given array.</div>
</td>
</tr>
<tr id="i118" class="altColor">
<tr id="i117" class="rowColor">
<td class="colFirst"><code>static boolean</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#tableExists(android.database.sqlite.SQLiteDatabase,java.lang.String)">tableExists</a></span>&#8203;(<a href="https://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html" title="class or interface in android.database.sqlite" class="externalLink" target="_top">SQLiteDatabase</a>&nbsp;database,
<a href="https://developer.android.com/reference/java/lang/String.html" title="class or interface in java.lang" class="externalLink" target="_top">String</a>&nbsp;tableName)</code></th>
@ -1186,21 +1175,21 @@ extends <a href="https://developer.android.com/reference/java/lang/Object.html"
<div class="block">Returns whether the table exists in the database.</div>
</td>
</tr>
<tr id="i119" class="rowColor">
<tr id="i118" class="altColor">
<td class="colFirst"><code>static byte[]</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#toByteArray(java.io.InputStream)">toByteArray</a></span>&#8203;(<a href="https://developer.android.com/reference/java/io/InputStream.html" title="class or interface in java.io" class="externalLink" target="_top">InputStream</a>&nbsp;inputStream)</code></th>
<td class="colLast">
<div class="block">Converts the entirety of an <a href="https://developer.android.com/reference/java/io/InputStream.html" title="class or interface in java.io" class="externalLink" target="_top"><code>InputStream</code></a> to a byte array.</div>
</td>
</tr>
<tr id="i120" class="altColor">
<tr id="i119" class="rowColor">
<td class="colFirst"><code>static <a href="https://developer.android.com/reference/java/lang/String.html" title="class or interface in java.lang" class="externalLink" target="_top">String</a></code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#toHexString(byte%5B%5D)">toHexString</a></span>&#8203;(byte[]&nbsp;bytes)</code></th>
<td class="colLast">
<div class="block">Returns a string containing a lower-case hex representation of the bytes provided.</div>
</td>
</tr>
<tr id="i121" class="rowColor">
<tr id="i120" class="altColor">
<td class="colFirst"><code>static long</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#toLong(int,int)">toLong</a></span>&#8203;(int&nbsp;mostSignificantBits,
int&nbsp;leastSignificantBits)</code></th>
@ -1208,14 +1197,14 @@ extends <a href="https://developer.android.com/reference/java/lang/Object.html"
<div class="block">Returns the long that is composed of the bits of the 2 specified integers.</div>
</td>
</tr>
<tr id="i122" class="altColor">
<tr id="i121" class="rowColor">
<td class="colFirst"><code>static long</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#toUnsignedLong(int)">toUnsignedLong</a></span>&#8203;(int&nbsp;x)</code></th>
<td class="colLast">
<div class="block">Converts an integer to a long by unsigned conversion.</div>
</td>
</tr>
<tr id="i123" class="rowColor">
<tr id="i122" class="altColor">
<td class="colFirst"><code>static &lt;T,&#8203;U&gt;<br><a href="https://guava.dev/releases/31.0.1-android/api/docs/com/google/common/util/concurrent/ListenableFuture.html?is-external=true" title="class or interface in com.google.common.util.concurrent" class="externalLink">ListenableFuture</a>&lt;T&gt;</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#transformFutureAsync(com.google.common.util.concurrent.ListenableFuture,com.google.common.util.concurrent.AsyncFunction)">transformFutureAsync</a></span>&#8203;(<a href="https://guava.dev/releases/31.0.1-android/api/docs/com/google/common/util/concurrent/ListenableFuture.html?is-external=true" title="class or interface in com.google.common.util.concurrent" class="externalLink">ListenableFuture</a>&lt;U&gt;&nbsp;future,
<a href="https://guava.dev/releases/31.0.1-android/api/docs/com/google/common/util/concurrent/AsyncFunction.html?is-external=true" title="class or interface in com.google.common.util.concurrent" class="externalLink">AsyncFunction</a>&lt;U,&#8203;T&gt;&nbsp;transformFunction)</code></th>
@ -1223,7 +1212,7 @@ extends <a href="https://developer.android.com/reference/java/lang/Object.html"
<div class="block">Asynchronously transforms the result of a <a href="https://guava.dev/releases/31.0.1-android/api/docs/com/google/common/util/concurrent/ListenableFuture.html?is-external=true" title="class or interface in com.google.common.util.concurrent" class="externalLink"><code>ListenableFuture</code></a>.</div>
</td>
</tr>
<tr id="i124" class="altColor">
<tr id="i123" class="rowColor">
<td class="colFirst"><code>static <a href="https://developer.android.com/reference/java/lang/CharSequence.html" title="class or interface in java.lang" class="externalLink" target="_top">CharSequence</a></code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#truncateAscii(java.lang.CharSequence,int)">truncateAscii</a></span>&#8203;(<a href="https://developer.android.com/reference/java/lang/CharSequence.html" title="class or interface in java.lang" class="externalLink" target="_top">CharSequence</a>&nbsp;sequence,
int&nbsp;maxLength)</code></th>
@ -1231,21 +1220,21 @@ extends <a href="https://developer.android.com/reference/java/lang/Object.html"
<div class="block">Truncates a sequence of ASCII characters to a maximum length.</div>
</td>
</tr>
<tr id="i125" class="rowColor">
<tr id="i124" class="altColor">
<td class="colFirst"><code>static <a href="https://developer.android.com/reference/java/lang/String.html" title="class or interface in java.lang" class="externalLink" target="_top">String</a></code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#unescapeFileName(java.lang.String)">unescapeFileName</a></span>&#8203;(<a href="https://developer.android.com/reference/java/lang/String.html" title="class or interface in java.lang" class="externalLink" target="_top">String</a>&nbsp;fileName)</code></th>
<td class="colLast">
<div class="block">Unescapes an escaped file or directory name back to its original value.</div>
</td>
</tr>
<tr id="i126" class="altColor">
<tr id="i125" class="rowColor">
<td class="colFirst"><code>static long</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#usToMs(long)">usToMs</a></span>&#8203;(long&nbsp;timeUs)</code></th>
<td class="colLast">
<div class="block">Converts a time in microseconds to the corresponding time in milliseconds, preserving <a href="../C.html#TIME_UNSET"><code>C.TIME_UNSET</code></a> and <a href="../C.html#TIME_END_OF_SOURCE"><code>C.TIME_END_OF_SOURCE</code></a> values.</div>
</td>
</tr>
<tr id="i127" class="rowColor">
<tr id="i126" class="altColor">
<td class="colFirst"><code>static void</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#writeBoolean(android.os.Parcel,boolean)">writeBoolean</a></span>&#8203;(<a href="https://developer.android.com/reference/android/os/Parcel.html" title="class or interface in android.os" class="externalLink" target="_top">Parcel</a>&nbsp;parcel,
boolean&nbsp;value)</code></th>
@ -1383,7 +1372,10 @@ public static&nbsp;<a href="https://developer.android.com/reference/android/cont
<a href="https://developer.android.com/reference/android/content/BroadcastReceiver.html" title="class or interface in android.content" class="externalLink" target="_top">BroadcastReceiver</a>&nbsp;receiver,
<a href="https://developer.android.com/reference/android/content/IntentFilter.html" title="class or interface in android.content" class="externalLink" target="_top">IntentFilter</a>&nbsp;filter)</pre>
<div class="block">Registers a <a href="https://developer.android.com/reference/android/content/BroadcastReceiver.html" title="class or interface in android.content" class="externalLink" target="_top"><code>BroadcastReceiver</code></a> that's not intended to receive broadcasts from other
apps. This will be enforced by specifying <a href="https://developer.android.com/reference/android/content/Context.html#RECEIVER_NOT_EXPORTED" title="class or interface in android.content" class="externalLink"><code>Context.RECEIVER_NOT_EXPORTED</code></a> if <a href="#SDK_INT" target="_top"><code>SDK_INT</code></a> is 33 or above.</div>
apps. This will be enforced by specifying <a href="https://developer.android.com/reference/android/content/Context.html#RECEIVER_NOT_EXPORTED" title="class or interface in android.content" class="externalLink"><code>Context.RECEIVER_NOT_EXPORTED</code></a> if <a href="#SDK_INT" target="_top"><code>SDK_INT</code></a> is 33 or above.
<p>Do not use this method if registering a receiver for a <a href="https://android.googlesource.com/platform/frameworks/base/+/master/core/res/AndroidManifest.xml">protected
system broadcast</a>.</div>
<dl>
<dt><span class="paramLabel">Parameters:</span></dt>
<dd><code>context</code> - The context on which <a href="https://developer.android.com/reference/android/content/Context.html#registerReceiver(android.content.BroadcastReceiver,android.content.IntentFilter)" title="class or interface in android.content" class="externalLink" target="_top"><code>Context.registerReceiver(android.content.BroadcastReceiver, android.content.IntentFilter)</code></a> will be called.</dd>
@ -1394,30 +1386,6 @@ public static&nbsp;<a href="https://developer.android.com/reference/android/cont
</dl>
</li>
</ul>
<a id="registerReceiverNotExported(android.content.Context,android.content.BroadcastReceiver,android.content.IntentFilter,android.os.Handler)">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>registerReceiverNotExported</h4>
<pre class="methodSignature">@Nullable
public static&nbsp;<a href="https://developer.android.com/reference/android/content/Intent.html" title="class or interface in android.content" class="externalLink">Intent</a>&nbsp;registerReceiverNotExported&#8203;(<a href="https://developer.android.com/reference/android/content/Context.html?is-external=true" title="class or interface in android.content" class="externalLink" target="_top">Context</a>&nbsp;context,
<a href="https://developer.android.com/reference/android/content/BroadcastReceiver.html" title="class or interface in android.content" class="externalLink" target="_top">BroadcastReceiver</a>&nbsp;receiver,
<a href="https://developer.android.com/reference/android/content/IntentFilter.html" title="class or interface in android.content" class="externalLink" target="_top">IntentFilter</a>&nbsp;filter,
<a href="https://developer.android.com/reference/android/os/Handler.html" title="class or interface in android.os" class="externalLink" target="_top">Handler</a>&nbsp;handler)</pre>
<div class="block">Registers a <a href="https://developer.android.com/reference/android/content/BroadcastReceiver.html" title="class or interface in android.content" class="externalLink" target="_top"><code>BroadcastReceiver</code></a> that's not intended to receive broadcasts from other
apps. This will be enforced by specifying <a href="https://developer.android.com/reference/android/content/Context.html#RECEIVER_NOT_EXPORTED" title="class or interface in android.content" class="externalLink"><code>Context.RECEIVER_NOT_EXPORTED</code></a> if <a href="#SDK_INT" target="_top"><code>SDK_INT</code></a> is 33 or above.</div>
<dl>
<dt><span class="paramLabel">Parameters:</span></dt>
<dd><code>context</code> - The context on which <a href="https://developer.android.com/reference/android/content/Context.html#registerReceiver(android.content.BroadcastReceiver,android.content.IntentFilter)" title="class or interface in android.content" class="externalLink" target="_top"><code>Context.registerReceiver(android.content.BroadcastReceiver, android.content.IntentFilter)</code></a> will be called.</dd>
<dd><code>receiver</code> - The <a href="https://developer.android.com/reference/android/content/BroadcastReceiver.html" title="class or interface in android.content" class="externalLink" target="_top"><code>BroadcastReceiver</code></a> to register. This value may be null.</dd>
<dd><code>filter</code> - Selects the Intent broadcasts to be received.</dd>
<dd><code>handler</code> - Handler identifying the thread that will receive the Intent.</dd>
<dt><span class="returnLabel">Returns:</span></dt>
<dd>The first sticky intent found that matches <code>filter</code>, or null if there are none.</dd>
</dl>
</li>
</ul>
<a id="startForegroundService(android.content.Context,android.content.Intent)">
<!-- -->
</a>

View file

@ -1946,21 +1946,21 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
<!-- -->
</a><code>public&nbsp;static&nbsp;final&nbsp;<a href="https://developer.android.com/reference/java/lang/String.html" title="class or interface in java.lang" class="externalLink" target="_top">String</a></code></td>
<th class="colSecond" scope="row"><code><a href="com/google/android/exoplayer2/ExoPlayerLibraryInfo.html#VERSION">VERSION</a></code></th>
<td class="colLast"><code>"2.18.3"</code></td>
<td class="colLast"><code>"2.18.4"</code></td>
</tr>
<tr class="altColor">
<td class="colFirst"><a id="com.google.android.exoplayer2.ExoPlayerLibraryInfo.VERSION_INT">
<!-- -->
</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
<th class="colSecond" scope="row"><code><a href="com/google/android/exoplayer2/ExoPlayerLibraryInfo.html#VERSION_INT">VERSION_INT</a></code></th>
<td class="colLast"><code>2018003</code></td>
<td class="colLast"><code>2018004</code></td>
</tr>
<tr class="rowColor">
<td class="colFirst"><a id="com.google.android.exoplayer2.ExoPlayerLibraryInfo.VERSION_SLASHY">
<!-- -->
</a><code>public&nbsp;static&nbsp;final&nbsp;<a href="https://developer.android.com/reference/java/lang/String.html" title="class or interface in java.lang" class="externalLink" target="_top">String</a></code></td>
<th class="colSecond" scope="row"><code><a href="com/google/android/exoplayer2/ExoPlayerLibraryInfo.html#VERSION_SLASHY">VERSION_SLASHY</a></code></th>
<td class="colLast"><code>"ExoPlayerLib/2.18.3"</code></td>
<td class="colLast"><code>"ExoPlayerLib/2.18.4"</code></td>
</tr>
</tbody>
</table>
@ -7453,6 +7453,25 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
</tbody>
</table>
</li>
<li class="blockList">
<table class="constantsSummary">
<caption><span>com.google.android.exoplayer2.offline.<a href="com/google/android/exoplayer2/offline/SegmentDownloader.html" title="class in com.google.android.exoplayer2.offline">SegmentDownloader</a>&lt;<a href="com/google/android/exoplayer2/offline/SegmentDownloader.html" title="type parameter in SegmentDownloader">M</a> extends <a href="com/google/android/exoplayer2/offline/FilterableManifest.html" title="interface in com.google.android.exoplayer2.offline">FilterableManifest</a>&lt;<a href="com/google/android/exoplayer2/offline/SegmentDownloader.html" title="type parameter in SegmentDownloader">M</a>&gt;&gt;</span><span class="tabEnd">&nbsp;</span></caption>
<tr>
<th class="colFirst" scope="col">Modifier and Type</th>
<th class="colSecond" scope="col">Constant Field</th>
<th class="colLast" scope="col">Value</th>
</tr>
<tbody>
<tr class="altColor">
<td class="colFirst"><a id="com.google.android.exoplayer2.offline.SegmentDownloader.DEFAULT_MAX_MERGED_SEGMENT_START_TIME_DIFF_MS">
<!-- -->
</a><code>public&nbsp;static&nbsp;final&nbsp;long</code></td>
<th class="colSecond" scope="row"><code><a href="com/google/android/exoplayer2/offline/SegmentDownloader.html#DEFAULT_MAX_MERGED_SEGMENT_START_TIME_DIFF_MS">DEFAULT_MAX_MERGED_SEGMENT_START_TIME_DIFF_MS</a></code></th>
<td class="colLast"><code>20000L</code></td>
</tr>
</tbody>
</table>
</li>
</ul>
<ul class="blockList">
<li class="blockList">

View file

@ -2293,37 +2293,65 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
</td>
</tr>
<tr class="rowColor">
<th class="colDeprecatedItemName" scope="row"><a href="com/google/android/exoplayer2/offline/SegmentDownloader.html#%3Cinit%3E(com.google.android.exoplayer2.MediaItem,com.google.android.exoplayer2.upstream.ParsingLoadable.Parser,com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory,java.util.concurrent.Executor)">com.google.android.exoplayer2.offline.SegmentDownloader&#8203;(MediaItem, ParsingLoadable.Parser&lt;M&gt;, CacheDataSource.Factory, Executor)</a></th>
<td class="colLast">
<div class="deprecationComment">Use <a href="com/google/android/exoplayer2/offline/SegmentDownloader.html#%3Cinit%3E(com.google.android.exoplayer2.MediaItem,com.google.android.exoplayer2.upstream.ParsingLoadable.Parser,com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory,java.util.concurrent.Executor,long)"><code>SegmentDownloader(MediaItem, Parser,
CacheDataSource.Factory, Executor, long)</code></a> instead.</div>
</td>
</tr>
<tr class="altColor">
<th class="colDeprecatedItemName" scope="row"><a href="com/google/android/exoplayer2/Player.PositionInfo.html#%3Cinit%3E(java.lang.Object,int,java.lang.Object,int,long,long,int,int)">com.google.android.exoplayer2.Player.PositionInfo&#8203;(Object, int, Object, int, long, long, int, int)</a></th>
<td class="colLast">
<div class="deprecationComment">Use <a href="com/google/android/exoplayer2/Player.PositionInfo.html#%3Cinit%3E(java.lang.Object,int,com.google.android.exoplayer2.MediaItem,java.lang.Object,int,long,long,int,int)"><code>PositionInfo(Object, int, MediaItem, Object, int, long, long, int,
int)</code></a> instead.</div>
</td>
</tr>
<tr class="altColor">
<tr class="rowColor">
<th class="colDeprecatedItemName" scope="row"><a href="com/google/android/exoplayer2/SimpleExoPlayer.html#%3Cinit%3E(android.content.Context,com.google.android.exoplayer2.RenderersFactory,com.google.android.exoplayer2.trackselection.TrackSelector,com.google.android.exoplayer2.source.MediaSource.Factory,com.google.android.exoplayer2.LoadControl,com.google.android.exoplayer2.upstream.BandwidthMeter,com.google.android.exoplayer2.analytics.AnalyticsCollector,boolean,com.google.android.exoplayer2.util.Clock,android.os.Looper)">com.google.android.exoplayer2.SimpleExoPlayer&#8203;(Context, RenderersFactory, TrackSelector, MediaSource.Factory, LoadControl, BandwidthMeter, AnalyticsCollector, boolean, Clock, Looper)</a></th>
<td class="colLast">
<div class="deprecationComment">Use the <a href="com/google/android/exoplayer2/ExoPlayer.Builder.html" title="class in com.google.android.exoplayer2"><code>ExoPlayer.Builder</code></a>.</div>
</td>
</tr>
<tr class="rowColor">
<tr class="altColor">
<th class="colDeprecatedItemName" scope="row"><a href="com/google/android/exoplayer2/SimpleExoPlayer.Builder.html#%3Cinit%3E(android.content.Context)">com.google.android.exoplayer2.SimpleExoPlayer.Builder&#8203;(Context)</a></th>
<td class="colLast">
<div class="deprecationComment">Use <a href="com/google/android/exoplayer2/ExoPlayer.Builder.html#%3Cinit%3E(android.content.Context)"><code>Builder(Context)</code></a> instead.</div>
</td>
</tr>
<tr class="rowColor">
<th class="colDeprecatedItemName" scope="row"><a href="com/google/android/exoplayer2/source/dash/offline/DashDownloader.html#%3Cinit%3E(com.google.android.exoplayer2.MediaItem,com.google.android.exoplayer2.upstream.ParsingLoadable.Parser,com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory,java.util.concurrent.Executor)">com.google.android.exoplayer2.source.dash.offline.DashDownloader&#8203;(MediaItem, ParsingLoadable.Parser&lt;DashManifest&gt;, CacheDataSource.Factory, Executor)</a></th>
<td class="colLast">
<div class="deprecationComment">Use <a href="com/google/android/exoplayer2/source/dash/offline/DashDownloader.html#%3Cinit%3E(com.google.android.exoplayer2.MediaItem,com.google.android.exoplayer2.upstream.ParsingLoadable.Parser,com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory,java.util.concurrent.Executor,long)"><code>DashDownloader(MediaItem, Parser,
CacheDataSource.Factory, Executor, long)</code></a> instead.</div>
</td>
</tr>
<tr class="altColor">
<th class="colDeprecatedItemName" scope="row"><a href="com/google/android/exoplayer2/source/hls/offline/HlsDownloader.html#%3Cinit%3E(com.google.android.exoplayer2.MediaItem,com.google.android.exoplayer2.upstream.ParsingLoadable.Parser,com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory,java.util.concurrent.Executor)">com.google.android.exoplayer2.source.hls.offline.HlsDownloader&#8203;(MediaItem, ParsingLoadable.Parser&lt;HlsPlaylist&gt;, CacheDataSource.Factory, Executor)</a></th>
<td class="colLast">
<div class="deprecationComment">Use <a href="com/google/android/exoplayer2/source/hls/offline/HlsDownloader.html#%3Cinit%3E(com.google.android.exoplayer2.MediaItem,com.google.android.exoplayer2.upstream.ParsingLoadable.Parser,com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory,java.util.concurrent.Executor,long)"><code>HlsDownloader(MediaItem, Parser, CacheDataSource.Factory,
Executor, long)</code></a> instead.</div>
</td>
</tr>
<tr class="rowColor">
<th class="colDeprecatedItemName" scope="row"><a href="com/google/android/exoplayer2/source/hls/playlist/HlsMasterPlaylist.html#%3Cinit%3E(java.lang.String,java.util.List,java.util.List,java.util.List,java.util.List,java.util.List,java.util.List,com.google.android.exoplayer2.Format,java.util.List,boolean,java.util.Map,java.util.List)">com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist&#8203;(String, List&lt;String&gt;, List&lt;HlsMultivariantPlaylist.Variant&gt;, List&lt;HlsMultivariantPlaylist.Rendition&gt;, List&lt;HlsMultivariantPlaylist.Rendition&gt;, List&lt;HlsMultivariantPlaylist.Rendition&gt;, List&lt;HlsMultivariantPlaylist.Rendition&gt;, Format, List&lt;Format&gt;, boolean, Map&lt;String, String&gt;, List&lt;DrmInitData&gt;)</a></th>
<td class="colLast">
<div class="deprecationComment">Use <a href="com/google/android/exoplayer2/source/hls/playlist/HlsMultivariantPlaylist.html#%3Cinit%3E(java.lang.String,java.util.List,java.util.List,java.util.List,java.util.List,java.util.List,java.util.List,com.google.android.exoplayer2.Format,java.util.List,boolean,java.util.Map,java.util.List)"><code>HlsMultivariantPlaylist(java.lang.String, java.util.List&lt;java.lang.String&gt;, java.util.List&lt;com.google.android.exoplayer2.source.hls.playlist.HlsMultivariantPlaylist.Variant&gt;, java.util.List&lt;com.google.android.exoplayer2.source.hls.playlist.HlsMultivariantPlaylist.Rendition&gt;, java.util.List&lt;com.google.android.exoplayer2.source.hls.playlist.HlsMultivariantPlaylist.Rendition&gt;, java.util.List&lt;com.google.android.exoplayer2.source.hls.playlist.HlsMultivariantPlaylist.Rendition&gt;, java.util.List&lt;com.google.android.exoplayer2.source.hls.playlist.HlsMultivariantPlaylist.Rendition&gt;, com.google.android.exoplayer2.Format, java.util.List&lt;com.google.android.exoplayer2.Format&gt;, boolean, java.util.Map&lt;java.lang.String, java.lang.String&gt;, java.util.List&lt;com.google.android.exoplayer2.drm.DrmInitData&gt;)</code></a> instead.</div>
</td>
</tr>
<tr class="rowColor">
<tr class="altColor">
<th class="colDeprecatedItemName" scope="row"><a href="com/google/android/exoplayer2/source/SinglePeriodTimeline.html#%3Cinit%3E(long,boolean,boolean,boolean,java.lang.Object,java.lang.Object)">com.google.android.exoplayer2.source.SinglePeriodTimeline&#8203;(long, boolean, boolean, boolean, Object, Object)</a></th>
<td class="colLast">
<div class="deprecationComment">Use <a href="com/google/android/exoplayer2/source/SinglePeriodTimeline.html#%3Cinit%3E(long,boolean,boolean,boolean,java.lang.Object,com.google.android.exoplayer2.MediaItem)"><code>SinglePeriodTimeline(long, boolean, boolean, boolean, Object,
MediaItem)</code></a> instead.</div>
</td>
</tr>
<tr class="rowColor">
<th class="colDeprecatedItemName" scope="row"><a href="com/google/android/exoplayer2/source/smoothstreaming/offline/SsDownloader.html#%3Cinit%3E(com.google.android.exoplayer2.MediaItem,com.google.android.exoplayer2.upstream.ParsingLoadable.Parser,com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory,java.util.concurrent.Executor)">com.google.android.exoplayer2.source.smoothstreaming.offline.SsDownloader&#8203;(MediaItem, ParsingLoadable.Parser&lt;SsManifest&gt;, CacheDataSource.Factory, Executor)</a></th>
<td class="colLast">
<div class="deprecationComment">Use <a href="com/google/android/exoplayer2/source/smoothstreaming/offline/SsDownloader.html#%3Cinit%3E(com.google.android.exoplayer2.MediaItem,com.google.android.exoplayer2.upstream.ParsingLoadable.Parser,com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory,java.util.concurrent.Executor,long)"><code>SsDownloader(MediaItem, Parser, CacheDataSource.Factory,
Executor, long)</code></a> instead.</div>
</td>
</tr>
<tr class="altColor">
<th class="colDeprecatedItemName" scope="row"><a href="com/google/android/exoplayer2/testutil/FakeExoMediaDrm.html#%3Cinit%3E()">com.google.android.exoplayer2.testutil.FakeExoMediaDrm()</a></th>
<td class="colLast">

View file

@ -7635,6 +7635,13 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
</dd>
<dt><span class="memberNameLink"><a href="com/google/android/exoplayer2/source/dash/offline/DashDownloader.html#%3Cinit%3E(com.google.android.exoplayer2.MediaItem,com.google.android.exoplayer2.upstream.ParsingLoadable.Parser,com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory,java.util.concurrent.Executor)">DashDownloader(MediaItem, ParsingLoadable.Parser&lt;DashManifest&gt;, CacheDataSource.Factory, Executor)</a></span> - Constructor for class com.google.android.exoplayer2.source.dash.offline.<a href="com/google/android/exoplayer2/source/dash/offline/DashDownloader.html" title="class in com.google.android.exoplayer2.source.dash.offline">DashDownloader</a></dt>
<dd>
<div class="deprecationBlock"><span class="deprecatedLabel">Deprecated.</span>
<div class="deprecationComment">Use <a href="com/google/android/exoplayer2/source/dash/offline/DashDownloader.html#%3Cinit%3E(com.google.android.exoplayer2.MediaItem,com.google.android.exoplayer2.upstream.ParsingLoadable.Parser,com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory,java.util.concurrent.Executor,long)"><code>DashDownloader(MediaItem, Parser,
CacheDataSource.Factory, Executor, long)</code></a> instead.</div>
</div>
</dd>
<dt><span class="memberNameLink"><a href="com/google/android/exoplayer2/source/dash/offline/DashDownloader.html#%3Cinit%3E(com.google.android.exoplayer2.MediaItem,com.google.android.exoplayer2.upstream.ParsingLoadable.Parser,com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory,java.util.concurrent.Executor,long)">DashDownloader(MediaItem, ParsingLoadable.Parser&lt;DashManifest&gt;, CacheDataSource.Factory, Executor, long)</a></span> - Constructor for class com.google.android.exoplayer2.source.dash.offline.<a href="com/google/android/exoplayer2/source/dash/offline/DashDownloader.html" title="class in com.google.android.exoplayer2.source.dash.offline">DashDownloader</a></dt>
<dd>
<div class="block">Creates a new instance.</div>
</dd>
<dt><a href="com/google/android/exoplayer2/source/dash/manifest/DashManifest.html" title="class in com.google.android.exoplayer2.source.dash.manifest"><span class="typeNameLink">DashManifest</span></a> - Class in <a href="com/google/android/exoplayer2/source/dash/manifest/package-summary.html">com.google.android.exoplayer2.source.dash.manifest</a></dt>
@ -8535,6 +8542,8 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
<div class="block">The default maximum difference between the current live offset and the target live offset, in
milliseconds, for which unit speed (1.0f) is used.</div>
</dd>
<dt><span class="memberNameLink"><a href="com/google/android/exoplayer2/offline/SegmentDownloader.html#DEFAULT_MAX_MERGED_SEGMENT_START_TIME_DIFF_MS">DEFAULT_MAX_MERGED_SEGMENT_START_TIME_DIFF_MS</a></span> - Static variable in class com.google.android.exoplayer2.offline.<a href="com/google/android/exoplayer2/offline/SegmentDownloader.html" title="class in com.google.android.exoplayer2.offline">SegmentDownloader</a></dt>
<dd>&nbsp;</dd>
<dt><span class="memberNameLink"><a href="com/google/android/exoplayer2/upstream/UdpDataSource.html#DEFAULT_MAX_PACKET_SIZE">DEFAULT_MAX_PACKET_SIZE</a></span> - Static variable in class com.google.android.exoplayer2.upstream.<a href="com/google/android/exoplayer2/upstream/UdpDataSource.html" title="class in com.google.android.exoplayer2.upstream">UdpDataSource</a></dt>
<dd>
<div class="block">The default maximum datagram packet size, in bytes.</div>
@ -14114,7 +14123,7 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
<dd>&nbsp;</dd>
<dt><a href="com/google/android/exoplayer2/ForwardingPlayer.html" title="class in com.google.android.exoplayer2"><span class="typeNameLink">ForwardingPlayer</span></a> - Class in <a href="com/google/android/exoplayer2/package-summary.html">com.google.android.exoplayer2</a></dt>
<dd>
<div class="block">A <a href="com/google/android/exoplayer2/Player.html" title="interface in com.google.android.exoplayer2"><code>Player</code></a> that forwards operations to another <a href="com/google/android/exoplayer2/Player.html" title="interface in com.google.android.exoplayer2"><code>Player</code></a>.</div>
<div class="block">A <a href="com/google/android/exoplayer2/Player.html" title="interface in com.google.android.exoplayer2"><code>Player</code></a> that forwards method calls to another <a href="com/google/android/exoplayer2/Player.html" title="interface in com.google.android.exoplayer2"><code>Player</code></a>.</div>
</dd>
<dt><span class="memberNameLink"><a href="com/google/android/exoplayer2/ForwardingPlayer.html#%3Cinit%3E(com.google.android.exoplayer2.Player)">ForwardingPlayer(Player)</a></span> - Constructor for class com.google.android.exoplayer2.<a href="com/google/android/exoplayer2/ForwardingPlayer.html" title="class in com.google.android.exoplayer2">ForwardingPlayer</a></dt>
<dd>
@ -20927,6 +20936,13 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
</dd>
<dt><span class="memberNameLink"><a href="com/google/android/exoplayer2/source/hls/offline/HlsDownloader.html#%3Cinit%3E(com.google.android.exoplayer2.MediaItem,com.google.android.exoplayer2.upstream.ParsingLoadable.Parser,com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory,java.util.concurrent.Executor)">HlsDownloader(MediaItem, ParsingLoadable.Parser&lt;HlsPlaylist&gt;, CacheDataSource.Factory, Executor)</a></span> - Constructor for class com.google.android.exoplayer2.source.hls.offline.<a href="com/google/android/exoplayer2/source/hls/offline/HlsDownloader.html" title="class in com.google.android.exoplayer2.source.hls.offline">HlsDownloader</a></dt>
<dd>
<div class="deprecationBlock"><span class="deprecatedLabel">Deprecated.</span>
<div class="deprecationComment">Use <a href="com/google/android/exoplayer2/source/hls/offline/HlsDownloader.html#%3Cinit%3E(com.google.android.exoplayer2.MediaItem,com.google.android.exoplayer2.upstream.ParsingLoadable.Parser,com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory,java.util.concurrent.Executor,long)"><code>HlsDownloader(MediaItem, Parser, CacheDataSource.Factory,
Executor, long)</code></a> instead.</div>
</div>
</dd>
<dt><span class="memberNameLink"><a href="com/google/android/exoplayer2/source/hls/offline/HlsDownloader.html#%3Cinit%3E(com.google.android.exoplayer2.MediaItem,com.google.android.exoplayer2.upstream.ParsingLoadable.Parser,com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory,java.util.concurrent.Executor,long)">HlsDownloader(MediaItem, ParsingLoadable.Parser&lt;HlsPlaylist&gt;, CacheDataSource.Factory, Executor, long)</a></span> - Constructor for class com.google.android.exoplayer2.source.hls.offline.<a href="com/google/android/exoplayer2/source/hls/offline/HlsDownloader.html" title="class in com.google.android.exoplayer2.source.hls.offline">HlsDownloader</a></dt>
<dd>
<div class="block">Creates a new instance.</div>
</dd>
<dt><a href="com/google/android/exoplayer2/source/hls/HlsExtractorFactory.html" title="interface in com.google.android.exoplayer2.source.hls"><span class="typeNameLink">HlsExtractorFactory</span></a> - Interface in <a href="com/google/android/exoplayer2/source/hls/package-summary.html">com.google.android.exoplayer2.source.hls</a></dt>
@ -31679,11 +31695,6 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
<div class="block">Registers a <a href="https://developer.android.com/reference/android/content/BroadcastReceiver.html" title="class or interface in android.content" class="externalLink" target="_top"><code>BroadcastReceiver</code></a> that's not intended to receive broadcasts from other
apps.</div>
</dd>
<dt><span class="memberNameLink"><a href="com/google/android/exoplayer2/util/Util.html#registerReceiverNotExported(android.content.Context,android.content.BroadcastReceiver,android.content.IntentFilter,android.os.Handler)">registerReceiverNotExported(Context, BroadcastReceiver, IntentFilter, Handler)</a></span> - Static method in class com.google.android.exoplayer2.util.<a href="com/google/android/exoplayer2/util/Util.html" title="class in com.google.android.exoplayer2.util">Util</a></dt>
<dd>
<div class="block">Registers a <a href="https://developer.android.com/reference/android/content/BroadcastReceiver.html" title="class or interface in android.content" class="externalLink" target="_top"><code>BroadcastReceiver</code></a> that's not intended to receive broadcasts from other
apps.</div>
</dd>
<dt><span class="memberNameLink"><a href="com/google/android/exoplayer2/upstream/HttpDataSource.html#REJECT_PAYWALL_TYPES">REJECT_PAYWALL_TYPES</a></span> - Static variable in interface com.google.android.exoplayer2.upstream.<a href="com/google/android/exoplayer2/upstream/HttpDataSource.html" title="interface in com.google.android.exoplayer2.upstream">HttpDataSource</a></dt>
<dd>
<div class="block">A <a href="https://guava.dev/releases/31.0.1-android/api/docs/com/google/common/base/Predicate.html?is-external=true" title="class or interface in com.google.common.base" class="externalLink"><code>Predicate</code></a> that rejects content types often used for pay-walls.</div>
@ -34367,6 +34378,13 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
<div class="block">Base class for multi segment stream downloaders.</div>
</dd>
<dt><span class="memberNameLink"><a href="com/google/android/exoplayer2/offline/SegmentDownloader.html#%3Cinit%3E(com.google.android.exoplayer2.MediaItem,com.google.android.exoplayer2.upstream.ParsingLoadable.Parser,com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory,java.util.concurrent.Executor)">SegmentDownloader(MediaItem, ParsingLoadable.Parser&lt;M&gt;, CacheDataSource.Factory, Executor)</a></span> - Constructor for class com.google.android.exoplayer2.offline.<a href="com/google/android/exoplayer2/offline/SegmentDownloader.html" title="class in com.google.android.exoplayer2.offline">SegmentDownloader</a></dt>
<dd>
<div class="deprecationBlock"><span class="deprecatedLabel">Deprecated.</span>
<div class="deprecationComment">Use <a href="com/google/android/exoplayer2/offline/SegmentDownloader.html#%3Cinit%3E(com.google.android.exoplayer2.MediaItem,com.google.android.exoplayer2.upstream.ParsingLoadable.Parser,com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory,java.util.concurrent.Executor,long)"><code>SegmentDownloader(MediaItem, Parser,
CacheDataSource.Factory, Executor, long)</code></a> instead.</div>
</div>
</dd>
<dt><span class="memberNameLink"><a href="com/google/android/exoplayer2/offline/SegmentDownloader.html#%3Cinit%3E(com.google.android.exoplayer2.MediaItem,com.google.android.exoplayer2.upstream.ParsingLoadable.Parser,com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory,java.util.concurrent.Executor,long)">SegmentDownloader(MediaItem, ParsingLoadable.Parser&lt;M&gt;, CacheDataSource.Factory, Executor, long)</a></span> - Constructor for class com.google.android.exoplayer2.offline.<a href="com/google/android/exoplayer2/offline/SegmentDownloader.html" title="class in com.google.android.exoplayer2.offline">SegmentDownloader</a></dt>
<dd>&nbsp;</dd>
<dt><a href="com/google/android/exoplayer2/offline/SegmentDownloader.Segment.html" title="class in com.google.android.exoplayer2.offline"><span class="typeNameLink">SegmentDownloader.Segment</span></a> - Class in <a href="com/google/android/exoplayer2/offline/package-summary.html">com.google.android.exoplayer2.offline</a></dt>
<dd>
@ -41010,6 +41028,13 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
</dd>
<dt><span class="memberNameLink"><a href="com/google/android/exoplayer2/source/smoothstreaming/offline/SsDownloader.html#%3Cinit%3E(com.google.android.exoplayer2.MediaItem,com.google.android.exoplayer2.upstream.ParsingLoadable.Parser,com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory,java.util.concurrent.Executor)">SsDownloader(MediaItem, ParsingLoadable.Parser&lt;SsManifest&gt;, CacheDataSource.Factory, Executor)</a></span> - Constructor for class com.google.android.exoplayer2.source.smoothstreaming.offline.<a href="com/google/android/exoplayer2/source/smoothstreaming/offline/SsDownloader.html" title="class in com.google.android.exoplayer2.source.smoothstreaming.offline">SsDownloader</a></dt>
<dd>
<div class="deprecationBlock"><span class="deprecatedLabel">Deprecated.</span>
<div class="deprecationComment">Use <a href="com/google/android/exoplayer2/source/smoothstreaming/offline/SsDownloader.html#%3Cinit%3E(com.google.android.exoplayer2.MediaItem,com.google.android.exoplayer2.upstream.ParsingLoadable.Parser,com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory,java.util.concurrent.Executor,long)"><code>SsDownloader(MediaItem, Parser, CacheDataSource.Factory,
Executor, long)</code></a> instead.</div>
</div>
</dd>
<dt><span class="memberNameLink"><a href="com/google/android/exoplayer2/source/smoothstreaming/offline/SsDownloader.html#%3Cinit%3E(com.google.android.exoplayer2.MediaItem,com.google.android.exoplayer2.upstream.ParsingLoadable.Parser,com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory,java.util.concurrent.Executor,long)">SsDownloader(MediaItem, ParsingLoadable.Parser&lt;SsManifest&gt;, CacheDataSource.Factory, Executor, long)</a></span> - Constructor for class com.google.android.exoplayer2.source.smoothstreaming.offline.<a href="com/google/android/exoplayer2/source/smoothstreaming/offline/SsDownloader.html" title="class in com.google.android.exoplayer2.source.smoothstreaming.offline">SsDownloader</a></dt>
<dd>
<div class="block">Creates a new instance.</div>
</dd>
<dt><a href="com/google/android/exoplayer2/source/smoothstreaming/manifest/SsManifest.html" title="class in com.google.android.exoplayer2.source.smoothstreaming.manifest"><span class="typeNameLink">SsManifest</span></a> - Class in <a href="com/google/android/exoplayer2/source/smoothstreaming/manifest/package-summary.html">com.google.android.exoplayer2.source.smoothstreaming.manifest</a></dt>
@ -44697,7 +44722,7 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
</dd>
<dt><a href="com/google/android/exoplayer2/text/webvtt/WebvttCssStyle.html" title="class in com.google.android.exoplayer2.text.webvtt"><span class="typeNameLink">WebvttCssStyle</span></a> - Class in <a href="com/google/android/exoplayer2/text/webvtt/package-summary.html">com.google.android.exoplayer2.text.webvtt</a></dt>
<dd>
<div class="block">Style object of a Css style block in a Webvtt file.</div>
<div class="block">Style object of a CSS style block in a WebVTT file.</div>
</dd>
<dt><span class="memberNameLink"><a href="com/google/android/exoplayer2/text/webvtt/WebvttCssStyle.html#%3Cinit%3E()">WebvttCssStyle()</a></span> - Constructor for class com.google.android.exoplayer2.text.webvtt.<a href="com/google/android/exoplayer2/text/webvtt/WebvttCssStyle.html" title="class in com.google.android.exoplayer2.text.webvtt">WebvttCssStyle</a></dt>
<dd>&nbsp;</dd>

File diff suppressed because one or more lines are too long

View file

@ -1235,6 +1235,7 @@ public final class CastPlayer extends BasePlayer {
int receiverAppStatus = remoteMediaClient.getPlayerState();
switch (receiverAppStatus) {
case MediaStatus.PLAYER_STATE_BUFFERING:
case MediaStatus.PLAYER_STATE_LOADING:
return STATE_BUFFERING;
case MediaStatus.PLAYER_STATE_PLAYING:
case MediaStatus.PLAYER_STATE_PAUSED:
@ -1297,6 +1298,7 @@ public final class CastPlayer extends BasePlayer {
return false;
}
@SuppressWarnings("VisibleForTests")
private static int getCastRepeatMode(@RepeatMode int repeatMode) {
switch (repeatMode) {
case REPEAT_MODE_ONE:

View file

@ -552,11 +552,10 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
StreamManagerLoadable streamManagerLoadable =
new StreamManagerLoadable(
sdkAdsLoader,
adsLoader.configuration,
/* imaServerSideAdInsertionMediaSource= */ this,
streamRequest,
streamPlayer,
applicationAdErrorListener,
loadVideoTimeoutMs);
applicationAdErrorListener);
loader.startLoading(
streamManagerLoadable,
new StreamManagerLoadableCallback(),
@ -631,7 +630,6 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
}
this.streamManager.removeAdEventListener(componentListener);
this.streamManager.destroy();
this.streamManager = null;
}
this.streamManager = streamManager;
if (streamManager != null) {
@ -642,6 +640,12 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
if (applicationAdErrorListener != null) {
streamManager.addAdErrorListener(applicationAdErrorListener);
}
AdsRenderingSettings adsRenderingSettings =
ImaSdkFactory.getInstance().createAdsRenderingSettings();
adsRenderingSettings.setLoadVideoTimeout(loadVideoTimeoutMs);
adsRenderingSettings.setFocusSkipButtonWhenAvailable(
adsLoader.configuration.focusSkipButtonWhenAvailable);
streamManager.init(adsRenderingSettings);
}
}
@ -950,7 +954,6 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
@Override
public void onLoadCompleted(
StreamManagerLoadable loadable, long elapsedRealtimeMs, long loadDurationMs) {
mainHandler.post(() -> setStreamManager(checkNotNull(loadable.getStreamManager())));
setContentUri(checkNotNull(loadable.getContentUri()));
}
@ -981,14 +984,12 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
implements Loadable, AdsLoadedListener, AdErrorListener {
private final com.google.ads.interactivemedia.v3.api.AdsLoader adsLoader;
private final ServerSideAdInsertionConfiguration serverSideAdInsertionConfiguration;
private final ImaServerSideAdInsertionMediaSource imaServerSideAdInsertionMediaSource;
private final StreamRequest request;
private final StreamPlayer streamPlayer;
@Nullable private final AdErrorListener adErrorListener;
private final int loadVideoTimeoutMs;
private final ConditionVariable conditionVariable;
@Nullable private volatile StreamManager streamManager;
@Nullable private volatile Uri contentUri;
private volatile boolean cancelled;
private volatile boolean error;
@ -998,17 +999,15 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
/** Creates an instance. */
private StreamManagerLoadable(
com.google.ads.interactivemedia.v3.api.AdsLoader adsLoader,
ServerSideAdInsertionConfiguration serverSideAdInsertionConfiguration,
ImaServerSideAdInsertionMediaSource imaServerSideAdInsertionMediaSource,
StreamRequest request,
StreamPlayer streamPlayer,
@Nullable AdErrorListener adErrorListener,
int loadVideoTimeoutMs) {
@Nullable AdErrorListener adErrorListener) {
this.adsLoader = adsLoader;
this.serverSideAdInsertionConfiguration = serverSideAdInsertionConfiguration;
this.imaServerSideAdInsertionMediaSource = imaServerSideAdInsertionMediaSource;
this.request = request;
this.streamPlayer = streamPlayer;
this.adErrorListener = adErrorListener;
this.loadVideoTimeoutMs = loadVideoTimeoutMs;
conditionVariable = new ConditionVariable();
errorCode = -1;
}
@ -1019,12 +1018,6 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
return contentUri;
}
/** Returns the stream manager or null if not yet loaded. */
@Nullable
public StreamManager getStreamManager() {
return streamManager;
}
// Implement Loadable.
@Override
@ -1078,14 +1071,7 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
conditionVariable.open();
return;
}
AdsRenderingSettings adsRenderingSettings =
ImaSdkFactory.getInstance().createAdsRenderingSettings();
adsRenderingSettings.setLoadVideoTimeout(loadVideoTimeoutMs);
adsRenderingSettings.setFocusSkipButtonWhenAvailable(
serverSideAdInsertionConfiguration.focusSkipButtonWhenAvailable);
// After initialization completed the streamUri will be reported to the streamPlayer.
streamManager.init(adsRenderingSettings);
this.streamManager = streamManager;
imaServerSideAdInsertionMediaSource.setStreamManager(streamManager);
}
// AdErrorEvent.AdErrorListener implementation.

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="exo_media_action_repeat_off_description">Nu repetați niciunul</string>
<string name="exo_media_action_repeat_one_description">Repetați unul</string>
<string name="exo_media_action_repeat_all_description">Repetați-le pe toate</string>
<string name="exo_media_action_repeat_off_description">Nu repeta niciunul</string>
<string name="exo_media_action_repeat_one_description">Repetă unul</string>
<string name="exo_media_action_repeat_all_description">Repetă-le pe toate</string>
</resources>

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="exo_media_action_repeat_off_description">దేన్నీ పునరావృతం చేయకండి</string>
<string name="exo_media_action_repeat_one_description">ఒకదాన్ని పునరావృతం చేయండి</string>
<string name="exo_media_action_repeat_all_description">అన్నింటినీ పునరావృతం చేయండి</string>
<string name="exo_media_action_repeat_off_description">దేన్నీ రిపీట్‌ చేయకండి</string>
<string name="exo_media_action_repeat_one_description">ఒకదాన్ని రిపీట్‌ చేయండి</string>
<string name="exo_media_action_repeat_all_description">అన్నింటినీ రిపీట్‌ చేయండి</string>
</resources>

View file

@ -327,7 +327,10 @@ public final class C {
*/
public static final int ENCODING_OPUS = AudioFormat.ENCODING_OPUS;
/** Represents the behavior affecting whether spatialization will be used. */
/**
* Represents the behavior affecting whether spatialization will be used. One of {@link
* #SPATIALIZATION_BEHAVIOR_AUTO} or {@link #SPATIALIZATION_BEHAVIOR_NEVER}.
*/
@Documented
@Retention(RetentionPolicy.SOURCE)
@Target(TYPE_USE)

View file

@ -27,11 +27,11 @@ public final class ExoPlayerLibraryInfo {
/** The version of the library expressed as a string, for example "1.2.3". */
// Intentionally hardcoded. Do not derive from other constants (e.g. VERSION_INT) or vice versa.
public static final String VERSION = "2.18.3";
public static final String VERSION = "2.18.4";
/** The version of the library expressed as {@code TAG + "/" + VERSION}. */
// Intentionally hardcoded. Do not derive from other constants (e.g. VERSION) or vice versa.
public static final String VERSION_SLASHY = "ExoPlayerLib/2.18.3";
public static final String VERSION_SLASHY = "ExoPlayerLib/2.18.4";
/**
* The version of the library expressed as an integer, for example 1002003.
@ -41,7 +41,7 @@ public final class ExoPlayerLibraryInfo {
* integer version 123045006 (123-045-006).
*/
// Intentionally hardcoded. Do not derive from other constants (e.g. VERSION) or vice versa.
public static final int VERSION_INT = 2_018_003;
public static final int VERSION_INT = 2_018_004;
/** Whether the library was compiled with {@link Assertions} checks enabled. */
public static final boolean ASSERTIONS_ENABLED = true;

View file

@ -31,7 +31,7 @@ import com.google.android.exoplayer2.video.VideoSize;
import java.util.List;
/**
* A {@link Player} that forwards operations to another {@link Player}. Applications can use this
* A {@link Player} that forwards method calls to another {@link Player}. Applications can use this
* class to suppress or modify specific operations, by overriding the respective methods.
*/
public class ForwardingPlayer implements Player {

View file

@ -27,8 +27,12 @@ import java.util.regex.Pattern;
/**
* Parser for color expressions found in styling formats, e.g. TTML and CSS.
*
* @see <a href="https://w3c.github.io/webvtt/#styling">WebVTT CSS Styling</a>
* @see <a href="https://www.w3.org/TR/ttml2/">Timed Text Markup Language 2 (TTML2) - 10.3.5</a>
* <p>See also:
*
* <ul>
* <li><a href="https://w3c.github.io/webvtt/#styling">WebVTT CSS Styling</a>
* <li><a href="https://www.w3.org/TR/ttml2/">Timed Text Markup Language 2 (TTML2) - 10.3.5</a>
* </ul>
*/
public final class ColorParser {

View file

@ -93,7 +93,7 @@ public final class NetworkTypeObserver {
networkType = C.NETWORK_TYPE_UNKNOWN;
IntentFilter filter = new IntentFilter();
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
Util.registerReceiverNotExported(context, new Receiver(), filter);
context.registerReceiver(new Receiver(), filter);
}
/**

View file

@ -203,6 +203,10 @@ public final class Util {
* apps. This will be enforced by specifying {@link Context#RECEIVER_NOT_EXPORTED} if {@link
* #SDK_INT} is 33 or above.
*
* <p>Do not use this method if registering a receiver for a <a
* href="https://android.googlesource.com/platform/frameworks/base/+/master/core/res/AndroidManifest.xml">protected
* system broadcast</a>.
*
* @param context The context on which {@link Context#registerReceiver} will be called.
* @param receiver The {@link BroadcastReceiver} to register. This value may be null.
* @param filter Selects the Intent broadcasts to be received.
@ -218,32 +222,6 @@ public final class Util {
}
}
/**
* Registers a {@link BroadcastReceiver} that's not intended to receive broadcasts from other
* apps. This will be enforced by specifying {@link Context#RECEIVER_NOT_EXPORTED} if {@link
* #SDK_INT} is 33 or above.
*
* @param context The context on which {@link Context#registerReceiver} will be called.
* @param receiver The {@link BroadcastReceiver} to register. This value may be null.
* @param filter Selects the Intent broadcasts to be received.
* @param handler Handler identifying the thread that will receive the Intent.
* @return The first sticky intent found that matches {@code filter}, or null if there are none.
*/
@Nullable
public static Intent registerReceiverNotExported(
Context context, BroadcastReceiver receiver, IntentFilter filter, Handler handler) {
if (SDK_INT < 33) {
return context.registerReceiver(receiver, filter, /* broadcastPermission= */ null, handler);
} else {
return context.registerReceiver(
receiver,
filter,
/* broadcastPermission= */ null,
handler,
Context.RECEIVER_NOT_EXPORTED);
}
}
/**
* Calls {@link Context#startForegroundService(Intent)} if {@link #SDK_INT} is 26 or higher, or
* {@link Context#startService(Intent)} otherwise.

View file

@ -21,7 +21,6 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;
import android.os.Handler;
import com.google.android.exoplayer2.util.Util;
/* package */ final class AudioBecomingNoisyManager {
@ -47,8 +46,8 @@ import com.google.android.exoplayer2.util.Util;
*/
public void setEnabled(boolean enabled) {
if (enabled && !receiverRegistered) {
Util.registerReceiverNotExported(
context, receiver, new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY));
context.registerReceiver(
receiver, new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY));
receiverRegistered = true;
} else if (!enabled && receiverRegistered) {
context.unregisterReceiver(receiver);

View file

@ -1713,8 +1713,9 @@ import java.util.concurrent.TimeoutException;
@Override
public boolean isTunnelingEnabled() {
verifyApplicationThread();
for (RendererConfiguration config : playbackInfo.trackSelectorResult.rendererConfigurations) {
if (config.tunneling) {
for (@Nullable
RendererConfiguration config : playbackInfo.trackSelectorResult.rendererConfigurations) {
if (config != null && config.tunneling) {
return true;
}
}

View file

@ -938,7 +938,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
livePlaybackSpeedControl.getAdjustedPlaybackSpeed(
getCurrentLiveOffsetUs(), getTotalBufferedDurationUs());
if (mediaClock.getPlaybackParameters().speed != adjustedSpeed) {
mediaClock.setPlaybackParameters(playbackInfo.playbackParameters.withSpeed(adjustedSpeed));
setMediaClockPlaybackParameters(playbackInfo.playbackParameters.withSpeed(adjustedSpeed));
handlePlaybackParameters(
playbackInfo.playbackParameters,
/* currentPlaybackSpeed= */ mediaClock.getPlaybackParameters().speed,
@ -948,6 +948,12 @@ import java.util.concurrent.atomic.AtomicBoolean;
}
}
private void setMediaClockPlaybackParameters(PlaybackParameters playbackParameters) {
// Previously sent speed updates from the media clock now become stale.
handler.removeMessages(MSG_PLAYBACK_PARAMETERS_CHANGED_INTERNAL);
mediaClock.setPlaybackParameters(playbackParameters);
}
private void notifyTrackSelectionRebuffer() {
MediaPeriodHolder periodHolder = queue.getPlayingPeriod();
while (periodHolder != null) {
@ -1334,7 +1340,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
private void setPlaybackParametersInternal(PlaybackParameters playbackParameters)
throws ExoPlaybackException {
mediaClock.setPlaybackParameters(playbackParameters);
setMediaClockPlaybackParameters(playbackParameters);
handlePlaybackParameters(mediaClock.getPlaybackParameters(), /* acknowledgeCommand= */ true);
}
@ -1649,7 +1655,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
nextPendingMessageIndexHint = nextPendingMessageIndex;
}
private void ensureStopped(Renderer renderer) throws ExoPlaybackException {
private void ensureStopped(Renderer renderer) {
if (renderer.getState() == Renderer.STATE_STARTED) {
renderer.stop();
}
@ -1906,14 +1912,20 @@ import java.util.concurrent.atomic.AtomicBoolean;
MediaPeriodId newPeriodId,
Timeline oldTimeline,
MediaPeriodId oldPeriodId,
long positionForTargetOffsetOverrideUs) {
long positionForTargetOffsetOverrideUs)
throws ExoPlaybackException {
if (!shouldUseLivePlaybackSpeedControl(newTimeline, newPeriodId)) {
// Live playback speed control is unused for the current period, reset speed to user-defined
// playback parameters or 1.0 for ad playback.
PlaybackParameters targetPlaybackParameters =
newPeriodId.isAd() ? PlaybackParameters.DEFAULT : playbackInfo.playbackParameters;
if (!mediaClock.getPlaybackParameters().equals(targetPlaybackParameters)) {
mediaClock.setPlaybackParameters(targetPlaybackParameters);
setMediaClockPlaybackParameters(targetPlaybackParameters);
handlePlaybackParameters(
playbackInfo.playbackParameters,
targetPlaybackParameters.speed,
/* updatePlaybackInfo= */ false,
/* acknowledgeCommand= */ false);
}
return;
}
@ -1962,7 +1974,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
return maxReadPositionUs;
}
private void updatePeriods() throws ExoPlaybackException, IOException {
private void updatePeriods() throws ExoPlaybackException {
if (playbackInfo.timeline.isEmpty() || !mediaSourceList.isPrepared()) {
// No periods available.
return;
@ -2004,7 +2016,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
}
}
private void maybeUpdateReadingPeriod() {
private void maybeUpdateReadingPeriod() throws ExoPlaybackException {
@Nullable MediaPeriodHolder readingPeriodHolder = queue.getReadingPeriod();
if (readingPeriodHolder == null) {
return;

View file

@ -74,7 +74,7 @@ import com.google.android.exoplayer2.util.Util;
VolumeChangeReceiver receiver = new VolumeChangeReceiver();
IntentFilter filter = new IntentFilter(VOLUME_CHANGED_ACTION);
try {
Util.registerReceiverNotExported(applicationContext, receiver, filter);
applicationContext.registerReceiver(receiver, filter);
this.receiver = receiver;
} catch (RuntimeException e) {
Log.w(TAG, "Error registering stream volume receiver", e);

View file

@ -86,8 +86,8 @@ public final class AudioCapabilities {
@SuppressWarnings("InlinedApi")
public static AudioCapabilities getCapabilities(Context context) {
Intent intent =
Util.registerReceiverNotExported(
context, /* receiver= */ null, new IntentFilter(AudioManager.ACTION_HDMI_AUDIO_PLUG));
context.registerReceiver(
/* receiver= */ null, new IntentFilter(AudioManager.ACTION_HDMI_AUDIO_PLUG));
return getCapabilities(context, intent);
}

View file

@ -91,7 +91,9 @@ public final class AudioCapabilitiesReceiver {
@Nullable Intent stickyIntent = null;
if (receiver != null) {
IntentFilter intentFilter = new IntentFilter(AudioManager.ACTION_HDMI_AUDIO_PLUG);
stickyIntent = Util.registerReceiverNotExported(context, receiver, intentFilter, handler);
stickyIntent =
context.registerReceiver(
receiver, intentFilter, /* broadcastPermission= */ null, handler);
}
audioCapabilities = AudioCapabilities.getCapabilities(context, stickyIntent);
return audioCapabilities;

View file

@ -15,6 +15,7 @@
*/
package com.google.android.exoplayer2.audio;
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
import static com.google.android.exoplayer2.util.Util.castNonNull;
import static java.lang.Math.max;
import static java.lang.Math.min;
@ -26,7 +27,6 @@ import android.os.SystemClock;
import androidx.annotation.IntDef;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Util;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
@ -146,6 +146,9 @@ import java.lang.reflect.Method;
/** The duration of time used to smooth over an adjustment between position sampling modes. */
private static final long MODE_SWITCH_SMOOTHING_DURATION_US = C.MICROS_PER_SECOND;
/** Minimum update interval for getting the raw playback head position, in milliseconds. */
private static final long RAW_PLAYBACK_HEAD_POSITION_UPDATE_INTERVAL_MS = 5;
private static final long FORCE_RESET_WORKAROUND_TIMEOUT_MS = 200;
private static final int MAX_PLAYHEAD_OFFSET_COUNT = 10;
@ -174,7 +177,8 @@ import java.lang.reflect.Method;
private boolean isOutputPcm;
private long lastLatencySampleTimeUs;
private long lastRawPlaybackHeadPosition;
private long lastRawPlaybackHeadPositionSampleTimeMs;
private long rawPlaybackHeadPosition;
private long rawPlaybackHeadWrapCount;
private long passthroughWorkaroundPauseOffset;
private int nextPlayheadOffsetIndex;
@ -199,7 +203,7 @@ import java.lang.reflect.Method;
* @param listener A listener for position tracking events.
*/
public AudioTrackPositionTracker(Listener listener) {
this.listener = Assertions.checkNotNull(listener);
this.listener = checkNotNull(listener);
if (Util.SDK_INT >= 18) {
try {
getLatencyMethod = AudioTrack.class.getMethod("getLatency", (Class<?>[]) null);
@ -235,7 +239,7 @@ import java.lang.reflect.Method;
needsPassthroughWorkarounds = isPassthrough && needsPassthroughWorkarounds(outputEncoding);
isOutputPcm = Util.isEncodingLinearPcm(outputEncoding);
bufferSizeUs = isOutputPcm ? framesToDurationUs(bufferSize / outputPcmFrameSize) : C.TIME_UNSET;
lastRawPlaybackHeadPosition = 0;
rawPlaybackHeadPosition = 0;
rawPlaybackHeadWrapCount = 0;
passthroughWorkaroundPauseOffset = 0;
hasData = false;
@ -253,10 +257,11 @@ import java.lang.reflect.Method;
if (audioTimestampPoller != null) {
audioTimestampPoller.reset();
}
resetSyncParams();
}
public long getCurrentPositionUs(boolean sourceEnded) {
if (Assertions.checkNotNull(this.audioTrack).getPlayState() == PLAYSTATE_PLAYING) {
if (checkNotNull(this.audioTrack).getPlayState() == PLAYSTATE_PLAYING) {
maybeSampleSyncParams();
}
@ -264,7 +269,7 @@ import java.lang.reflect.Method;
// Otherwise, derive a smoothed position by sampling the track's frame position.
long systemTimeUs = System.nanoTime() / 1000;
long positionUs;
AudioTimestampPoller audioTimestampPoller = Assertions.checkNotNull(this.audioTimestampPoller);
AudioTimestampPoller audioTimestampPoller = checkNotNull(this.audioTimestampPoller);
boolean useGetTimestampMode = audioTimestampPoller.hasAdvancingTimestamp();
if (useGetTimestampMode) {
// Calculate the speed-adjusted position using the timestamp (which may be in the future).
@ -282,7 +287,9 @@ import java.lang.reflect.Method;
// getPlaybackHeadPositionUs() only has a granularity of ~20 ms, so we base the position off
// the system clock (and a smoothed offset between it and the playhead position) so as to
// prevent jitter in the reported positions.
positionUs = systemTimeUs + smoothedPlayheadOffsetUs;
positionUs =
Util.getMediaDurationForPlayoutDuration(
systemTimeUs + smoothedPlayheadOffsetUs, audioTrackPlaybackSpeed);
}
if (!sourceEnded) {
positionUs = max(0, positionUs - latencyUs);
@ -329,12 +336,12 @@ import java.lang.reflect.Method;
/** Starts position tracking. Must be called immediately before {@link AudioTrack#play()}. */
public void start() {
Assertions.checkNotNull(audioTimestampPoller).reset();
checkNotNull(audioTimestampPoller).reset();
}
/** Returns whether the audio track is in the playing state. */
public boolean isPlaying() {
return Assertions.checkNotNull(audioTrack).getPlayState() == PLAYSTATE_PLAYING;
return checkNotNull(audioTrack).getPlayState() == PLAYSTATE_PLAYING;
}
/**
@ -345,7 +352,7 @@ import java.lang.reflect.Method;
* @return Whether the caller can write data to the track.
*/
public boolean mayHandleBuffer(long writtenFrames) {
@PlayState int playState = Assertions.checkNotNull(audioTrack).getPlayState();
@PlayState int playState = checkNotNull(audioTrack).getPlayState();
if (needsPassthroughWorkarounds) {
// An AC-3 audio track continues to play data written while it is paused. Stop writing so its
// buffer empties. See [Internal: b/18899620].
@ -426,7 +433,7 @@ import java.lang.reflect.Method;
if (stopTimestampUs == C.TIME_UNSET) {
// The audio track is going to be paused, so reset the timestamp poller to ensure it doesn't
// supply an advancing position.
Assertions.checkNotNull(audioTimestampPoller).reset();
checkNotNull(audioTimestampPoller).reset();
return true;
}
// We've handled the end of the stream already, so there's no need to pause the track.
@ -444,15 +451,17 @@ import java.lang.reflect.Method;
}
private void maybeSampleSyncParams() {
long playbackPositionUs = getPlaybackHeadPositionUs();
if (playbackPositionUs == 0) {
// The AudioTrack hasn't output anything yet.
return;
}
long systemTimeUs = System.nanoTime() / 1000;
if (systemTimeUs - lastPlayheadSampleTimeUs >= MIN_PLAYHEAD_OFFSET_SAMPLE_INTERVAL_US) {
long playbackPositionUs = getPlaybackHeadPositionUs();
if (playbackPositionUs == 0) {
// The AudioTrack hasn't output anything yet.
return;
}
// Take a new sample and update the smoothed offset between the system clock and the playhead.
playheadOffsets[nextPlayheadOffsetIndex] = playbackPositionUs - systemTimeUs;
playheadOffsets[nextPlayheadOffsetIndex] =
Util.getPlayoutDurationForMediaDuration(playbackPositionUs, audioTrackPlaybackSpeed)
- systemTimeUs;
nextPlayheadOffsetIndex = (nextPlayheadOffsetIndex + 1) % MAX_PLAYHEAD_OFFSET_COUNT;
if (playheadOffsetCount < MAX_PLAYHEAD_OFFSET_COUNT) {
playheadOffsetCount++;
@ -470,12 +479,12 @@ import java.lang.reflect.Method;
return;
}
maybePollAndCheckTimestamp(systemTimeUs, playbackPositionUs);
maybePollAndCheckTimestamp(systemTimeUs);
maybeUpdateLatency(systemTimeUs);
}
private void maybePollAndCheckTimestamp(long systemTimeUs, long playbackPositionUs) {
AudioTimestampPoller audioTimestampPoller = Assertions.checkNotNull(this.audioTimestampPoller);
private void maybePollAndCheckTimestamp(long systemTimeUs) {
AudioTimestampPoller audioTimestampPoller = checkNotNull(this.audioTimestampPoller);
if (!audioTimestampPoller.maybePollTimestamp(systemTimeUs)) {
return;
}
@ -483,6 +492,7 @@ import java.lang.reflect.Method;
// Check the timestamp and accept/reject it.
long audioTimestampSystemTimeUs = audioTimestampPoller.getTimestampSystemTimeUs();
long audioTimestampPositionFrames = audioTimestampPoller.getTimestampPositionFrames();
long playbackPositionUs = getPlaybackHeadPositionUs();
if (Math.abs(audioTimestampSystemTimeUs - systemTimeUs) > MAX_AUDIO_TIMESTAMP_OFFSET_US) {
listener.onSystemTimeUsMismatch(
audioTimestampPositionFrames,
@ -511,8 +521,7 @@ import java.lang.reflect.Method;
// Compute the audio track latency, excluding the latency due to the buffer (leaving
// latency due to the mixer and audio hardware driver).
latencyUs =
castNonNull((Integer) getLatencyMethod.invoke(Assertions.checkNotNull(audioTrack)))
* 1000L
castNonNull((Integer) getLatencyMethod.invoke(checkNotNull(audioTrack))) * 1000L
- bufferSizeUs;
// Check that the latency is non-negative.
latencyUs = max(latencyUs, 0);
@ -550,7 +559,7 @@ import java.lang.reflect.Method;
*/
private boolean forceHasPendingData() {
return needsPassthroughWorkarounds
&& Assertions.checkNotNull(audioTrack).getPlayState() == AudioTrack.PLAYSTATE_PAUSED
&& checkNotNull(audioTrack).getPlayState() == AudioTrack.PLAYSTATE_PAUSED
&& getPlaybackHeadPosition() == 0;
}
@ -576,34 +585,44 @@ import java.lang.reflect.Method;
* @return The playback head position, in frames.
*/
private long getPlaybackHeadPosition() {
AudioTrack audioTrack = Assertions.checkNotNull(this.audioTrack);
long currentTimeMs = SystemClock.elapsedRealtime();
if (stopTimestampUs != C.TIME_UNSET) {
// Simulate the playback head position up to the total number of frames submitted.
long elapsedTimeSinceStopUs = (SystemClock.elapsedRealtime() * 1000) - stopTimestampUs;
long framesSinceStop = (elapsedTimeSinceStopUs * outputSampleRate) / C.MICROS_PER_SECOND;
long elapsedTimeSinceStopUs = (currentTimeMs * 1000) - stopTimestampUs;
long mediaTimeSinceStopUs =
Util.getMediaDurationForPlayoutDuration(elapsedTimeSinceStopUs, audioTrackPlaybackSpeed);
long framesSinceStop = (mediaTimeSinceStopUs * outputSampleRate) / C.MICROS_PER_SECOND;
return min(endPlaybackHeadPosition, stopPlaybackHeadPosition + framesSinceStop);
}
if (currentTimeMs - lastRawPlaybackHeadPositionSampleTimeMs
>= RAW_PLAYBACK_HEAD_POSITION_UPDATE_INTERVAL_MS) {
updateRawPlaybackHeadPosition(currentTimeMs);
lastRawPlaybackHeadPositionSampleTimeMs = currentTimeMs;
}
return rawPlaybackHeadPosition + (rawPlaybackHeadWrapCount << 32);
}
private void updateRawPlaybackHeadPosition(long currentTimeMs) {
AudioTrack audioTrack = checkNotNull(this.audioTrack);
int state = audioTrack.getPlayState();
if (state == PLAYSTATE_STOPPED) {
// The audio track hasn't been started.
return 0;
// The audio track hasn't been started. Keep initial zero timestamp.
return;
}
long rawPlaybackHeadPosition = 0xFFFFFFFFL & audioTrack.getPlaybackHeadPosition();
if (needsPassthroughWorkarounds) {
// Work around an issue with passthrough/direct AudioTracks on platform API versions 21/22
// where the playback head position jumps back to zero on paused passthrough/direct audio
// tracks. See [Internal: b/19187573].
if (state == PLAYSTATE_PAUSED && rawPlaybackHeadPosition == 0) {
passthroughWorkaroundPauseOffset = lastRawPlaybackHeadPosition;
passthroughWorkaroundPauseOffset = this.rawPlaybackHeadPosition;
}
rawPlaybackHeadPosition += passthroughWorkaroundPauseOffset;
}
if (Util.SDK_INT <= 29) {
if (rawPlaybackHeadPosition == 0
&& lastRawPlaybackHeadPosition > 0
&& this.rawPlaybackHeadPosition > 0
&& state == PLAYSTATE_PLAYING) {
// If connecting a Bluetooth audio device fails, the AudioTrack may be left in a state
// where its Java API is in the playing state, but the native track is stopped. When this
@ -611,19 +630,18 @@ import java.lang.reflect.Method;
// playback head position and force the track to be reset after
// {@link #FORCE_RESET_WORKAROUND_TIMEOUT_MS} has elapsed.
if (forceResetWorkaroundTimeMs == C.TIME_UNSET) {
forceResetWorkaroundTimeMs = SystemClock.elapsedRealtime();
forceResetWorkaroundTimeMs = currentTimeMs;
}
return lastRawPlaybackHeadPosition;
return;
} else {
forceResetWorkaroundTimeMs = C.TIME_UNSET;
}
}
if (lastRawPlaybackHeadPosition > rawPlaybackHeadPosition) {
if (this.rawPlaybackHeadPosition > rawPlaybackHeadPosition) {
// The value must have wrapped around.
rawPlaybackHeadWrapCount++;
}
lastRawPlaybackHeadPosition = rawPlaybackHeadPosition;
return rawPlaybackHeadPosition + (rawPlaybackHeadWrapCount << 32);
this.rawPlaybackHeadPosition = rawPlaybackHeadPosition;
}
}

View file

@ -191,11 +191,13 @@ import java.nio.ByteBuffer;
@Override
public int dequeueInputBufferIndex() {
bufferEnqueuer.maybeThrowException();
return asynchronousMediaCodecCallback.dequeueInputBufferIndex();
}
@Override
public int dequeueOutputBufferIndex(MediaCodec.BufferInfo bufferInfo) {
bufferEnqueuer.maybeThrowException();
return asynchronousMediaCodecCallback.dequeueOutputBufferIndex(bufferInfo);
}

View file

@ -162,7 +162,8 @@ class AsynchronousMediaCodecBufferEnqueuer {
blockUntilHandlerThreadIsIdle();
}
private void maybeThrowException() {
/** Throw any exception that occurred on the enqueuer's background queueing thread. */
public void maybeThrowException() {
@Nullable RuntimeException exception = pendingRuntimeException.getAndSet(null);
if (exception != null) {
throw exception;

View file

@ -263,11 +263,12 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
// else, pendingOutputFormat may already be non-null following a previous flush, and remains
// set in this case.
// mediaCodecException is not reset to null. If the codec has raised an error, then it remains
// in FAILED_STATE even after flushing.
availableInputBuffers.clear();
availableOutputBuffers.clear();
bufferInfos.clear();
formats.clear();
mediaCodecException = null;
}
@GuardedBy("lock")

View file

@ -855,7 +855,7 @@ public final class MediaCodecInfo {
* @param name The name of the codec.
* @return Whether to enable the workaround.
*/
private static final boolean needsRotatedVerticalResolutionWorkaround(String name) {
private static boolean needsRotatedVerticalResolutionWorkaround(String name) {
if ("OMX.MTK.VIDEO.DECODER.HEVC".equals(name) && "mcv5a".equals(Util.DEVICE)) {
// See https://github.com/google/ExoPlayer/issues/6612.
return false;
@ -874,6 +874,17 @@ public final class MediaCodecInfo {
&& ("sailfish".equals(Util.DEVICE) || "marlin".equals(Util.DEVICE));
}
/** Whether the device is known to have wrong {@link PerformancePoint} declarations. */
private static boolean needsIgnorePerformancePointsWorkaround() {
// See https://github.com/google/ExoPlayer/issues/10898 and [internal ref: b/267324685].
return /* Chromecast with Google TV */ Util.DEVICE.equals("sabrina")
|| Util.DEVICE.equals("boreal")
/* Lenovo Tablet M10 FHD Plus */
|| Util.MODEL.startsWith("Lenovo TB-X605")
|| Util.MODEL.startsWith("Lenovo TB-X606")
|| Util.MODEL.startsWith("Lenovo TB-X616");
}
/** Possible outcomes of evaluating PerformancePoint coverage */
@Documented
@Retention(RetentionPolicy.SOURCE)
@ -898,7 +909,9 @@ public final class MediaCodecInfo {
VideoCapabilities videoCapabilities, int width, int height, double frameRate) {
List<PerformancePoint> performancePointList =
videoCapabilities.getSupportedPerformancePoints();
if (performancePointList == null || performancePointList.isEmpty()) {
if (performancePointList == null
|| performancePointList.isEmpty()
|| needsIgnorePerformancePointsWorkaround()) {
return COVERAGE_RESULT_NO_EMPTY_LIST;
}

View file

@ -206,10 +206,6 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
*/
private static final long MAX_CODEC_HOTSWAP_TIME_MS = 1000;
// Generally there is zero or one pending output stream offset. We track more offsets to allow for
// pending output streams that have fewer frames than the codec latency.
private static final int MAX_PENDING_OUTPUT_STREAM_OFFSET_COUNT = 10;
@Documented
@Retention(RetentionPolicy.SOURCE)
@Target(TYPE_USE)
@ -301,12 +297,9 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
private final DecoderInputBuffer buffer;
private final DecoderInputBuffer bypassSampleBuffer;
private final BatchBuffer bypassBatchBuffer;
private final TimedValueQueue<Format> formatQueue;
private final ArrayList<Long> decodeOnlyPresentationTimestamps;
private final MediaCodec.BufferInfo outputBufferInfo;
private final long[] pendingOutputStreamStartPositionsUs;
private final long[] pendingOutputStreamOffsetsUs;
private final long[] pendingOutputStreamSwitchTimesUs;
private final ArrayDeque<OutputStreamInfo> pendingOutputStreamChanges;
@Nullable private Format inputFormat;
@Nullable private Format outputFormat;
@ -361,9 +354,9 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
private boolean pendingOutputEndOfStream;
@Nullable private ExoPlaybackException pendingPlaybackException;
protected DecoderCounters decoderCounters;
private long outputStreamStartPositionUs;
private long outputStreamOffsetUs;
private int pendingOutputStreamOffsetCount;
private OutputStreamInfo outputStreamInfo;
private long lastProcessedOutputBufferTimeUs;
private boolean needToNotifyOutputFormatChangeAfterStreamChange;
/**
* @param trackType The {@link C.TrackType track type} that the renderer handles.
@ -390,17 +383,13 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
buffer = new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_DISABLED);
bypassSampleBuffer = new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_DIRECT);
bypassBatchBuffer = new BatchBuffer();
formatQueue = new TimedValueQueue<>();
decodeOnlyPresentationTimestamps = new ArrayList<>();
outputBufferInfo = new MediaCodec.BufferInfo();
currentPlaybackSpeed = 1f;
targetPlaybackSpeed = 1f;
renderTimeLimitMs = C.TIME_UNSET;
pendingOutputStreamStartPositionsUs = new long[MAX_PENDING_OUTPUT_STREAM_OFFSET_COUNT];
pendingOutputStreamOffsetsUs = new long[MAX_PENDING_OUTPUT_STREAM_OFFSET_COUNT];
pendingOutputStreamSwitchTimesUs = new long[MAX_PENDING_OUTPUT_STREAM_OFFSET_COUNT];
outputStreamStartPositionUs = C.TIME_UNSET;
setOutputStreamOffsetUs(C.TIME_UNSET);
pendingOutputStreamChanges = new ArrayDeque<>();
setOutputStreamInfo(OutputStreamInfo.UNSET);
// MediaCodec outputs audio buffers in native endian:
// https://developer.android.com/reference/android/media/MediaCodec#raw-audio-buffers
// and code called from MediaCodecAudioRenderer.processOutputBuffer expects this endianness.
@ -417,6 +406,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
codecHotswapDeadlineMs = C.TIME_UNSET;
largestQueuedPresentationTimeUs = C.TIME_UNSET;
lastBufferInStreamPresentationTimeUs = C.TIME_UNSET;
lastProcessedOutputBufferTimeUs = C.TIME_UNSET;
codecDrainState = DRAIN_STATE_NONE;
codecDrainAction = DRAIN_ACTION_NONE;
}
@ -604,13 +594,15 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
protected final void updateOutputFormatForTime(long presentationTimeUs)
throws ExoPlaybackException {
boolean outputFormatChanged = false;
@Nullable Format format = formatQueue.pollFloor(presentationTimeUs);
if (format == null && codecOutputMediaFormatChanged) {
// If the codec's output MediaFormat has changed then there should be a corresponding Format
// change, which we've not found. Check the Format queue in case the corresponding
// presentation timestamp is greater than presentationTimeUs, which can happen for some codecs
// [Internal ref: b/162719047].
format = formatQueue.pollFirst();
@Nullable Format format = outputStreamInfo.formatQueue.pollFloor(presentationTimeUs);
if (format == null
&& needToNotifyOutputFormatChangeAfterStreamChange
&& codecOutputMediaFormat != null) {
// After a stream change or after the initial start, there should be an input format change,
// which we've not found. Check the Format queue in case the corresponding presentation
// timestamp is greater than presentationTimeUs, which can happen for some codecs
// [Internal ref: b/162719047 and https://github.com/google/ExoPlayer/issues/8594].
format = outputStreamInfo.formatQueue.pollFirst();
}
if (format != null) {
outputFormat = format;
@ -619,6 +611,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
if (outputFormatChanged || (codecOutputMediaFormatChanged && outputFormat != null)) {
onOutputFormatChanged(outputFormat, codecOutputMediaFormat);
codecOutputMediaFormatChanged = false;
needToNotifyOutputFormatChangeAfterStreamChange = false;
}
}
@ -646,23 +639,17 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
@Override
protected void onStreamChanged(Format[] formats, long startPositionUs, long offsetUs)
throws ExoPlaybackException {
if (this.outputStreamOffsetUs == C.TIME_UNSET) {
checkState(this.outputStreamStartPositionUs == C.TIME_UNSET);
this.outputStreamStartPositionUs = startPositionUs;
setOutputStreamOffsetUs(offsetUs);
if (outputStreamInfo.streamOffsetUs == C.TIME_UNSET
|| (pendingOutputStreamChanges.isEmpty()
&& lastProcessedOutputBufferTimeUs != C.TIME_UNSET
&& lastProcessedOutputBufferTimeUs >= largestQueuedPresentationTimeUs)) {
// This is the first stream, or the previous has been fully output already.
setOutputStreamInfo(
new OutputStreamInfo(
/* previousStreamLastBufferTimeUs= */ C.TIME_UNSET, startPositionUs, offsetUs));
} else {
if (pendingOutputStreamOffsetCount == pendingOutputStreamOffsetsUs.length) {
Log.w(
TAG,
"Too many stream changes, so dropping offset: "
+ pendingOutputStreamOffsetsUs[pendingOutputStreamOffsetCount - 1]);
} else {
pendingOutputStreamOffsetCount++;
}
pendingOutputStreamStartPositionsUs[pendingOutputStreamOffsetCount - 1] = startPositionUs;
pendingOutputStreamOffsetsUs[pendingOutputStreamOffsetCount - 1] = offsetUs;
pendingOutputStreamSwitchTimesUs[pendingOutputStreamOffsetCount - 1] =
largestQueuedPresentationTimeUs;
pendingOutputStreamChanges.add(
new OutputStreamInfo(largestQueuedPresentationTimeUs, startPositionUs, offsetUs));
}
}
@ -681,16 +668,11 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
// If there is a format change on the input side still pending propagation to the output, we
// need to queue a format next time a buffer is read. This is because we may not read a new
// input format after the position reset.
if (formatQueue.size() > 0) {
if (outputStreamInfo.formatQueue.size() > 0) {
waitingForFirstSampleInFormat = true;
}
formatQueue.clear();
if (pendingOutputStreamOffsetCount != 0) {
setOutputStreamOffsetUs(pendingOutputStreamOffsetsUs[pendingOutputStreamOffsetCount - 1]);
outputStreamStartPositionUs =
pendingOutputStreamStartPositionsUs[pendingOutputStreamOffsetCount - 1];
pendingOutputStreamOffsetCount = 0;
}
outputStreamInfo.formatQueue.clear();
pendingOutputStreamChanges.clear();
}
@Override
@ -704,9 +686,8 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
@Override
protected void onDisabled() {
inputFormat = null;
outputStreamStartPositionUs = C.TIME_UNSET;
setOutputStreamOffsetUs(C.TIME_UNSET);
pendingOutputStreamOffsetCount = 0;
setOutputStreamInfo(OutputStreamInfo.UNSET);
pendingOutputStreamChanges.clear();
flushOrReleaseCodec();
}
@ -895,6 +876,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
decodeOnlyPresentationTimestamps.clear();
largestQueuedPresentationTimeUs = C.TIME_UNSET;
lastBufferInStreamPresentationTimeUs = C.TIME_UNSET;
lastProcessedOutputBufferTimeUs = C.TIME_UNSET;
if (c2Mp3TimestampTracker != null) {
c2Mp3TimestampTracker.reset();
}
@ -1351,7 +1333,11 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
decodeOnlyPresentationTimestamps.add(presentationTimeUs);
}
if (waitingForFirstSampleInFormat) {
formatQueue.add(presentationTimeUs, inputFormat);
if (!pendingOutputStreamChanges.isEmpty()) {
pendingOutputStreamChanges.peekLast().formatQueue.add(presentationTimeUs, inputFormat);
} else {
outputStreamInfo.formatQueue.add(presentationTimeUs, inputFormat);
}
waitingForFirstSampleInFormat = false;
}
largestQueuedPresentationTimeUs = max(largestQueuedPresentationTimeUs, presentationTimeUs);
@ -1591,29 +1577,10 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
*/
@CallSuper
protected void onProcessedOutputBuffer(long presentationTimeUs) {
while (pendingOutputStreamOffsetCount != 0
&& presentationTimeUs >= pendingOutputStreamSwitchTimesUs[0]) {
outputStreamStartPositionUs = pendingOutputStreamStartPositionsUs[0];
setOutputStreamOffsetUs(pendingOutputStreamOffsetsUs[0]);
pendingOutputStreamOffsetCount--;
System.arraycopy(
pendingOutputStreamStartPositionsUs,
/* srcPos= */ 1,
pendingOutputStreamStartPositionsUs,
/* destPos= */ 0,
pendingOutputStreamOffsetCount);
System.arraycopy(
pendingOutputStreamOffsetsUs,
/* srcPos= */ 1,
pendingOutputStreamOffsetsUs,
/* destPos= */ 0,
pendingOutputStreamOffsetCount);
System.arraycopy(
pendingOutputStreamSwitchTimesUs,
/* srcPos= */ 1,
pendingOutputStreamSwitchTimesUs,
/* destPos= */ 0,
pendingOutputStreamOffsetCount);
lastProcessedOutputBufferTimeUs = presentationTimeUs;
if (!pendingOutputStreamChanges.isEmpty()
&& presentationTimeUs >= pendingOutputStreamChanges.peek().previousStreamLastBufferTimeUs) {
setOutputStreamInfo(pendingOutputStreamChanges.poll());
onProcessedStreamChange();
}
}
@ -2060,13 +2027,14 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
* boolean, Format)} to get the playback position with respect to the media.
*/
protected final long getOutputStreamOffsetUs() {
return outputStreamOffsetUs;
return outputStreamInfo.streamOffsetUs;
}
private void setOutputStreamOffsetUs(long outputStreamOffsetUs) {
this.outputStreamOffsetUs = outputStreamOffsetUs;
if (outputStreamOffsetUs != C.TIME_UNSET) {
onOutputStreamOffsetUsChanged(outputStreamOffsetUs);
private void setOutputStreamInfo(OutputStreamInfo outputStreamInfo) {
this.outputStreamInfo = outputStreamInfo;
if (outputStreamInfo.streamOffsetUs != C.TIME_UNSET) {
needToNotifyOutputFormatChangeAfterStreamChange = true;
onOutputStreamOffsetUsChanged(outputStreamInfo.streamOffsetUs);
}
}
@ -2513,6 +2481,28 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
&& "OMX.MTK.AUDIO.DECODER.MP3".equals(name);
}
private static final class OutputStreamInfo {
public static final OutputStreamInfo UNSET =
new OutputStreamInfo(
/* previousStreamLastBufferTimeUs= */ C.TIME_UNSET,
/* startPositionUs= */ C.TIME_UNSET,
/* streamOffsetUs= */ C.TIME_UNSET);
public final long previousStreamLastBufferTimeUs;
public final long startPositionUs;
public final long streamOffsetUs;
public final TimedValueQueue<Format> formatQueue;
public OutputStreamInfo(
long previousStreamLastBufferTimeUs, long startPositionUs, long streamOffsetUs) {
this.previousStreamLastBufferTimeUs = previousStreamLastBufferTimeUs;
this.startPositionUs = startPositionUs;
this.streamOffsetUs = streamOffsetUs;
this.formatQueue = new TimedValueQueue<>();
}
}
@RequiresApi(31)
private static final class Api31 {
private Api31() {}

View file

@ -250,7 +250,7 @@ public final class MediaCodecUtil {
return getVp9ProfileAndLevel(format.codecs, parts);
case CODEC_ID_HEV1:
case CODEC_ID_HVC1:
return getHevcProfileAndLevel(format.codecs, parts);
return getHevcProfileAndLevel(format.codecs, parts, format.colorInfo);
case CODEC_ID_AV01:
return getAv1ProfileAndLevel(format.codecs, parts, format.colorInfo);
case CODEC_ID_MP4A:
@ -729,7 +729,8 @@ public final class MediaCodecUtil {
}
@Nullable
private static Pair<Integer, Integer> getHevcProfileAndLevel(String codec, String[] parts) {
private static Pair<Integer, Integer> getHevcProfileAndLevel(
String codec, String[] parts, @Nullable ColorInfo colorInfo) {
if (parts.length < 4) {
// The codec has fewer parts than required by the HEVC codec string format.
Log.w(TAG, "Ignoring malformed HEVC codec string: " + codec);
@ -746,7 +747,15 @@ public final class MediaCodecUtil {
if ("1".equals(profileString)) {
profile = CodecProfileLevel.HEVCProfileMain;
} else if ("2".equals(profileString)) {
profile = CodecProfileLevel.HEVCProfileMain10;
if (colorInfo != null && colorInfo.colorTransfer == C.COLOR_TRANSFER_ST2084) {
profile = CodecProfileLevel.HEVCProfileMain10HDR10;
} else {
// For all other cases, we map to the Main10 profile. Note that this includes HLG
// HDR. On Android 13+, the platform guarantees that a decoder that advertises
// HEVCProfileMain10 will be able to decode HLG. This is not guaranteed for older
// Android versions, but we still map to Main10 for backwards compatibility.
profile = CodecProfileLevel.HEVCProfileMain10;
}
} else {
Log.w(TAG, "Unknown HEVC profile string: " + profileString);
return null;

View file

@ -103,7 +103,7 @@ public class DefaultDownloaderFactory implements DownloaderFactory {
return constructor.newInstance(mediaItem, cacheDataSourceFactory, executor);
} catch (Exception e) {
throw new IllegalStateException(
"Failed to instantiate downloader for content type " + contentType);
"Failed to instantiate downloader for content type " + contentType, e);
}
}

View file

@ -72,8 +72,9 @@ public abstract class SegmentDownloader<M extends FilterableManifest<M>> impleme
}
}
public static final long DEFAULT_MAX_MERGED_SEGMENT_START_TIME_DIFF_MS = 20 * C.MILLIS_PER_SECOND;
private static final int BUFFER_SIZE_BYTES = 128 * 1024;
private static final long MAX_MERGED_SEGMENT_START_TIME_DIFF_US = 20 * C.MICROS_PER_SECOND;
private final DataSpec manifestDataSpec;
private final Parser<M> manifestParser;
@ -83,6 +84,7 @@ public abstract class SegmentDownloader<M extends FilterableManifest<M>> impleme
private final CacheKeyFactory cacheKeyFactory;
@Nullable private final PriorityTaskManager priorityTaskManager;
private final Executor executor;
private final long maxMergedSegmentStartTimeDiffUs;
/**
* The currently active runnables.
@ -96,6 +98,24 @@ public abstract class SegmentDownloader<M extends FilterableManifest<M>> impleme
private volatile boolean isCanceled;
/**
* @deprecated Use {@link SegmentDownloader#SegmentDownloader(MediaItem, Parser,
* CacheDataSource.Factory, Executor, long)} instead.
*/
@Deprecated
public SegmentDownloader(
MediaItem mediaItem,
Parser<M> manifestParser,
CacheDataSource.Factory cacheDataSourceFactory,
Executor executor) {
this(
mediaItem,
manifestParser,
cacheDataSourceFactory,
executor,
DEFAULT_MAX_MERGED_SEGMENT_START_TIME_DIFF_MS);
}
/**
* @param mediaItem The {@link MediaItem} to be downloaded.
* @param manifestParser A parser for manifests belonging to the media to be downloaded.
@ -104,12 +124,16 @@ public abstract class SegmentDownloader<M extends FilterableManifest<M>> impleme
* @param executor An {@link Executor} used to make requests for the media being downloaded.
* Providing an {@link Executor} that uses multiple threads will speed up the download by
* allowing parts of it to be executed in parallel.
* @param maxMergedSegmentStartTimeDiffMs The maximum difference of the start time of two
* segments, up to which the segments (of the same URI) should be merged into a single
* download segment, in milliseconds.
*/
public SegmentDownloader(
MediaItem mediaItem,
Parser<M> manifestParser,
CacheDataSource.Factory cacheDataSourceFactory,
Executor executor) {
Executor executor,
long maxMergedSegmentStartTimeDiffMs) {
checkNotNull(mediaItem.localConfiguration);
this.manifestDataSpec = getCompressibleDataSpec(mediaItem.localConfiguration.uri);
this.manifestParser = manifestParser;
@ -120,6 +144,7 @@ public abstract class SegmentDownloader<M extends FilterableManifest<M>> impleme
cacheKeyFactory = cacheDataSourceFactory.getCacheKeyFactory();
priorityTaskManager = cacheDataSourceFactory.getUpstreamPriorityTaskManager();
activeRunnables = new ArrayList<>();
maxMergedSegmentStartTimeDiffUs = Util.msToUs(maxMergedSegmentStartTimeDiffMs);
}
@Override
@ -142,7 +167,7 @@ public abstract class SegmentDownloader<M extends FilterableManifest<M>> impleme
// Sort the segments so that we download media in the right order from the start of the
// content, and merge segments where possible to minimize the number of server round trips.
Collections.sort(segments);
mergeSegments(segments, cacheKeyFactory);
mergeSegments(segments, cacheKeyFactory, maxMergedSegmentStartTimeDiffUs);
// Scan the segments, removing any that are fully downloaded.
int totalSegments = segments.size();
@ -413,7 +438,8 @@ public abstract class SegmentDownloader<M extends FilterableManifest<M>> impleme
}
}
private static void mergeSegments(List<Segment> segments, CacheKeyFactory keyFactory) {
private static void mergeSegments(
List<Segment> segments, CacheKeyFactory keyFactory, long maxMergedSegmentStartTimeDiffUs) {
HashMap<String, Integer> lastIndexByCacheKey = new HashMap<>();
int nextOutIndex = 0;
for (int i = 0; i < segments.size(); i++) {
@ -422,7 +448,7 @@ public abstract class SegmentDownloader<M extends FilterableManifest<M>> impleme
@Nullable Integer lastIndex = lastIndexByCacheKey.get(cacheKey);
@Nullable Segment lastSegment = lastIndex == null ? null : segments.get(lastIndex);
if (lastSegment == null
|| segment.startTimeUs > lastSegment.startTimeUs + MAX_MERGED_SEGMENT_START_TIME_DIFF_US
|| segment.startTimeUs > lastSegment.startTimeUs + maxMergedSegmentStartTimeDiffUs
|| !canMergeSegments(lastSegment.dataSpec, segment.dataSpec)) {
lastIndexByCacheKey.put(cacheKey, nextOutIndex);
segments.set(nextOutIndex, segment);

View file

@ -182,8 +182,8 @@ public final class Requirements implements Parcelable {
private boolean isDeviceCharging(Context context) {
@Nullable
Intent batteryStatus =
Util.registerReceiverNotExported(
context, /* receiver= */ null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
context.registerReceiver(
/* receiver= */ null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
if (batteryStatus == null) {
return false;
}
@ -201,8 +201,8 @@ public final class Requirements implements Parcelable {
}
private boolean isStorageNotLow(Context context) {
return Util.registerReceiverNotExported(
context, /* receiver= */ null, new IntentFilter(Intent.ACTION_DEVICE_STORAGE_LOW))
return context.registerReceiver(
/* receiver= */ null, new IntentFilter(Intent.ACTION_DEVICE_STORAGE_LOW))
== null;
}

View file

@ -109,7 +109,7 @@ public final class RequirementsWatcher {
filter.addAction(Intent.ACTION_DEVICE_STORAGE_OK);
}
receiver = new DeviceStatusChangeReceiver();
Util.registerReceiverNotExported(context, receiver, filter, handler);
context.registerReceiver(receiver, filter, /* broadcastPermission= */ null, handler);
return notMetRequirements;
}

View file

@ -29,8 +29,12 @@ import java.util.Comparator;
* rate observations. This is an alternative to sliding mean and exponential averaging which suffer
* from susceptibility to outliers and slow adaptation to step functions.
*
* @see <a href="http://en.wikipedia.org/wiki/Moving_average">Wiki: Moving average</a>
* @see <a href="http://en.wikipedia.org/wiki/Selection_algorithm">Wiki: Selection algorithm</a>
* <p>See the following Wikipedia articles:
*
* <ul>
* <li><a href="http://en.wikipedia.org/wiki/Moving_average">Moving average</a>
* <li><a href="http://en.wikipedia.org/wiki/Selection_algorithm">Selection algorithm</a>
* </ul>
*/
public class SlidingPercentile {

View file

@ -150,6 +150,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
private long lastRenderRealtimeUs;
private long totalVideoFrameProcessingOffsetUs;
private int videoFrameProcessingOffsetCount;
private long lastFrameReleaseTimeNs;
private int currentWidth;
private int currentHeight;
@ -1125,9 +1126,18 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
if (Util.SDK_INT >= 21) {
// Let the underlying framework time the release.
if (earlyUs < 50000) {
notifyFrameMetadataListener(presentationTimeUs, adjustedReleaseTimeNs, format);
renderOutputBufferV21(codec, bufferIndex, presentationTimeUs, adjustedReleaseTimeNs);
if (adjustedReleaseTimeNs == lastFrameReleaseTimeNs) {
// This frame should be displayed on the same vsync with the previous released frame. We
// are likely rendering frames at a rate higher than the screen refresh rate. Skip
// this buffer so that it's returned to MediaCodec sooner otherwise MediaCodec may not
// be able to keep decoding with this rate [b/263454203].
skipOutputBuffer(codec, bufferIndex, presentationTimeUs);
} else {
notifyFrameMetadataListener(presentationTimeUs, adjustedReleaseTimeNs, format);
renderOutputBufferV21(codec, bufferIndex, presentationTimeUs, adjustedReleaseTimeNs);
}
updateVideoFrameProcessingOffsetCounters(earlyUs);
lastFrameReleaseTimeNs = adjustedReleaseTimeNs;
return true;
}
} else {

View file

@ -1,18 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2019 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="exo_download_description">Aflaai</string>
<string name="exo_download_notification_channel_name">Aflaaie</string>

View file

@ -1,18 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2019 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="exo_download_description">አውርድ</string>
<string name="exo_download_notification_channel_name">የወረዱ</string>

View file

@ -1,18 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2019 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="exo_download_description">تنزيل</string>
<string name="exo_download_notification_channel_name">عمليات التنزيل</string>

View file

@ -1,18 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2019 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="exo_download_description">Endirin</string>
<string name="exo_download_notification_channel_name">Endirmələr</string>

View file

@ -1,18 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2019 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="exo_download_description">Preuzmi</string>
<string name="exo_download_notification_channel_name">Preuzimanja</string>

View file

@ -1,18 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2019 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="exo_download_description">Спампаваць</string>
<string name="exo_download_notification_channel_name">Спампоўкі</string>

View file

@ -1,18 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2019 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="exo_download_description">Изтегляне</string>
<string name="exo_download_notification_channel_name">Изтегляния</string>

View file

@ -1,18 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2019 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="exo_download_description">ডাউনলোড করুন</string>
<string name="exo_download_notification_channel_name">ডাউনলোড</string>

View file

@ -1,18 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2019 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="exo_download_description">Preuzmi</string>
<string name="exo_download_notification_channel_name">Preuzimanja</string>

View file

@ -1,18 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2019 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="exo_download_description">Baixa</string>
<string name="exo_download_notification_channel_name">Baixades</string>

View file

@ -1,18 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2019 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="exo_download_description">Stáhnout</string>
<string name="exo_download_notification_channel_name">Stahování</string>

View file

@ -1,18 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2019 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="exo_download_description">Download</string>
<string name="exo_download_notification_channel_name">Downloads</string>

View file

@ -1,18 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2019 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="exo_download_description">Herunterladen</string>
<string name="exo_download_notification_channel_name">Downloads</string>

View file

@ -1,18 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2019 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="exo_download_description">Λήψη</string>
<string name="exo_download_notification_channel_name">Λήψεις</string>

View file

@ -1,18 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2019 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="exo_download_description">Download</string>
<string name="exo_download_notification_channel_name">Downloads</string>

View file

@ -1,18 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2019 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="exo_download_description">Download</string>
<string name="exo_download_notification_channel_name">Downloads</string>

View file

@ -1,18 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2019 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="exo_download_description">Download</string>
<string name="exo_download_notification_channel_name">Downloads</string>

View file

@ -1,18 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2019 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="exo_download_description">Descargar</string>
<string name="exo_download_notification_channel_name">Descargas</string>

View file

@ -1,18 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2019 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="exo_download_description">Descargar</string>
<string name="exo_download_notification_channel_name">Descargas</string>

View file

@ -1,18 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2019 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="exo_download_description">Allalaadimine</string>
<string name="exo_download_notification_channel_name">Allalaadimised</string>

View file

@ -1,18 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2019 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="exo_download_description">Deskargak</string>
<string name="exo_download_notification_channel_name">Deskargak</string>

View file

@ -1,18 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2019 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="exo_download_description">بارگیری</string>
<string name="exo_download_notification_channel_name">بارگیری‌ها</string>

View file

@ -1,18 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2019 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="exo_download_description">Lataa</string>
<string name="exo_download_notification_channel_name">Lataukset</string>

View file

@ -1,18 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2019 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="exo_download_description">Télécharger</string>
<string name="exo_download_notification_channel_name">Téléchargements</string>

View file

@ -1,18 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2019 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="exo_download_description">Télécharger</string>
<string name="exo_download_notification_channel_name">Téléchargements</string>

View file

@ -1,18 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2019 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="exo_download_description">Descargar</string>
<string name="exo_download_notification_channel_name">Descargas</string>

View file

@ -1,18 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2019 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="exo_download_description">ડાઉનલોડ કરો</string>
<string name="exo_download_notification_channel_name">ડાઉનલોડ</string>

View file

@ -1,18 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2019 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="exo_download_description">डाउनलोड करें</string>
<string name="exo_download_notification_channel_name">डाउनलोड की गई मीडिया फ़ाइलें</string>

View file

@ -1,18 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2019 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="exo_download_description">Preuzmi</string>
<string name="exo_download_notification_channel_name">Preuzimanja</string>

View file

@ -1,18 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2019 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="exo_download_description">Letöltés</string>
<string name="exo_download_notification_channel_name">Letöltések</string>

View file

@ -1,18 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2019 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="exo_download_description">Ներբեռնել</string>
<string name="exo_download_notification_channel_name">Ներբեռնումներ</string>

View file

@ -1,18 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2019 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="exo_download_description">Download</string>
<string name="exo_download_notification_channel_name">Download</string>

View file

@ -1,18 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2019 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="exo_download_description">Sækja</string>
<string name="exo_download_notification_channel_name">Niðurhal</string>

View file

@ -1,18 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2019 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="exo_download_description">Scarica</string>
<string name="exo_download_notification_channel_name">Download</string>

View file

@ -1,18 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2019 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="exo_download_description">הורדה</string>
<string name="exo_download_notification_channel_name">הורדות</string>

View file

@ -1,18 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2019 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="exo_download_description">ダウンロード</string>
<string name="exo_download_notification_channel_name">ダウンロード</string>

Some files were not shown because too many files have changed in this diff Show more