Implement fullscreen and quality selector

- Implement cache
- Abstract player
- Quality selector
- Fullscreen switcher
- Change some drawables
This commit is contained in:
Mauricio Colli 2017-03-27 01:08:16 -03:00
parent 83d2ab95e0
commit b43c56085d
55 changed files with 2397 additions and 1093 deletions

View File

@ -45,7 +45,7 @@ dependencies {
compile 'com.google.code.gson:gson:2.4'
compile 'com.nononsenseapps:filepicker:3.0.0'
compile 'ch.acra:acra:4.9.0'
compile 'com.devbrackets.android:exomedia:3.1.1'
compile 'com.google.android.exoplayer:exoplayer:r2.3.1'
testCompile 'junit:junit:4.12'
testCompile 'org.mockito:mockito-core:1.10.19'
testCompile 'org.json:json:20160810'

View File

@ -51,19 +51,7 @@
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:label="@string/app_name"
android:launchMode="singleInstance"
android:theme="@style/PlayerTheme">
<intent-filter>
<action android:name="org.schabi.newpipe.exoplayer.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="http" />
<data android:scheme="https" />
<data android:scheme="content" />
<data android:scheme="asset" />
<data android:scheme="file" />
</intent-filter>
</activity>
android:theme="@style/PlayerTheme"/>
<service
android:name=".player.BackgroundPlayer"
@ -180,7 +168,7 @@
<activity android:name=".PopupActivity"
android:theme="@android:style/Theme.NoDisplay"
android:label="NewPipe Popup mode">
android:label="@string/popup_mode_share_menu_title">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH" />

View File

@ -51,6 +51,7 @@ import org.schabi.newpipe.extractor.stream_info.AudioStream;
import org.schabi.newpipe.extractor.stream_info.StreamInfo;
import org.schabi.newpipe.extractor.stream_info.VideoStream;
import org.schabi.newpipe.info_list.InfoItemBuilder;
import org.schabi.newpipe.player.AbstractPlayer;
import org.schabi.newpipe.player.BackgroundPlayer;
import org.schabi.newpipe.player.ExoPlayerActivity;
import org.schabi.newpipe.player.PlayVideoActivity;
@ -59,6 +60,7 @@ import org.schabi.newpipe.report.ErrorActivity;
import org.schabi.newpipe.util.NavStack;
import org.schabi.newpipe.util.PermissionHelper;
import java.util.ArrayList;
import java.util.Vector;
import static android.app.Activity.RESULT_OK;
@ -331,10 +333,12 @@ public class VideoItemDetailFragment extends Fragment {
// so, I can notify the service through a broadcast, but the problem is
// when I click in another video, another thumbnail will be load, and will
// notify again, so I send the videoUrl and compare with the service's url
ActivityCommunicator.getCommunicator().backgroundPlayerThumbnail = streamThumbnail;
Intent intent = new Intent(PopupVideoPlayer.InternalListener.ACTION_UPDATE_THUMB);
intent.putExtra(PopupVideoPlayer.VIDEO_URL, info.webpage_url);
getContext().sendBroadcast(intent);
if (getContext() != null) {
ActivityCommunicator.getCommunicator().backgroundPlayerThumbnail = streamThumbnail;
Intent intent = new Intent(AbstractPlayer.ACTION_UPDATE_THUMB);
intent.putExtra(AbstractPlayer.VIDEO_URL, info.webpage_url);
getContext().sendBroadcast(intent);
}
}
}
@ -388,13 +392,15 @@ public class VideoItemDetailFragment extends Fragment {
if (streamThumbnail != null)
ActivityCommunicator.getCommunicator().backgroundPlayerThumbnail = streamThumbnail;
VideoStream selectedVideoStream = info.video_streams.get(selectedStreamId);
Intent i = new Intent(activity, PopupVideoPlayer.class);
Toast.makeText(activity, "Starting in popup mode", Toast.LENGTH_SHORT).show();
i.putExtra(PopupVideoPlayer.VIDEO_TITLE, info.title)
.putExtra(PopupVideoPlayer.STREAM_URL, selectedVideoStream.url)
.putExtra(PopupVideoPlayer.CHANNEL_NAME, info.uploader)
.putExtra(PopupVideoPlayer.VIDEO_URL, info.webpage_url);
Toast.makeText(activity, R.string.popup_playing_toast, Toast.LENGTH_SHORT).show();
i.putExtra(AbstractPlayer.VIDEO_TITLE, info.title)
.putExtra(AbstractPlayer.CHANNEL_NAME, info.uploader)
.putExtra(AbstractPlayer.VIDEO_URL, info.webpage_url)
.putExtra(AbstractPlayer.INDEX_SEL_VIDEO_STREAM, selectedStreamId)
.putExtra(AbstractPlayer.VIDEO_STREAMS_LIST, new ArrayList<>(info.video_streams));
if (info.start_position > 0) i.putExtra(AbstractPlayer.START_POSITION, info.start_position * 1000);
activity.startService(i);
}
});
@ -784,47 +790,27 @@ public class VideoItemDetailFragment extends Fragment {
builder.create().show();
}
} else {
if (PreferenceManager.getDefaultSharedPreferences(activity)
.getBoolean(activity.getString(R.string.use_exoplayer_key), false)) {
// TODO: Fix this mess
if (streamThumbnail != null)
ActivityCommunicator.getCommunicator().backgroundPlayerThumbnail = streamThumbnail;
// exo player
if(info.dashMpdUrl != null && !info.dashMpdUrl.isEmpty()) {
// try dash
Intent intent = new Intent(activity, ExoPlayerActivity.class)
.setData(Uri.parse(info.dashMpdUrl));
//.putExtra(ExoPlayerActivity.CONTENT_TYPE_EXTRA, Util.TYPE_DASH);
startActivity(intent);
} else if((info.audio_streams != null && !info.audio_streams.isEmpty()) &&
(info.video_only_streams != null && !info.video_only_streams.isEmpty())) {
// try smooth streaming
} else {
//default streaming
Intent intent = new Intent(activity, ExoPlayerActivity.class)
.setDataAndType(Uri.parse(selectedVideoStream.url),
MediaFormat.getMimeById(selectedVideoStream.format))
.putExtra(ExoPlayerActivity.VIDEO_TITLE, info.title)
.putExtra(ExoPlayerActivity.CHANNEL_NAME, info.uploader);
//.putExtra(ExoPlayerActivity.CONTENT_TYPE_EXTRA, Util.TYPE_OTHER);
activity.startActivity(intent); // HERE !!!
}
//-------------
Intent intent;
if (PreferenceManager.getDefaultSharedPreferences(activity).getBoolean(activity.getString(R.string.use_exoplayer_key), false)) {
// ExoPlayer
if (streamThumbnail != null) ActivityCommunicator.getCommunicator().backgroundPlayerThumbnail = streamThumbnail;
intent = new Intent(activity, ExoPlayerActivity.class)
.putExtra(AbstractPlayer.VIDEO_TITLE, info.title)
.putExtra(AbstractPlayer.VIDEO_URL, info.webpage_url)
.putExtra(AbstractPlayer.CHANNEL_NAME, info.uploader)
.putExtra(AbstractPlayer.INDEX_SEL_VIDEO_STREAM, actionBarHandler.getSelectedVideoStream())
.putExtra(AbstractPlayer.VIDEO_STREAMS_LIST, new ArrayList<>(info.video_streams));
if (info.start_position > 0) intent.putExtra(AbstractPlayer.START_POSITION, info.start_position * 1000);
} else {
// Internal Player
Intent intent = new Intent(activity, PlayVideoActivity.class)
intent = new Intent(activity, PlayVideoActivity.class)
.putExtra(PlayVideoActivity.VIDEO_TITLE, info.title)
.putExtra(PlayVideoActivity.STREAM_URL, selectedVideoStream.url)
.putExtra(PlayVideoActivity.VIDEO_URL, info.webpage_url)
.putExtra(PlayVideoActivity.START_POSITION, info.start_position);
activity.startActivity(intent); //also HERE !!!
}
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
activity.startActivity(intent);
}
// --------------------------------------------

File diff suppressed because it is too large Load Diff

View File

@ -26,7 +26,6 @@ import org.schabi.newpipe.ActivityCommunicator;
import org.schabi.newpipe.BuildConfig;
import org.schabi.newpipe.R;
import org.schabi.newpipe.detail.VideoItemDetailActivity;
import org.schabi.newpipe.detail.VideoItemDetailFragment;
import org.schabi.newpipe.util.NavStack;
import java.io.IOException;
@ -343,7 +342,7 @@ public class BackgroundPlayer extends Service /*implements MediaPlayer.OnPrepare
/*
NotificationCompat.Action pauseButton = new NotificationCompat.Action.Builder
(R.drawable.ic_pause_white_24dp, "Pause", playPI).build();
(R.drawable.ic_pause_white, "Pause", playPI).build();
*/
PendingIntent playPI = PendingIntent.getBroadcast(owner, noteID,
@ -465,7 +464,7 @@ public class BackgroundPlayer extends Service /*implements MediaPlayer.OnPrepare
RemoteViews views = getContentView(), bigViews = getBigContentView();
int imageSrc;
if(isPlaying) {
imageSrc = R.drawable.ic_pause_white_24dp;
imageSrc = R.drawable.ic_pause_white;
} else {
imageSrc = R.drawable.ic_play_circle_filled_white_24dp;
}

View File

@ -1,220 +1,559 @@
package org.schabi.newpipe.player;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Color;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageButton;
import android.widget.PopupMenu;
import android.widget.SeekBar;
import com.devbrackets.android.exomedia.listener.OnCompletionListener;
import com.devbrackets.android.exomedia.listener.OnPreparedListener;
import com.devbrackets.android.exomedia.listener.VideoControlsVisibilityListener;
import com.devbrackets.android.exomedia.ui.widget.EMVideoView;
import com.devbrackets.android.exomedia.ui.widget.VideoControlsMobile;
import android.widget.TextView;
import android.widget.Toast;
import org.schabi.newpipe.R;
import org.schabi.newpipe.util.NavStack;
import org.schabi.newpipe.util.PermissionHelper;
import org.schabi.newpipe.util.ThemeHelper;
public class ExoPlayerActivity extends Activity implements OnPreparedListener, OnCompletionListener {
private static final String TAG = "ExoPlayerActivity";
private static final boolean DEBUG = false;
private EMVideoView videoView;
private CustomVideoControls videoControls;
/**
* Activity Player implementing AbstractPlayer
*
* @author mauriciocolli
*/
public class ExoPlayerActivity extends Activity {
private static final String TAG = ".ExoPlayerActivity";
private static final boolean DEBUG = AbstractPlayer.DEBUG;
public static final String VIDEO_TITLE = "video_title";
public static final String CHANNEL_NAME = "channel_name";
private String videoTitle = "";
private volatile String channelName = "";
private int lastPosition;
private boolean isFinished;
private AudioManager audioManager;
private BroadcastReceiver broadcastReceiver;
private GestureDetector gestureDetector;
private final Runnable hideUiRunnable = new Runnable() {
@Override
public void run() {
hideSystemUi();
}
};
private boolean activityPaused;
private AbstractPlayerImpl playerImpl;
/*//////////////////////////////////////////////////////////////////////////
// Activity LifeCycle
//////////////////////////////////////////////////////////////////////////*/
@Override
public void onCreate(Bundle savedInstanceState) {
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (DEBUG) Log.d(TAG, "onCreate() called with: savedInstanceState = [" + savedInstanceState + "]");
ThemeHelper.setTheme(this, false);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) getWindow().setStatusBarColor(Color.BLACK);
setVolumeControlStream(AudioManager.STREAM_MUSIC);
audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
if (getIntent() == null) {
Toast.makeText(this, R.string.general_error, Toast.LENGTH_SHORT).show();
finish();
return;
}
setContentView(R.layout.activity_exo_player);
videoView = (EMVideoView) findViewById(R.id.emVideoView);
playerImpl = new AbstractPlayerImpl();
playerImpl.setup(findViewById(android.R.id.content));
initReceiver();
playerImpl.handleIntent(getIntent());
}
@Override
protected void onStart() {
super.onStart();
Intent intent = getIntent();
videoTitle = intent.getStringExtra(VIDEO_TITLE);
channelName = intent.getStringExtra(CHANNEL_NAME);
videoView.setOnPreparedListener(this);
videoView.setOnCompletionListener(this);
videoView.setVideoURI(intent.getData());
videoControls = new CustomVideoControls(this);
videoControls.setTitle(videoTitle);
videoControls.setSubTitle(channelName);
//We don't need these button until the playlist or queue is implemented
videoControls.setNextButtonRemoved(true);
videoControls.setPreviousButtonRemoved(true);
videoControls.setVisibilityListener(new VideoControlsVisibilityListener() {
@Override
public void onControlsShown() {
if (DEBUG) Log.d(TAG, "------------ onControlsShown() called");
showSystemUi();
}
@Override
public void onControlsHidden() {
if (DEBUG) Log.d(TAG, "------------ onControlsHidden() called");
hideSystemUi();
}
});
videoView.setControls(videoControls);
protected void onNewIntent(Intent intent) {
if (DEBUG) Log.d(TAG, "onNewIntent() called with: intent = [" + intent + "]");
super.onNewIntent(intent);
playerImpl.handleIntent(intent);
}
@Override
public void onPrepared() {
if (DEBUG) Log.d(TAG, "onPrepared() called");
videoView.start();
public void onBackPressed() {
if (DEBUG) Log.d(TAG, "onBackPressed() called");
super.onBackPressed();
if (playerImpl.isStartedFromNewPipe()) NavStack.getInstance().openDetailActivity(this, playerImpl.getVideoUrl(), 0);
if (playerImpl.isPlaying()) playerImpl.getPlayer().setPlayWhenReady(false);
}
@Override
public void onCompletion() {
if (DEBUG) Log.d(TAG, "onCompletion() called");
// videoView.getVideoControls().setButtonListener();
//videoView.restart();
videoControls.setRewindButtonRemoved(true);
videoControls.setFastForwardButtonRemoved(true);
isFinished = true;
videoControls.getSeekBar().setEnabled(false);
}
@Override
protected void onPause() {
super.onPause();
videoView.stopPlayback();
lastPosition = videoView.getCurrentPosition();
protected void onStop() {
super.onStop();
if (DEBUG) Log.d(TAG, "onStop() called");
activityPaused = true;
playerImpl.destroy();
playerImpl.setVideoStartPos((int) playerImpl.getPlayer().getCurrentPosition());
}
@Override
protected void onResume() {
super.onResume();
if (lastPosition > 0) videoView.seekTo(lastPosition);
if (DEBUG) Log.d(TAG, "onResume() called");
if (activityPaused) {
//playerImpl.getPlayer().setPlayWhenReady(true);
playerImpl.getPlayPauseButton().setImageResource(R.drawable.ic_play_arrow_white);
playerImpl.initPlayer();
playerImpl.playVideo(playerImpl.getSelectedStreamUri(), false);
activityPaused = false;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
videoView.stopPlayback();
if (DEBUG) Log.d(TAG, "onDestroy() called");
if (playerImpl != null) playerImpl.destroy();
if (broadcastReceiver != null) unregisterReceiver(broadcastReceiver);
}
/*//////////////////////////////////////////////////////////////////////////
// Init
//////////////////////////////////////////////////////////////////////////*/
private void initReceiver() {
if (DEBUG) Log.d(TAG, "initReceiver() called");
broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (DEBUG) Log.d(TAG, "onReceive() called with: context = [" + context + "], intent = [" + intent + "]");
switch (intent.getAction()) {
case AbstractPlayer.ACTION_UPDATE_THUMB:
playerImpl.onUpdateThumbnail(intent);
break;
}
}
};
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(AbstractPlayer.ACTION_UPDATE_THUMB);
registerReceiver(broadcastReceiver, intentFilter);
}
/*//////////////////////////////////////////////////////////////////////////
// Utils
//////////////////////////////////////////////////////////////////////////*/
private void showSystemUi() {
if (DEBUG) Log.d(TAG, "showSystemUi() called");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
);
} else getWindow().getDecorView().setSystemUiVisibility(0);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().getDecorView().setSystemUiVisibility(0);
}
private void hideSystemUi() {
if (DEBUG) Log.d(TAG, "hideSystemUi() called");
if (android.os.Build.VERSION.SDK_INT >= 17) {
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
if (android.os.Build.VERSION.SDK_INT >= 16) {
int visibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) visibility |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
getWindow().getDecorView().setSystemUiVisibility(visibility);
}
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
private class CustomVideoControls extends VideoControlsMobile {
protected static final int FAST_FORWARD_REWIND_AMOUNT = 8000;
///////////////////////////////////////////////////////////////////////////
protected ImageButton fastForwardButton;
protected ImageButton rewindButton;
@SuppressWarnings({"unused", "WeakerAccess"})
private class AbstractPlayerImpl extends AbstractPlayer {
private TextView titleTextView;
private TextView channelTextView;
private TextView volumeTextView;
private TextView brightnessTextView;
private ImageButton repeatButton;
public CustomVideoControls(Context context) {
super(context);
private ImageButton playPauseButton;
AbstractPlayerImpl() {
super("AbstractPlayerImpl" + ExoPlayerActivity.TAG, ExoPlayerActivity.this);
}
@Override
protected int getLayoutResource() {
return R.layout.exomedia_custom_controls;
public void initViews(View rootView) {
super.initViews(rootView);
this.titleTextView = (TextView) rootView.findViewById(R.id.titleTextView);
this.channelTextView = (TextView) rootView.findViewById(R.id.channelTextView);
this.volumeTextView = (TextView) rootView.findViewById(R.id.volumeTextView);
this.brightnessTextView = (TextView) rootView.findViewById(R.id.brightnessTextView);
this.repeatButton = (ImageButton) rootView.findViewById(R.id.repeatButton);
this.playPauseButton = (ImageButton) 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);
}
}
@Override
protected void retrieveViews() {
super.retrieveViews();
rewindButton = (ImageButton) findViewById(R.id.exomedia_controls_frewind_btn);
fastForwardButton = (ImageButton) findViewById(R.id.exomedia_controls_fforward_btn);
public void initListeners() {
super.initListeners();
MySimpleOnGestureListener listener = new MySimpleOnGestureListener();
gestureDetector = new GestureDetector(context, listener);
gestureDetector.setIsLongpressEnabled(false);
playerImpl.getRootView().setOnTouchListener(listener);
repeatButton.setOnClickListener(this);
playPauseButton.setOnClickListener(this);
}
@Override
protected void registerListeners() {
super.registerListeners();
rewindButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
onRewindClicked();
}
});
fastForwardButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
onFastForwardClicked();
}
});
}
public boolean onFastForwardClicked() {
if (videoView == null) return false;
int newPosition = videoView.getCurrentPosition() + FAST_FORWARD_REWIND_AMOUNT;
if (newPosition > seekBar.getMax()) newPosition = seekBar.getMax();
performSeek(newPosition);
return true;
}
public boolean onRewindClicked() {
if (videoView == null) return false;
int newPosition = videoView.getCurrentPosition() - FAST_FORWARD_REWIND_AMOUNT;
if (newPosition < 0) newPosition = 0;
performSeek(newPosition);
return true;
public void handleIntent(Intent intent) {
super.handleIntent(intent);
titleTextView.setText(getVideoTitle());
channelTextView.setText(getChannelName());
}
@Override
public void setFastForwardButtonRemoved(boolean removed) {
fastForwardButton.setVisibility(removed ? View.GONE : View.VISIBLE);
public void playVideo(Uri videoURI, boolean autoPlay) {
super.playVideo(videoURI, autoPlay);
playPauseButton.setImageResource(autoPlay ? R.drawable.ic_pause_white : R.drawable.ic_play_arrow_white);
}
@Override
public void setRewindButtonRemoved(boolean removed) {
rewindButton.setVisibility(removed ? View.GONE : View.VISIBLE);
public void onFullScreenButtonClicked() {
if (DEBUG) Log.d(TAG, "onFullScreenButtonClicked() called");
if (playerImpl.getPlayer() == null) return;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
&& !PermissionHelper.checkSystemAlertWindowPermission(ExoPlayerActivity.this)) {
Toast.makeText(ExoPlayerActivity.this, R.string.msg_popup_permission, Toast.LENGTH_LONG).show();
return;
}
Intent i = new Intent(ExoPlayerActivity.this, PopupVideoPlayer.class);
i.putExtra(AbstractPlayer.VIDEO_TITLE, getVideoTitle())
.putExtra(AbstractPlayer.CHANNEL_NAME, getChannelName())
.putExtra(AbstractPlayer.VIDEO_URL, getVideoUrl())
.putExtra(AbstractPlayer.INDEX_SEL_VIDEO_STREAM, getSelectedIndexStream())
.putExtra(AbstractPlayer.VIDEO_STREAMS_LIST, getVideoStreamsList())
.putExtra(AbstractPlayer.START_POSITION, ((int) getPlayer().getCurrentPosition()));
context.startService(i);
((View) getControlAnimationView().getParent()).setVisibility(View.GONE);
if (playerImpl.isPlaying()) playerImpl.getPlayer().setPlayWhenReady(false);
ExoPlayerActivity.this.finish();
}
@Override
protected void onPlayPauseClick() {
super.onPlayPauseClick();
if (videoView == null) return;
if (DEBUG) Log.d(TAG, "onPlayPauseClick() called" + videoView.getDuration() + " position= " + videoView.getCurrentPosition());
if (isFinished) {
videoView.restart();
setRewindButtonRemoved(false);
setFastForwardButtonRemoved(false);
isFinished = false;
seekBar.setEnabled(true);
@SuppressWarnings("deprecation")
public void onRepeatClicked() {
super.onRepeatClicked();
if (DEBUG) Log.d(TAG, "onRepeatClicked() called");
switch (getCurrentRepeatMode()) {
case REPEAT_DISABLED:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) repeatButton.setImageAlpha(77);
else repeatButton.setAlpha(77);
break;
case REPEAT_ONE:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) repeatButton.setImageAlpha(255);
else repeatButton.setAlpha(255);
break;
case REPEAT_ALL:
// Waiting :)
break;
}
}
private void performSeek(int newPosition) {
internalListener.onSeekEnded(newPosition);
@Override
public void onClick(View v) {
super.onClick(v);
if (v.getId() == repeatButton.getId()) onRepeatClicked();
else if (v.getId() == playPauseButton.getId()) onVideoPlayPause();
if (getCurrentState() != STATE_COMPLETED) {
animateView(playerImpl.getControlsRoot(), true, 300, 0, new Runnable() {
@Override
public void run() {
if (getCurrentState() == STATE_PLAYING && !playerImpl.isQualityMenuVisible()) {
animateView(playerImpl.getControlsRoot(), false, 300, DEFAULT_CONTROLS_HIDE_TIME, true);
}
}
}, false);
}
}
public SeekBar getSeekBar() {
return seekBar;
@Override
public void onVideoPlayPause() {
super.onVideoPlayPause();
if (getPlayer().getPlayWhenReady()) {
animateView(playPauseButton, false, 80, 0, new Runnable() {
@Override
public void run() {
playPauseButton.setImageResource(R.drawable.ic_pause_white);
animateView(playPauseButton, true, 200, 0);
}
});
} else {
animateView(playPauseButton, false, 80, 0, new Runnable() {
@Override
public void run() {
playPauseButton.setImageResource(R.drawable.ic_play_arrow_white);
animateView(playPauseButton, true, 200, 0);
}
});
}
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
super.onStopTrackingTouch(seekBar);
if (playerImpl.wasPlaying()) {
hideSystemUi();
playerImpl.getControlsRoot().setVisibility(View.GONE);
}
}
@Override
public void onDismiss(PopupMenu menu) {
super.onDismiss(menu);
if (isPlaying()) animateView(getControlsRoot(), false, 500, 0, true);
}
@Override
public void onError() {
Toast.makeText(context, "Failed to play this video", Toast.LENGTH_SHORT).show();
finish();
}
/*//////////////////////////////////////////////////////////////////////////
// States
//////////////////////////////////////////////////////////////////////////*/
@Override
public void onLoading() {
super.onLoading();
hideSystemUi();
playPauseButton.setImageResource(R.drawable.ic_pause_white);
}
@Override
public void onPaused() {
super.onPaused();
animateView(playPauseButton, true, 100, 0);
showSystemUi();
}
@Override
public void onPausedSeek() {
super.onPausedSeek();
animateView(playPauseButton, false, 100, 0);
}
@Override
public void onPlaying() {
super.onPlaying();
animateView(playPauseButton, true, 500, 0);
}
@Override
public void onCompleted() {
if (getCurrentRepeatMode() == RepeatMode.REPEAT_ONE) {
playPauseButton.setImageResource(R.drawable.ic_pause_white);
} else {
showSystemUi();
animateView(playPauseButton, false, 0, 0, new Runnable() {
@Override
public void run() {
playPauseButton.setImageResource(R.drawable.ic_replay_white);
animateView(playPauseButton, true, 300, 0);
}
});
}
super.onCompleted();
}
/*//////////////////////////////////////////////////////////////////////////
// Utils
//////////////////////////////////////////////////////////////////////////*/
@Override
public void animateView(View view, boolean enterOrExit, long duration, long delay, final Runnable execOnEnd, boolean hideUi) {
//if (execOnEnd == null) playerImpl.setDefaultAnimationEnd(hideUiRunnable);
if (hideUi && execOnEnd != null) {
Runnable combinedRunnable = new Runnable() {
@Override
public void run() {
execOnEnd.run();
hideUiRunnable.run();
}
};
super.animateView(view, enterOrExit, duration, delay, combinedRunnable, true);
} else super.animateView(view, enterOrExit, duration, delay, hideUi ? hideUiRunnable : execOnEnd, hideUi);
}
///////////////////////////////////////////////////////////////////////////
// Getters
///////////////////////////////////////////////////////////////////////////
public TextView getTitleTextView() {
return titleTextView;
}
public TextView getChannelTextView() {
return channelTextView;
}
public TextView getVolumeTextView() {
return volumeTextView;
}
public TextView getBrightnessTextView() {
return brightnessTextView;
}
public ImageButton getRepeatButton() {
return repeatButton;
}
public ImageButton getPlayPauseButton() {
return playPauseButton;
}
}
}
private class MySimpleOnGestureListener extends GestureDetector.SimpleOnGestureListener implements View.OnTouchListener {
private boolean isMoving;
@Override
public boolean onDoubleTap(MotionEvent e) {
if (DEBUG) Log.d(TAG, "onDoubleTap() called with: e = [" + e + "]" + "rawXy = " + e.getRawX() + ", " + e.getRawY() + ", xy = " + e.getX() + ", " + e.getY());
if (!playerImpl.isPlaying()) return false;
if (e.getX() > playerImpl.getRootView().getWidth() / 2) playerImpl.onFastForward();
else playerImpl.onFastRewind();
return true;
}
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
if (DEBUG) Log.d(TAG, "onSingleTapConfirmed() called with: e = [" + e + "]");
if (playerImpl.getCurrentState() != StateInterface.STATE_PLAYING) return true;
if (playerImpl.isControlsVisible()) playerImpl.animateView(playerImpl.getControlsRoot(), false, 150, 0, true);
else {
playerImpl.animateView(playerImpl.getControlsRoot(), true, 500, 0, new Runnable() {
@Override
public void run() {
playerImpl.animateView(playerImpl.getControlsRoot(), false, 300, AbstractPlayer.DEFAULT_CONTROLS_HIDE_TIME, true);
}
});
showSystemUi();
}
return true;
}
private final float stepsBrightness = 21, stepBrightness = (1f / stepsBrightness), minBrightness = .01f;
private float currentBrightness = .5f;
private int currentVolume, maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
private final String brightnessUnicode = new String(Character.toChars(0x2600));
// private final String volumeUnicode = new String(Character.toChars(0x1F50A));
private final String volumeUnicode = new String(Character.toChars(0x1F508));
private final int MOVEMENT_THRESHOLD = 40;
private final int eventsThreshold = 3;
private boolean triggered = false;
private int eventsNum;
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
//noinspection PointlessBooleanExpression
if (DEBUG && false) Log.d(TAG, "ExoPlayerActivity.onScroll = " +
", e1.getRaw = [" + e1.getRawX() + ", " + e1.getRawY() + "]" +
", e2.getRaw = [" + e2.getRawX() + ", " + e2.getRawY() + "]" +
", distanceXy = [" + distanceX + ", " + distanceY + "]");
float abs = Math.abs(e2.getY() - e1.getY());
if (!triggered) {
triggered = abs > MOVEMENT_THRESHOLD;
return false;
}
if (eventsNum++ % eventsThreshold != 0 || playerImpl.getCurrentState() == StateInterface.STATE_COMPLETED) return false;
isMoving = true;
// boolean up = !((e2.getY() - e1.getY()) > 0) && distanceY > 0; // Android's origin point is on top
boolean up = distanceY > 0;
if (e1.getX() > playerImpl.getRootView().getWidth() / 2) {
currentVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC) + (up ? 1 : -1);
if (currentVolume >= maxVolume) currentVolume = maxVolume;
if (currentVolume <= 0) currentVolume = 0;
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, currentVolume, 0);
if (DEBUG) Log.d(TAG, "onScroll().volumeControl, currentVolume = " + currentVolume);
playerImpl.getVolumeTextView().setText(volumeUnicode + " " + Math.round((((float) currentVolume) / maxVolume) * 100) + "%");
if (playerImpl.getVolumeTextView().getVisibility() != View.VISIBLE) playerImpl.animateView(playerImpl.getVolumeTextView(), true, 200, 0);
if (playerImpl.getBrightnessTextView().getVisibility() == View.VISIBLE) playerImpl.getBrightnessTextView().setVisibility(View.GONE);
} else {
WindowManager.LayoutParams lp = getWindow().getAttributes();
currentBrightness += up ? stepBrightness : -stepBrightness;
if (currentBrightness >= 1f) currentBrightness = 1f;
if (currentBrightness <= minBrightness) currentBrightness = minBrightness;
lp.screenBrightness = currentBrightness;
getWindow().setAttributes(lp);
if (DEBUG) Log.d(TAG, "onScroll().brightnessControl, currentBrightness = " + currentBrightness);
int brightnessNormalized = Math.round(currentBrightness * 100);
playerImpl.getBrightnessTextView().setText(brightnessUnicode + " " + (brightnessNormalized == 1 ? 0 : brightnessNormalized) + "%");
if (playerImpl.getBrightnessTextView().getVisibility() != View.VISIBLE) playerImpl.animateView(playerImpl.getBrightnessTextView(), true, 200, 0);
if (playerImpl.getVolumeTextView().getVisibility() == View.VISIBLE) playerImpl.getVolumeTextView().setVisibility(View.GONE);
}
return true;
}
private void onScrollEnd() {
if (DEBUG) Log.d(TAG, "onScrollEnd() called");
triggered = false;
eventsNum = 0;
/* if (playerImpl.getVolumeTextView().getVisibility() == View.VISIBLE) playerImpl.getVolumeTextView().setVisibility(View.GONE);
if (playerImpl.getBrightnessTextView().getVisibility() == View.VISIBLE) playerImpl.getBrightnessTextView().setVisibility(View.GONE);*/
if (playerImpl.getVolumeTextView().getVisibility() == View.VISIBLE) playerImpl.animateView(playerImpl.getVolumeTextView(), false, 200, 200);
if (playerImpl.getBrightnessTextView().getVisibility() == View.VISIBLE) playerImpl.animateView(playerImpl.getBrightnessTextView(), false, 200, 200);
if (playerImpl.isControlsVisible() && playerImpl.getCurrentState() == StateInterface.STATE_PLAYING) {
playerImpl.animateView(playerImpl.getControlsRoot(), false, 300, AbstractPlayer.DEFAULT_CONTROLS_HIDE_TIME);
}
}
@Override
public boolean onTouch(View v, MotionEvent event) {
gestureDetector.onTouchEvent(event);
if (event.getAction() == MotionEvent.ACTION_UP && isMoving) {
isMoving = false;
onScrollEnd();
}
return true;
}
}
}

