commit
d73d64bc6f
@ -1,6 +1,14 @@
|
|||||||
# Release notes #
|
# Release notes #
|
||||||
|
|
||||||
### 2.10.6 (2019-10-18) ###
|
### 2.10.7 (2019-11-12) ###
|
||||||
|
|
||||||
|
* HLS: Fix detection of Dolby Atmos to match the HLS authoring specification.
|
||||||
|
* MediaSession extension: Update shuffle and repeat modes when playback state
|
||||||
|
is invalidated ([#6582](https://github.com/google/ExoPlayer/issues/6582)).
|
||||||
|
* Fix the start of audio getting truncated when transitioning to a new
|
||||||
|
item in a playlist of opus streams.
|
||||||
|
|
||||||
|
### 2.10.6 (2019-10-17) ###
|
||||||
|
|
||||||
* Add `Player.onPlaybackSuppressionReasonChanged` to allow listeners to
|
* Add `Player.onPlaybackSuppressionReasonChanged` to allow listeners to
|
||||||
detect playbacks suppressions (e.g. transient audio focus loss) directly
|
detect playbacks suppressions (e.g. transient audio focus loss) directly
|
||||||
|
@ -13,8 +13,8 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
project.ext {
|
project.ext {
|
||||||
// ExoPlayer version and version code.
|
// ExoPlayer version and version code.
|
||||||
releaseVersion = '2.10.6'
|
releaseVersion = '2.10.7'
|
||||||
releaseVersionCode = 2010006
|
releaseVersionCode = 2010007
|
||||||
minSdkVersion = 16
|
minSdkVersion = 16
|
||||||
targetSdkVersion = 28
|
targetSdkVersion = 28
|
||||||
compileSdkVersion = 28
|
compileSdkVersion = 28
|
||||||
|
@ -308,7 +308,11 @@ public final class LeanbackPlayerAdapter extends PlayerAdapter implements Runnab
|
|||||||
@Override
|
@Override
|
||||||
public void onVideoSizeChanged(
|
public void onVideoSizeChanged(
|
||||||
int width, int height, int unappliedRotationDegrees, float pixelWidthHeightRatio) {
|
int width, int height, int unappliedRotationDegrees, float pixelWidthHeightRatio) {
|
||||||
getCallback().onVideoSizeChanged(LeanbackPlayerAdapter.this, width, height);
|
// There's no way to pass pixelWidthHeightRatio to leanback, so we scale the width that we
|
||||||
|
// pass to take it into account. This is necessary to ensure that leanback uses the correct
|
||||||
|
// aspect ratio when playing content with non-square pixels.
|
||||||
|
int scaledWidth = Math.round(width * pixelWidthHeightRatio);
|
||||||
|
getCallback().onVideoSizeChanged(LeanbackPlayerAdapter.this, scaledWidth, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -700,6 +700,9 @@ public final class MediaSessionConnector {
|
|||||||
/* position= */ 0,
|
/* position= */ 0,
|
||||||
/* playbackSpeed= */ 0,
|
/* playbackSpeed= */ 0,
|
||||||
/* updateTime= */ SystemClock.elapsedRealtime());
|
/* updateTime= */ SystemClock.elapsedRealtime());
|
||||||
|
|
||||||
|
mediaSession.setRepeatMode(PlaybackStateCompat.REPEAT_MODE_NONE);
|
||||||
|
mediaSession.setShuffleMode(PlaybackStateCompat.SHUFFLE_MODE_NONE);
|
||||||
mediaSession.setPlaybackState(builder.build());
|
mediaSession.setPlaybackState(builder.build());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -748,6 +751,18 @@ public final class MediaSessionConnector {
|
|||||||
sessionPlaybackSpeed,
|
sessionPlaybackSpeed,
|
||||||
/* updateTime= */ SystemClock.elapsedRealtime())
|
/* updateTime= */ SystemClock.elapsedRealtime())
|
||||||
.setExtras(extras);
|
.setExtras(extras);
|
||||||
|
|
||||||
|
@Player.RepeatMode int repeatMode = player.getRepeatMode();
|
||||||
|
mediaSession.setRepeatMode(
|
||||||
|
repeatMode == Player.REPEAT_MODE_ONE
|
||||||
|
? PlaybackStateCompat.REPEAT_MODE_ONE
|
||||||
|
: repeatMode == Player.REPEAT_MODE_ALL
|
||||||
|
? PlaybackStateCompat.REPEAT_MODE_ALL
|
||||||
|
: PlaybackStateCompat.REPEAT_MODE_NONE);
|
||||||
|
mediaSession.setShuffleMode(
|
||||||
|
player.getShuffleModeEnabled()
|
||||||
|
? PlaybackStateCompat.SHUFFLE_MODE_ALL
|
||||||
|
: PlaybackStateCompat.SHUFFLE_MODE_NONE);
|
||||||
mediaSession.setPlaybackState(builder.build());
|
mediaSession.setPlaybackState(builder.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1047,21 +1062,11 @@ public final class MediaSessionConnector {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRepeatModeChanged(@Player.RepeatMode int repeatMode) {
|
public void onRepeatModeChanged(@Player.RepeatMode int repeatMode) {
|
||||||
mediaSession.setRepeatMode(
|
|
||||||
repeatMode == Player.REPEAT_MODE_ONE
|
|
||||||
? PlaybackStateCompat.REPEAT_MODE_ONE
|
|
||||||
: repeatMode == Player.REPEAT_MODE_ALL
|
|
||||||
? PlaybackStateCompat.REPEAT_MODE_ALL
|
|
||||||
: PlaybackStateCompat.REPEAT_MODE_NONE);
|
|
||||||
invalidateMediaSessionPlaybackState();
|
invalidateMediaSessionPlaybackState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {
|
public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {
|
||||||
mediaSession.setShuffleMode(
|
|
||||||
shuffleModeEnabled
|
|
||||||
? PlaybackStateCompat.SHUFFLE_MODE_ALL
|
|
||||||
: PlaybackStateCompat.SHUFFLE_MODE_NONE);
|
|
||||||
invalidateMediaSessionPlaybackState();
|
invalidateMediaSessionPlaybackState();
|
||||||
invalidateMediaSessionQueue();
|
invalidateMediaSessionQueue();
|
||||||
}
|
}
|
||||||
|
@ -29,11 +29,11 @@ public final class ExoPlayerLibraryInfo {
|
|||||||
|
|
||||||
/** The version of the library expressed as a string, for example "1.2.3". */
|
/** 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.
|
// Intentionally hardcoded. Do not derive from other constants (e.g. VERSION_INT) or vice versa.
|
||||||
public static final String VERSION = "2.10.6";
|
public static final String VERSION = "2.10.7";
|
||||||
|
|
||||||
/** The version of the library expressed as {@code "ExoPlayerLib/" + VERSION}. */
|
/** The version of the library expressed as {@code "ExoPlayerLib/" + VERSION}. */
|
||||||
// Intentionally hardcoded. Do not derive from other constants (e.g. VERSION) or vice versa.
|
// Intentionally hardcoded. Do not derive from other constants (e.g. VERSION) or vice versa.
|
||||||
public static final String VERSION_SLASHY = "ExoPlayerLib/2.10.6";
|
public static final String VERSION_SLASHY = "ExoPlayerLib/2.10.7";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The version of the library expressed as an integer, for example 1002003.
|
* The version of the library expressed as an integer, for example 1002003.
|
||||||
@ -43,7 +43,7 @@ public final class ExoPlayerLibraryInfo {
|
|||||||
* integer version 123045006 (123-045-006).
|
* integer version 123045006 (123-045-006).
|
||||||
*/
|
*/
|
||||||
// Intentionally hardcoded. Do not derive from other constants (e.g. VERSION) or vice versa.
|
// Intentionally hardcoded. Do not derive from other constants (e.g. VERSION) or vice versa.
|
||||||
public static final int VERSION_INT = 2010006;
|
public static final int VERSION_INT = 2010007;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the library was compiled with {@link com.google.android.exoplayer2.util.Assertions}
|
* Whether the library was compiled with {@link com.google.android.exoplayer2.util.Assertions}
|
||||||
|
@ -434,13 +434,34 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
|
|||||||
} else if (codecInfo.isSeamlessAdaptationSupported(
|
} else if (codecInfo.isSeamlessAdaptationSupported(
|
||||||
oldFormat, newFormat, /* isNewFormatComplete= */ true)) {
|
oldFormat, newFormat, /* isNewFormatComplete= */ true)) {
|
||||||
return KEEP_CODEC_RESULT_YES_WITHOUT_RECONFIGURATION;
|
return KEEP_CODEC_RESULT_YES_WITHOUT_RECONFIGURATION;
|
||||||
} else if (areCodecConfigurationCompatible(oldFormat, newFormat)) {
|
} else if (canKeepCodecWithFlush(oldFormat, newFormat)) {
|
||||||
return KEEP_CODEC_RESULT_YES_WITH_FLUSH;
|
return KEEP_CODEC_RESULT_YES_WITH_FLUSH;
|
||||||
} else {
|
} else {
|
||||||
return KEEP_CODEC_RESULT_NO;
|
return KEEP_CODEC_RESULT_NO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the codec can be flushed and reused when switching to a new format. Reuse is
|
||||||
|
* generally possible when the codec would be configured in an identical way after the format
|
||||||
|
* change (excluding {@link MediaFormat#KEY_MAX_INPUT_SIZE} and configuration that does not come
|
||||||
|
* from the {@link Format}).
|
||||||
|
*
|
||||||
|
* @param oldFormat The first format.
|
||||||
|
* @param newFormat The second format.
|
||||||
|
* @return Whether the codec can be flushed and reused when switching to a new format.
|
||||||
|
*/
|
||||||
|
protected boolean canKeepCodecWithFlush(Format oldFormat, Format newFormat) {
|
||||||
|
// Flush and reuse the codec if the audio format and initialization data matches. For Opus, we
|
||||||
|
// don't flush and reuse the codec because the decoder may discard samples after flushing, which
|
||||||
|
// would result in audio being dropped just after a stream change (see [Internal: b/143450854]).
|
||||||
|
return Util.areEqual(oldFormat.sampleMimeType, newFormat.sampleMimeType)
|
||||||
|
&& oldFormat.channelCount == newFormat.channelCount
|
||||||
|
&& oldFormat.sampleRate == newFormat.sampleRate
|
||||||
|
&& oldFormat.initializationDataEquals(newFormat)
|
||||||
|
&& !MimeTypes.AUDIO_OPUS.equals(oldFormat.sampleMimeType);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MediaClock getMediaClock() {
|
public MediaClock getMediaClock() {
|
||||||
return this;
|
return this;
|
||||||
@ -818,24 +839,6 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
|
|||||||
return format.maxInputSize;
|
return format.maxInputSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether two {@link Format}s will cause the same codec to be configured in an identical
|
|
||||||
* way, excluding {@link MediaFormat#KEY_MAX_INPUT_SIZE} and configuration that does not come from
|
|
||||||
* the {@link Format}.
|
|
||||||
*
|
|
||||||
* @param oldFormat The first format.
|
|
||||||
* @param newFormat The second format.
|
|
||||||
* @return Whether the two formats will cause a codec to be configured in an identical way,
|
|
||||||
* excluding {@link MediaFormat#KEY_MAX_INPUT_SIZE} and configuration that does not come from
|
|
||||||
* the {@link Format}.
|
|
||||||
*/
|
|
||||||
protected boolean areCodecConfigurationCompatible(Format oldFormat, Format newFormat) {
|
|
||||||
return Util.areEqual(oldFormat.sampleMimeType, newFormat.sampleMimeType)
|
|
||||||
&& oldFormat.channelCount == newFormat.channelCount
|
|
||||||
&& oldFormat.sampleRate == newFormat.sampleRate
|
|
||||||
&& oldFormat.initializationDataEquals(newFormat);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the framework {@link MediaFormat} that can be used to configure a {@link MediaCodec}
|
* Returns the framework {@link MediaFormat} that can be used to configure a {@link MediaCodec}
|
||||||
* for decoding the given {@link Format} for playback.
|
* for decoding the given {@link Format} for playback.
|
||||||
|
@ -89,6 +89,10 @@ public interface Extractor {
|
|||||||
* {@link #RESULT_SEEK} is returned. If the extractor reached the end of the data provided by the
|
* {@link #RESULT_SEEK} is returned. If the extractor reached the end of the data provided by the
|
||||||
* {@link ExtractorInput}, then {@link #RESULT_END_OF_INPUT} is returned.
|
* {@link ExtractorInput}, then {@link #RESULT_END_OF_INPUT} is returned.
|
||||||
*
|
*
|
||||||
|
* <p>When this method throws an {@link IOException} or an {@link InterruptedException},
|
||||||
|
* extraction may continue by providing an {@link ExtractorInput} with an unchanged {@link
|
||||||
|
* ExtractorInput#getPosition() read position} to a subsequent call to this method.
|
||||||
|
*
|
||||||
* @param input The {@link ExtractorInput} from which data should be read.
|
* @param input The {@link ExtractorInput} from which data should be read.
|
||||||
* @param seekPosition If {@link #RESULT_SEEK} is returned, this holder is updated to hold the
|
* @param seekPosition If {@link #RESULT_SEEK} is returned, this holder is updated to hold the
|
||||||
* position of the required data.
|
* position of the required data.
|
||||||
|
@ -348,9 +348,7 @@ import java.util.List;
|
|||||||
}
|
}
|
||||||
long durationUs = Util.scaleLargeTimestamp(duration, C.MICROS_PER_SECOND, track.timescale);
|
long durationUs = Util.scaleLargeTimestamp(duration, C.MICROS_PER_SECOND, track.timescale);
|
||||||
|
|
||||||
if (track.editListDurations == null || gaplessInfoHolder.hasGaplessInfo()) {
|
if (track.editListDurations == null) {
|
||||||
// There is no edit list, or we are ignoring it as we already have gapless metadata to apply.
|
|
||||||
// This implementation does not support applying both gapless metadata and an edit list.
|
|
||||||
Util.scaleLargeTimestampsInPlace(timestamps, C.MICROS_PER_SECOND, track.timescale);
|
Util.scaleLargeTimestampsInPlace(timestamps, C.MICROS_PER_SECOND, track.timescale);
|
||||||
return new TrackSampleTable(
|
return new TrackSampleTable(
|
||||||
track, offsets, sizes, maximumSize, timestamps, flags, durationUs);
|
track, offsets, sizes, maximumSize, timestamps, flags, durationUs);
|
||||||
|
@ -78,17 +78,17 @@ import java.util.List;
|
|||||||
List<byte[]> initializationData = Collections.singletonList(metadata);
|
List<byte[]> initializationData = Collections.singletonList(metadata);
|
||||||
setupData.format =
|
setupData.format =
|
||||||
Format.createAudioSampleFormat(
|
Format.createAudioSampleFormat(
|
||||||
null,
|
/* id= */ null,
|
||||||
MimeTypes.AUDIO_FLAC,
|
MimeTypes.AUDIO_FLAC,
|
||||||
null,
|
/* codecs= */ null,
|
||||||
Format.NO_VALUE,
|
|
||||||
streamMetadata.bitRate(),
|
streamMetadata.bitRate(),
|
||||||
|
/* maxInputSize= */ Format.NO_VALUE,
|
||||||
streamMetadata.channels,
|
streamMetadata.channels,
|
||||||
streamMetadata.sampleRate,
|
streamMetadata.sampleRate,
|
||||||
initializationData,
|
initializationData,
|
||||||
null,
|
/* drmInitData= */ null,
|
||||||
0,
|
/* selectionFlags= */ 0,
|
||||||
null);
|
/* language= */ null);
|
||||||
} else if ((data[0] & 0x7F) == SEEKTABLE_PACKET_TYPE) {
|
} else if ((data[0] & 0x7F) == SEEKTABLE_PACKET_TYPE) {
|
||||||
flacOggSeeker = new FlacOggSeeker();
|
flacOggSeeker = new FlacOggSeeker();
|
||||||
flacOggSeeker.parseSeekTable(packet);
|
flacOggSeeker.parseSeekTable(packet);
|
||||||
|
@ -23,7 +23,7 @@ import com.google.android.exoplayer2.util.Util;
|
|||||||
/** Header for a WAV file. */
|
/** Header for a WAV file. */
|
||||||
/* package */ final class WavHeader implements SeekMap {
|
/* package */ final class WavHeader implements SeekMap {
|
||||||
|
|
||||||
/** Number of audio chanels. */
|
/** Number of audio channels. */
|
||||||
private final int numChannels;
|
private final int numChannels;
|
||||||
/** Sample rate in Hertz. */
|
/** Sample rate in Hertz. */
|
||||||
private final int sampleRateHz;
|
private final int sampleRateHz;
|
||||||
|
@ -328,13 +328,13 @@ public final class MediaCodecInfo {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the decoder supports video with a given width, height and frame rate.
|
* Whether the decoder supports video with a given width, height and frame rate.
|
||||||
* <p>
|
*
|
||||||
* Must not be called if the device SDK version is less than 21.
|
* <p>Must not be called if the device SDK version is less than 21.
|
||||||
*
|
*
|
||||||
* @param width Width in pixels.
|
* @param width Width in pixels.
|
||||||
* @param height Height in pixels.
|
* @param height Height in pixels.
|
||||||
* @param frameRate Optional frame rate in frames per second. Ignored if set to
|
* @param frameRate Optional frame rate in frames per second. Ignored if set to {@link
|
||||||
* {@link Format#NO_VALUE} or any value less than or equal to 0.
|
* Format#NO_VALUE} or any value less than or equal to 0.
|
||||||
* @return Whether the decoder supports video with the given width, height and frame rate.
|
* @return Whether the decoder supports video with the given width, height and frame rate.
|
||||||
*/
|
*/
|
||||||
@TargetApi(21)
|
@TargetApi(21)
|
||||||
|
@ -32,7 +32,8 @@ public class Cue {
|
|||||||
public static final Cue EMPTY = new Cue("");
|
public static final Cue EMPTY = new Cue("");
|
||||||
|
|
||||||
/** An unset position or width. */
|
/** An unset position or width. */
|
||||||
public static final float DIMEN_UNSET = Float.MIN_VALUE;
|
// Note: We deliberately don't use Float.MIN_VALUE because it's positive & very close to zero.
|
||||||
|
public static final float DIMEN_UNSET = -Float.MAX_VALUE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type of anchor, which may be unset. One of {@link #TYPE_UNSET}, {@link #ANCHOR_TYPE_START},
|
* The type of anchor, which may be unset. One of {@link #TYPE_UNSET}, {@link #ANCHOR_TYPE_START},
|
||||||
|
@ -5,11 +5,11 @@ seekMap:
|
|||||||
numberOfTracks = 1
|
numberOfTracks = 1
|
||||||
track 0:
|
track 0:
|
||||||
format:
|
format:
|
||||||
bitrate = -1
|
bitrate = 768000
|
||||||
id = null
|
id = null
|
||||||
containerMimeType = null
|
containerMimeType = null
|
||||||
sampleMimeType = audio/flac
|
sampleMimeType = audio/flac
|
||||||
maxInputSize = 768000
|
maxInputSize = -1
|
||||||
width = -1
|
width = -1
|
||||||
height = -1
|
height = -1
|
||||||
frameRate = -1.0
|
frameRate = -1.0
|
||||||
|
@ -5,11 +5,11 @@ seekMap:
|
|||||||
numberOfTracks = 1
|
numberOfTracks = 1
|
||||||
track 0:
|
track 0:
|
||||||
format:
|
format:
|
||||||
bitrate = -1
|
bitrate = 768000
|
||||||
id = null
|
id = null
|
||||||
containerMimeType = null
|
containerMimeType = null
|
||||||
sampleMimeType = audio/flac
|
sampleMimeType = audio/flac
|
||||||
maxInputSize = 768000
|
maxInputSize = -1
|
||||||
width = -1
|
width = -1
|
||||||
height = -1
|
height = -1
|
||||||
frameRate = -1.0
|
frameRate = -1.0
|
||||||
|
@ -5,11 +5,11 @@ seekMap:
|
|||||||
numberOfTracks = 1
|
numberOfTracks = 1
|
||||||
track 0:
|
track 0:
|
||||||
format:
|
format:
|
||||||
bitrate = -1
|
bitrate = 768000
|
||||||
id = null
|
id = null
|
||||||
containerMimeType = null
|
containerMimeType = null
|
||||||
sampleMimeType = audio/flac
|
sampleMimeType = audio/flac
|
||||||
maxInputSize = 768000
|
maxInputSize = -1
|
||||||
width = -1
|
width = -1
|
||||||
height = -1
|
height = -1
|
||||||
frameRate = -1.0
|
frameRate = -1.0
|
||||||
|
@ -5,11 +5,11 @@ seekMap:
|
|||||||
numberOfTracks = 1
|
numberOfTracks = 1
|
||||||
track 0:
|
track 0:
|
||||||
format:
|
format:
|
||||||
bitrate = -1
|
bitrate = 768000
|
||||||
id = null
|
id = null
|
||||||
containerMimeType = null
|
containerMimeType = null
|
||||||
sampleMimeType = audio/flac
|
sampleMimeType = audio/flac
|
||||||
maxInputSize = 768000
|
maxInputSize = -1
|
||||||
width = -1
|
width = -1
|
||||||
height = -1
|
height = -1
|
||||||
frameRate = -1.0
|
frameRate = -1.0
|
||||||
|
@ -5,11 +5,11 @@ seekMap:
|
|||||||
numberOfTracks = 1
|
numberOfTracks = 1
|
||||||
track 0:
|
track 0:
|
||||||
format:
|
format:
|
||||||
bitrate = -1
|
bitrate = 768000
|
||||||
id = null
|
id = null
|
||||||
containerMimeType = null
|
containerMimeType = null
|
||||||
sampleMimeType = audio/flac
|
sampleMimeType = audio/flac
|
||||||
maxInputSize = 768000
|
maxInputSize = -1
|
||||||
width = -1
|
width = -1
|
||||||
height = -1
|
height = -1
|
||||||
frameRate = -1.0
|
frameRate = -1.0
|
||||||
|
@ -5,11 +5,11 @@ seekMap:
|
|||||||
numberOfTracks = 1
|
numberOfTracks = 1
|
||||||
track 0:
|
track 0:
|
||||||
format:
|
format:
|
||||||
bitrate = -1
|
bitrate = 768000
|
||||||
id = null
|
id = null
|
||||||
containerMimeType = null
|
containerMimeType = null
|
||||||
sampleMimeType = audio/flac
|
sampleMimeType = audio/flac
|
||||||
maxInputSize = 768000
|
maxInputSize = -1
|
||||||
width = -1
|
width = -1
|
||||||
height = -1
|
height = -1
|
||||||
frameRate = -1.0
|
frameRate = -1.0
|
||||||
|
@ -5,11 +5,11 @@ seekMap:
|
|||||||
numberOfTracks = 1
|
numberOfTracks = 1
|
||||||
track 0:
|
track 0:
|
||||||
format:
|
format:
|
||||||
bitrate = -1
|
bitrate = 768000
|
||||||
id = null
|
id = null
|
||||||
containerMimeType = null
|
containerMimeType = null
|
||||||
sampleMimeType = audio/flac
|
sampleMimeType = audio/flac
|
||||||
maxInputSize = 768000
|
maxInputSize = -1
|
||||||
width = -1
|
width = -1
|
||||||
height = -1
|
height = -1
|
||||||
frameRate = -1.0
|
frameRate = -1.0
|
||||||
|
@ -5,11 +5,11 @@ seekMap:
|
|||||||
numberOfTracks = 1
|
numberOfTracks = 1
|
||||||
track 0:
|
track 0:
|
||||||
format:
|
format:
|
||||||
bitrate = -1
|
bitrate = 768000
|
||||||
id = null
|
id = null
|
||||||
containerMimeType = null
|
containerMimeType = null
|
||||||
sampleMimeType = audio/flac
|
sampleMimeType = audio/flac
|
||||||
maxInputSize = 768000
|
maxInputSize = -1
|
||||||
width = -1
|
width = -1
|
||||||
height = -1
|
height = -1
|
||||||
frameRate = -1.0
|
frameRate = -1.0
|
||||||
|
@ -5,11 +5,11 @@ seekMap:
|
|||||||
numberOfTracks = 1
|
numberOfTracks = 1
|
||||||
track 0:
|
track 0:
|
||||||
format:
|
format:
|
||||||
bitrate = -1
|
bitrate = 768000
|
||||||
id = null
|
id = null
|
||||||
containerMimeType = null
|
containerMimeType = null
|
||||||
sampleMimeType = audio/flac
|
sampleMimeType = audio/flac
|
||||||
maxInputSize = 768000
|
maxInputSize = -1
|
||||||
width = -1
|
width = -1
|
||||||
height = -1
|
height = -1
|
||||||
frameRate = -1.0
|
frameRate = -1.0
|
||||||
|
@ -5,11 +5,11 @@ seekMap:
|
|||||||
numberOfTracks = 1
|
numberOfTracks = 1
|
||||||
track 0:
|
track 0:
|
||||||
format:
|
format:
|
||||||
bitrate = -1
|
bitrate = 768000
|
||||||
id = null
|
id = null
|
||||||
containerMimeType = null
|
containerMimeType = null
|
||||||
sampleMimeType = audio/flac
|
sampleMimeType = audio/flac
|
||||||
maxInputSize = 768000
|
maxInputSize = -1
|
||||||
width = -1
|
width = -1
|
||||||
height = -1
|
height = -1
|
||||||
frameRate = -1.0
|
frameRate = -1.0
|
||||||
|
@ -445,7 +445,15 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
|
|||||||
? Util.getCodecsOfType(variant.format.codecs, C.TRACK_TYPE_AUDIO)
|
? Util.getCodecsOfType(variant.format.codecs, C.TRACK_TYPE_AUDIO)
|
||||||
: null;
|
: null;
|
||||||
sampleMimeType = codecs != null ? MimeTypes.getMediaMimeType(codecs) : null;
|
sampleMimeType = codecs != null ? MimeTypes.getMediaMimeType(codecs) : null;
|
||||||
int channelCount = parseChannelsAttribute(line, variableDefinitions);
|
String channelsString =
|
||||||
|
parseOptionalStringAttr(line, REGEX_CHANNELS, variableDefinitions);
|
||||||
|
int channelCount = Format.NO_VALUE;
|
||||||
|
if (channelsString != null) {
|
||||||
|
channelCount = Integer.parseInt(Util.splitAtFirst(channelsString, "/")[0]);
|
||||||
|
if (MimeTypes.AUDIO_E_AC3.equals(sampleMimeType) && channelsString.endsWith("/JOC")) {
|
||||||
|
sampleMimeType = MimeTypes.AUDIO_E_AC3_JOC;
|
||||||
|
}
|
||||||
|
}
|
||||||
format =
|
format =
|
||||||
Format.createAudioContainerFormat(
|
Format.createAudioContainerFormat(
|
||||||
/* id= */ formatId,
|
/* id= */ formatId,
|
||||||
@ -819,13 +827,6 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
|
|||||||
return roleFlags;
|
return roleFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int parseChannelsAttribute(String line, Map<String, String> variableDefinitions) {
|
|
||||||
String channelsString = parseOptionalStringAttr(line, REGEX_CHANNELS, variableDefinitions);
|
|
||||||
return channelsString != null
|
|
||||||
? Integer.parseInt(Util.splitAtFirst(channelsString, "/")[0])
|
|
||||||
: Format.NO_VALUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private static SchemeData parseDrmSchemeData(
|
private static SchemeData parseDrmSchemeData(
|
||||||
String line, String keyFormat, Map<String, String> variableDefinitions)
|
String line, String keyFormat, Map<String, String> variableDefinitions)
|
||||||
|
@ -1348,7 +1348,12 @@ public class PlayerNotificationManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRepeatModeChanged(int repeatMode) {
|
public void onRepeatModeChanged(@Player.RepeatMode int repeatMode) {
|
||||||
|
startOrUpdateNotification();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {
|
||||||
startOrUpdateNotification();
|
startOrUpdateNotification();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,6 +60,7 @@ public class FakeAdaptiveMediaPeriod extends FakeMediaPeriod
|
|||||||
this.transferListener = transferListener;
|
this.transferListener = transferListener;
|
||||||
this.durationUs = durationUs;
|
this.durationUs = durationUs;
|
||||||
this.sampleStreams = newSampleStreamArray(0);
|
this.sampleStreams = newSampleStreamArray(0);
|
||||||
|
this.sequenceableLoader = new CompositeSequenceableLoader(new SequenceableLoader[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
x
Reference in New Issue
Block a user