Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
mkaflowski committed May 28, 2019
1 parent 25fdff3 commit a0eb4d3
Show file tree
Hide file tree
Showing 4 changed files with 199 additions and 4 deletions.
7 changes: 5 additions & 2 deletions demo/src/main/java/hybridmediaplayer/demo/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,10 @@ private void createPlayer() {
// sources.add(source1);
sources.add(source1);
sources.add(source2);
// sources.add(source3);
sources.add(source3);
sources.add(source1);
sources.add(source2);
sources.add(source3);
// sources.add(source4);
// sources.add(source5);
mediaPlayer.setPlayerView(this, playerView);
Expand Down Expand Up @@ -206,7 +209,7 @@ public void onClick(View view) {
KLog.i(mediaPlayer.getDuration());
}
} else if (view.getId() == R.id.fastForward) {
mediaPlayer.seekTo(mediaPlayer.getDuration() - 2000);
mediaPlayer.seekTo(mediaPlayer.getDuration() - 200);
} else if (view.getId() == R.id.btSpeed) {
// if (speed == 1)
// speed = 2f;
Expand Down
181 changes: 181 additions & 0 deletions hybridmediaplayer/src/main/java/hybridmediaplayer/BasePlayer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
package hybridmediaplayer;

import androidx.annotation.Nullable;

import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.util.Util;

/** Abstract base {@link Player} which implements common implementation independent methods. */
public abstract class BasePlayer implements Player {

protected final Timeline.Window window;

public BasePlayer() {
window = new Timeline.Window();
}

@Override
public final void seekToDefaultPosition() {
seekToDefaultPosition(getCurrentWindowIndex());
}

@Override
public final void seekToDefaultPosition(int windowIndex) {
seekTo(windowIndex, /* positionMs= */ C.TIME_UNSET);
}

@Override
public final void seekTo(long positionMs) {
seekTo(getCurrentWindowIndex(), positionMs);
}

@Override
public final boolean hasPrevious() {
return getPreviousWindowIndex() != C.INDEX_UNSET;
}

@Override
public final void previous() {
int previousWindowIndex = getPreviousWindowIndex();
if (previousWindowIndex != C.INDEX_UNSET) {
seekToDefaultPosition(previousWindowIndex);
}
}

@Override
public final boolean hasNext() {
return getNextWindowIndex() != C.INDEX_UNSET;
}

@Override
public final void next() {
int nextWindowIndex = getNextWindowIndex();
if (nextWindowIndex != C.INDEX_UNSET) {
seekToDefaultPosition(nextWindowIndex);
}
}

@Override
public final void stop() {
stop(/* reset= */ false);
}

@Override
public final int getNextWindowIndex() {
Timeline timeline = getCurrentTimeline();
return timeline.isEmpty()
? C.INDEX_UNSET
: timeline.getNextWindowIndex(
getCurrentWindowIndex(), getRepeatModeForNavigation(), getShuffleModeEnabled());
}

@Override
public final int getPreviousWindowIndex() {
Timeline timeline = getCurrentTimeline();
return timeline.isEmpty()
? C.INDEX_UNSET
: timeline.getPreviousWindowIndex(
getCurrentWindowIndex(), getRepeatModeForNavigation(), getShuffleModeEnabled());
}

@Override
@Nullable
public final Object getCurrentTag() {
int windowIndex = getCurrentWindowIndex();
Timeline timeline = getCurrentTimeline();
return windowIndex >= timeline.getWindowCount()
? null
: timeline.getWindow(windowIndex, window, /* setTag= */ true).tag;
}

@Override
public final int getBufferedPercentage() {
long position = getBufferedPosition();
long duration = getDuration();
return position == C.TIME_UNSET || duration == C.TIME_UNSET
? 0
: duration == 0 ? 100 : Util.constrainValue((int) ((position * 100) / duration), 0, 100);
}

@Override
public final boolean isCurrentWindowDynamic() {
Timeline timeline = getCurrentTimeline();
return !timeline.isEmpty() && timeline.getWindow(getCurrentWindowIndex(), window).isDynamic;
}

@Override
public final boolean isCurrentWindowSeekable() {
Timeline timeline = getCurrentTimeline();
return !timeline.isEmpty() && timeline.getWindow(getCurrentWindowIndex(), window).isSeekable;
}

@Override
public final long getContentDuration() {
Timeline timeline = getCurrentTimeline();
return timeline.isEmpty()
? C.TIME_UNSET
: timeline.getWindow(getCurrentWindowIndex(), window).getDurationMs();
}

@RepeatMode
private int getRepeatModeForNavigation() {
@RepeatMode int repeatMode = getRepeatMode();
return repeatMode == REPEAT_MODE_ONE ? REPEAT_MODE_OFF : repeatMode;
}

/** Holds a listener reference. */
protected static final class ListenerHolder {

/**
* The listener on which {link #invoke} will execute {@link ListenerInvocation listener
* invocations}.
*/
public final Player.EventListener listener;

private boolean released;

public ListenerHolder(Player.EventListener listener) {
this.listener = listener;
}

/** Prevents any further {@link ListenerInvocation} to be executed on {@link #listener}. */
public void release() {
released = true;
}

/**
* Executes the given {@link ListenerInvocation} on {@link #listener}. Does nothing if {@link
* #release} has been called on this instance.
*/
public void invoke(ListenerInvocation listenerInvocation) {
if (!released) {
listenerInvocation.invokeListener(listener);
}
}

@Override
public boolean equals(@Nullable Object other) {
if (this == other) {
return true;
}
if (other == null || getClass() != other.getClass()) {
return false;
}
return listener.equals(((ListenerHolder) other).listener);
}

@Override
public int hashCode() {
return listener.hashCode();
}
}

/** Parameterized invocation of a {@link Player.EventListener} method. */
protected interface ListenerInvocation {

/** Executes the invocation on the given {@link Player.EventListener}. */
void invokeListener(Player.EventListener listener);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@
import com.google.android.gms.cast.framework.media.RemoteMediaClient.MediaChannelResult;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.ResultCallback;
import com.socks.library.KLog;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CopyOnWriteArraySet;

Expand Down Expand Up @@ -487,6 +489,8 @@ public int getCurrentPeriodIndex() {

@Override
public int getCurrentWindowIndex() {
KLog.d(fetchCurrentWindowIndex(getMediaStatus()));
KLog.e(pendingSeekWindowIndex);
return pendingSeekWindowIndex != C.INDEX_UNSET ? pendingSeekWindowIndex : currentWindowIndex;
}

Expand Down Expand Up @@ -581,6 +585,7 @@ public void updateInternalState() {
}
}
int currentWindowIndex = fetchCurrentWindowIndex(getMediaStatus());
KLog.d("cdcd "+currentWindowIndex);
if (this.currentWindowIndex != currentWindowIndex && pendingSeekCount == 0) {
this.currentWindowIndex = currentWindowIndex;
for (EventListener listener : listeners) {
Expand Down Expand Up @@ -745,9 +750,9 @@ private static int fetchRepeatMode(RemoteMediaClient remoteMediaClient) {
* Retrieves the current item index from {@code mediaStatus} and maps it into a window index. If
* there is no media session, returns 0.
*/
private static int fetchCurrentWindowIndex(@Nullable MediaStatus mediaStatus) {
private int fetchCurrentWindowIndex(@Nullable MediaStatus mediaStatus) {
Integer currentItemId = mediaStatus != null
? mediaStatus.getIndexById(mediaStatus.getCurrentItemId()) : null;
? Arrays.binarySearch(remoteMediaClient.getMediaQueue().getItemIds(),remoteMediaClient.getMediaStatus().getCurrentItemId() ) : null;
return currentItemId != null ? currentItemId : -1;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import com.google.android.gms.cast.framework.SessionManager;
import com.google.android.gms.cast.framework.media.RemoteMediaClient;
import com.google.android.gms.common.images.WebImage;
import com.socks.library.KLog;

import java.util.ArrayList;
import java.util.List;
Expand Down Expand Up @@ -562,12 +563,17 @@ public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
break;

case Player.STATE_IDLE:
KLog.e(currentWindow);
KLog.w(getWindowCount());
if (isCasting && currentWindow == getWindowCount() - 1) {
SessionManager sessionManager = CastContext.getSharedInstance(context).getSessionManager();
CastSession castSession = sessionManager.getCurrentCastSession();
if (castSession != null) {
KLog.e();
RemoteMediaClient remoteMediaClient = castSession.getRemoteMediaClient();
if (remoteMediaClient != null) {
KLog.e(remoteMediaClient.getIdleReason());

if (MediaStatus.IDLE_REASON_FINISHED == remoteMediaClient.getIdleReason()) {
if (onCompletionListener != null) {
currentPlayer.setPlayWhenReady(false);
Expand Down

0 comments on commit a0eb4d3

Please sign in to comment.