View File

@ -5,9 +5,8 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.drawable.Drawable;
import android.media.MediaPlayer;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
@ -28,7 +27,6 @@ import android.widget.MediaController;
import android.widget.ProgressBar;
import android.widget.VideoView;
import org.schabi.newpipe.App;
import org.schabi.newpipe.R;
/**

View File

@ -1,8 +1,9 @@
package org.schabi.newpipe.player.popup;
package org.schabi.newpipe.player;
public interface StateInterface {
int STATE_LOADING = 123;
int STATE_PLAYING = 125;
int STATE_PLAYING = 124;
int STATE_BUFFERING = 125;
int STATE_PAUSED = 126;
int STATE_PAUSED_SEEK = 127;
int STATE_COMPLETED = 128;
@ -11,6 +12,7 @@ public interface StateInterface {
void onLoading();
void onPlaying();
void onBuffering();
void onPaused();
void onPausedSeek();
void onCompleted();

View File

@ -1,93 +0,0 @@
package org.schabi.newpipe.player.popup;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.os.Build;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import com.devbrackets.android.exomedia.ui.widget.EMVideoView;
import org.schabi.newpipe.R;
public class PopupViewHolder {
private View rootView;
private EMVideoView videoView;
private View loadingPanel;
private ImageView endScreen;
private ImageView controlAnimationView;
private LinearLayout controlsRoot;
private SeekBar playbackSeekBar;
private TextView playbackCurrentTime;
private TextView playbackEndTime;
public PopupViewHolder(View rootView) {
if (rootView == null) return;
this.rootView = rootView;
this.videoView = (EMVideoView) rootView.findViewById(R.id.popupVideoView);
this.loadingPanel = rootView.findViewById(R.id.loadingPanel);
this.endScreen = (ImageView) rootView.findViewById(R.id.endScreen);
this.controlAnimationView = (ImageView) rootView.findViewById(R.id.controlAnimationView);
this.controlsRoot = (LinearLayout) rootView.findViewById(R.id.playbackControlRoot);
this.playbackSeekBar = (SeekBar) rootView.findViewById(R.id.playbackSeekBar);
this.playbackCurrentTime = (TextView) rootView.findViewById(R.id.playbackCurrentTime);
this.playbackEndTime = (TextView) rootView.findViewById(R.id.playbackEndTime);
doModifications();
}
private void doModifications() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) playbackSeekBar.getThumb().setColorFilter(Color.RED, PorterDuff.Mode.SRC_IN);
playbackSeekBar.getProgressDrawable().setColorFilter(Color.RED, PorterDuff.Mode.MULTIPLY);
}
public boolean isControlsVisible() {
return controlsRoot != null && controlsRoot.getVisibility() == View.VISIBLE;
}
public boolean isVisible(View view) {
return view != null && view.getVisibility() == View.VISIBLE;
}
///////////////////////////////////////////////////////////////////////////
// GETTERS
///////////////////////////////////////////////////////////////////////////
public View getRootView() {
return rootView;
}
public EMVideoView getVideoView() {
return videoView;
}
public View getLoadingPanel() {
return loadingPanel;
}
public ImageView getEndScreen() {
return endScreen;
}
public ImageView getControlAnimationView() {
return controlAnimationView;
}
public LinearLayout getControlsRoot() {
return controlsRoot;
}
public SeekBar getPlaybackSeekBar() {
return playbackSeekBar;
}
public TextView getPlaybackCurrentTime() {
return playbackCurrentTime;
}
public TextView getPlaybackEndTime() {
return playbackEndTime;
}
}

View File

@ -19,17 +19,14 @@ import android.view.inputmethod.InputMethodManager;
import android.widget.ProgressBar;
import android.widget.Toast;
import org.schabi.newpipe.ChannelActivity;
import org.schabi.newpipe.R;
import org.schabi.newpipe.ReCaptchaActivity;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.search.SearchEngine;
import org.schabi.newpipe.extractor.search.SearchResult;
import org.schabi.newpipe.info_list.InfoItemBuilder;
import org.schabi.newpipe.report.ErrorActivity;
import org.schabi.newpipe.R;
import org.schabi.newpipe.detail.VideoItemDetailActivity;
import org.schabi.newpipe.detail.VideoItemDetailFragment;
import org.schabi.newpipe.info_list.InfoListAdapter;
import org.schabi.newpipe.report.ErrorActivity;
import org.schabi.newpipe.util.NavStack;
import java.util.EnumSet;

View File

Before

Width:  |  Height:  |  Size: 347 B

After

Width:  |  Height:  |  Size: 347 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 221 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 B

View File

Before

Width:  |  Height:  |  Size: 92 B

After

Width:  |  Height:  |  Size: 92 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 B

View File

Before

Width:  |  Height:  |  Size: 283 B

After

Width:  |  Height:  |  Size: 283 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 B

View File

Before

Width:  |  Height:  |  Size: 257 B

After

Width:  |  Height:  |  Size: 257 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 175 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 B

View File

Before

Width:  |  Height:  |  Size: 90 B

After

Width:  |  Height:  |  Size: 90 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 B

View File

Before

Width:  |  Height:  |  Size: 220 B

After

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 B

View File

Before

Width:  |  Height:  |  Size: 436 B

After

Width:  |  Height:  |  Size: 436 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 B

View File

Before

Width:  |  Height:  |  Size: 94 B

After

Width:  |  Height:  |  Size: 94 B

View File

Before

Width:  |  Height:  |  Size: 343 B

After

Width:  |  Height:  |  Size: 343 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 524 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 B

View File

Before

Width:  |  Height:  |  Size: 461 B

After

Width:  |  Height:  |  Size: 461 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 356 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 707 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 B

View File

Before

Width:  |  Height:  |  Size: 605 B

After

Width:  |  Height:  |  Size: 605 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 403 B

View File

@ -1,8 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="#a0000000"
android:centerColor="#26000000"
android:startColor="#8c000000"
android:endColor="#00000000"
android:angle="90"
/>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="#8c000000"
android:endColor="#00000000"
android:angle="-90"
/>
</shape>

View File

@ -1,15 +1,303 @@
<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root"
android:focusable="true"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:keepScreenOn="true">
android:background="@android:color/black"
android:gravity="center">
<com.devbrackets.android.exomedia.ui.widget.EMVideoView
android:id="@+id/emVideoView"
<com.google.android.exoplayer2.ui.AspectRatioFrameLayout
android:id="@+id/aspectRatioLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
android:layout_height="match_parent"
android:layout_gravity="center">
</RelativeLayout>
<SurfaceView
android:id="@+id/surfaceView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"/>
<View
android:id="@+id/surfaceForeground"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black"/>
</com.google.android.exoplayer2.ui.AspectRatioFrameLayout>
<ImageView
android:id="@+id/endScreen"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:scaleType="centerInside"
android:visibility="gone"
tools:background="@android:color/white"
tools:ignore="ContentDescription"
tools:visibility="visible"/>
<RelativeLayout
android:id="@+id/playbackControlRoot"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#64000000"
android:visibility="gone"
tools:visibility="visible">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<RelativeLayout
android:id="@+id/topControls"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:background="@drawable/player_top_controls_bg"
android:gravity="top"
android:paddingBottom="70dp"
android:paddingLeft="2dp"
android:paddingRight="10dp"
android:paddingTop="10dp"
tools:ignore="RtlHardcoded">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_toLeftOf="@+id/qualityTextView"
android:gravity="top"
android:orientation="vertical"
android:paddingLeft="8dp"
android:paddingRight="8dp"
tools:ignore="RtlHardcoded">
<TextView
android:id="@+id/titleTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:textColor="@android:color/white"
android:textSize="15sp"
android:textStyle="bold"
tools:ignore="RtlHardcoded"
tools:text="The Video Title LONG very LONG"/>
<TextView
android:id="@+id/channelTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:textColor="@android:color/white"
android:textSize="12sp"
tools:text="The Video Artist LONG very LONG very Long"/>
</LinearLayout>
<TextView
android:id="@+id/qualityTextView"
android:layout_width="wrap_content"
android:layout_height="35dp"
android:layout_marginLeft="4dp"
android:layout_marginRight="2dp"
android:layout_toLeftOf="@+id/repeatButton"
android:gravity="center"
android:minWidth="50dp"
android:text="720p"
android:textColor="@android:color/white"
android:textStyle="bold"
tools:ignore="HardcodedText,RtlHardcoded"/>
<ImageButton
android:id="@+id/repeatButton"
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:layout_toLeftOf="@+id/fullScreenButton"
android:background="#00ffffff"
android:clickable="true"
android:padding="5dp"
android:scaleType="fitXY"
android:src="@drawable/ic_repeat_white"
tools:ignore="ContentDescription,RtlHardcoded"/>
<ImageButton
android:id="@+id/fullScreenButton"
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_alignParentRight="true"
android:layout_marginLeft="4dp"
android:background="#00ffffff"
android:clickable="true"
android:scaleType="fitXY"
android:src="@drawable/ic_fullscreen_exit_white"
tools:ignore="ContentDescription,RtlHardcoded"/>
</RelativeLayout>
<LinearLayout
android:id="@+id/bottomControls"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="@drawable/player_controls_bg"
android:gravity="center"
android:orientation="horizontal"
android:paddingLeft="16dp"
android:paddingRight="16dp">
<TextView
android:id="@+id/playbackCurrentTime"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:minHeight="40dp"
android:text="-:--:--"
android:textColor="@android:color/white"
tools:ignore="HardcodedText"
tools:text="1:06:29"/>
<android.support.v7.widget.AppCompatSeekBar
android:id="@+id/playbackSeekBar"
style="@style/Widget.AppCompat.SeekBar"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:paddingBottom="4dp"
android:paddingTop="8dp"
tools:progress="25"
tools:secondaryProgress="50"/>
<TextView
android:id="@+id/playbackEndTime"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:text="-:--:--"
android:textColor="@android:color/white"
tools:ignore="HardcodedText"
tools:text="1:23:49"/>
</LinearLayout>
</RelativeLayout>
<ImageButton
android:id="@+id/playPauseButton"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_centerInParent="true"
android:background="#00000000"
android:scaleType="fitXY"
android:src="@drawable/ic_pause_white"
tools:ignore="ContentDescription"/>
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="@+id/controlAnimationView"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@drawable/ic_action_av_fast_rewind"
android:visibility="gone"
tools:ignore="ContentDescription"
tools:visibility="visible"/>
</LinearLayout>
<RelativeLayout
android:id="@+id/loadingPanel"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black"
tools:visibility="gone">
<ProgressBar
android:id="@+id/progressBarLoadingPanel"
style="?android:attr/progressBarStyleLargeInverse"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:indeterminate="true"/>
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
tools:ignore="RtlHardcoded">
<TextView
android:id="@+id/volumeTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerInParent="true"
android:layout_marginLeft="20dp"
android:background="#64000000"
android:paddingBottom="10dp"
android:paddingLeft="30dp"
android:paddingRight="30dp"
android:paddingTop="10dp"
android:textColor="@android:color/white"
android:textSize="35sp"
android:visibility="gone"
tools:ignore="RtlHardcoded"
tools:text="Volume 0"
tools:visibility="visible"/>
<TextView
android:id="@+id/brightnessTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerInParent="true"
android:layout_marginRight="20dp"
android:background="#64000000"
android:paddingBottom="10dp"
android:paddingLeft="30dp"
android:paddingRight="30dp"
android:paddingTop="10dp"
android:textColor="@android:color/white"
android:textSize="35sp"
android:visibility="gone"
tools:ignore="RtlHardcoded"
tools:text="Brightness 0"
tools:visibility="visible"/>
<TextView
android:id="@+id/currentDisplaySeek"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_marginBottom="58dp"
android:background="#64000000"
android:paddingBottom="10dp"
android:paddingLeft="30dp"
android:paddingRight="30dp"
android:paddingTop="10dp"
android:textColor="@android:color/white"
android:textSize="26sp"
android:textStyle="bold"
android:visibility="gone"
tools:ignore="RtlHardcoded"
tools:text="1:06:29"
tools:visibility="visible"/>
</RelativeLayout>
</FrameLayout>

View File

@ -1,180 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<com.devbrackets.android.exomedia.ui.widget.FitsSystemWindowRelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/exomedia_controls_text_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:background="@drawable/exomedia_default_controls_text_background"
android:orientation="vertical"
android:paddingBottom="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="16dp"
android:visibility="gone"
tools:visibility="visible">
<TextView
android:id="@+id/exomedia_controls_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@android:color/white"
android:textSize="16sp"
android:textStyle="bold"
tools:text="The Video Title"/>
<TextView
android:id="@+id/exomedia_controls_sub_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@android:color/white"
android:textSize="14sp"
tools:text="The Video Album"/>
<TextView
android:id="@+id/exomedia_controls_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@android:color/white"
android:textSize="14sp"
tools:text="The Video Artist"/>
</LinearLayout>
<LinearLayout
android:id="@+id/exomedia_controls_interactive_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:background="@drawable/exomedia_default_controls_interactive_background"
android:orientation="vertical"
android:paddingBottom="16dp"
android:paddingTop="16dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:orientation="horizontal">
<TextView
android:id="@+id/exomedia_controls_current_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="2dp"
android:paddingRight="2dp"
android:textColor="@android:color/white"
tools:ignore="RtlHardcoded"
tools:text="1:06:29"/>
<SeekBar
android:id="@+id/exomedia_controls_video_seek"
style="?android:seekBarStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
tools:ignore="RtlHardcoded"/>
<TextView
android:id="@+id/exomedia_controls_end_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="2dp"
android:paddingRight="2dp"
android:textColor="@android:color/white"
tools:ignore="RtlHardcoded"
tools:text="1:23:49"/>
<LinearLayout
android:id="@+id/exomedia_controls_extra_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
tools:ignore="RtlHardcoded,UselessLeaf"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:gravity="center"
android:orientation="horizontal">
<ImageButton
android:id="@+id/exomedia_controls_previous_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="24dp"
android:background="@android:color/transparent"
android:minHeight="24dp"
android:minWidth="24dp"
app:srcCompat="@drawable/exomedia_ic_skip_previous_white"
tools:ignore="ContentDescription,RtlHardcoded"
tools:visibility="visible"/>
<ImageButton
android:id="@+id/exomedia_controls_frewind_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="24dp"
android:background="@android:color/transparent"
android:minHeight="24dp"
android:minWidth="24dp"
android:src="@drawable/exomedia_ic_rewind_white"
tools:ignore="ContentDescription,RtlHardcoded"
tools:visibility="visible"/>
<ImageButton
android:id="@+id/exomedia_controls_play_pause_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:minHeight="24dp"
android:minWidth="24dp"
app:srcCompat="@drawable/exomedia_ic_play_arrow_white"
tools:ignore="ContentDescription"/>
<ImageButton
android:id="@+id/exomedia_controls_fforward_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="24dp"
android:background="@android:color/transparent"
android:minHeight="24dp"
android:minWidth="24dp"
android:src="@drawable/exomedia_ic_fast_forward_white"
tools:ignore="ContentDescription,RtlHardcoded"
tools:visibility="visible"/>
<ImageButton
android:id="@+id/exomedia_controls_next_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="24dp"
android:background="@android:color/transparent"
android:minHeight="24dp"
android:minWidth="24dp"
app:srcCompat="@drawable/exomedia_ic_skip_next_white"
tools:ignore="ContentDescription,RtlHardcoded"
tools:visibility="visible"/>
</LinearLayout>
</LinearLayout>
<ProgressBar
android:id="@+id/exomedia_controls_video_loading"
style="?android:progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:visibility="gone"/>
</com.devbrackets.android.exomedia.ui.widget.FitsSystemWindowRelativeLayout>

View File

@ -65,7 +65,7 @@
android:background="#00ffffff"
android:clickable="true"
android:scaleType="fitXY"
android:src="@drawable/ic_pause_white_24dp" />
android:src="@drawable/ic_pause_white" />
<ImageButton
android:id="@+id/notificationStop"
@ -75,7 +75,7 @@
android:background="#00ffffff"
android:clickable="true"
android:scaleType="fitXY"
android:src="@drawable/ic_close_white_24dp" />
android:src="@drawable/ic_close_white" />
</LinearLayout>

View File

@ -58,7 +58,7 @@
android:background="#00ffffff"
android:clickable="true"
android:scaleType="fitXY"
android:src="@drawable/ic_close_white_24dp" />
android:src="@drawable/ic_close_white" />
<RelativeLayout
@ -77,7 +77,7 @@
android:background="#00ffffff"
android:clickable="true"
android:scaleType="fitXY"
android:src="@drawable/ic_pause_white_24dp"
android:src="@drawable/ic_pause_white"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" />

View File

@ -4,18 +4,29 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black"
android:gravity="center">
<RelativeLayout
android:id="@+id/blackBackground"
<com.google.android.exoplayer2.ui.AspectRatioFrameLayout
android:id="@+id/aspectRatioLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black"/>
android:layout_gravity="center">
<com.devbrackets.android.exomedia.ui.widget.EMVideoView
android:id="@+id/popupVideoView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<SurfaceView
android:id="@+id/surfaceView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"/>
<View
android:id="@+id/surfaceForeground"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black"/>
</com.google.android.exoplayer2.ui.AspectRatioFrameLayout>
<ImageView
@ -24,72 +35,142 @@
android:layout_height="match_parent"
android:background="@color/black"
android:visibility="gone"
tools:visibility="visible"
tools:background="@android:color/white"
tools:ignore="ContentDescription"/>
tools:ignore="ContentDescription"
tools:visibility="visible"/>
<RelativeLayout
android:id="@+id/playbackControlRoot"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#32000000"
android:visibility="gone"
tools:visibility="visible">
<RelativeLayout
android:id="@+id/topControls"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:background="@drawable/player_top_controls_bg"
android:paddingBottom="20dp"
android:paddingLeft="6dp"
android:paddingRight="6dp"
android:paddingTop="4dp">
<TextView
android:id="@+id/qualityTextView"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_alignParentLeft="true"
android:padding="5dp"
android:gravity="center"
android:text="720p"
android:textColor="@android:color/white"
android:textStyle="bold"
tools:ignore="HardcodedText,RtlHardcoded,RtlSymmetry"/>
<ImageButton
android:id="@+id/fullScreenButton"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignParentRight="true"
android:background="#00ffffff"
android:clickable="true"
android:scaleType="fitCenter"
android:src="@drawable/ic_fullscreen_white"
tools:ignore="ContentDescription,RtlHardcoded"/>
</RelativeLayout>
<!--Shadow Bottom Control-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="@drawable/player_controls_bg"
android:orientation="horizontal"
android:paddingTop="50dp"/>
<LinearLayout
android:id="@+id/bottomControls"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingBottom="2dp"
android:paddingLeft="8dp"
android:paddingRight="8dp">
<TextView
android:id="@+id/playbackCurrentTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:text="-:--:--"
android:textColor="@android:color/white"
tools:ignore="HardcodedText,RtlHardcoded,RtlSymmetry"
tools:text="1:06:29"/>
<android.support.v7.widget.AppCompatSeekBar
android:id="@+id/playbackSeekBar"
style="@style/Widget.AppCompat.SeekBar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1"
tools:progress="25"
tools:secondaryProgress="50"/>
<TextView
android:id="@+id/playbackEndTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:text="-:--:--"
android:textColor="@android:color/white"
tools:ignore="HardcodedText,RtlHardcoded,RtlSymmetry"
tools:text="1:23:49"/>
</LinearLayout>
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:weightSum="2">
android:orientation="horizontal"
android:weightSum="5">
<!--tools:visibility="gone">-->
<ImageView
android:id="@+id/controlAnimationView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:src="@drawable/ic_action_av_fast_rewind"
android:visibility="gone"
tools:visibility="visible"
tools:ignore="ContentDescription"/>
tools:ignore="ContentDescription"
tools:visibility="visible"/>
</LinearLayout>
<LinearLayout
android:id="@+id/playbackControlRoot"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_gravity="bottom"
<TextView
android:id="@+id/currentDisplaySeek"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="#64000000"
android:paddingBottom="5dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:gravity="bottom|center"
android:orientation="horizontal"
android:background="@drawable/popup_controls_bg"
android:paddingLeft="20dp"
android:paddingRight="20dp"
android:paddingTop="5dp"
android:textColor="@android:color/white"
android:textSize="18sp"
android:textStyle="bold"
android:visibility="gone"
tools:visibility="visible">
<TextView
android:id="@+id/playbackCurrentTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="2dp"
android:paddingRight="2dp"
android:textColor="@android:color/white"
tools:ignore="HardcodedText"
android:text="-:--:--"/>
<!--style="?android:attr/progressBarStyleHorizontal"-->
<SeekBar
android:id="@+id/playbackSeekBar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:max="100"
android:layout_weight="1"
android:progress="0"/>
<TextView
android:id="@+id/playbackEndTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="2dp"
android:paddingRight="2dp"
android:textColor="@android:color/white"
tools:ignore="HardcodedText"
android:text="-:--:--"/>
</LinearLayout>
tools:ignore="RtlHardcoded"
tools:text="1:06:29"
tools:visibility="visible"/>
<RelativeLayout
android:id="@+id/loadingPanel"
@ -102,6 +183,7 @@
tools:visibility="gone">
<ProgressBar
android:id="@+id/progressBarLoadingPanel"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"

View File

@ -33,7 +33,7 @@
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:maxLines="1"
tools:text="title"/>
tools:text="a long, long, long, long, long title"/>
<TextView
android:id="@+id/notificationArtist"
@ -42,28 +42,38 @@
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:maxLines="1"
tools:text="artist"/>
tools:text="a long, long artist"/>
</LinearLayout>
<ImageButton
android:id="@+id/notificationPlayPause"
android:id="@+id/notificationRepeat"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_margin="5dp"
android:background="#00ffffff"
android:layout_height="match_parent"
android:background="#00000000"
android:clickable="true"
android:scaleType="fitXY"
android:src="@drawable/ic_pause_white_24dp"
android:padding="5dp"
android:scaleType="fitCenter"
android:src="@drawable/ic_repeat_white"
tools:ignore="ContentDescription"/>
<ImageButton
android:id="@+id/notificationPlayPause"
android:layout_width="45dp"
android:layout_height="match_parent"
android:background="#00000000"
android:clickable="true"
android:src="@drawable/ic_pause_white"
tools:ignore="ContentDescription"/>
<ImageButton
android:id="@+id/notificationStop"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_margin="5dp"
android:background="#00ffffff"
android:layout_marginLeft="5dp"
android:background="#00000000"
android:clickable="true"
android:scaleType="fitXY"
android:src="@drawable/ic_close_white_24dp"
tools:ignore="ContentDescription"/>
android:padding="5dp"
android:scaleType="fitCenter"
android:src="@drawable/ic_close_white"
tools:ignore="ContentDescription,RtlHardcoded"/>
</LinearLayout>

View File

@ -25,6 +25,7 @@
<string name="settings_activity_title">Settings</string>
<string name="use_external_video_player_title">Use external video player</string>
<string name="use_external_audio_player_title">Use external audio player</string>
<string name="popup_mode_share_menu_title">NewPipe Popup mode</string>
<string name="download_path_title">Video download path</string>
<string name="download_path_summary">Path to store downloaded videos in.</string>
@ -75,6 +76,7 @@
<string name="settings_category_other_title">Other</string>
<string name="background_player_time_text" translatable="false">%1$s - NewPipe</string>
<string name="background_player_playing_toast">Playing in background</string>
<string name="popup_playing_toast">Playing in popup mode</string>
<string name="c3s_url" translatable="false">https://www.c3s.cc/</string>
<string name="play_btn_text">Play</string>
<string name="content">Content</string>

View File

@ -2,7 +2,7 @@
<style name="RootTheme" parent="android:Theme.Holo"/>
<style name="PlayerTheme" parent="@style/RootTheme">
<style name="PlayerTheme" parent="Theme.AppCompat.NoActionBar">
<item name="android:windowNoTitle">true</item>
<item name="android:windowBackground">@android:color/black</item>
</style>