|
|
@ -1,15 +1,19 @@ |
|
|
|
package awais.instagrabber.customviews; |
|
|
|
|
|
|
|
import android.content.Context; |
|
|
|
import android.content.res.ColorStateList; |
|
|
|
import android.content.res.Resources; |
|
|
|
import android.graphics.drawable.Animatable; |
|
|
|
import android.net.Uri; |
|
|
|
import android.os.Looper; |
|
|
|
import android.util.Log; |
|
|
|
import android.view.View; |
|
|
|
import android.view.ViewGroup; |
|
|
|
import android.widget.ImageView; |
|
|
|
|
|
|
|
import androidx.annotation.NonNull; |
|
|
|
import androidx.appcompat.widget.PopupMenu; |
|
|
|
import androidx.annotation.Nullable; |
|
|
|
import androidx.appcompat.widget.AppCompatImageButton; |
|
|
|
|
|
|
|
import com.facebook.drawee.backends.pipeline.Fresco; |
|
|
|
import com.facebook.drawee.backends.pipeline.PipelineDraweeControllerBuilder; |
|
|
@ -23,18 +27,23 @@ import com.google.android.exoplayer2.Player; |
|
|
|
import com.google.android.exoplayer2.SimpleExoPlayer; |
|
|
|
import com.google.android.exoplayer2.audio.AudioListener; |
|
|
|
import com.google.android.exoplayer2.source.ProgressiveMediaSource; |
|
|
|
import com.google.android.exoplayer2.source.TrackGroupArray; |
|
|
|
import com.google.android.exoplayer2.trackselection.TrackSelectionArray; |
|
|
|
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout; |
|
|
|
import com.google.android.exoplayer2.ui.StyledPlayerControlView; |
|
|
|
import com.google.android.exoplayer2.ui.StyledPlayerView; |
|
|
|
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory; |
|
|
|
import com.google.android.material.button.MaterialButton; |
|
|
|
|
|
|
|
import java.lang.reflect.Field; |
|
|
|
import java.lang.reflect.InvocationTargetException; |
|
|
|
import java.lang.reflect.Method; |
|
|
|
|
|
|
|
import awais.instagrabber.R; |
|
|
|
import awais.instagrabber.databinding.LayoutVideoPlayerWithThumbnailBinding; |
|
|
|
import awais.instagrabber.utils.Utils; |
|
|
|
|
|
|
|
public class VideoPlayerViewHelper implements Player.EventListener { |
|
|
|
private static final String TAG = "VideoPlayerViewHelper"; |
|
|
|
// private static final long INITIAL_DELAY = 0; |
|
|
|
// private static final long RECURRING_DELAY = 60; |
|
|
|
private static final String TAG = VideoPlayerViewHelper.class.getSimpleName(); |
|
|
|
|
|
|
|
private final Context context; |
|
|
|
private final LayoutVideoPlayerWithThumbnailBinding binding; |
|
|
@ -42,74 +51,20 @@ public class VideoPlayerViewHelper implements Player.EventListener { |
|
|
|
private final float thumbnailAspectRatio; |
|
|
|
private final String thumbnailUrl; |
|
|
|
private final boolean loadPlayerOnClick; |
|
|
|
// private final LayoutExoCustomControlsBinding controlsBinding; |
|
|
|
private final VideoPlayerCallback videoPlayerCallback; |
|
|
|
private final String videoUrl; |
|
|
|
private final DefaultDataSourceFactory dataSourceFactory; |
|
|
|
private SimpleExoPlayer player; |
|
|
|
private PopupMenu speedPopup; |
|
|
|
// private PositionCheckRunnable positionChecker; |
|
|
|
// private Handler positionUpdateHandler; |
|
|
|
|
|
|
|
// private final Player.EventListener listener = new Player.EventListener() { |
|
|
|
// @Override |
|
|
|
// public void onPlaybackStateChanged(final int state) { |
|
|
|
// // switch (state) { |
|
|
|
// // case Player.STATE_BUFFERING: |
|
|
|
// // case STATE_IDLE: |
|
|
|
// // case STATE_ENDED: |
|
|
|
// // positionUpdateHandler.removeCallbacks(positionChecker); |
|
|
|
// // return; |
|
|
|
// // case STATE_READY: |
|
|
|
// // setupTimeline(); |
|
|
|
// // positionUpdateHandler.postDelayed(positionChecker, INITIAL_DELAY); |
|
|
|
// // break; |
|
|
|
// // } |
|
|
|
// } |
|
|
|
// |
|
|
|
// @Override |
|
|
|
// public void onPlayWhenReadyChanged(final boolean playWhenReady, final int reason) { |
|
|
|
// // updatePlayPauseDrawable(playWhenReady); |
|
|
|
// // if (positionUpdateHandler == null || positionChecker == null) return; |
|
|
|
// // if (playWhenReady) { |
|
|
|
// // positionUpdateHandler.removeCallbacks(positionChecker); |
|
|
|
// // positionUpdateHandler.postDelayed(positionChecker, INITIAL_DELAY); |
|
|
|
// // } |
|
|
|
// } |
|
|
|
// }; |
|
|
|
private AppCompatImageButton mute; |
|
|
|
|
|
|
|
private final AudioListener audioListener = new AudioListener() { |
|
|
|
@Override |
|
|
|
public void onVolumeChanged(final float volume) { |
|
|
|
updateMuteIcon(volume); |
|
|
|
} |
|
|
|
}; |
|
|
|
// private final Slider.OnChangeListener onChangeListener = (slider, value, fromUser) -> { |
|
|
|
// if (!fromUser) return; |
|
|
|
// long actualValue = (long) value; |
|
|
|
// if (actualValue < 0) { |
|
|
|
// actualValue = 0; |
|
|
|
// } else if (actualValue > player.getDuration()) { |
|
|
|
// actualValue = player.getDuration(); |
|
|
|
// } |
|
|
|
// player.seekTo(actualValue); |
|
|
|
// }; |
|
|
|
// private final View.OnClickListener onClickListener = v -> player.setPlayWhenReady(!player.getPlayWhenReady()); |
|
|
|
// // private final LabelFormatter labelFormatter = value -> TextUtils.millisToTimeString((long) value); |
|
|
|
private final View.OnClickListener muteOnClickListener = v -> toggleMute(); |
|
|
|
private MaterialButton mute; |
|
|
|
// private final View.OnClickListener rewOnClickListener = v -> { |
|
|
|
// final long positionMs = player.getCurrentPosition() - 5000; |
|
|
|
// player.seekTo(positionMs < 0 ? 0 : positionMs); |
|
|
|
// }; |
|
|
|
// private final View.OnClickListener ffOnClickListener = v -> { |
|
|
|
// long positionMs = player.getCurrentPosition() + 5000; |
|
|
|
// long duration = player.getDuration(); |
|
|
|
// if (duration == TIME_UNSET) { |
|
|
|
// duration = 0; |
|
|
|
// } |
|
|
|
// player.seekTo(Math.min(positionMs, duration)); |
|
|
|
// }; |
|
|
|
// private final View.OnClickListener showMenu = this::showMenu; |
|
|
|
private Object layoutManager; |
|
|
|
|
|
|
|
public VideoPlayerViewHelper(@NonNull final Context context, |
|
|
|
@NonNull final LayoutVideoPlayerWithThumbnailBinding binding, |
|
|
@ -118,7 +73,6 @@ public class VideoPlayerViewHelper implements Player.EventListener { |
|
|
|
final float thumbnailAspectRatio, |
|
|
|
final String thumbnailUrl, |
|
|
|
final boolean loadPlayerOnClick, |
|
|
|
// final LayoutExoCustomControlsBinding controlsBinding, |
|
|
|
final VideoPlayerCallback videoPlayerCallback) { |
|
|
|
this.context = context; |
|
|
|
this.binding = binding; |
|
|
@ -126,7 +80,6 @@ public class VideoPlayerViewHelper implements Player.EventListener { |
|
|
|
this.thumbnailAspectRatio = thumbnailAspectRatio; |
|
|
|
this.thumbnailUrl = thumbnailUrl; |
|
|
|
this.loadPlayerOnClick = loadPlayerOnClick; |
|
|
|
// this.controlsBinding = controlsBinding; |
|
|
|
this.videoPlayerCallback = videoPlayerCallback; |
|
|
|
this.videoUrl = videoUrl; |
|
|
|
this.dataSourceFactory = new DefaultDataSourceFactory(binding.getRoot().getContext(), "instagram"); |
|
|
@ -143,7 +96,6 @@ public class VideoPlayerViewHelper implements Player.EventListener { |
|
|
|
} |
|
|
|
}); |
|
|
|
setThumbnail(); |
|
|
|
// setupControls(); |
|
|
|
} |
|
|
|
|
|
|
|
private void setThumbnail() { |
|
|
@ -196,11 +148,6 @@ public class VideoPlayerViewHelper implements Player.EventListener { |
|
|
|
player = new SimpleExoPlayer.Builder(context) |
|
|
|
.setLooper(Looper.getMainLooper()) |
|
|
|
.build(); |
|
|
|
// positionUpdateHandler = new Handler(); |
|
|
|
// positionChecker = new PositionCheckRunnable(positionUpdateHandler, |
|
|
|
// player, |
|
|
|
// controlsBinding.timeline, |
|
|
|
// controlsBinding.fromTime); |
|
|
|
player.addListener(this); |
|
|
|
player.addAudioListener(audioListener); |
|
|
|
player.setVolume(initialVolume); |
|
|
@ -210,138 +157,118 @@ public class VideoPlayerViewHelper implements Player.EventListener { |
|
|
|
final MediaItem mediaItem = MediaItem.fromUri(videoUrl); |
|
|
|
final ProgressiveMediaSource mediaSource = sourceFactory.createMediaSource(mediaItem); |
|
|
|
player.setMediaSource(mediaSource); |
|
|
|
// setupControls(); |
|
|
|
player.prepare(); |
|
|
|
binding.playerView.setPlayer(player); |
|
|
|
// binding.playerView.setShowFastForwardButton(false); |
|
|
|
// binding.playerView.setShowRewindButton(false); |
|
|
|
binding.playerView.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_FIXED_HEIGHT); |
|
|
|
binding.playerView.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_FIT); |
|
|
|
binding.playerView.setShowNextButton(false); |
|
|
|
binding.playerView.setShowPreviousButton(false); |
|
|
|
// binding.controls.setPlayer(player); |
|
|
|
mute = binding.playerView.findViewById(R.id.mute); |
|
|
|
// mute = binding.controls.findViewById(R.id.mute); |
|
|
|
if (mute != null) { |
|
|
|
mute.setOnClickListener(muteOnClickListener); |
|
|
|
binding.playerView.setControllerOnFullScreenModeChangedListener(isFullScreen -> { |
|
|
|
if (videoPlayerCallback == null) return; |
|
|
|
videoPlayerCallback.onFullScreenModeChanged(isFullScreen, binding.playerView); |
|
|
|
}); |
|
|
|
setupControllerView(); |
|
|
|
} |
|
|
|
|
|
|
|
private void setupControllerView() { |
|
|
|
try { |
|
|
|
final StyledPlayerControlView controllerView = getStyledPlayerControlView(); |
|
|
|
if (controllerView == null) return; |
|
|
|
layoutManager = setControlViewLayoutManager(controllerView); |
|
|
|
if (videoPlayerCallback != null && videoPlayerCallback.isInFullScreen()) { |
|
|
|
setControllerViewToFullScreenMode(controllerView); |
|
|
|
} |
|
|
|
final ViewGroup exoBasicControls = controllerView.findViewById(R.id.exo_basic_controls); |
|
|
|
if (exoBasicControls == null) return; |
|
|
|
mute = new AppCompatImageButton(context); |
|
|
|
final Resources resources = context.getResources(); |
|
|
|
if (resources == null) return; |
|
|
|
final int width = resources.getDimensionPixelSize(R.dimen.exo_small_icon_width); |
|
|
|
final int height = resources.getDimensionPixelSize(R.dimen.exo_small_icon_height); |
|
|
|
final int margin = resources.getDimensionPixelSize(R.dimen.exo_small_icon_horizontal_margin); |
|
|
|
final int paddingHorizontal = resources.getDimensionPixelSize(R.dimen.exo_small_icon_padding_horizontal); |
|
|
|
final int paddingVertical = resources.getDimensionPixelSize(R.dimen.exo_small_icon_padding_vertical); |
|
|
|
final ViewGroup.MarginLayoutParams layoutParams = new ViewGroup.MarginLayoutParams(width, height); |
|
|
|
layoutParams.setMargins(margin, 0, margin, 0); |
|
|
|
mute.setLayoutParams(layoutParams); |
|
|
|
mute.setPadding(paddingHorizontal, paddingVertical, paddingHorizontal, paddingVertical); |
|
|
|
mute.setScaleType(ImageView.ScaleType.FIT_XY); |
|
|
|
mute.setBackgroundResource(Utils.getAttrResId(context, android.R.attr.selectableItemBackground)); |
|
|
|
mute.setImageTintList(ColorStateList.valueOf(resources.getColor(R.color.white))); |
|
|
|
updateMuteIcon(player.getVolume()); |
|
|
|
exoBasicControls.addView(mute, 0); |
|
|
|
mute.setOnClickListener(muteOnClickListener); |
|
|
|
} catch (Exception e) { |
|
|
|
Log.e(TAG, "loadPlayer: ", e); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// private void setupControls() { |
|
|
|
// if (controlsBinding == null) return; |
|
|
|
// // binding.playerView.setUseController(false); |
|
|
|
// if (player == null) { |
|
|
|
// // enableControls(false); |
|
|
|
// // controlsBinding.playPause.setEnabled(true); |
|
|
|
// // controlsBinding.playPause.setOnClickListener(new NoPlayerPlayPauseClickListener(binding.thumbnailParent)); |
|
|
|
// return; |
|
|
|
// } |
|
|
|
// // enableControls(true); |
|
|
|
// // updatePlayPauseDrawable(player.getPlayWhenReady()); |
|
|
|
// // updateMuteIcon(player.getVolume()); |
|
|
|
// player.addListener(listener); |
|
|
|
// // player.addAudioListener(audioListener); |
|
|
|
// // controlsBinding.timeline.addOnChangeListener(onChangeListener); |
|
|
|
// // controlsBinding.timeline.setLabelFormatter(labelFormatter); |
|
|
|
// // controlsBinding.playPause.setOnClickListener(onClickListener); |
|
|
|
// // controlsBinding.mute.setOnClickListener(muteOnClickListener); |
|
|
|
// // controlsBinding.rewWithAmount.setOnClickListener(rewOnClickListener); |
|
|
|
// // controlsBinding.ffWithAmount.setOnClickListener(ffOnClickListener); |
|
|
|
// // controlsBinding.speed.setOnClickListener(showMenu); |
|
|
|
// } |
|
|
|
|
|
|
|
// private void setupTimeline() { |
|
|
|
// final long duration = player.getDuration(); |
|
|
|
// controlsBinding.timeline.setEnabled(true); |
|
|
|
// controlsBinding.timeline.setValueFrom(0); |
|
|
|
// controlsBinding.timeline.setValueTo(duration); |
|
|
|
// controlsBinding.fromTime.setText(TextUtils.millisToTimeString(0)); |
|
|
|
// controlsBinding.toTime.setText(TextUtils.millisToTimeString(duration)); |
|
|
|
// } |
|
|
|
|
|
|
|
// private void enableControls(final boolean enable) { |
|
|
|
// controlsBinding.speed.setEnabled(enable); |
|
|
|
// controlsBinding.speed.setClickable(enable); |
|
|
|
// controlsBinding.mute.setEnabled(enable); |
|
|
|
// controlsBinding.mute.setClickable(enable); |
|
|
|
// controlsBinding.ffWithAmount.setEnabled(enable); |
|
|
|
// controlsBinding.ffWithAmount.setClickable(enable); |
|
|
|
// controlsBinding.rewWithAmount.setEnabled(enable); |
|
|
|
// controlsBinding.rewWithAmount.setClickable(enable); |
|
|
|
// // controlsBinding.fromTime.setEnabled(enable); |
|
|
|
// // controlsBinding.toTime.setEnabled(enable); |
|
|
|
// controlsBinding.playPause.setEnabled(enable); |
|
|
|
// controlsBinding.playPause.setClickable(enable); |
|
|
|
// // controlsBinding.timeline.setEnabled(enable); |
|
|
|
// } |
|
|
|
|
|
|
|
// public void showMenu(View anchor) { |
|
|
|
// PopupMenu popup = getPopupMenu(anchor); |
|
|
|
// popup.show(); |
|
|
|
// } |
|
|
|
|
|
|
|
// @NonNull |
|
|
|
// private PopupMenu getPopupMenu(final View anchor) { |
|
|
|
// if (speedPopup != null) { |
|
|
|
// return speedPopup; |
|
|
|
// } |
|
|
|
// final ContextThemeWrapper themeWrapper = new ContextThemeWrapper(context, R.style.popupMenuStyle); |
|
|
|
// // final ContextThemeWrapper themeWrapper = new ContextThemeWrapper(context, R.style.Widget_MaterialComponents_PopupMenu_Exoplayer); |
|
|
|
// speedPopup = new PopupMenu(themeWrapper, anchor); |
|
|
|
// speedPopup.getMenuInflater().inflate(R.menu.speed_menu, speedPopup.getMenu()); |
|
|
|
// speedPopup.setOnMenuItemClickListener(item -> { |
|
|
|
// float nextSpeed; |
|
|
|
// int textResId; |
|
|
|
// int itemId = item.getItemId(); |
|
|
|
// if (itemId == R.id.pt_two_five_x) { |
|
|
|
// nextSpeed = 0.25f; |
|
|
|
// textResId = R.string.pt_two_five_x; |
|
|
|
// } else if (itemId == R.id.pt_five_x) { |
|
|
|
// nextSpeed = 0.5f; |
|
|
|
// textResId = R.string.pt_five_x; |
|
|
|
// } else if (itemId == R.id.pt_seven_five_x) { |
|
|
|
// nextSpeed = 0.75f; |
|
|
|
// textResId = R.string.pt_seven_five_x; |
|
|
|
// } else if (itemId == R.id.one_x) { |
|
|
|
// nextSpeed = 1f; |
|
|
|
// textResId = R.string.one_x; |
|
|
|
// } else if (itemId == R.id.one_pt_two_five_x) { |
|
|
|
// nextSpeed = 1.25f; |
|
|
|
// textResId = R.string.one_pt_two_five_x; |
|
|
|
// } else if (itemId == R.id.one_pt_five_x) { |
|
|
|
// nextSpeed = 1.5f; |
|
|
|
// textResId = R.string.one_pt_five_x; |
|
|
|
// } else if (itemId == R.id.two_x) { |
|
|
|
// nextSpeed = 2f; |
|
|
|
// textResId = R.string.two_x; |
|
|
|
// } else { |
|
|
|
// nextSpeed = 1; |
|
|
|
// textResId = R.string.one_x; |
|
|
|
// } |
|
|
|
// player.setPlaybackParameters(new PlaybackParameters(nextSpeed)); |
|
|
|
// controlsBinding.speed.setText(textResId); |
|
|
|
// return true; |
|
|
|
// }); |
|
|
|
// return speedPopup; |
|
|
|
// } |
|
|
|
@Nullable |
|
|
|
private Object setControlViewLayoutManager(@NonNull final StyledPlayerControlView controllerView) |
|
|
|
throws NoSuchFieldException, IllegalAccessException { |
|
|
|
final Field controlViewLayoutManagerField = controllerView.getClass().getDeclaredField("controlViewLayoutManager"); |
|
|
|
controlViewLayoutManagerField.setAccessible(true); |
|
|
|
return controlViewLayoutManagerField.get(controllerView); |
|
|
|
} |
|
|
|
|
|
|
|
private void setControllerViewToFullScreenMode(@NonNull final StyledPlayerControlView controllerView) |
|
|
|
throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { |
|
|
|
// Exoplayer doesn't expose the fullscreen state, so using reflection |
|
|
|
final Field fullScreenButtonField = controllerView.getClass().getDeclaredField("fullScreenButton"); |
|
|
|
fullScreenButtonField.setAccessible(true); |
|
|
|
final ImageView fullScreenButton = (ImageView) fullScreenButtonField.get(controllerView); |
|
|
|
final Field isFullScreen = controllerView.getClass().getDeclaredField("isFullScreen"); |
|
|
|
isFullScreen.setAccessible(true); |
|
|
|
isFullScreen.set(controllerView, true); |
|
|
|
final Method updateFullScreenButtonForState = controllerView |
|
|
|
.getClass() |
|
|
|
.getDeclaredMethod("updateFullScreenButtonForState", ImageView.class, boolean.class); |
|
|
|
updateFullScreenButtonForState.setAccessible(true); |
|
|
|
updateFullScreenButtonForState.invoke(controllerView, fullScreenButton, true); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
@Nullable |
|
|
|
private StyledPlayerControlView getStyledPlayerControlView() throws NoSuchFieldException, IllegalAccessException { |
|
|
|
final Field controller = binding.playerView.getClass().getDeclaredField("controller"); |
|
|
|
controller.setAccessible(true); |
|
|
|
return (StyledPlayerControlView) controller.get(binding.playerView); |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
public void onTracksChanged(@NonNull TrackGroupArray trackGroups, @NonNull TrackSelectionArray trackSelections) { |
|
|
|
if (trackGroups.isEmpty()) { |
|
|
|
setHasAudio(false); |
|
|
|
return; |
|
|
|
} |
|
|
|
boolean hasAudio = false; |
|
|
|
for (int i = 0; i < trackGroups.length; i++) { |
|
|
|
for (int g = 0; g < trackGroups.get(i).length; g++) { |
|
|
|
final String sampleMimeType = trackGroups.get(i).getFormat(g).sampleMimeType; |
|
|
|
if (sampleMimeType != null && sampleMimeType.contains("audio")) { |
|
|
|
hasAudio = true; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
setHasAudio(hasAudio); |
|
|
|
} |
|
|
|
|
|
|
|
private void setHasAudio(final boolean hasAudio) { |
|
|
|
if (mute == null) return; |
|
|
|
mute.setEnabled(hasAudio); |
|
|
|
mute.setAlpha(hasAudio ? 1f : 0.5f); |
|
|
|
updateMuteIcon(hasAudio ? 1f : 0f); |
|
|
|
} |
|
|
|
|
|
|
|
private void updateMuteIcon(final float volume) { |
|
|
|
if (mute == null) return; |
|
|
|
if (volume == 0) { |
|
|
|
mute.setIconResource(R.drawable.ic_volume_off_24_states); |
|
|
|
mute.setImageResource(R.drawable.ic_volume_off_24); |
|
|
|
return; |
|
|
|
} |
|
|
|
mute.setIconResource(R.drawable.ic_volume_up_24_states); |
|
|
|
mute.setImageResource(R.drawable.ic_volume_up_24); |
|
|
|
} |
|
|
|
|
|
|
|
// private void updatePlayPauseDrawable(final boolean playWhenReady) { |
|
|
|
// if (playWhenReady) { |
|
|
|
// controlsBinding.playPause.setIconResource(R.drawable.ic_pause_24); |
|
|
|
// return; |
|
|
|
// } |
|
|
|
// controlsBinding.playPause.setIconResource(R.drawable.ic_play_states); |
|
|
|
// } |
|
|
|
|
|
|
|
@Override |
|
|
|
public void onPlayWhenReadyChanged(final boolean playWhenReady, final int reason) { |
|
|
|
if (videoPlayerCallback == null) return; |
|
|
@ -359,18 +286,18 @@ public class VideoPlayerViewHelper implements Player.EventListener { |
|
|
|
|
|
|
|
private void toggleMute() { |
|
|
|
if (player == null) return; |
|
|
|
if (layoutManager != null) { |
|
|
|
try { |
|
|
|
final Method resetHideCallbacks = layoutManager.getClass().getDeclaredMethod("resetHideCallbacks"); |
|
|
|
resetHideCallbacks.invoke(layoutManager); |
|
|
|
} catch (Exception e) { |
|
|
|
Log.e(TAG, "toggleMute: ", e); |
|
|
|
} |
|
|
|
} |
|
|
|
final float vol = player.getVolume() == 0f ? 1f : 0f; |
|
|
|
player.setVolume(vol); |
|
|
|
} |
|
|
|
|
|
|
|
// public void togglePlayback() { |
|
|
|
// if (player == null) return; |
|
|
|
// final int playbackState = player.getPlaybackState(); |
|
|
|
// if (playbackState == STATE_IDLE || playbackState == STATE_ENDED) return; |
|
|
|
// final boolean playWhenReady = player.getPlayWhenReady(); |
|
|
|
// player.setPlayWhenReady(!playWhenReady); |
|
|
|
// } |
|
|
|
|
|
|
|
public void releasePlayer() { |
|
|
|
if (videoPlayerCallback != null) { |
|
|
|
videoPlayerCallback.onRelease(); |
|
|
@ -379,85 +306,13 @@ public class VideoPlayerViewHelper implements Player.EventListener { |
|
|
|
player.release(); |
|
|
|
player = null; |
|
|
|
} |
|
|
|
// if (positionUpdateHandler != null) { |
|
|
|
// if (positionChecker != null) { |
|
|
|
// positionUpdateHandler.removeCallbacks(positionChecker); |
|
|
|
// positionChecker = null; |
|
|
|
// } |
|
|
|
// positionUpdateHandler = null; |
|
|
|
// } |
|
|
|
} |
|
|
|
|
|
|
|
public void pause() { |
|
|
|
if (player != null) { |
|
|
|
player.pause(); |
|
|
|
} |
|
|
|
// if (positionUpdateHandler != null) { |
|
|
|
// if (positionChecker != null) { |
|
|
|
// positionUpdateHandler.removeCallbacks(positionChecker); |
|
|
|
// } |
|
|
|
// } |
|
|
|
} |
|
|
|
|
|
|
|
// public void resetTimeline() { |
|
|
|
// if (player == null) { |
|
|
|
// enableControls(false); |
|
|
|
// return; |
|
|
|
// } |
|
|
|
// setupTimeline(); |
|
|
|
// final long currentPosition = player.getCurrentPosition(); |
|
|
|
// controlsBinding.timeline.setValue(Math.min(currentPosition, player.getDuration())); |
|
|
|
// setupControls(); |
|
|
|
// } |
|
|
|
|
|
|
|
// public void removeCallbacks() { |
|
|
|
// if (player != null) { |
|
|
|
// player.removeListener(listener); |
|
|
|
// player.removeAudioListener(audioListener); |
|
|
|
// } |
|
|
|
// controlsBinding.timeline.removeOnChangeListener(onChangeListener); |
|
|
|
// controlsBinding.timeline.setLabelFormatter(null); |
|
|
|
// controlsBinding.playPause.setOnClickListener(null); |
|
|
|
// controlsBinding.mute.setOnClickListener(null); |
|
|
|
// controlsBinding.rewWithAmount.setOnClickListener(null); |
|
|
|
// controlsBinding.ffWithAmount.setOnClickListener(null); |
|
|
|
// controlsBinding.speed.setOnClickListener(null); |
|
|
|
// } |
|
|
|
|
|
|
|
// private static class PositionCheckRunnable implements Runnable { |
|
|
|
// private final Handler positionUpdateHandler; |
|
|
|
// private final SimpleExoPlayer player; |
|
|
|
// private final Slider timeline; |
|
|
|
// private final AppCompatTextView fromTime; |
|
|
|
// |
|
|
|
// public PositionCheckRunnable(final Handler positionUpdateHandler, |
|
|
|
// final SimpleExoPlayer simpleExoPlayer, |
|
|
|
// final Slider slider, |
|
|
|
// final AppCompatTextView fromTime) { |
|
|
|
// this.positionUpdateHandler = positionUpdateHandler; |
|
|
|
// this.player = simpleExoPlayer; |
|
|
|
// this.timeline = slider; |
|
|
|
// this.fromTime = fromTime; |
|
|
|
// } |
|
|
|
// |
|
|
|
// @Override |
|
|
|
// public void run() { |
|
|
|
// if (positionUpdateHandler == null) return; |
|
|
|
// positionUpdateHandler.removeCallbacks(this); |
|
|
|
// if (player == null) return; |
|
|
|
// final long currentPosition = player.getCurrentPosition(); |
|
|
|
// final long duration = player.getDuration(); |
|
|
|
// if (duration == TIME_UNSET) { |
|
|
|
// timeline.setValueFrom(0); |
|
|
|
// timeline.setValueTo(0); |
|
|
|
// timeline.setEnabled(false); |
|
|
|
// return; |
|
|
|
// } |
|
|
|
// timeline.setValue(Math.min(currentPosition, duration)); |
|
|
|
// fromTime.setText(TextUtils.millisToTimeString(currentPosition)); |
|
|
|
// positionUpdateHandler.postDelayed(this, RECURRING_DELAY); |
|
|
|
// } |
|
|
|
// } |
|
|
|
} |
|
|
|
|
|
|
|
public interface VideoPlayerCallback { |
|
|
|
void onThumbnailLoaded(); |
|
|
@ -471,5 +326,9 @@ public class VideoPlayerViewHelper implements Player.EventListener { |
|
|
|
void onPause(); |
|
|
|
|
|
|
|
void onRelease(); |
|
|
|
|
|
|
|
void onFullScreenModeChanged(boolean isFullScreen, final StyledPlayerView playerView); |
|
|
|
|
|
|
|
boolean isInFullScreen(); |
|
|
|
} |
|
|
|
} |