forked from ryanheise/just_audio
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement MappingAudioSource on Android
Inspiration taken from: - google/ExoPlayer#7087 - google/ExoPlayer#5883 - google/ExoPlayer#7279
- Loading branch information
1 parent
5e45b08
commit 15854ec
Showing
2 changed files
with
196 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
160 changes: 160 additions & 0 deletions
160
just_audio/android/src/main/java/com/ryanheise/just_audio/LazyMediaSource.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
package com.ryanheise.just_audio; | ||
|
||
import android.os.Handler; | ||
|
||
import com.google.android.exoplayer2.MediaItem; | ||
import com.google.android.exoplayer2.Timeline; | ||
import com.google.android.exoplayer2.analytics.PlayerId; | ||
import com.google.android.exoplayer2.drm.DrmSessionEventListener; | ||
import com.google.android.exoplayer2.source.MediaPeriod; | ||
import com.google.android.exoplayer2.source.MediaSource; | ||
import com.google.android.exoplayer2.source.MediaSourceEventListener; | ||
import com.google.android.exoplayer2.upstream.Allocator; | ||
import com.google.android.exoplayer2.upstream.TransferListener; | ||
|
||
import java.io.IOException; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
|
||
/** | ||
* A {@link MediaSource} that lazily defers to another {@link MediaSource} when it is required. | ||
* <p> | ||
* This {@link MediaSource} must be used with a {@link com.google.android.exoplayer2.source.MaskingMediaSource}. | ||
*/ | ||
class LazyMediaSource implements MediaSource { | ||
private final LazyMediaSourceProvider mediaSourceProvider; | ||
public final String id; | ||
public final MediaItem placeholderMediaItem; | ||
|
||
private final Map<MediaSourceEventListener, Handler> pendingEventListeners = new HashMap<>(); | ||
private final Map<DrmSessionEventListener, Handler> pendingDrmEventListeners = new HashMap<>(); | ||
|
||
private MediaSource mediaSource; | ||
|
||
LazyMediaSource(LazyMediaSourceProvider mediaSourceProvider, String id, MediaItem placeholderMediaItem) { | ||
this.mediaSourceProvider = mediaSourceProvider; | ||
this.id = id; | ||
this.placeholderMediaItem = placeholderMediaItem; | ||
} | ||
|
||
@Override | ||
public void addEventListener(Handler handler, MediaSourceEventListener eventListener) { | ||
if (mediaSource == null) { | ||
pendingEventListeners.put(eventListener, handler); | ||
} else { | ||
mediaSource.addEventListener(handler, eventListener); | ||
} | ||
} | ||
|
||
@Override | ||
public void removeEventListener(MediaSourceEventListener eventListener) { | ||
if (mediaSource == null) { | ||
pendingEventListeners.remove(eventListener); | ||
} else { | ||
mediaSource.removeEventListener(eventListener); | ||
} | ||
} | ||
|
||
@Override | ||
public void addDrmEventListener(Handler handler, DrmSessionEventListener eventListener) { | ||
if (mediaSource == null) { | ||
pendingDrmEventListeners.put(eventListener, handler); | ||
} else { | ||
mediaSource.addDrmEventListener(handler, eventListener); | ||
} | ||
} | ||
|
||
@Override | ||
public void removeDrmEventListener(DrmSessionEventListener eventListener) { | ||
if (mediaSource == null) { | ||
pendingDrmEventListeners.remove(eventListener); | ||
} else { | ||
mediaSource.removeDrmEventListener(eventListener); | ||
} | ||
} | ||
|
||
@Override | ||
public Timeline getInitialTimeline() { | ||
if (mediaSource == null) return null; | ||
return mediaSource.getInitialTimeline(); | ||
} | ||
|
||
@Override | ||
public boolean isSingleWindow() { | ||
if (mediaSource == null) return false; | ||
return mediaSource.isSingleWindow(); | ||
} | ||
|
||
@Override | ||
public MediaItem getMediaItem() { | ||
if (mediaSource == null) { | ||
return placeholderMediaItem; | ||
} else { | ||
return mediaSource.getMediaItem(); | ||
} | ||
} | ||
|
||
@Override | ||
public void prepareSource( | ||
MediaSourceCaller caller, | ||
TransferListener mediaTransferListener, | ||
PlayerId playerId | ||
) { | ||
mediaSourceProvider.createMediaSource(id, (mediaSource) -> { | ||
this.mediaSource = mediaSource; | ||
for (Map.Entry<MediaSourceEventListener, Handler> entry : pendingEventListeners.entrySet()) { | ||
mediaSource.addEventListener(entry.getValue(), entry.getKey()); | ||
} | ||
pendingEventListeners.clear(); | ||
for (Map.Entry<DrmSessionEventListener, Handler> entry : pendingDrmEventListeners.entrySet()) { | ||
mediaSource.addDrmEventListener(entry.getValue(), entry.getKey()); | ||
} | ||
pendingDrmEventListeners.clear(); | ||
mediaSource.prepareSource(caller, mediaTransferListener, playerId); | ||
}); | ||
} | ||
|
||
@Override | ||
public void maybeThrowSourceInfoRefreshError() throws IOException { | ||
if (mediaSource == null) return; | ||
mediaSource.maybeThrowSourceInfoRefreshError(); | ||
} | ||
|
||
@Override | ||
public void enable(MediaSourceCaller caller) { | ||
if (mediaSource == null) throw new IllegalStateException(); | ||
mediaSource.enable(caller); | ||
} | ||
|
||
@Override | ||
public MediaPeriod createPeriod(MediaPeriodId id, Allocator allocator, long startPositionUs) { | ||
if (mediaSource == null) throw new IllegalStateException(); | ||
return mediaSource.createPeriod(id, allocator, startPositionUs); | ||
} | ||
|
||
@Override | ||
public void releasePeriod(MediaPeriod mediaPeriod) { | ||
if (mediaSource == null) throw new IllegalStateException(); | ||
mediaSource.releasePeriod(mediaPeriod); | ||
} | ||
|
||
@Override | ||
public void disable(MediaSourceCaller caller) { | ||
if (mediaSource == null) throw new IllegalStateException(); | ||
mediaSource.disable(caller); | ||
} | ||
|
||
@Override | ||
public void releaseSource(MediaSourceCaller caller) { | ||
if (mediaSource == null) return; | ||
mediaSource.releaseSource(caller); | ||
} | ||
} | ||
|
||
interface LazyMediaSourceReceiver { | ||
void onMediaSourceCreated(MediaSource mediaSource); | ||
} | ||
|
||
interface LazyMediaSourceProvider { | ||
void createMediaSource(String id, LazyMediaSourceReceiver receiver); | ||
} |