Add seek view for ijk and exo

pull/123/head
FongMi 3 years ago
parent e843a016c6
commit e92f71f004
  1. 4
      app/src/main/java/com/fongmi/android/tv/player/Players.java
  2. 75
      app/src/main/java/com/fongmi/android/tv/ui/custom/CustomSeekView.java
  3. 5
      ijkplayer/src/main/java/tv/danmaku/ijk/media/player/AbstractMediaPlayer.java
  4. 3
      ijkplayer/src/main/java/tv/danmaku/ijk/media/player/IMediaPlayer.java
  5. 5
      ijkplayer/src/main/java/tv/danmaku/ijk/media/player/IjkMediaPlayer.java
  6. 5
      ijkplayer/src/main/java/tv/danmaku/ijk/media/player/MediaPlayerProxy.java
  7. 16
      ijkplayer/src/main/java/tv/danmaku/ijk/media/player/ui/IjkVideoView.java

@ -137,6 +137,10 @@ public class Players implements Player.Listener, IMediaPlayer.OnInfoListener, IM
return isExo() ? exoPlayer.getDuration() : ijkPlayer.getDuration();
}
public long getBuffered() {
return isExo() ? exoPlayer.getBufferedPosition() : ijkPlayer.getBufferedPosition();
}
public void seekTo(int time) {
if (time == 0) return;
if (isExo()) exoPlayer.seekTo(getPosition() + time);

@ -13,16 +13,23 @@ import com.fongmi.android.tv.R;
import com.fongmi.android.tv.player.Players;
import com.google.android.exoplayer2.ui.DefaultTimeBar;
import com.google.android.exoplayer2.ui.TimeBar;
import com.google.android.exoplayer2.util.Util;
public class CustomSeekView extends FrameLayout implements TimeBar.OnScrubListener {
private Players listener;
private static final int MAX_UPDATE_INTERVAL_MS = 1000;
private static final int MIN_UPDATE_INTERVAL_MS = 200;
private TextView positionView;
private TextView durationView;
private DefaultTimeBar timeBar;
private Runnable runnable;
private Players listener;
private long currentDuration;
private long currentPosition;
private boolean scrubbing;
private boolean postProgress;
public CustomSeekView(Context context) {
this(context, null);
@ -35,11 +42,20 @@ public class CustomSeekView extends FrameLayout implements TimeBar.OnScrubListen
public CustomSeekView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
LayoutInflater.from(context).inflate(R.layout.view_control_seek, this);
initView();
initEvent();
startProgress();
}
private void initView() {
positionView = findViewById(R.id.position);
durationView = findViewById(R.id.duration);
timeBar = findViewById(R.id.timeBar);
runnable = this::updateProgress;
}
private void initEvent() {
timeBar.addListener(this);
startProgress();
}
public void setListener(Players listener) {
@ -48,38 +64,51 @@ public class CustomSeekView extends FrameLayout implements TimeBar.OnScrubListen
private void seekToTimeBarPosition(long positionMs) {
listener.seekTo(positionMs);
updateProgress();
}
public void startProgress() {
stopProgress();
postProgress = true;
post(runnable);
}
public void stopProgress() {
postProgress = false;
removeCallbacks(runnable);
}
private final Runnable runnable = new Runnable() {
@Override
public void run() {
if (listener.isPlaying()) {
setProgress();
}
if (postProgress) {
postDelayed(this, getDelay());
}
private void updateProgress() {
long duration = listener.getDuration();
long position = listener.getPosition();
long buffered = listener.getBuffered();
boolean positionChanged = position != currentPosition;
boolean durationChanged = duration != currentDuration;
currentDuration = duration;
currentPosition = position;
if (durationView != null && durationChanged) {
durationView.setText(listener.stringToTime(duration));
}
if (timeBar != null && durationChanged) {
timeBar.setDuration(duration);
}
if (positionView != null && !scrubbing && positionChanged) {
positionView.setText(listener.stringToTime(position));
}
if (timeBar != null) {
timeBar.setPosition(position);
timeBar.setBufferedPosition(buffered);
}
removeCallbacks(runnable);
if (listener.isPlaying()) {
long mediaTimeDelayMs = timeBar != null ? timeBar.getPreferredUpdateDelay() : MAX_UPDATE_INTERVAL_MS;
long mediaTimeUntilNextFullSecondMs = 1000 - position % 1000;
mediaTimeDelayMs = Math.min(mediaTimeDelayMs, mediaTimeUntilNextFullSecondMs);
float playbackSpeed = listener.getSpeed();
long delayMs = playbackSpeed > 0 ? (long) (mediaTimeDelayMs / playbackSpeed) : MAX_UPDATE_INTERVAL_MS;
delayMs = Util.constrainValue(delayMs, MIN_UPDATE_INTERVAL_MS, MAX_UPDATE_INTERVAL_MS);
postDelayed(runnable, delayMs);
} else {
postDelayed(runnable, MAX_UPDATE_INTERVAL_MS);
}
};
private long getDelay() {
return (long) ((1000 - listener.getPosition() % 1000) / listener.getSpeed());
}
private void setProgress() {
positionView.setText(listener.stringToTime(listener.getPosition()));
durationView.setText(listener.stringToTime(listener.getDuration()));
}
@Override

@ -85,6 +85,11 @@ public abstract class AbstractMediaPlayer implements IMediaPlayer {
mOnCompletionListener.onCompletion(this);
}
protected final void notifyOnBufferingUpdate(long position) {
if (mOnBufferingUpdateListener != null)
mOnBufferingUpdateListener.onBufferingUpdate(this, position);
}
protected final void notifyOnBufferingUpdate(int percent) {
if (mOnBufferingUpdateListener != null)
mOnBufferingUpdateListener.onBufferingUpdate(this, percent);

@ -155,6 +155,9 @@ public interface IMediaPlayer {
}
interface OnBufferingUpdateListener {
void onBufferingUpdate(IMediaPlayer mp, long position);
void onBufferingUpdate(IMediaPlayer mp, int percent);
}

@ -23,8 +23,8 @@ import android.annotation.TargetApi;
import android.content.ContentResolver;
import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.graphics.SurfaceTexture;
import android.graphics.Rect;
import android.graphics.SurfaceTexture;
import android.media.MediaCodecInfo;
import android.media.MediaCodecList;
import android.media.RingtoneManager;
@ -997,7 +997,8 @@ public final class IjkMediaPlayer extends AbstractMediaPlayer {
}
// DebugLog.efmt(TAG, "Buffer (%d%%) %d/%d", percent, bufferPosition, duration);
player.notifyOnBufferingUpdate((int)percent);
player.notifyOnBufferingUpdate(bufferPosition);
player.notifyOnBufferingUpdate((int) percent);
return;
case MEDIA_SEEK_COMPLETE:

@ -212,6 +212,11 @@ public class MediaPlayerProxy implements IMediaPlayer {
if (listener != null) {
final OnBufferingUpdateListener finalListener = listener;
mBackEndMediaPlayer.setOnBufferingUpdateListener(new OnBufferingUpdateListener() {
@Override
public void onBufferingUpdate(IMediaPlayer mp, long position) {
finalListener.onBufferingUpdate(MediaPlayerProxy.this, position);
}
@Override
public void onBufferingUpdate(IMediaPlayer mp, int percent) {
finalListener.onBufferingUpdate(MediaPlayerProxy.this, percent);

@ -52,6 +52,9 @@ public class IjkVideoView extends FrameLayout implements MediaController.MediaPl
private int mCurrentState = STATE_IDLE;
private int mTargetState = STATE_IDLE;
private int mCurrentBufferPercentage;
private long mCurrentBufferPosition;
// All the stuff we need for playing and showing a video
private IRenderView.ISurfaceHolder mSurfaceHolder = null;
private IjkMediaPlayer mMediaPlayer = null;
@ -62,7 +65,6 @@ public class IjkVideoView extends FrameLayout implements MediaController.MediaPl
private int mVideoRotationDegree;
private IMediaPlayer.OnCompletionListener mOnCompletionListener;
private IMediaPlayer.OnPreparedListener mOnPreparedListener;
private int mCurrentBufferPercentage;
private IMediaPlayer.OnErrorListener mOnErrorListener;
private IMediaPlayer.OnInfoListener mOnInfoListener;
@ -183,6 +185,7 @@ public class IjkVideoView extends FrameLayout implements MediaController.MediaPl
try {
createPlayer();
setRender(mCurrentRender);
mCurrentBufferPosition = 0;
mCurrentBufferPercentage = 0;
mMediaPlayer.setDataSource(mAppContext, mUri, mHeaders);
bindSurfaceHolder(mMediaPlayer, mSurfaceHolder);
@ -312,6 +315,12 @@ public class IjkVideoView extends FrameLayout implements MediaController.MediaPl
};
private final IMediaPlayer.OnBufferingUpdateListener mBufferingUpdateListener = new IMediaPlayer.OnBufferingUpdateListener() {
@Override
public void onBufferingUpdate(IMediaPlayer mp, long position) {
mCurrentBufferPosition = position;
}
@Override
public void onBufferingUpdate(IMediaPlayer mp, int percent) {
mCurrentBufferPercentage = percent;
}
@ -454,6 +463,11 @@ public class IjkVideoView extends FrameLayout implements MediaController.MediaPl
return isInPlaybackState() && mMediaPlayer.isPlaying();
}
public long getBufferedPosition() {
if (mMediaPlayer != null) return mCurrentBufferPosition;
return 0;
}
@Override
public int getBufferPercentage() {
if (mMediaPlayer != null) return mCurrentBufferPercentage;

Loading…
Cancel
Save