mirror of
https://github.com/TeamNewPipe/NewPipe
synced 2024-12-24 09:00:31 +00:00
-Added new intents to append streams to current player.
-Added long clicks for popup and background player buttons on details fragment for append intents. -Removed restrictions for preventing UI to show up when player is buffering. -Fixed icons for all repeat modes. -Added Progress bar to background activity when player is in not ready state. -Fixed Track Selection when switching between video and audio only on video players. -Fixed video player to enable tunnelling only after sdk > 21. -Fixed activity exception from restarting after service is shutdown on earlier sdk versions.
This commit is contained in:
parent
6a9e3ef639
commit
9685456ee4
@ -92,7 +92,7 @@ import io.reactivex.schedulers.Schedulers;
|
|||||||
|
|
||||||
import static org.schabi.newpipe.util.AnimationUtils.animateView;
|
import static org.schabi.newpipe.util.AnimationUtils.animateView;
|
||||||
|
|
||||||
public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implements BackPressable, SharedPreferences.OnSharedPreferenceChangeListener, View.OnClickListener {
|
public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implements BackPressable, SharedPreferences.OnSharedPreferenceChangeListener, View.OnClickListener, View.OnLongClickListener {
|
||||||
public static final String AUTO_PLAY = "auto_play";
|
public static final String AUTO_PLAY = "auto_play";
|
||||||
|
|
||||||
// Amount of videos to show on start
|
// Amount of videos to show on start
|
||||||
@ -320,10 +320,10 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
|
|||||||
|
|
||||||
switch (v.getId()) {
|
switch (v.getId()) {
|
||||||
case R.id.detail_controls_background:
|
case R.id.detail_controls_background:
|
||||||
openBackgroundPlayer();
|
openBackgroundPlayer(false);
|
||||||
break;
|
break;
|
||||||
case R.id.detail_controls_popup:
|
case R.id.detail_controls_popup:
|
||||||
openPopupPlayer();
|
openPopupPlayer(false);
|
||||||
break;
|
break;
|
||||||
case R.id.detail_uploader_root_layout:
|
case R.id.detail_uploader_root_layout:
|
||||||
if (currentInfo.uploader_url == null || currentInfo.uploader_url.isEmpty()) {
|
if (currentInfo.uploader_url == null || currentInfo.uploader_url.isEmpty()) {
|
||||||
@ -344,6 +344,22 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onLongClick(View v) {
|
||||||
|
if (isLoading.get() || currentInfo == null) return false;
|
||||||
|
|
||||||
|
switch (v.getId()) {
|
||||||
|
case R.id.detail_controls_background:
|
||||||
|
openBackgroundPlayer(true);
|
||||||
|
break;
|
||||||
|
case R.id.detail_controls_popup:
|
||||||
|
openPopupPlayer(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private void toggleTitleAndDescription() {
|
private void toggleTitleAndDescription() {
|
||||||
if (videoDescriptionRootLayout.getVisibility() == View.VISIBLE) {
|
if (videoDescriptionRootLayout.getVisibility() == View.VISIBLE) {
|
||||||
videoTitleTextView.setMaxLines(1);
|
videoTitleTextView.setMaxLines(1);
|
||||||
@ -448,6 +464,11 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
|
|||||||
detailControlsBackground.setOnClickListener(this);
|
detailControlsBackground.setOnClickListener(this);
|
||||||
detailControlsPopup.setOnClickListener(this);
|
detailControlsPopup.setOnClickListener(this);
|
||||||
relatedStreamExpandButton.setOnClickListener(this);
|
relatedStreamExpandButton.setOnClickListener(this);
|
||||||
|
|
||||||
|
detailControlsBackground.setLongClickable(true);
|
||||||
|
detailControlsPopup.setLongClickable(true);
|
||||||
|
detailControlsBackground.setOnLongClickListener(this);
|
||||||
|
detailControlsPopup.setOnLongClickListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initThumbnailViews(StreamInfo info) {
|
private void initThumbnailViews(StreamInfo info) {
|
||||||
@ -716,7 +737,7 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
|
|||||||
// Play Utils
|
// Play Utils
|
||||||
//////////////////////////////////////////////////////////////////////////*/
|
//////////////////////////////////////////////////////////////////////////*/
|
||||||
|
|
||||||
private void openBackgroundPlayer() {
|
private void openBackgroundPlayer(final boolean append) {
|
||||||
AudioStream audioStream = currentInfo.audio_streams.get(ListHelper.getDefaultAudioFormat(activity, currentInfo.audio_streams));
|
AudioStream audioStream = currentInfo.audio_streams.get(ListHelper.getDefaultAudioFormat(activity, currentInfo.audio_streams));
|
||||||
|
|
||||||
if (activity instanceof HistoryListener) {
|
if (activity instanceof HistoryListener) {
|
||||||
@ -727,7 +748,7 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
|
|||||||
.getBoolean(activity.getString(R.string.use_external_audio_player_key), false);
|
.getBoolean(activity.getString(R.string.use_external_audio_player_key), false);
|
||||||
|
|
||||||
if (!useExternalAudioPlayer && android.os.Build.VERSION.SDK_INT >= 16) {
|
if (!useExternalAudioPlayer && android.os.Build.VERSION.SDK_INT >= 16) {
|
||||||
openNormalBackgroundPlayer();
|
openNormalBackgroundPlayer(append);
|
||||||
} else {
|
} else {
|
||||||
openExternalBackgroundPlayer(audioStream);
|
openExternalBackgroundPlayer(audioStream);
|
||||||
}
|
}
|
||||||
@ -742,7 +763,7 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void openPopupPlayer() {
|
private void openPopupPlayer(final boolean append) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !PermissionHelper.checkSystemAlertWindowPermission(activity)) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !PermissionHelper.checkSystemAlertWindowPermission(activity)) {
|
||||||
Toast toast = Toast.makeText(activity, R.string.msg_popup_permission, Toast.LENGTH_LONG);
|
Toast toast = Toast.makeText(activity, R.string.msg_popup_permission, Toast.LENGTH_LONG);
|
||||||
TextView messageView = toast.getView().findViewById(android.R.id.message);
|
TextView messageView = toast.getView().findViewById(android.R.id.message);
|
||||||
@ -759,7 +780,13 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
|
|||||||
|
|
||||||
final PlayQueue playQueue = new SinglePlayQueue(currentInfo);
|
final PlayQueue playQueue = new SinglePlayQueue(currentInfo);
|
||||||
final VideoStream candidate = sortedStreamVideosList.get(actionBarHandler.getSelectedVideoStream());
|
final VideoStream candidate = sortedStreamVideosList.get(actionBarHandler.getSelectedVideoStream());
|
||||||
final Intent intent = NavigationHelper.getPlayerIntent(activity, PopupVideoPlayer.class, playQueue, resolutionOf(candidate.resolution));
|
|
||||||
|
final Intent intent;
|
||||||
|
if (append) {
|
||||||
|
intent = NavigationHelper.getPlayerIntent(activity, PopupVideoPlayer.class, playQueue, true);
|
||||||
|
} else {
|
||||||
|
intent = NavigationHelper.getPlayerIntent(activity, PopupVideoPlayer.class, playQueue, resolutionOf(candidate.resolution));
|
||||||
|
}
|
||||||
activity.startService(intent);
|
activity.startService(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -778,9 +805,9 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void openNormalBackgroundPlayer() {
|
private void openNormalBackgroundPlayer(final boolean append) {
|
||||||
final PlayQueue playQueue = new SinglePlayQueue(currentInfo);
|
final PlayQueue playQueue = new SinglePlayQueue(currentInfo);
|
||||||
activity.startService(NavigationHelper.getPlayerIntent(activity, BackgroundPlayer.class, playQueue));
|
activity.startService(NavigationHelper.getPlayerIntent(activity, BackgroundPlayer.class, playQueue, append));
|
||||||
Toast.makeText(activity, R.string.background_player_playing_toast, Toast.LENGTH_SHORT).show();
|
Toast.makeText(activity, R.string.background_player_playing_toast, Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,14 +44,11 @@ import com.google.android.exoplayer2.Player;
|
|||||||
import com.google.android.exoplayer2.source.MediaSource;
|
import com.google.android.exoplayer2.source.MediaSource;
|
||||||
|
|
||||||
import org.schabi.newpipe.BuildConfig;
|
import org.schabi.newpipe.BuildConfig;
|
||||||
import org.schabi.newpipe.MainActivity;
|
|
||||||
import org.schabi.newpipe.R;
|
import org.schabi.newpipe.R;
|
||||||
import org.schabi.newpipe.extractor.MediaFormat;
|
import org.schabi.newpipe.extractor.MediaFormat;
|
||||||
import org.schabi.newpipe.extractor.StreamingService;
|
|
||||||
import org.schabi.newpipe.extractor.stream.AudioStream;
|
import org.schabi.newpipe.extractor.stream.AudioStream;
|
||||||
import org.schabi.newpipe.extractor.stream.StreamInfo;
|
import org.schabi.newpipe.extractor.stream.StreamInfo;
|
||||||
import org.schabi.newpipe.playlist.PlayQueueItem;
|
import org.schabi.newpipe.playlist.PlayQueueItem;
|
||||||
import org.schabi.newpipe.util.Constants;
|
|
||||||
import org.schabi.newpipe.util.ListHelper;
|
import org.schabi.newpipe.util.ListHelper;
|
||||||
import org.schabi.newpipe.util.ThemeHelper;
|
import org.schabi.newpipe.util.ThemeHelper;
|
||||||
|
|
||||||
@ -108,6 +105,7 @@ public final class BackgroundPlayer extends Service {
|
|||||||
private RemoteViews notRemoteView;
|
private RemoteViews notRemoteView;
|
||||||
private RemoteViews bigNotRemoteView;
|
private RemoteViews bigNotRemoteView;
|
||||||
private final String setAlphaMethodName = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) ? "setImageAlpha" : "setAlpha";
|
private final String setAlphaMethodName = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) ? "setImageAlpha" : "setAlpha";
|
||||||
|
private final String setImageResourceMethodName = "setImageResource";
|
||||||
|
|
||||||
/*//////////////////////////////////////////////////////////////////////////
|
/*//////////////////////////////////////////////////////////////////////////
|
||||||
// Service's LifeCycle
|
// Service's LifeCycle
|
||||||
@ -137,12 +135,7 @@ public final class BackgroundPlayer extends Service {
|
|||||||
@Override
|
@Override
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
if (DEBUG) Log.d(TAG, "destroy() called");
|
if (DEBUG) Log.d(TAG, "destroy() called");
|
||||||
releaseWifiAndCpu();
|
onClose();
|
||||||
stopForeground(true);
|
|
||||||
|
|
||||||
if (basePlayerImpl != null) basePlayerImpl.destroy();
|
|
||||||
basePlayerImpl = null;
|
|
||||||
mBinder = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -156,18 +149,22 @@ public final class BackgroundPlayer extends Service {
|
|||||||
|
|
||||||
public void openControl(final Context context) {
|
public void openControl(final Context context) {
|
||||||
final Intent intent = new Intent(context, BackgroundPlayerActivity.class);
|
final Intent intent = new Intent(context, BackgroundPlayerActivity.class);
|
||||||
|
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
context.startActivity(intent);
|
context.startActivity(intent);
|
||||||
context.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
|
context.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onClose() {
|
private void onClose() {
|
||||||
if (basePlayerImpl != null) {
|
|
||||||
basePlayerImpl.stopActivityBinding();
|
|
||||||
basePlayerImpl.destroyPlayer();
|
|
||||||
}
|
|
||||||
|
|
||||||
stopForeground(true);
|
stopForeground(true);
|
||||||
releaseWifiAndCpu();
|
releaseWifiAndCpu();
|
||||||
|
|
||||||
|
if (basePlayerImpl != null) {
|
||||||
|
basePlayerImpl.stopActivityBinding();
|
||||||
|
basePlayerImpl.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
basePlayerImpl = null;
|
||||||
|
mBinder = null;
|
||||||
stopSelf();
|
stopSelf();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,18 +219,7 @@ public final class BackgroundPlayer extends Service {
|
|||||||
remoteViews.setOnClickPendingIntent(R.id.notificationFForward,
|
remoteViews.setOnClickPendingIntent(R.id.notificationFForward,
|
||||||
PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_FAST_FORWARD), PendingIntent.FLAG_UPDATE_CURRENT));
|
PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_FAST_FORWARD), PendingIntent.FLAG_UPDATE_CURRENT));
|
||||||
|
|
||||||
switch (basePlayerImpl.simpleExoPlayer.getRepeatMode()) {
|
setRepeatModeIcon(remoteViews, basePlayerImpl.simpleExoPlayer.getRepeatMode());
|
||||||
case Player.REPEAT_MODE_OFF:
|
|
||||||
remoteViews.setInt(R.id.notificationRepeat, setAlphaMethodName, 77);
|
|
||||||
break;
|
|
||||||
case Player.REPEAT_MODE_ONE:
|
|
||||||
// todo change image
|
|
||||||
remoteViews.setInt(R.id.notificationRepeat, setAlphaMethodName, 168);
|
|
||||||
break;
|
|
||||||
case Player.REPEAT_MODE_ALL:
|
|
||||||
remoteViews.setInt(R.id.notificationRepeat, setAlphaMethodName, 255);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -285,6 +271,19 @@ public final class BackgroundPlayer extends Service {
|
|||||||
wifiLock = null;
|
wifiLock = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setRepeatModeIcon(final RemoteViews remoteViews, final int repeatMode) {
|
||||||
|
switch (repeatMode) {
|
||||||
|
case Player.REPEAT_MODE_OFF:
|
||||||
|
remoteViews.setInt(R.id.notificationRepeat, setImageResourceMethodName, R.drawable.exo_controls_repeat_off);
|
||||||
|
break;
|
||||||
|
case Player.REPEAT_MODE_ONE:
|
||||||
|
remoteViews.setInt(R.id.notificationRepeat, setImageResourceMethodName, R.drawable.exo_controls_repeat_one);
|
||||||
|
break;
|
||||||
|
case Player.REPEAT_MODE_ALL:
|
||||||
|
remoteViews.setInt(R.id.notificationRepeat, setImageResourceMethodName, R.drawable.exo_controls_repeat_all);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
protected class BasePlayerImpl extends BasePlayer {
|
protected class BasePlayerImpl extends BasePlayer {
|
||||||
@ -424,21 +423,8 @@ public final class BackgroundPlayer extends Service {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRepeatModeChanged(int i) {
|
public void onRepeatModeChanged(int i) {
|
||||||
int opacity = 255;
|
setRepeatModeIcon(notRemoteView, i);
|
||||||
switch (simpleExoPlayer.getRepeatMode()) {
|
setRepeatModeIcon(bigNotRemoteView, i);
|
||||||
case Player.REPEAT_MODE_OFF:
|
|
||||||
opacity = 77;
|
|
||||||
break;
|
|
||||||
case Player.REPEAT_MODE_ONE:
|
|
||||||
// todo change image
|
|
||||||
opacity = 168;
|
|
||||||
break;
|
|
||||||
case Player.REPEAT_MODE_ALL:
|
|
||||||
opacity = 255;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (notRemoteView != null) notRemoteView.setInt(R.id.notificationRepeat, setAlphaMethodName, opacity);
|
|
||||||
if (bigNotRemoteView != null) bigNotRemoteView.setInt(R.id.notificationRepeat, setAlphaMethodName, opacity);
|
|
||||||
updateNotification(-1);
|
updateNotification(-1);
|
||||||
updatePlayback();
|
updatePlayback();
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ import android.view.MenuItem;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.ImageButton;
|
import android.widget.ImageButton;
|
||||||
import android.widget.PopupMenu;
|
import android.widget.PopupMenu;
|
||||||
|
import android.widget.ProgressBar;
|
||||||
import android.widget.SeekBar;
|
import android.widget.SeekBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
@ -70,6 +71,7 @@ public class BackgroundPlayerActivity extends AppCompatActivity
|
|||||||
private ImageButton playPauseButton;
|
private ImageButton playPauseButton;
|
||||||
private ImageButton forwardButton;
|
private ImageButton forwardButton;
|
||||||
private ImageButton shuffleButton;
|
private ImageButton shuffleButton;
|
||||||
|
private ProgressBar progressBar;
|
||||||
|
|
||||||
private TextView playbackSpeedButton;
|
private TextView playbackSpeedButton;
|
||||||
private PopupMenu playbackSpeedPopupMenu;
|
private PopupMenu playbackSpeedPopupMenu;
|
||||||
@ -164,7 +166,7 @@ public class BackgroundPlayerActivity extends AppCompatActivity
|
|||||||
Log.d(TAG, "Background player service is connected");
|
Log.d(TAG, "Background player service is connected");
|
||||||
final BackgroundPlayer.LocalBinder mLocalBinder = (BackgroundPlayer.LocalBinder) service;
|
final BackgroundPlayer.LocalBinder mLocalBinder = (BackgroundPlayer.LocalBinder) service;
|
||||||
player = mLocalBinder.getBackgroundPlayerInstance();
|
player = mLocalBinder.getBackgroundPlayerInstance();
|
||||||
if (player == null) {
|
if (player == null || player.playQueue == null || player.playQueueAdapter == null || player.simpleExoPlayer == null) {
|
||||||
unbind();
|
unbind();
|
||||||
} else {
|
} else {
|
||||||
buildComponents();
|
buildComponents();
|
||||||
@ -219,6 +221,7 @@ public class BackgroundPlayerActivity extends AppCompatActivity
|
|||||||
shuffleButton = rootView.findViewById(R.id.control_shuffle);
|
shuffleButton = rootView.findViewById(R.id.control_shuffle);
|
||||||
playbackSpeedButton = rootView.findViewById(R.id.control_playback_speed);
|
playbackSpeedButton = rootView.findViewById(R.id.control_playback_speed);
|
||||||
playbackPitchButton = rootView.findViewById(R.id.control_playback_pitch);
|
playbackPitchButton = rootView.findViewById(R.id.control_playback_pitch);
|
||||||
|
progressBar = rootView.findViewById(R.id.control_progress_bar);
|
||||||
|
|
||||||
repeatButton.setOnClickListener(this);
|
repeatButton.setOnClickListener(this);
|
||||||
backwardButton.setOnClickListener(this);
|
backwardButton.setOnClickListener(this);
|
||||||
@ -431,52 +434,9 @@ public class BackgroundPlayerActivity extends AppCompatActivity
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPlaybackUpdate(int state, int repeatMode, boolean shuffled, PlaybackParameters parameters) {
|
public void onPlaybackUpdate(int state, int repeatMode, boolean shuffled, PlaybackParameters parameters) {
|
||||||
switch (state) {
|
onStateChanged(state);
|
||||||
case BasePlayer.STATE_PAUSED:
|
onPlayModeChanged(repeatMode, shuffled);
|
||||||
playPauseButton.setImageResource(R.drawable.ic_play_arrow_white);
|
onPlaybackParameterChanged(parameters);
|
||||||
break;
|
|
||||||
case BasePlayer.STATE_PLAYING:
|
|
||||||
playPauseButton.setImageResource(R.drawable.ic_pause_white);
|
|
||||||
break;
|
|
||||||
case BasePlayer.STATE_COMPLETED:
|
|
||||||
playPauseButton.setImageResource(R.drawable.ic_replay_white);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
int repeatAlpha = 255;
|
|
||||||
switch (repeatMode) {
|
|
||||||
case Player.REPEAT_MODE_OFF:
|
|
||||||
repeatAlpha = 77;
|
|
||||||
break;
|
|
||||||
case Player.REPEAT_MODE_ONE:
|
|
||||||
// todo change image
|
|
||||||
repeatAlpha = 168;
|
|
||||||
break;
|
|
||||||
case Player.REPEAT_MODE_ALL:
|
|
||||||
repeatAlpha = 255;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
int shuffleAlpha = 255;
|
|
||||||
if (!shuffled) {
|
|
||||||
shuffleAlpha = 77;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
|
||||||
repeatButton.setImageAlpha(repeatAlpha);
|
|
||||||
shuffleButton.setImageAlpha(shuffleAlpha);
|
|
||||||
} else {
|
|
||||||
repeatButton.setAlpha(repeatAlpha);
|
|
||||||
shuffleButton.setAlpha(shuffleAlpha);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parameters != null) {
|
|
||||||
playbackSpeedButton.setText(player.formatSpeed(parameters.speed));
|
|
||||||
playbackPitchButton.setText(player.formatPitch(parameters.pitch));
|
|
||||||
}
|
|
||||||
|
|
||||||
scrollToSelected();
|
scrollToSelected();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -509,4 +469,67 @@ public class BackgroundPlayerActivity extends AppCompatActivity
|
|||||||
public void onServiceStopped() {
|
public void onServiceStopped() {
|
||||||
unbind();
|
unbind();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Binding Service Helper
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
private void onStateChanged(final int state) {
|
||||||
|
switch (state) {
|
||||||
|
case BasePlayer.STATE_PAUSED:
|
||||||
|
playPauseButton.setImageResource(R.drawable.ic_play_arrow_white);
|
||||||
|
break;
|
||||||
|
case BasePlayer.STATE_PLAYING:
|
||||||
|
playPauseButton.setImageResource(R.drawable.ic_pause_white);
|
||||||
|
break;
|
||||||
|
case BasePlayer.STATE_COMPLETED:
|
||||||
|
playPauseButton.setImageResource(R.drawable.ic_replay_white);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case BasePlayer.STATE_PAUSED:
|
||||||
|
case BasePlayer.STATE_PLAYING:
|
||||||
|
case BasePlayer.STATE_COMPLETED:
|
||||||
|
playPauseButton.setClickable(true);
|
||||||
|
playPauseButton.setVisibility(View.VISIBLE);
|
||||||
|
progressBar.setVisibility(View.GONE);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
playPauseButton.setClickable(false);
|
||||||
|
playPauseButton.setVisibility(View.INVISIBLE);
|
||||||
|
progressBar.setVisibility(View.VISIBLE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onPlayModeChanged(final int repeatMode, final boolean shuffled) {
|
||||||
|
switch (repeatMode) {
|
||||||
|
case Player.REPEAT_MODE_OFF:
|
||||||
|
repeatButton.setImageResource(R.drawable.exo_controls_repeat_off);
|
||||||
|
break;
|
||||||
|
case Player.REPEAT_MODE_ONE:
|
||||||
|
repeatButton.setImageResource(R.drawable.exo_controls_repeat_one);
|
||||||
|
break;
|
||||||
|
case Player.REPEAT_MODE_ALL:
|
||||||
|
repeatButton.setImageResource(R.drawable.exo_controls_repeat_all);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
final int shuffleAlpha = shuffled ? 255 : 77;
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
||||||
|
shuffleButton.setImageAlpha(shuffleAlpha);
|
||||||
|
} else {
|
||||||
|
shuffleButton.setAlpha(shuffleAlpha);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onPlaybackParameterChanged(final PlaybackParameters parameters) {
|
||||||
|
if (parameters != null) {
|
||||||
|
playbackSpeedButton.setText(player.formatSpeed(parameters.speed));
|
||||||
|
playbackPitchButton.setText(player.formatPitch(parameters.pitch));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,6 +137,7 @@ public abstract class BasePlayer implements Player.EventListener,
|
|||||||
public static final String PLAY_QUEUE = "play_queue";
|
public static final String PLAY_QUEUE = "play_queue";
|
||||||
public static final String RESTORE_QUEUE_INDEX = "restore_queue_index";
|
public static final String RESTORE_QUEUE_INDEX = "restore_queue_index";
|
||||||
public static final String RESTORE_WINDOW_POS = "restore_window_pos";
|
public static final String RESTORE_WINDOW_POS = "restore_window_pos";
|
||||||
|
public static final String APPEND_ONLY = "append_only";
|
||||||
|
|
||||||
/*//////////////////////////////////////////////////////////////////////////
|
/*//////////////////////////////////////////////////////////////////////////
|
||||||
// Playback
|
// Playback
|
||||||
@ -260,6 +261,12 @@ public abstract class BasePlayer implements Player.EventListener,
|
|||||||
if (!(playQueueCandidate instanceof PlayQueue)) return;
|
if (!(playQueueCandidate instanceof PlayQueue)) return;
|
||||||
final PlayQueue queue = (PlayQueue) playQueueCandidate;
|
final PlayQueue queue = (PlayQueue) playQueueCandidate;
|
||||||
|
|
||||||
|
// Resolve append intents
|
||||||
|
if (intent.getBooleanExtra(APPEND_ONLY, false) && playQueue != null) {
|
||||||
|
playQueue.append(queue.getStreams());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Resolve playback details
|
// Resolve playback details
|
||||||
if (intent.hasExtra(RESTORE_QUEUE_INDEX) && intent.hasExtra(START_POSITION)) {
|
if (intent.hasExtra(RESTORE_QUEUE_INDEX) && intent.hasExtra(START_POSITION)) {
|
||||||
setRecovery(
|
setRecovery(
|
||||||
@ -310,6 +317,7 @@ public abstract class BasePlayer implements Player.EventListener,
|
|||||||
public void destroyPlayer() {
|
public void destroyPlayer() {
|
||||||
if (DEBUG) Log.d(TAG, "destroyPlayer() called");
|
if (DEBUG) Log.d(TAG, "destroyPlayer() called");
|
||||||
if (simpleExoPlayer != null) {
|
if (simpleExoPlayer != null) {
|
||||||
|
simpleExoPlayer.removeListener(this);
|
||||||
simpleExoPlayer.stop();
|
simpleExoPlayer.stop();
|
||||||
simpleExoPlayer.release();
|
simpleExoPlayer.release();
|
||||||
}
|
}
|
||||||
|
@ -189,6 +189,20 @@ public final class MainVideoPlayer extends Activity {
|
|||||||
: ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
|
: ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void setRepeatModeButton(final ImageButton imageButton, final int repeatMode) {
|
||||||
|
switch (repeatMode) {
|
||||||
|
case Player.REPEAT_MODE_OFF:
|
||||||
|
imageButton.setImageResource(R.drawable.exo_controls_repeat_off);
|
||||||
|
break;
|
||||||
|
case Player.REPEAT_MODE_ONE:
|
||||||
|
imageButton.setImageResource(R.drawable.exo_controls_repeat_one);
|
||||||
|
break;
|
||||||
|
case Player.REPEAT_MODE_ALL:
|
||||||
|
imageButton.setImageResource(R.drawable.exo_controls_repeat_all);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@SuppressWarnings({"unused", "WeakerAccess"})
|
@SuppressWarnings({"unused", "WeakerAccess"})
|
||||||
@ -218,12 +232,6 @@ public final class MainVideoPlayer extends Activity {
|
|||||||
this.screenRotationButton = rootView.findViewById(R.id.screenRotationButton);
|
this.screenRotationButton = rootView.findViewById(R.id.screenRotationButton);
|
||||||
this.playPauseButton = rootView.findViewById(R.id.playPauseButton);
|
this.playPauseButton = rootView.findViewById(R.id.playPauseButton);
|
||||||
|
|
||||||
// Due to a bug on lower API, lets set the alpha instead of using a drawable
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) repeatButton.setImageAlpha(77);
|
|
||||||
else { //noinspection deprecation
|
|
||||||
repeatButton.setAlpha(77);
|
|
||||||
}
|
|
||||||
|
|
||||||
getRootView().setKeepScreenOn(true);
|
getRootView().setKeepScreenOn(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,6 +249,16 @@ public final class MainVideoPlayer extends Activity {
|
|||||||
screenRotationButton.setOnClickListener(this);
|
screenRotationButton.setOnClickListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*//////////////////////////////////////////////////////////////////////////
|
||||||
|
// ExoPlayer Video Listener
|
||||||
|
//////////////////////////////////////////////////////////////////////////*/
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRepeatModeChanged(int i) {
|
||||||
|
super.onRepeatModeChanged(i);
|
||||||
|
setRepeatModeButton(repeatButton, simpleExoPlayer.getRepeatMode());
|
||||||
|
}
|
||||||
|
|
||||||
/*//////////////////////////////////////////////////////////////////////////
|
/*//////////////////////////////////////////////////////////////////////////
|
||||||
// Playback Listener
|
// Playback Listener
|
||||||
//////////////////////////////////////////////////////////////////////////*/
|
//////////////////////////////////////////////////////////////////////////*/
|
||||||
@ -289,31 +307,6 @@ public final class MainVideoPlayer extends Activity {
|
|||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public void onRepeatClicked() {
|
|
||||||
super.onRepeatClicked();
|
|
||||||
if (DEBUG) Log.d(TAG, "onRepeatClicked() called");
|
|
||||||
switch (simpleExoPlayer.getRepeatMode()) {
|
|
||||||
case Player.REPEAT_MODE_OFF:
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) repeatButton.setImageAlpha(77);
|
|
||||||
else repeatButton.setAlpha(77);
|
|
||||||
|
|
||||||
break;
|
|
||||||
case Player.REPEAT_MODE_ONE:
|
|
||||||
// todo change image
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) repeatButton.setImageAlpha(168);
|
|
||||||
else repeatButton.setAlpha(168);
|
|
||||||
|
|
||||||
break;
|
|
||||||
case Player.REPEAT_MODE_ALL:
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) repeatButton.setImageAlpha(255);
|
|
||||||
else repeatButton.setAlpha(255);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
super.onClick(v);
|
super.onClick(v);
|
||||||
@ -509,7 +502,7 @@ public final class MainVideoPlayer extends Activity {
|
|||||||
@Override
|
@Override
|
||||||
public boolean onSingleTapConfirmed(MotionEvent e) {
|
public boolean onSingleTapConfirmed(MotionEvent e) {
|
||||||
if (DEBUG) Log.d(TAG, "onSingleTapConfirmed() called with: e = [" + e + "]");
|
if (DEBUG) Log.d(TAG, "onSingleTapConfirmed() called with: e = [" + e + "]");
|
||||||
if (playerImpl.getCurrentState() != BasePlayer.STATE_PLAYING) return true;
|
if (playerImpl.getCurrentState() == BasePlayer.STATE_BLOCKED) return true;
|
||||||
|
|
||||||
if (playerImpl.isControlsVisible()) playerImpl.hideControls(150, 0);
|
if (playerImpl.isControlsVisible()) playerImpl.hideControls(150, 0);
|
||||||
else {
|
else {
|
||||||
|
@ -111,7 +111,8 @@ public final class PopupVideoPlayer extends Service {
|
|||||||
private float minimumWidth, minimumHeight;
|
private float minimumWidth, minimumHeight;
|
||||||
private float maximumWidth, maximumHeight;
|
private float maximumWidth, maximumHeight;
|
||||||
|
|
||||||
private final String setAlphaMethodName = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) ? "setImageAlpha" : "setAlpha";
|
private final String setImageResourceMethodName = "setImageResource";
|
||||||
|
|
||||||
private NotificationManager notificationManager;
|
private NotificationManager notificationManager;
|
||||||
private NotificationCompat.Builder notBuilder;
|
private NotificationCompat.Builder notBuilder;
|
||||||
private RemoteViews notRemoteView;
|
private RemoteViews notRemoteView;
|
||||||
@ -255,18 +256,7 @@ public final class PopupVideoPlayer extends Service {
|
|||||||
notRemoteView.setOnClickPendingIntent(R.id.notificationRepeat,
|
notRemoteView.setOnClickPendingIntent(R.id.notificationRepeat,
|
||||||
PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_REPEAT), PendingIntent.FLAG_UPDATE_CURRENT));
|
PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_REPEAT), PendingIntent.FLAG_UPDATE_CURRENT));
|
||||||
|
|
||||||
switch (playerImpl.simpleExoPlayer.getRepeatMode()) {
|
setRepeatModeRemote(notRemoteView, playerImpl.simpleExoPlayer.getRepeatMode());
|
||||||
case Player.REPEAT_MODE_OFF:
|
|
||||||
notRemoteView.setInt(R.id.notificationRepeat, setAlphaMethodName, 77);
|
|
||||||
break;
|
|
||||||
case Player.REPEAT_MODE_ONE:
|
|
||||||
//todo change image
|
|
||||||
notRemoteView.setInt(R.id.notificationRepeat, setAlphaMethodName, 168);
|
|
||||||
break;
|
|
||||||
case Player.REPEAT_MODE_ALL:
|
|
||||||
notRemoteView.setInt(R.id.notificationRepeat, setAlphaMethodName, 255);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new NotificationCompat.Builder(this, getString(R.string.notification_channel_id))
|
return new NotificationCompat.Builder(this, getString(R.string.notification_channel_id))
|
||||||
.setOngoing(true)
|
.setOngoing(true)
|
||||||
@ -370,6 +360,20 @@ public final class PopupVideoPlayer extends Service {
|
|||||||
windowManager.updateViewLayout(playerImpl.getRootView(), windowLayoutParams);
|
windowManager.updateViewLayout(playerImpl.getRootView(), windowLayoutParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void setRepeatModeRemote(final RemoteViews remoteViews, final int repeatMode) {
|
||||||
|
switch (repeatMode) {
|
||||||
|
case Player.REPEAT_MODE_OFF:
|
||||||
|
remoteViews.setInt(R.id.notificationRepeat, setImageResourceMethodName, R.drawable.exo_controls_repeat_off);
|
||||||
|
break;
|
||||||
|
case Player.REPEAT_MODE_ONE:
|
||||||
|
remoteViews.setInt(R.id.notificationRepeat, setImageResourceMethodName, R.drawable.exo_controls_repeat_one);
|
||||||
|
break;
|
||||||
|
case Player.REPEAT_MODE_ALL:
|
||||||
|
remoteViews.setInt(R.id.notificationRepeat, setImageResourceMethodName, R.drawable.exo_controls_repeat_all);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
private class VideoPlayerImpl extends VideoPlayer {
|
private class VideoPlayerImpl extends VideoPlayer {
|
||||||
@ -435,27 +439,6 @@ public final class PopupVideoPlayer extends Service {
|
|||||||
stopSelf();
|
stopSelf();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRepeatClicked() {
|
|
||||||
super.onRepeatClicked();
|
|
||||||
switch (simpleExoPlayer.getRepeatMode()) {
|
|
||||||
case Player.REPEAT_MODE_OFF:
|
|
||||||
// Drawable didn't work on low API :/
|
|
||||||
//notRemoteView.setImageViewResource(R.id.notificationRepeat, R.drawable.ic_repeat_disabled_white);
|
|
||||||
// Set the icon to 30% opacity - 255 (max) * .3
|
|
||||||
notRemoteView.setInt(R.id.notificationRepeat, setAlphaMethodName, 77);
|
|
||||||
break;
|
|
||||||
case Player.REPEAT_MODE_ONE:
|
|
||||||
// todo change image
|
|
||||||
notRemoteView.setInt(R.id.notificationRepeat, setAlphaMethodName, 168);
|
|
||||||
break;
|
|
||||||
case Player.REPEAT_MODE_ALL:
|
|
||||||
notRemoteView.setInt(R.id.notificationRepeat, setAlphaMethodName, 255);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
updateNotification(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDismiss(PopupMenu menu) {
|
public void onDismiss(PopupMenu menu) {
|
||||||
super.onDismiss(menu);
|
super.onDismiss(menu);
|
||||||
@ -482,6 +465,16 @@ public final class PopupVideoPlayer extends Service {
|
|||||||
hideControls(100, 0);
|
hideControls(100, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*//////////////////////////////////////////////////////////////////////////
|
||||||
|
// ExoPlayer Video Listener
|
||||||
|
//////////////////////////////////////////////////////////////////////////*/
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRepeatModeChanged(int i) {
|
||||||
|
super.onRepeatModeChanged(i);
|
||||||
|
setRepeatModeRemote(notRemoteView, i);
|
||||||
|
updateNotification(-1);
|
||||||
|
}
|
||||||
|
|
||||||
/*//////////////////////////////////////////////////////////////////////////
|
/*//////////////////////////////////////////////////////////////////////////
|
||||||
// Playback Listener
|
// Playback Listener
|
||||||
|
@ -211,8 +211,10 @@ public abstract class VideoPlayer extends BasePlayer implements SimpleExoPlayer.
|
|||||||
simpleExoPlayer.setVideoSurfaceView(surfaceView);
|
simpleExoPlayer.setVideoSurfaceView(surfaceView);
|
||||||
simpleExoPlayer.addVideoListener(this);
|
simpleExoPlayer.addVideoListener(this);
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= 21) {
|
||||||
trackSelector.setTunnelingAudioSessionId(C.generateAudioSessionIdV21(context));
|
trackSelector.setTunnelingAudioSessionId(C.generateAudioSessionIdV21(context));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@ -286,6 +288,7 @@ public abstract class VideoPlayer extends BasePlayer implements SimpleExoPlayer.
|
|||||||
|
|
||||||
qualityPopupMenu.setOnMenuItemClickListener(this);
|
qualityPopupMenu.setOnMenuItemClickListener(this);
|
||||||
qualityPopupMenu.setOnDismissListener(this);
|
qualityPopupMenu.setOnDismissListener(this);
|
||||||
|
qualityTextView.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void buildPlaybackSpeedMenu() {
|
private void buildPlaybackSpeedMenu() {
|
||||||
@ -409,12 +412,8 @@ public abstract class VideoPlayer extends BasePlayer implements SimpleExoPlayer.
|
|||||||
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
|
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
|
||||||
super.onTracksChanged(trackGroups, trackSelections);
|
super.onTracksChanged(trackGroups, trackSelections);
|
||||||
|
|
||||||
if (trackSelector.getCurrentMappedTrackInfo() == null) {
|
if (trackSelector.getCurrentMappedTrackInfo() == null) return;
|
||||||
qualityTextView.setVisibility(View.GONE);
|
qualityTextView.setVisibility(View.GONE);
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
qualityTextView.setVisibility(View.VISIBLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int t = 0; t < simpleExoPlayer.getRendererCount(); t++) {
|
for (int t = 0; t < simpleExoPlayer.getRendererCount(); t++) {
|
||||||
if (simpleExoPlayer.getRendererType(t) == C.TRACK_TYPE_VIDEO) {
|
if (simpleExoPlayer.getRendererType(t) == C.TRACK_TYPE_VIDEO) {
|
||||||
@ -422,10 +421,12 @@ public abstract class VideoPlayer extends BasePlayer implements SimpleExoPlayer.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
videoTrackGroups = trackSelector.getCurrentMappedTrackInfo().getTrackGroups(videoRendererIndex);
|
videoTrackGroups = trackSelector.getCurrentMappedTrackInfo().getTrackGroups(videoRendererIndex);
|
||||||
selectedVideoTrackGroup = trackSelections.get(videoRendererIndex).getTrackGroup();
|
final TrackSelection trackSelection = trackSelections.get(videoRendererIndex);
|
||||||
|
if (trackSelection != null) {
|
||||||
|
selectedVideoTrackGroup = trackSelection.getTrackGroup();
|
||||||
buildQualityMenu();
|
buildQualityMenu();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees, float pixelWidthHeightRatio) {
|
public void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees, float pixelWidthHeightRatio) {
|
||||||
|
@ -57,6 +57,14 @@ public class NavigationHelper {
|
|||||||
.putExtra(VideoPlayer.PLAY_QUEUE, playQueue);
|
.putExtra(VideoPlayer.PLAY_QUEUE, playQueue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Intent getPlayerIntent(final Context context,
|
||||||
|
final Class targetClazz,
|
||||||
|
final PlayQueue playQueue,
|
||||||
|
final boolean isAppending) {
|
||||||
|
return getPlayerIntent(context, targetClazz, playQueue)
|
||||||
|
.putExtra(BasePlayer.APPEND_ONLY, isAppending);
|
||||||
|
}
|
||||||
|
|
||||||
public static Intent getPlayerIntent(final Context context,
|
public static Intent getPlayerIntent(final Context context,
|
||||||
final Class targetClazz,
|
final Class targetClazz,
|
||||||
final PlayQueue playQueue,
|
final PlayQueue playQueue,
|
||||||
|
@ -183,6 +183,23 @@
|
|||||||
android:src="@drawable/ic_pause_white"
|
android:src="@drawable/ic_pause_white"
|
||||||
tools:ignore="ContentDescription"/>
|
tools:ignore="ContentDescription"/>
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/control_progress_bar"
|
||||||
|
style="?android:attr/progressBarStyleLargeInverse"
|
||||||
|
android:layout_width="50dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:layout_marginLeft="5dp"
|
||||||
|
android:layout_marginRight="5dp"
|
||||||
|
android:background="#00000000"
|
||||||
|
android:padding="2dp"
|
||||||
|
android:clickable="false"
|
||||||
|
android:scaleType="fitCenter"
|
||||||
|
android:indeterminate="true"
|
||||||
|
android:visibility="invisible"/>
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/control_forward"
|
android:id="@+id/control_forward"
|
||||||
android:layout_width="40dp"
|
android:layout_width="40dp"
|
||||||
|
@ -155,7 +155,7 @@
|
|||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:padding="5dp"
|
android:padding="5dp"
|
||||||
android:scaleType="fitXY"
|
android:scaleType="fitXY"
|
||||||
android:src="@drawable/ic_repeat_white"
|
android:src="@drawable/exo_controls_repeat_off"
|
||||||
tools:ignore="ContentDescription,RtlHardcoded"/>
|
tools:ignore="ContentDescription,RtlHardcoded"/>
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
|
Loading…
Reference in New Issue
Block a user