• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.source;
17 
18 import androidx.annotation.Nullable;
19 import com.google.android.exoplayer2.C;
20 import com.google.android.exoplayer2.Format;
21 import com.google.android.exoplayer2.Player;
22 import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
23 import com.google.android.exoplayer2.util.Assertions;
24 import com.google.android.exoplayer2.util.CopyOnWriteMultiset;
25 import com.google.android.exoplayer2.util.MediaSourceEventDispatcher;
26 import java.io.IOException;
27 
28 /** Interface for callbacks to be notified of {@link MediaSource} events. */
29 public interface MediaSourceEventListener {
30 
31   /**
32    * Called when a media period is created by the media source.
33    *
34    * @param windowIndex The window index in the timeline this media period belongs to.
35    * @param mediaPeriodId The {@link MediaPeriodId} of the created media period.
36    */
onMediaPeriodCreated(int windowIndex, MediaPeriodId mediaPeriodId)37   default void onMediaPeriodCreated(int windowIndex, MediaPeriodId mediaPeriodId) {}
38 
39   /**
40    * Called when a media period is released by the media source.
41    *
42    * @param windowIndex The window index in the timeline this media period belongs to.
43    * @param mediaPeriodId The {@link MediaPeriodId} of the released media period.
44    */
onMediaPeriodReleased(int windowIndex, MediaPeriodId mediaPeriodId)45   default void onMediaPeriodReleased(int windowIndex, MediaPeriodId mediaPeriodId) {}
46 
47   /**
48    * Called when a load begins.
49    *
50    * @param windowIndex The window index in the timeline of the media source this load belongs to.
51    * @param mediaPeriodId The {@link MediaPeriodId} this load belongs to. Null if the load does not
52    *     belong to a specific media period.
53    * @param loadEventInfo The {@link LoadEventInfo} corresponding to the event. The value of {@link
54    *     LoadEventInfo#uri} won't reflect potential redirection yet and {@link
55    *     LoadEventInfo#responseHeaders} will be empty.
56    * @param mediaLoadData The {@link MediaLoadData} defining the data being loaded.
57    */
onLoadStarted( int windowIndex, @Nullable MediaPeriodId mediaPeriodId, LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData)58   default void onLoadStarted(
59       int windowIndex,
60       @Nullable MediaPeriodId mediaPeriodId,
61       LoadEventInfo loadEventInfo,
62       MediaLoadData mediaLoadData) {}
63 
64   /**
65    * Called when a load ends.
66    *
67    * @param windowIndex The window index in the timeline of the media source this load belongs to.
68    * @param mediaPeriodId The {@link MediaPeriodId} this load belongs to. Null if the load does not
69    *     belong to a specific media period.
70    * @param loadEventInfo The {@link LoadEventInfo} corresponding to the event. The values of {@link
71    *     LoadEventInfo#elapsedRealtimeMs} and {@link LoadEventInfo#bytesLoaded} are relative to the
72    *     corresponding {@link #onLoadStarted(int, MediaPeriodId, LoadEventInfo, MediaLoadData)}
73    *     event.
74    * @param mediaLoadData The {@link MediaLoadData} defining the data being loaded.
75    */
onLoadCompleted( int windowIndex, @Nullable MediaPeriodId mediaPeriodId, LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData)76   default void onLoadCompleted(
77       int windowIndex,
78       @Nullable MediaPeriodId mediaPeriodId,
79       LoadEventInfo loadEventInfo,
80       MediaLoadData mediaLoadData) {}
81 
82   /**
83    * Called when a load is canceled.
84    *
85    * @param windowIndex The window index in the timeline of the media source this load belongs to.
86    * @param mediaPeriodId The {@link MediaPeriodId} this load belongs to. Null if the load does not
87    *     belong to a specific media period.
88    * @param loadEventInfo The {@link LoadEventInfo} corresponding to the event. The values of {@link
89    *     LoadEventInfo#elapsedRealtimeMs} and {@link LoadEventInfo#bytesLoaded} are relative to the
90    *     corresponding {@link #onLoadStarted(int, MediaPeriodId, LoadEventInfo, MediaLoadData)}
91    *     event.
92    * @param mediaLoadData The {@link MediaLoadData} defining the data being loaded.
93    */
onLoadCanceled( int windowIndex, @Nullable MediaPeriodId mediaPeriodId, LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData)94   default void onLoadCanceled(
95       int windowIndex,
96       @Nullable MediaPeriodId mediaPeriodId,
97       LoadEventInfo loadEventInfo,
98       MediaLoadData mediaLoadData) {}
99 
100   /**
101    * Called when a load error occurs.
102    *
103    * <p>The error may or may not have resulted in the load being canceled, as indicated by the
104    * {@code wasCanceled} parameter. If the load was canceled, {@link #onLoadCanceled} will
105    * <em>not</em> be called in addition to this method.
106    *
107    * <p>This method being called does not indicate that playback has failed, or that it will fail.
108    * The player may be able to recover from the error and continue. Hence applications should
109    * <em>not</em> implement this method to display a user visible error or initiate an application
110    * level retry ({@link Player.EventListener#onPlayerError} is the appropriate place to implement
111    * such behavior). This method is called to provide the application with an opportunity to log the
112    * error if it wishes to do so.
113    *
114    * @param windowIndex The window index in the timeline of the media source this load belongs to.
115    * @param mediaPeriodId The {@link MediaPeriodId} this load belongs to. Null if the load does not
116    *     belong to a specific media period.
117    * @param loadEventInfo The {@link LoadEventInfo} corresponding to the event. The values of {@link
118    *     LoadEventInfo#elapsedRealtimeMs} and {@link LoadEventInfo#bytesLoaded} are relative to the
119    *     corresponding {@link #onLoadStarted(int, MediaPeriodId, LoadEventInfo, MediaLoadData)}
120    *     event.
121    * @param mediaLoadData The {@link MediaLoadData} defining the data being loaded.
122    * @param error The load error.
123    * @param wasCanceled Whether the load was canceled as a result of the error.
124    */
onLoadError( int windowIndex, @Nullable MediaPeriodId mediaPeriodId, LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData, IOException error, boolean wasCanceled)125   default void onLoadError(
126       int windowIndex,
127       @Nullable MediaPeriodId mediaPeriodId,
128       LoadEventInfo loadEventInfo,
129       MediaLoadData mediaLoadData,
130       IOException error,
131       boolean wasCanceled) {}
132 
133   /**
134    * Called when a media period is first being read from.
135    *
136    * @param windowIndex The window index in the timeline this media period belongs to.
137    * @param mediaPeriodId The {@link MediaPeriodId} of the media period being read from.
138    */
onReadingStarted(int windowIndex, MediaPeriodId mediaPeriodId)139   default void onReadingStarted(int windowIndex, MediaPeriodId mediaPeriodId) {}
140 
141   /**
142    * Called when data is removed from the back of a media buffer, typically so that it can be
143    * re-buffered in a different format.
144    *
145    * @param windowIndex The window index in the timeline of the media source this load belongs to.
146    * @param mediaPeriodId The {@link MediaPeriodId} the media belongs to.
147    * @param mediaLoadData The {@link MediaLoadData} defining the media being discarded.
148    */
onUpstreamDiscarded( int windowIndex, MediaPeriodId mediaPeriodId, MediaLoadData mediaLoadData)149   default void onUpstreamDiscarded(
150       int windowIndex, MediaPeriodId mediaPeriodId, MediaLoadData mediaLoadData) {}
151 
152   /**
153    * Called when a downstream format change occurs (i.e. when the format of the media being read
154    * from one or more {@link SampleStream}s provided by the source changes).
155    *
156    * @param windowIndex The window index in the timeline of the media source this load belongs to.
157    * @param mediaPeriodId The {@link MediaPeriodId} the media belongs to.
158    * @param mediaLoadData The {@link MediaLoadData} defining the newly selected downstream data.
159    */
onDownstreamFormatChanged( int windowIndex, @Nullable MediaPeriodId mediaPeriodId, MediaLoadData mediaLoadData)160   default void onDownstreamFormatChanged(
161       int windowIndex, @Nullable MediaPeriodId mediaPeriodId, MediaLoadData mediaLoadData) {}
162 
163   /** @deprecated Use {@link MediaSourceEventDispatcher} directly instead. */
164   @Deprecated
165   final class EventDispatcher extends MediaSourceEventDispatcher {
166 
EventDispatcher()167     public EventDispatcher() {
168       super();
169     }
170 
EventDispatcher( CopyOnWriteMultiset<ListenerInfo> listeners, int windowIndex, @Nullable MediaPeriodId mediaPeriodId, long mediaTimeOffsetMs)171     private EventDispatcher(
172         CopyOnWriteMultiset<ListenerInfo> listeners,
173         int windowIndex,
174         @Nullable MediaPeriodId mediaPeriodId,
175         long mediaTimeOffsetMs) {
176       super(listeners, windowIndex, mediaPeriodId, mediaTimeOffsetMs);
177     }
178 
179     @Override
withParameters( int windowIndex, @Nullable MediaPeriodId mediaPeriodId, long mediaTimeOffsetMs)180     public EventDispatcher withParameters(
181         int windowIndex, @Nullable MediaPeriodId mediaPeriodId, long mediaTimeOffsetMs) {
182       return new EventDispatcher(listenerInfos, windowIndex, mediaPeriodId, mediaTimeOffsetMs);
183     }
184 
mediaPeriodCreated()185     public void mediaPeriodCreated() {
186       dispatch(
187           (listener, windowIndex, mediaPeriodId) ->
188               listener.onMediaPeriodCreated(windowIndex, Assertions.checkNotNull(mediaPeriodId)),
189           MediaSourceEventListener.class);
190     }
191 
mediaPeriodReleased()192     public void mediaPeriodReleased() {
193       dispatch(
194           (listener, windowIndex, mediaPeriodId) ->
195               listener.onMediaPeriodReleased(windowIndex, Assertions.checkNotNull(mediaPeriodId)),
196           MediaSourceEventListener.class);
197     }
198 
loadStarted(LoadEventInfo loadEventInfo, int dataType)199     public void loadStarted(LoadEventInfo loadEventInfo, int dataType) {
200       loadStarted(
201           loadEventInfo,
202           dataType,
203           /* trackType= */ C.TRACK_TYPE_UNKNOWN,
204           /* trackFormat= */ null,
205           /* trackSelectionReason= */ C.SELECTION_REASON_UNKNOWN,
206           /* trackSelectionData= */ null,
207           /* mediaStartTimeUs= */ C.TIME_UNSET,
208           /* mediaEndTimeUs= */ C.TIME_UNSET);
209     }
210 
loadStarted( LoadEventInfo loadEventInfo, int dataType, int trackType, @Nullable Format trackFormat, int trackSelectionReason, @Nullable Object trackSelectionData, long mediaStartTimeUs, long mediaEndTimeUs)211     public void loadStarted(
212         LoadEventInfo loadEventInfo,
213         int dataType,
214         int trackType,
215         @Nullable Format trackFormat,
216         int trackSelectionReason,
217         @Nullable Object trackSelectionData,
218         long mediaStartTimeUs,
219         long mediaEndTimeUs) {
220       loadStarted(
221           loadEventInfo,
222           new MediaLoadData(
223               dataType,
224               trackType,
225               trackFormat,
226               trackSelectionReason,
227               trackSelectionData,
228               adjustMediaTime(mediaStartTimeUs),
229               adjustMediaTime(mediaEndTimeUs)));
230     }
231 
loadStarted(LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData)232     public void loadStarted(LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData) {
233       dispatch(
234           (listener, windowIndex, mediaPeriodId) ->
235               listener.onLoadStarted(windowIndex, mediaPeriodId, loadEventInfo, mediaLoadData),
236           MediaSourceEventListener.class);
237     }
238 
loadCompleted(LoadEventInfo loadEventInfo, int dataType)239     public void loadCompleted(LoadEventInfo loadEventInfo, int dataType) {
240       loadCompleted(
241           loadEventInfo,
242           dataType,
243           /* trackType= */ C.TRACK_TYPE_UNKNOWN,
244           /* trackFormat= */ null,
245           /* trackSelectionReason= */ C.SELECTION_REASON_UNKNOWN,
246           /* trackSelectionData= */ null,
247           /* mediaStartTimeUs= */ C.TIME_UNSET,
248           /* mediaEndTimeUs= */ C.TIME_UNSET);
249     }
250 
loadCompleted( LoadEventInfo loadEventInfo, int dataType, int trackType, @Nullable Format trackFormat, int trackSelectionReason, @Nullable Object trackSelectionData, long mediaStartTimeUs, long mediaEndTimeUs)251     public void loadCompleted(
252         LoadEventInfo loadEventInfo,
253         int dataType,
254         int trackType,
255         @Nullable Format trackFormat,
256         int trackSelectionReason,
257         @Nullable Object trackSelectionData,
258         long mediaStartTimeUs,
259         long mediaEndTimeUs) {
260       loadCompleted(
261           loadEventInfo,
262           new MediaLoadData(
263               dataType,
264               trackType,
265               trackFormat,
266               trackSelectionReason,
267               trackSelectionData,
268               adjustMediaTime(mediaStartTimeUs),
269               adjustMediaTime(mediaEndTimeUs)));
270     }
271 
loadCompleted(LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData)272     public void loadCompleted(LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData) {
273       dispatch(
274           (listener, windowIndex, mediaPeriodId) ->
275               listener.onLoadCompleted(windowIndex, mediaPeriodId, loadEventInfo, mediaLoadData),
276           MediaSourceEventListener.class);
277     }
278 
loadCanceled(LoadEventInfo loadEventInfo, int dataType)279     public void loadCanceled(LoadEventInfo loadEventInfo, int dataType) {
280       loadCanceled(
281           loadEventInfo,
282           dataType,
283           /* trackType= */ C.TRACK_TYPE_UNKNOWN,
284           /* trackFormat= */ null,
285           /* trackSelectionReason= */ C.SELECTION_REASON_UNKNOWN,
286           /* trackSelectionData= */ null,
287           /* mediaStartTimeUs= */ C.TIME_UNSET,
288           /* mediaEndTimeUs= */ C.TIME_UNSET);
289     }
290 
loadCanceled( LoadEventInfo loadEventInfo, int dataType, int trackType, @Nullable Format trackFormat, int trackSelectionReason, @Nullable Object trackSelectionData, long mediaStartTimeUs, long mediaEndTimeUs)291     public void loadCanceled(
292         LoadEventInfo loadEventInfo,
293         int dataType,
294         int trackType,
295         @Nullable Format trackFormat,
296         int trackSelectionReason,
297         @Nullable Object trackSelectionData,
298         long mediaStartTimeUs,
299         long mediaEndTimeUs) {
300       loadCanceled(
301           loadEventInfo,
302           new MediaLoadData(
303               dataType,
304               trackType,
305               trackFormat,
306               trackSelectionReason,
307               trackSelectionData,
308               adjustMediaTime(mediaStartTimeUs),
309               adjustMediaTime(mediaEndTimeUs)));
310     }
311 
loadCanceled(LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData)312     public void loadCanceled(LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData) {
313       dispatch(
314           (listener, windowIndex, mediaPeriodId) ->
315               listener.onLoadCanceled(windowIndex, mediaPeriodId, loadEventInfo, mediaLoadData),
316           MediaSourceEventListener.class);
317     }
318 
loadError( LoadEventInfo loadEventInfo, int dataType, IOException error, boolean wasCanceled)319     public void loadError(
320         LoadEventInfo loadEventInfo, int dataType, IOException error, boolean wasCanceled) {
321       loadError(
322           loadEventInfo,
323           dataType,
324           /* trackType= */ C.TRACK_TYPE_UNKNOWN,
325           /* trackFormat= */ null,
326           /* trackSelectionReason= */ C.SELECTION_REASON_UNKNOWN,
327           /* trackSelectionData= */ null,
328           /* mediaStartTimeUs= */ C.TIME_UNSET,
329           /* mediaEndTimeUs= */ C.TIME_UNSET,
330           error,
331           wasCanceled);
332     }
333 
loadError( LoadEventInfo loadEventInfo, int dataType, int trackType, @Nullable Format trackFormat, int trackSelectionReason, @Nullable Object trackSelectionData, long mediaStartTimeUs, long mediaEndTimeUs, IOException error, boolean wasCanceled)334     public void loadError(
335         LoadEventInfo loadEventInfo,
336         int dataType,
337         int trackType,
338         @Nullable Format trackFormat,
339         int trackSelectionReason,
340         @Nullable Object trackSelectionData,
341         long mediaStartTimeUs,
342         long mediaEndTimeUs,
343         IOException error,
344         boolean wasCanceled) {
345       loadError(
346           loadEventInfo,
347           new MediaLoadData(
348               dataType,
349               trackType,
350               trackFormat,
351               trackSelectionReason,
352               trackSelectionData,
353               adjustMediaTime(mediaStartTimeUs),
354               adjustMediaTime(mediaEndTimeUs)),
355           error,
356           wasCanceled);
357     }
358 
loadError( LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData, IOException error, boolean wasCanceled)359     public void loadError(
360         LoadEventInfo loadEventInfo,
361         MediaLoadData mediaLoadData,
362         IOException error,
363         boolean wasCanceled) {
364       dispatch(
365           (listener, windowIndex, mediaPeriodId) ->
366               listener.onLoadError(
367                   windowIndex, mediaPeriodId, loadEventInfo, mediaLoadData, error, wasCanceled),
368           MediaSourceEventListener.class);
369     }
370 
readingStarted()371     public void readingStarted() {
372       dispatch(
373           (listener, windowIndex, mediaPeriodId) ->
374               listener.onReadingStarted(windowIndex, Assertions.checkNotNull(mediaPeriodId)),
375           MediaSourceEventListener.class);
376     }
377 
upstreamDiscarded(int trackType, long mediaStartTimeUs, long mediaEndTimeUs)378     public void upstreamDiscarded(int trackType, long mediaStartTimeUs, long mediaEndTimeUs) {
379       upstreamDiscarded(
380           new MediaLoadData(
381               C.DATA_TYPE_MEDIA,
382               trackType,
383               /* trackFormat= */ null,
384               C.SELECTION_REASON_ADAPTIVE,
385               /* trackSelectionData= */ null,
386               adjustMediaTime(mediaStartTimeUs),
387               adjustMediaTime(mediaEndTimeUs)));
388     }
389 
upstreamDiscarded(MediaLoadData mediaLoadData)390     public void upstreamDiscarded(MediaLoadData mediaLoadData) {
391       dispatch(
392           (listener, windowIndex, mediaPeriodId) ->
393               listener.onUpstreamDiscarded(
394                   windowIndex, Assertions.checkNotNull(mediaPeriodId), mediaLoadData),
395           MediaSourceEventListener.class);
396     }
397 
downstreamFormatChanged( int trackType, @Nullable Format trackFormat, int trackSelectionReason, @Nullable Object trackSelectionData, long mediaTimeUs)398     public void downstreamFormatChanged(
399         int trackType,
400         @Nullable Format trackFormat,
401         int trackSelectionReason,
402         @Nullable Object trackSelectionData,
403         long mediaTimeUs) {
404       downstreamFormatChanged(
405           new MediaLoadData(
406               C.DATA_TYPE_MEDIA,
407               trackType,
408               trackFormat,
409               trackSelectionReason,
410               trackSelectionData,
411               adjustMediaTime(mediaTimeUs),
412               /* mediaEndTimeMs= */ C.TIME_UNSET));
413     }
414 
downstreamFormatChanged(MediaLoadData mediaLoadData)415     public void downstreamFormatChanged(MediaLoadData mediaLoadData) {
416       dispatch(
417           (listener, windowIndex, mediaPeriodId) ->
418               listener.onDownstreamFormatChanged(windowIndex, mediaPeriodId, mediaLoadData),
419           MediaSourceEventListener.class);
420     }
421 
adjustMediaTime(long mediaTimeUs)422     private long adjustMediaTime(long mediaTimeUs) {
423       return adjustMediaTime(mediaTimeUs, mediaTimeOffsetMs);
424     }
425   }
426 }
427