1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.google.android.exoplayer2; 17 18 import androidx.annotation.CheckResult; 19 import androidx.annotation.Nullable; 20 import com.google.android.exoplayer2.Player.PlaybackSuppressionReason; 21 import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId; 22 import com.google.android.exoplayer2.source.TrackGroupArray; 23 import com.google.android.exoplayer2.trackselection.TrackSelectorResult; 24 25 /** 26 * Information about an ongoing playback. 27 */ 28 /* package */ final class PlaybackInfo { 29 30 /** 31 * Dummy media period id used while the timeline is empty and no period id is specified. This id 32 * is used when playback infos are created with {@link #createDummy(TrackSelectorResult)}. 33 */ 34 private static final MediaPeriodId DUMMY_MEDIA_PERIOD_ID = 35 new MediaPeriodId(/* periodUid= */ new Object()); 36 37 /** The current {@link Timeline}. */ 38 public final Timeline timeline; 39 /** The {@link MediaPeriodId} of the currently playing media period in the {@link #timeline}. */ 40 public final MediaPeriodId periodId; 41 /** 42 * The requested next start position for the current period in the {@link #timeline}, in 43 * microseconds, or {@link C#TIME_UNSET} if the period was requested to start at its default 44 * position. 45 * 46 * <p>Note that if {@link #periodId} refers to an ad, this is the requested start position for the 47 * suspended content. 48 */ 49 public final long requestedContentPositionUs; 50 /** The current playback state. One of the {@link Player}.STATE_ constants. */ 51 @Player.State public final int playbackState; 52 /** The current playback error, or null if this is not an error state. */ 53 @Nullable public final ExoPlaybackException playbackError; 54 /** Whether the player is currently loading. */ 55 public final boolean isLoading; 56 /** The currently available track groups. */ 57 public final TrackGroupArray trackGroups; 58 /** The result of the current track selection. */ 59 public final TrackSelectorResult trackSelectorResult; 60 /** The {@link MediaPeriodId} of the currently loading media period in the {@link #timeline}. */ 61 public final MediaPeriodId loadingMediaPeriodId; 62 /** Whether playback should proceed when {@link #playbackState} == {@link Player#STATE_READY}. */ 63 public final boolean playWhenReady; 64 /** Reason why playback is suppressed even though {@link #playWhenReady} is {@code true}. */ 65 @PlaybackSuppressionReason public final int playbackSuppressionReason; 66 67 /** 68 * Position up to which media is buffered in {@link #loadingMediaPeriodId) relative to the start 69 * of the associated period in the {@link #timeline}, in microseconds. 70 */ 71 public volatile long bufferedPositionUs; 72 /** 73 * Total duration of buffered media from {@link #positionUs} to {@link #bufferedPositionUs} 74 * including all ads. 75 */ 76 public volatile long totalBufferedDurationUs; 77 /** 78 * Current playback position in {@link #periodId} relative to the start of the associated period 79 * in the {@link #timeline}, in microseconds. 80 */ 81 public volatile long positionUs; 82 83 /** 84 * Creates empty dummy playback info which can be used for masking as long as no real playback 85 * info is available. 86 * 87 * @param emptyTrackSelectorResult An empty track selector result with null entries for each 88 * renderer. 89 * @return A dummy playback info. 90 */ createDummy(TrackSelectorResult emptyTrackSelectorResult)91 public static PlaybackInfo createDummy(TrackSelectorResult emptyTrackSelectorResult) { 92 return new PlaybackInfo( 93 Timeline.EMPTY, 94 DUMMY_MEDIA_PERIOD_ID, 95 /* requestedContentPositionUs= */ C.TIME_UNSET, 96 Player.STATE_IDLE, 97 /* playbackError= */ null, 98 /* isLoading= */ false, 99 TrackGroupArray.EMPTY, 100 emptyTrackSelectorResult, 101 DUMMY_MEDIA_PERIOD_ID, 102 /* playWhenReady= */ false, 103 Player.PLAYBACK_SUPPRESSION_REASON_NONE, 104 /* bufferedPositionUs= */ 0, 105 /* totalBufferedDurationUs= */ 0, 106 /* positionUs= */ 0); 107 } 108 109 /** 110 * Create playback info. 111 * 112 * @param timeline See {@link #timeline}. 113 * @param periodId See {@link #periodId}. 114 * @param requestedContentPositionUs See {@link #requestedContentPositionUs}. 115 * @param playbackState See {@link #playbackState}. 116 * @param isLoading See {@link #isLoading}. 117 * @param trackGroups See {@link #trackGroups}. 118 * @param trackSelectorResult See {@link #trackSelectorResult}. 119 * @param loadingMediaPeriodId See {@link #loadingMediaPeriodId}. 120 * @param bufferedPositionUs See {@link #bufferedPositionUs}. 121 * @param totalBufferedDurationUs See {@link #totalBufferedDurationUs}. 122 * @param positionUs See {@link #positionUs}. 123 */ PlaybackInfo( Timeline timeline, MediaPeriodId periodId, long requestedContentPositionUs, @Player.State int playbackState, @Nullable ExoPlaybackException playbackError, boolean isLoading, TrackGroupArray trackGroups, TrackSelectorResult trackSelectorResult, MediaPeriodId loadingMediaPeriodId, boolean playWhenReady, @PlaybackSuppressionReason int playbackSuppressionReason, long bufferedPositionUs, long totalBufferedDurationUs, long positionUs)124 public PlaybackInfo( 125 Timeline timeline, 126 MediaPeriodId periodId, 127 long requestedContentPositionUs, 128 @Player.State int playbackState, 129 @Nullable ExoPlaybackException playbackError, 130 boolean isLoading, 131 TrackGroupArray trackGroups, 132 TrackSelectorResult trackSelectorResult, 133 MediaPeriodId loadingMediaPeriodId, 134 boolean playWhenReady, 135 @PlaybackSuppressionReason int playbackSuppressionReason, 136 long bufferedPositionUs, 137 long totalBufferedDurationUs, 138 long positionUs) { 139 this.timeline = timeline; 140 this.periodId = periodId; 141 this.requestedContentPositionUs = requestedContentPositionUs; 142 this.playbackState = playbackState; 143 this.playbackError = playbackError; 144 this.isLoading = isLoading; 145 this.trackGroups = trackGroups; 146 this.trackSelectorResult = trackSelectorResult; 147 this.loadingMediaPeriodId = loadingMediaPeriodId; 148 this.playWhenReady = playWhenReady; 149 this.playbackSuppressionReason = playbackSuppressionReason; 150 this.bufferedPositionUs = bufferedPositionUs; 151 this.totalBufferedDurationUs = totalBufferedDurationUs; 152 this.positionUs = positionUs; 153 } 154 155 /** Returns dummy period id for an empty timeline. */ getDummyPeriodForEmptyTimeline()156 public static MediaPeriodId getDummyPeriodForEmptyTimeline() { 157 return DUMMY_MEDIA_PERIOD_ID; 158 } 159 160 /** 161 * Copies playback info with new playing position. 162 * 163 * @param periodId New playing media period. See {@link #periodId}. 164 * @param positionUs New position. See {@link #positionUs}. 165 * @param requestedContentPositionUs New requested content position. See {@link 166 * #requestedContentPositionUs}. 167 * @param totalBufferedDurationUs New buffered duration. See {@link #totalBufferedDurationUs}. 168 * @param trackGroups The track groups for the new position. See {@link #trackGroups}. 169 * @param trackSelectorResult The track selector result for the new position. See {@link 170 * #trackSelectorResult}. 171 * @return Copied playback info with new playing position. 172 */ 173 @CheckResult copyWithNewPosition( MediaPeriodId periodId, long positionUs, long requestedContentPositionUs, long totalBufferedDurationUs, TrackGroupArray trackGroups, TrackSelectorResult trackSelectorResult)174 public PlaybackInfo copyWithNewPosition( 175 MediaPeriodId periodId, 176 long positionUs, 177 long requestedContentPositionUs, 178 long totalBufferedDurationUs, 179 TrackGroupArray trackGroups, 180 TrackSelectorResult trackSelectorResult) { 181 return new PlaybackInfo( 182 timeline, 183 periodId, 184 requestedContentPositionUs, 185 playbackState, 186 playbackError, 187 isLoading, 188 trackGroups, 189 trackSelectorResult, 190 loadingMediaPeriodId, 191 playWhenReady, 192 playbackSuppressionReason, 193 bufferedPositionUs, 194 totalBufferedDurationUs, 195 positionUs); 196 } 197 198 /** 199 * Copies playback info with the new timeline. 200 * 201 * @param timeline New timeline. See {@link #timeline}. 202 * @return Copied playback info with the new timeline. 203 */ 204 @CheckResult copyWithTimeline(Timeline timeline)205 public PlaybackInfo copyWithTimeline(Timeline timeline) { 206 return new PlaybackInfo( 207 timeline, 208 periodId, 209 requestedContentPositionUs, 210 playbackState, 211 playbackError, 212 isLoading, 213 trackGroups, 214 trackSelectorResult, 215 loadingMediaPeriodId, 216 playWhenReady, 217 playbackSuppressionReason, 218 bufferedPositionUs, 219 totalBufferedDurationUs, 220 positionUs); 221 } 222 223 /** 224 * Copies playback info with new playback state. 225 * 226 * @param playbackState New playback state. See {@link #playbackState}. 227 * @return Copied playback info with new playback state. 228 */ 229 @CheckResult copyWithPlaybackState(int playbackState)230 public PlaybackInfo copyWithPlaybackState(int playbackState) { 231 return new PlaybackInfo( 232 timeline, 233 periodId, 234 requestedContentPositionUs, 235 playbackState, 236 playbackError, 237 isLoading, 238 trackGroups, 239 trackSelectorResult, 240 loadingMediaPeriodId, 241 playWhenReady, 242 playbackSuppressionReason, 243 bufferedPositionUs, 244 totalBufferedDurationUs, 245 positionUs); 246 } 247 248 /** 249 * Copies playback info with a playback error. 250 * 251 * @param playbackError The error. See {@link #playbackError}. 252 * @return Copied playback info with the playback error. 253 */ 254 @CheckResult copyWithPlaybackError(@ullable ExoPlaybackException playbackError)255 public PlaybackInfo copyWithPlaybackError(@Nullable ExoPlaybackException playbackError) { 256 return new PlaybackInfo( 257 timeline, 258 periodId, 259 requestedContentPositionUs, 260 playbackState, 261 playbackError, 262 isLoading, 263 trackGroups, 264 trackSelectorResult, 265 loadingMediaPeriodId, 266 playWhenReady, 267 playbackSuppressionReason, 268 bufferedPositionUs, 269 totalBufferedDurationUs, 270 positionUs); 271 } 272 273 /** 274 * Copies playback info with new loading state. 275 * 276 * @param isLoading New loading state. See {@link #isLoading}. 277 * @return Copied playback info with new loading state. 278 */ 279 @CheckResult copyWithIsLoading(boolean isLoading)280 public PlaybackInfo copyWithIsLoading(boolean isLoading) { 281 return new PlaybackInfo( 282 timeline, 283 periodId, 284 requestedContentPositionUs, 285 playbackState, 286 playbackError, 287 isLoading, 288 trackGroups, 289 trackSelectorResult, 290 loadingMediaPeriodId, 291 playWhenReady, 292 playbackSuppressionReason, 293 bufferedPositionUs, 294 totalBufferedDurationUs, 295 positionUs); 296 } 297 298 /** 299 * Copies playback info with new loading media period. 300 * 301 * @param loadingMediaPeriodId New loading media period id. See {@link #loadingMediaPeriodId}. 302 * @return Copied playback info with new loading media period. 303 */ 304 @CheckResult copyWithLoadingMediaPeriodId(MediaPeriodId loadingMediaPeriodId)305 public PlaybackInfo copyWithLoadingMediaPeriodId(MediaPeriodId loadingMediaPeriodId) { 306 return new PlaybackInfo( 307 timeline, 308 periodId, 309 requestedContentPositionUs, 310 playbackState, 311 playbackError, 312 isLoading, 313 trackGroups, 314 trackSelectorResult, 315 loadingMediaPeriodId, 316 playWhenReady, 317 playbackSuppressionReason, 318 bufferedPositionUs, 319 totalBufferedDurationUs, 320 positionUs); 321 } 322 323 /** 324 * Copies playback info with new information about whether playback should proceed when ready. 325 * 326 * @param playWhenReady Whether playback should proceed when {@link #playbackState} == {@link 327 * Player#STATE_READY}. 328 * @param playbackSuppressionReason Reason why playback is suppressed even though {@link 329 * #playWhenReady} is {@code true}. 330 * @return Copied playback info with new information. 331 */ 332 @CheckResult copyWithPlayWhenReady( boolean playWhenReady, @PlaybackSuppressionReason int playbackSuppressionReason)333 public PlaybackInfo copyWithPlayWhenReady( 334 boolean playWhenReady, @PlaybackSuppressionReason int playbackSuppressionReason) { 335 return new PlaybackInfo( 336 timeline, 337 periodId, 338 requestedContentPositionUs, 339 playbackState, 340 playbackError, 341 isLoading, 342 trackGroups, 343 trackSelectorResult, 344 loadingMediaPeriodId, 345 playWhenReady, 346 playbackSuppressionReason, 347 bufferedPositionUs, 348 totalBufferedDurationUs, 349 positionUs); 350 } 351 } 352