Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
ab82406c98
@ -2,14 +2,14 @@ apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion 25
|
||||
buildToolsVersion '25.0.0'
|
||||
buildToolsVersion '25.0.2'
|
||||
|
||||
defaultConfig {
|
||||
applicationId "org.schabi.newpipe"
|
||||
minSdkVersion 15
|
||||
targetSdkVersion 25
|
||||
versionCode 29
|
||||
versionName "0.9.2"
|
||||
versionCode 30
|
||||
versionName "0.9.3"
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
@ -35,17 +35,17 @@ dependencies {
|
||||
testCompile 'org.mockito:mockito-core:1.10.19'
|
||||
testCompile 'org.json:json:20160810'
|
||||
|
||||
compile 'com.android.support:appcompat-v7:25.1.0'
|
||||
compile 'com.android.support:support-v4:25.1.0'
|
||||
compile 'com.android.support:design:25.1.0'
|
||||
compile 'com.android.support:recyclerview-v7:25.1.0'
|
||||
compile 'com.android.support:appcompat-v7:25.3.1'
|
||||
compile 'com.android.support:support-v4:25.3.1'
|
||||
compile 'com.android.support:design:25.3.1'
|
||||
compile 'com.android.support:recyclerview-v7:25.3.1'
|
||||
compile 'org.jsoup:jsoup:1.8.3'
|
||||
compile 'org.mozilla:rhino:1.7.7'
|
||||
compile 'info.guardianproject.netcipher:netcipher:1.2'
|
||||
compile 'de.hdodenhof:circleimageview:2.0.0'
|
||||
compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
|
||||
compile 'com.github.nirhart:parallaxscroll:1.0'
|
||||
compile 'com.google.code.gson:gson:2.4'
|
||||
compile 'com.google.code.gson:gson:2.7'
|
||||
compile 'com.nononsenseapps:filepicker:3.0.0'
|
||||
compile 'ch.acra:acra:4.9.0'
|
||||
compile 'com.google.android.exoplayer:exoplayer:r2.3.1'
|
||||
|
||||
@ -40,7 +40,7 @@
|
||||
android:label="@string/background_player_name" />
|
||||
|
||||
<activity
|
||||
android:name=".player.ExoPlayerActivity"
|
||||
android:name=".player.MainVideoPlayer"
|
||||
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
|
||||
android:label="@string/app_name"
|
||||
android:launchMode="singleTask"
|
||||
|
||||
@ -20,10 +20,6 @@ package org.schabi.newpipe;
|
||||
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Singleton:
|
||||
* Used to send data between certain Activity/Services within the same process.
|
||||
@ -39,8 +35,5 @@ public class ActivityCommunicator {
|
||||
return activityCommunicator;
|
||||
}
|
||||
|
||||
// Thumbnail send from VideoItemDetailFragment to BackgroundPlayer
|
||||
public volatile Bitmap backgroundPlayerThumbnail;
|
||||
|
||||
public volatile Class returnActivity;
|
||||
}
|
||||
|
||||
@ -45,7 +45,7 @@ import org.schabi.newpipe.util.PermissionHelper;
|
||||
import org.schabi.newpipe.util.ThemeHelper;
|
||||
|
||||
public class MainActivity extends AppCompatActivity implements OnItemSelectedListener {
|
||||
private static final String TAG = MainActivity.class.toString();
|
||||
//private static final String TAG = "MainActivity";
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
// Activity's LifeCycle
|
||||
@ -57,12 +57,23 @@ public class MainActivity extends AppCompatActivity implements OnItemSelectedLis
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
setVolumeControlStream(AudioManager.STREAM_MUSIC);
|
||||
if (savedInstanceState == null) initFragments();
|
||||
|
||||
if (getSupportFragmentManager() != null && getSupportFragmentManager().getBackStackEntryCount() == 0) {
|
||||
initFragments();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onNewIntent(Intent intent) {
|
||||
if (intent != null) {
|
||||
// Return if launched from a launcher (e.g. Nova Launcher, Pixel Launcher ...)
|
||||
// to not destroy the already created backstack
|
||||
String action = intent.getAction();
|
||||
if ((action != null && action.equals(Intent.ACTION_MAIN)) && intent.hasCategory(Intent.CATEGORY_LAUNCHER)) return;
|
||||
}
|
||||
|
||||
super.onNewIntent(intent);
|
||||
setIntent(intent);
|
||||
handleIntent(intent);
|
||||
}
|
||||
|
||||
|
||||
@ -7,7 +7,6 @@ import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.Bitmap;
|
||||
import android.media.AudioManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
@ -43,7 +42,6 @@ import com.nostra13.universalimageloader.core.assist.FailReason;
|
||||
import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer;
|
||||
import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;
|
||||
|
||||
import org.schabi.newpipe.ActivityCommunicator;
|
||||
import org.schabi.newpipe.ImageErrorLoadingListener;
|
||||
import org.schabi.newpipe.Localization;
|
||||
import org.schabi.newpipe.R;
|
||||
@ -57,9 +55,7 @@ import org.schabi.newpipe.extractor.stream_info.StreamInfo;
|
||||
import org.schabi.newpipe.extractor.stream_info.VideoStream;
|
||||
import org.schabi.newpipe.fragments.OnItemSelectedListener;
|
||||
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.MainVideoPlayer;
|
||||
import org.schabi.newpipe.player.PlayVideoActivity;
|
||||
import org.schabi.newpipe.player.PopupVideoPlayer;
|
||||
import org.schabi.newpipe.report.ErrorActivity;
|
||||
@ -111,7 +107,6 @@ public class VideoDetailFragment extends Fragment implements StreamExtractorWork
|
||||
private static final ImageLoader imageLoader = ImageLoader.getInstance();
|
||||
private static final DisplayImageOptions displayImageOptions =
|
||||
new DisplayImageOptions.Builder().displayer(new FadeInBitmapDisplayer(400)).cacheInMemory(false).build();
|
||||
private Bitmap streamThumbnail = null;
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
// Views
|
||||
@ -409,25 +404,6 @@ public class VideoDetailFragment extends Fragment implements StreamExtractorWork
|
||||
if (info.thumbnail_url != null && !info.thumbnail_url.isEmpty()) {
|
||||
imageLoader.displayImage(info.thumbnail_url, thumbnailImageView,
|
||||
displayImageOptions, new SimpleImageLoadingListener() {
|
||||
|
||||
@Override
|
||||
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
|
||||
streamThumbnail = loadedImage;
|
||||
|
||||
if (streamThumbnail != null) {
|
||||
// TODO: Change the thumbnail implementation
|
||||
|
||||
// When the thumbnail is not loaded yet, it not passes to the service in time
|
||||
// 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(AbstractPlayer.ACTION_UPDATE_THUMB);
|
||||
intent.putExtra(AbstractPlayer.VIDEO_URL, currentStreamInfo.webpage_url);
|
||||
activity.sendBroadcast(intent);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
|
||||
ErrorActivity.reportError(activity,
|
||||
@ -529,11 +505,9 @@ public class VideoDetailFragment extends Fragment implements StreamExtractorWork
|
||||
Toast.makeText(activity, R.string.msg_popup_permission, Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
if (streamThumbnail != null) ActivityCommunicator.getCommunicator().backgroundPlayerThumbnail = streamThumbnail;
|
||||
|
||||
Toast.makeText(activity, R.string.popup_playing_toast, Toast.LENGTH_SHORT).show();
|
||||
Intent mIntent = NavigationHelper.getOpenPlayerIntent(activity, PopupVideoPlayer.class, info, selectedStreamId);
|
||||
if (info.start_position > 0) mIntent.putExtra(AbstractPlayer.START_POSITION, info.start_position * 1000);
|
||||
Intent mIntent = NavigationHelper.getOpenVideoPlayerIntent(activity, PopupVideoPlayer.class, info, selectedStreamId);
|
||||
activity.startService(mIntent);
|
||||
}
|
||||
});
|
||||
@ -624,24 +598,10 @@ public class VideoDetailFragment extends Fragment implements StreamExtractorWork
|
||||
boolean useExternalAudioPlayer = PreferenceManager.getDefaultSharedPreferences(activity)
|
||||
.getBoolean(activity.getString(R.string.use_external_audio_player_key), false);
|
||||
Intent intent;
|
||||
AudioStream audioStream =
|
||||
info.audio_streams.get(Utils.getPreferredAudioFormat(activity, info.audio_streams));
|
||||
if (!useExternalAudioPlayer && android.os.Build.VERSION.SDK_INT >= 18) {
|
||||
//internal music player: explicit intent
|
||||
if (!BackgroundPlayer.isRunning && streamThumbnail != null) {
|
||||
ActivityCommunicator.getCommunicator()
|
||||
.backgroundPlayerThumbnail = streamThumbnail;
|
||||
intent = new Intent(activity, BackgroundPlayer.class);
|
||||
|
||||
intent.setAction(Intent.ACTION_VIEW);
|
||||
intent.setDataAndType(Uri.parse(audioStream.url),
|
||||
MediaFormat.getMimeById(audioStream.format));
|
||||
intent.putExtra(BackgroundPlayer.TITLE, info.title);
|
||||
intent.putExtra(BackgroundPlayer.WEB_URL, info.webpage_url);
|
||||
intent.putExtra(BackgroundPlayer.SERVICE_ID, serviceId);
|
||||
intent.putExtra(BackgroundPlayer.CHANNEL_NAME, info.uploader);
|
||||
activity.startService(intent);
|
||||
}
|
||||
AudioStream audioStream = info.audio_streams.get(Utils.getPreferredAudioFormat(activity, info.audio_streams));
|
||||
if (!useExternalAudioPlayer && android.os.Build.VERSION.SDK_INT >= 16) {
|
||||
activity.startService(NavigationHelper.getOpenBackgroundPlayerIntent(activity, info, audioStream));
|
||||
Toast.makeText(activity, R.string.background_player_playing_toast, Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
intent = new Intent();
|
||||
try {
|
||||
@ -829,9 +789,7 @@ public class VideoDetailFragment extends Fragment implements StreamExtractorWork
|
||||
|| (Build.VERSION.SDK_INT < 16);
|
||||
if (!useOldPlayer) {
|
||||
// ExoPlayer
|
||||
if (streamThumbnail != null) ActivityCommunicator.getCommunicator().backgroundPlayerThumbnail = streamThumbnail;
|
||||
mIntent = NavigationHelper.getOpenPlayerIntent(activity, ExoPlayerActivity.class, info, actionBarHandler.getSelectedVideoStream());
|
||||
if (info.start_position > 0) mIntent.putExtra(AbstractPlayer.START_POSITION, info.start_position * 1000);
|
||||
mIntent = NavigationHelper.getOpenVideoPlayerIntent(activity, MainVideoPlayer.class, info, actionBarHandler.getSelectedVideoStream());
|
||||
} else {
|
||||
// Internal Player
|
||||
mIntent = new Intent(activity, PlayVideoActivity.class)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
717
app/src/main/java/org/schabi/newpipe/player/BasePlayer.java
Normal file
717
app/src/main/java/org/schabi/newpipe/player/BasePlayer.java
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,10 +1,8 @@
|
||||
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.content.pm.ActivityInfo;
|
||||
import android.graphics.Color;
|
||||
import android.media.AudioManager;
|
||||
@ -23,22 +21,20 @@ import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.schabi.newpipe.R;
|
||||
import org.schabi.newpipe.extractor.stream_info.VideoStream;
|
||||
import org.schabi.newpipe.util.NavigationHelper;
|
||||
import org.schabi.newpipe.util.PermissionHelper;
|
||||
import org.schabi.newpipe.util.ThemeHelper;
|
||||
|
||||
/**
|
||||
* Activity Player implementing AbstractPlayer
|
||||
* Activity Player implementing VideoPlayer
|
||||
*
|
||||
* @author mauriciocolli
|
||||
*/
|
||||
public class ExoPlayerActivity extends Activity {
|
||||
private static final String TAG = ".ExoPlayerActivity";
|
||||
private static final boolean DEBUG = AbstractPlayer.DEBUG;
|
||||
public class MainVideoPlayer extends Activity {
|
||||
private static final String TAG = ".MainVideoPlayer";
|
||||
private static final boolean DEBUG = BasePlayer.DEBUG;
|
||||
|
||||
private AudioManager audioManager;
|
||||
private BroadcastReceiver broadcastReceiver;
|
||||
private GestureDetector gestureDetector;
|
||||
|
||||
private final Runnable hideUiRunnable = new Runnable() {
|
||||
@ -49,7 +45,7 @@ public class ExoPlayerActivity extends Activity {
|
||||
};
|
||||
private boolean activityPaused;
|
||||
|
||||
private AbstractPlayerImpl playerImpl;
|
||||
private VideoPlayerImpl playerImpl;
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
// Activity LifeCycle
|
||||
@ -72,9 +68,8 @@ public class ExoPlayerActivity extends Activity {
|
||||
|
||||
showSystemUi();
|
||||
setContentView(R.layout.activity_exo_player);
|
||||
playerImpl = new AbstractPlayerImpl();
|
||||
playerImpl = new VideoPlayerImpl();
|
||||
playerImpl.setup(findViewById(android.R.id.content));
|
||||
initReceiver();
|
||||
playerImpl.handleIntent(getIntent());
|
||||
}
|
||||
|
||||
@ -97,8 +92,10 @@ public class ExoPlayerActivity extends Activity {
|
||||
super.onStop();
|
||||
if (DEBUG) Log.d(TAG, "onStop() called");
|
||||
activityPaused = true;
|
||||
playerImpl.destroy();
|
||||
playerImpl.setVideoStartPos((int) playerImpl.getPlayer().getCurrentPosition());
|
||||
if (playerImpl.getPlayer() != null) {
|
||||
playerImpl.setVideoStartPos((int) playerImpl.getPlayer().getCurrentPosition());
|
||||
playerImpl.destroyPlayer();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -106,9 +103,9 @@ public class ExoPlayerActivity extends Activity {
|
||||
super.onResume();
|
||||
if (DEBUG) Log.d(TAG, "onResume() called");
|
||||
if (activityPaused) {
|
||||
playerImpl.getPlayPauseButton().setImageResource(R.drawable.ic_play_arrow_white);
|
||||
playerImpl.initPlayer();
|
||||
playerImpl.playVideo(playerImpl.getSelectedVideoStream(), false);
|
||||
playerImpl.getPlayPauseButton().setImageResource(R.drawable.ic_play_arrow_white);
|
||||
playerImpl.play(false);
|
||||
activityPaused = false;
|
||||
}
|
||||
}
|
||||
@ -118,29 +115,6 @@ public class ExoPlayerActivity extends Activity {
|
||||
super.onDestroy();
|
||||
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);
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
@ -182,7 +156,7 @@ public class ExoPlayerActivity extends Activity {
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@SuppressWarnings({"unused", "WeakerAccess"})
|
||||
private class AbstractPlayerImpl extends AbstractPlayer {
|
||||
private class VideoPlayerImpl extends VideoPlayer {
|
||||
private TextView titleTextView;
|
||||
private TextView channelTextView;
|
||||
private TextView volumeTextView;
|
||||
@ -192,8 +166,8 @@ public class ExoPlayerActivity extends Activity {
|
||||
private ImageButton screenRotationButton;
|
||||
private ImageButton playPauseButton;
|
||||
|
||||
AbstractPlayerImpl() {
|
||||
super("AbstractPlayerImpl" + ExoPlayerActivity.TAG, ExoPlayerActivity.this);
|
||||
VideoPlayerImpl() {
|
||||
super("VideoPlayerImpl" + MainVideoPlayer.TAG, MainVideoPlayer.this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -238,8 +212,8 @@ public class ExoPlayerActivity extends Activity {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playVideo(VideoStream videoStream, boolean autoPlay) {
|
||||
super.playVideo(videoStream, autoPlay);
|
||||
public void playUrl(String url, String format, boolean autoPlay) {
|
||||
super.playUrl(url, format, autoPlay);
|
||||
playPauseButton.setImageResource(autoPlay ? R.drawable.ic_pause_white : R.drawable.ic_play_arrow_white);
|
||||
}
|
||||
|
||||
@ -249,16 +223,16 @@ public class ExoPlayerActivity extends Activity {
|
||||
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();
|
||||
&& !PermissionHelper.checkSystemAlertWindowPermission(MainVideoPlayer.this)) {
|
||||
Toast.makeText(MainVideoPlayer.this, R.string.msg_popup_permission, Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if (playerImpl != null) playerImpl.destroy();
|
||||
context.startService(NavigationHelper.getOpenPlayerIntent(context, PopupVideoPlayer.class, playerImpl));
|
||||
context.startService(NavigationHelper.getOpenVideoPlayerIntent(context, PopupVideoPlayer.class, playerImpl));
|
||||
if (playerImpl != null) playerImpl.destroyPlayer();
|
||||
|
||||
((View) getControlAnimationView().getParent()).setVisibility(View.GONE);
|
||||
ExoPlayerActivity.this.finish();
|
||||
MainVideoPlayer.this.finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -307,28 +281,6 @@ public class ExoPlayerActivity extends Activity {
|
||||
toggleOrientation();
|
||||
}
|
||||
|
||||
@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);
|
||||
@ -344,7 +296,8 @@ public class ExoPlayerActivity extends Activity {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError() {
|
||||
public void onError(Exception exception) {
|
||||
exception.printStackTrace();
|
||||
Toast.makeText(context, "Failed to play this video", Toast.LENGTH_SHORT).show();
|
||||
finish();
|
||||
}
|
||||
@ -366,10 +319,37 @@ public class ExoPlayerActivity extends Activity {
|
||||
animateView(playPauseButton, false, 100, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlaying() {
|
||||
super.onPlaying();
|
||||
//playPauseButton.setImageResource(R.drawable.ic_pause_white);
|
||||
//animateView(playPauseButton, true, 500, 0);
|
||||
|
||||
animateView(playPauseButton, false, 80, 0, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
playPauseButton.setImageResource(R.drawable.ic_pause_white);
|
||||
animateView(playPauseButton, true, 200, 0);
|
||||
}
|
||||
});
|
||||
|
||||
showSystemUi();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPaused() {
|
||||
super.onPaused();
|
||||
animateView(playPauseButton, true, 100, 0);
|
||||
//playPauseButton.setImageResource(R.drawable.ic_play_arrow_white);
|
||||
//animateView(playPauseButton, true, 100, 0);
|
||||
|
||||
animateView(playPauseButton, false, 80, 0, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
playPauseButton.setImageResource(R.drawable.ic_play_arrow_white);
|
||||
animateView(playPauseButton, true, 200, 0);
|
||||
}
|
||||
});
|
||||
|
||||
showSystemUi();
|
||||
}
|
||||
|
||||
@ -379,12 +359,6 @@ public class ExoPlayerActivity extends Activity {
|
||||
animateView(playPauseButton, false, 100, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlaying() {
|
||||
super.onPlaying();
|
||||
animateView(playPauseButton, true, 500, 0);
|
||||
showSystemUi();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCompleted() {
|
||||
@ -467,14 +441,14 @@ public class ExoPlayerActivity extends Activity {
|
||||
@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.getCurrentState() != BasePlayer.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);
|
||||
playerImpl.animateView(playerImpl.getControlsRoot(), false, 300, VideoPlayer.DEFAULT_CONTROLS_HIDE_TIME, true);
|
||||
}
|
||||
});
|
||||
showSystemUi();
|
||||
@ -482,25 +456,25 @@ public class ExoPlayerActivity extends Activity {
|
||||
return true;
|
||||
}
|
||||
|
||||
private final float stepsBrightness = 21, stepBrightness = (1f / stepsBrightness), minBrightness = .01f;
|
||||
private final float stepsBrightness = 15, stepBrightness = (1f / stepsBrightness), minBrightness = .01f;
|
||||
private float currentBrightness = .5f;
|
||||
|
||||
private int currentVolume, maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
|
||||
private final float stepsVolume = 15, stepVolume = (float) Math.ceil(maxVolume / stepsVolume), minVolume = 0;
|
||||
|
||||
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 final int eventsThreshold = 8;
|
||||
private boolean triggered = false;
|
||||
private int eventsNum;
|
||||
|
||||
// TODO: Improve video gesture controls
|
||||
@Override
|
||||
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
|
||||
//noinspection PointlessBooleanExpression
|
||||
if (DEBUG && false) Log.d(TAG, "ExoPlayerActivity.onScroll = " +
|
||||
if (DEBUG && true) Log.d(TAG, "MainVideoPlayer.onScroll = " +
|
||||
", e1.getRaw = [" + e1.getRawX() + ", " + e1.getRawY() + "]" +
|
||||
", e2.getRaw = [" + e2.getRawX() + ", " + e2.getRawY() + "]" +
|
||||
", distanceXy = [" + distanceX + ", " + distanceY + "]");
|
||||
@ -510,16 +484,17 @@ public class ExoPlayerActivity extends Activity {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (eventsNum++ % eventsThreshold != 0 || playerImpl.getCurrentState() == StateInterface.STATE_COMPLETED) return false;
|
||||
if (eventsNum++ % eventsThreshold != 0 || playerImpl.getCurrentState() == BasePlayer.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);
|
||||
double floor = Math.floor(up ? stepVolume : -stepVolume);
|
||||
currentVolume = (int) (audioManager.getStreamVolume(AudioManager.STREAM_MUSIC) + floor);
|
||||
if (currentVolume >= maxVolume) currentVolume = maxVolume;
|
||||
if (currentVolume <= 0) currentVolume = 0;
|
||||
if (currentVolume <= minVolume) currentVolume = (int) minVolume;
|
||||
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, currentVolume, 0);
|
||||
|
||||
if (DEBUG) Log.d(TAG, "onScroll().volumeControl, currentVolume = " + currentVolume);
|
||||
@ -555,8 +530,8 @@ public class ExoPlayerActivity extends Activity {
|
||||
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);
|
||||
if (playerImpl.isControlsVisible() && playerImpl.getCurrentState() == BasePlayer.STATE_PLAYING) {
|
||||
playerImpl.animateView(playerImpl.getControlsRoot(), false, 300, VideoPlayer.DEFAULT_CONTROLS_HIDE_TIME);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,7 +4,6 @@ import android.annotation.SuppressLint;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.Service;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
@ -31,7 +30,6 @@ import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||
import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;
|
||||
|
||||
import org.schabi.newpipe.ActivityCommunicator;
|
||||
import org.schabi.newpipe.BuildConfig;
|
||||
import org.schabi.newpipe.MainActivity;
|
||||
import org.schabi.newpipe.R;
|
||||
@ -39,7 +37,6 @@ import org.schabi.newpipe.ReCaptchaActivity;
|
||||
import org.schabi.newpipe.extractor.MediaFormat;
|
||||
import org.schabi.newpipe.extractor.StreamingService;
|
||||
import org.schabi.newpipe.extractor.stream_info.StreamInfo;
|
||||
import org.schabi.newpipe.extractor.stream_info.VideoStream;
|
||||
import org.schabi.newpipe.util.Constants;
|
||||
import org.schabi.newpipe.util.NavigationHelper;
|
||||
import org.schabi.newpipe.util.ThemeHelper;
|
||||
@ -47,13 +44,13 @@ import org.schabi.newpipe.util.Utils;
|
||||
import org.schabi.newpipe.workers.StreamExtractorWorker;
|
||||
|
||||
/**
|
||||
* Service Popup Player implementing AbstractPlayer
|
||||
* Service Popup Player implementing VideoPlayer
|
||||
*
|
||||
* @author mauriciocolli
|
||||
*/
|
||||
public class PopupVideoPlayer extends Service {
|
||||
private static final String TAG = ".PopupVideoPlayer";
|
||||
private static final boolean DEBUG = AbstractPlayer.DEBUG;
|
||||
private static final boolean DEBUG = BasePlayer.DEBUG;
|
||||
|
||||
private static final int NOTIFICATION_ID = 40028922;
|
||||
public static final String ACTION_CLOSE = "org.schabi.newpipe.player.PopupVideoPlayer.CLOSE";
|
||||
@ -61,8 +58,6 @@ public class PopupVideoPlayer extends Service {
|
||||
public static final String ACTION_OPEN_DETAIL = "org.schabi.newpipe.player.PopupVideoPlayer.OPEN_DETAIL";
|
||||
public static final String ACTION_REPEAT = "org.schabi.newpipe.player.PopupVideoPlayer.REPEAT";
|
||||
|
||||
private BroadcastReceiver broadcastReceiver;
|
||||
|
||||
private WindowManager windowManager;
|
||||
private WindowManager.LayoutParams windowLayoutParams;
|
||||
private GestureDetector gestureDetector;
|
||||
@ -81,7 +76,7 @@ public class PopupVideoPlayer extends Service {
|
||||
private ImageLoader imageLoader = ImageLoader.getInstance();
|
||||
private DisplayImageOptions displayImageOptions = new DisplayImageOptions.Builder().cacheInMemory(true).build();
|
||||
|
||||
private AbstractPlayerImpl playerImpl;
|
||||
private VideoPlayerImpl playerImpl;
|
||||
private StreamExtractorWorker currentExtractorWorker;
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
@ -92,9 +87,8 @@ public class PopupVideoPlayer extends Service {
|
||||
public void onCreate() {
|
||||
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
|
||||
notificationManager = ((NotificationManager) getSystemService(NOTIFICATION_SERVICE));
|
||||
initReceiver();
|
||||
|
||||
playerImpl = new AbstractPlayerImpl();
|
||||
playerImpl = new VideoPlayerImpl();
|
||||
ThemeHelper.setTheme(this, false);
|
||||
}
|
||||
|
||||
@ -132,7 +126,6 @@ public class PopupVideoPlayer extends Service {
|
||||
}
|
||||
if (imageLoader != null) imageLoader.clearMemoryCache();
|
||||
if (notificationManager != null) notificationManager.cancel(NOTIFICATION_ID);
|
||||
if (broadcastReceiver != null) unregisterReceiver(broadcastReceiver);
|
||||
if (currentExtractorWorker != null) {
|
||||
currentExtractorWorker.cancel();
|
||||
currentExtractorWorker = null;
|
||||
@ -148,39 +141,6 @@ public class PopupVideoPlayer extends Service {
|
||||
// Init
|
||||
//////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
private void initReceiver() {
|
||||
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 ACTION_CLOSE:
|
||||
onVideoClose();
|
||||
break;
|
||||
case ACTION_PLAY_PAUSE:
|
||||
playerImpl.onVideoPlayPause();
|
||||
break;
|
||||
case ACTION_OPEN_DETAIL:
|
||||
onOpenDetail(PopupVideoPlayer.this, playerImpl.getVideoUrl(), playerImpl.getVideoTitle());
|
||||
break;
|
||||
case ACTION_REPEAT:
|
||||
playerImpl.onRepeatClicked();
|
||||
break;
|
||||
case AbstractPlayer.ACTION_UPDATE_THUMB:
|
||||
playerImpl.onUpdateThumbnail(intent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
IntentFilter intentFilter = new IntentFilter();
|
||||
intentFilter.addAction(ACTION_CLOSE);
|
||||
intentFilter.addAction(ACTION_PLAY_PAUSE);
|
||||
intentFilter.addAction(ACTION_OPEN_DETAIL);
|
||||
intentFilter.addAction(ACTION_REPEAT);
|
||||
intentFilter.addAction(AbstractPlayer.ACTION_UPDATE_THUMB);
|
||||
registerReceiver(broadcastReceiver, intentFilter);
|
||||
}
|
||||
|
||||
@SuppressLint("RtlHardcoded")
|
||||
private void initPopup() {
|
||||
if (DEBUG) Log.d(TAG, "initPopup() called");
|
||||
@ -213,8 +173,9 @@ public class PopupVideoPlayer extends Service {
|
||||
private NotificationCompat.Builder createNotification() {
|
||||
notRemoteView = new RemoteViews(BuildConfig.APPLICATION_ID, R.layout.player_popup_notification);
|
||||
|
||||
if (playerImpl.getVideoThumbnail() != null) notRemoteView.setImageViewBitmap(R.id.notificationCover, playerImpl.getVideoThumbnail());
|
||||
else notRemoteView.setImageViewResource(R.id.notificationCover, R.drawable.dummy_thumbnail);
|
||||
if (playerImpl.getVideoThumbnail() == null) notRemoteView.setImageViewResource(R.id.notificationCover, R.drawable.dummy_thumbnail);
|
||||
else notRemoteView.setImageViewBitmap(R.id.notificationCover, playerImpl.getVideoThumbnail());
|
||||
|
||||
notRemoteView.setTextViewText(R.id.notificationSongName, playerImpl.getVideoTitle());
|
||||
notRemoteView.setTextViewText(R.id.notificationArtist, playerImpl.getChannelName());
|
||||
|
||||
@ -302,21 +263,35 @@ public class PopupVideoPlayer extends Service {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private class AbstractPlayerImpl extends AbstractPlayer {
|
||||
AbstractPlayerImpl() {
|
||||
super("AbstractPlayerImpl" + PopupVideoPlayer.TAG, PopupVideoPlayer.this);
|
||||
private class VideoPlayerImpl extends VideoPlayer {
|
||||
VideoPlayerImpl() {
|
||||
super("VideoPlayerImpl" + PopupVideoPlayer.TAG, PopupVideoPlayer.this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playVideo(VideoStream videoStream, boolean autoPlay) {
|
||||
super.playVideo(videoStream, autoPlay);
|
||||
public void playUrl(String url, String format, boolean autoPlay) {
|
||||
super.playUrl(url, format, autoPlay);
|
||||
|
||||
windowLayoutParams.width = (int) getMinimumVideoWidth(currentPopupHeight);
|
||||
windowManager.updateViewLayout(getRootView(), windowLayoutParams);
|
||||
|
||||
notBuilder = createNotification();
|
||||
startForeground(NOTIFICATION_ID, notBuilder.build());
|
||||
notificationManager.notify(NOTIFICATION_ID, notBuilder.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
super.destroy();
|
||||
if (notRemoteView != null) notRemoteView.setImageViewBitmap(R.id.notificationCover, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onThumbnailReceived(Bitmap thumbnail) {
|
||||
super.onThumbnailReceived(thumbnail);
|
||||
if (thumbnail != null) {
|
||||
if (notRemoteView != null) notRemoteView.setImageViewBitmap(R.id.notificationCover, thumbnail);
|
||||
updateNotification(-1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -324,8 +299,8 @@ public class PopupVideoPlayer extends Service {
|
||||
if (DEBUG) Log.d(TAG, "onFullScreenButtonClicked() called");
|
||||
Intent intent;
|
||||
if (!getSharedPreferences().getBoolean(getResources().getString(R.string.use_old_player_key), false)) {
|
||||
intent = NavigationHelper.getOpenPlayerIntent(context, ExoPlayerActivity.class, playerImpl);
|
||||
if (!playerImpl.isStartedFromNewPipe()) intent.putExtra(AbstractPlayer.STARTED_FROM_NEWPIPE, false);
|
||||
intent = NavigationHelper.getOpenVideoPlayerIntent(context, MainVideoPlayer.class, playerImpl);
|
||||
if (!playerImpl.isStartedFromNewPipe()) intent.putExtra(VideoPlayer.STARTED_FROM_NEWPIPE, false);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
} else {
|
||||
intent = new Intent(PopupVideoPlayer.this, PlayVideoActivity.class)
|
||||
@ -335,9 +310,9 @@ public class PopupVideoPlayer extends Service {
|
||||
.putExtra(PlayVideoActivity.START_POSITION, Math.round(getPlayer().getCurrentPosition() / 1000f));
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
}
|
||||
stopSelf();
|
||||
if (playerImpl != null) playerImpl.destroy();
|
||||
context.startActivity(intent);
|
||||
if (playerImpl != null) playerImpl.destroyPlayer();
|
||||
stopSelf();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -360,13 +335,6 @@ public class PopupVideoPlayer extends Service {
|
||||
updateNotification(-1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdateThumbnail(Intent intent) {
|
||||
super.onUpdateThumbnail(intent);
|
||||
if (getVideoThumbnail() != null) notRemoteView.setImageViewBitmap(R.id.notificationCover, getVideoThumbnail());
|
||||
updateNotification(-1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDismiss(PopupMenu menu) {
|
||||
super.onDismiss(menu);
|
||||
@ -374,11 +342,45 @@ public class PopupVideoPlayer extends Service {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError() {
|
||||
public void onError(Exception exception) {
|
||||
exception.printStackTrace();
|
||||
Toast.makeText(context, "Failed to play this video", Toast.LENGTH_SHORT).show();
|
||||
stopSelf();
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
// Broadcast Receiver
|
||||
//////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
@Override
|
||||
protected void setupBroadcastReceiver(IntentFilter intentFilter) {
|
||||
super.setupBroadcastReceiver(intentFilter);
|
||||
if (DEBUG) Log.d(TAG, "setupBroadcastReceiver() called with: intentFilter = [" + intentFilter + "]");
|
||||
intentFilter.addAction(ACTION_CLOSE);
|
||||
intentFilter.addAction(ACTION_PLAY_PAUSE);
|
||||
intentFilter.addAction(ACTION_OPEN_DETAIL);
|
||||
intentFilter.addAction(ACTION_REPEAT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBroadcastReceived(Intent intent) {
|
||||
super.onBroadcastReceived(intent);
|
||||
if (DEBUG) Log.d(TAG, "onBroadcastReceived() called with: intent = [" + intent + "]");
|
||||
switch (intent.getAction()) {
|
||||
case ACTION_CLOSE:
|
||||
onVideoClose();
|
||||
break;
|
||||
case ACTION_PLAY_PAUSE:
|
||||
playerImpl.onVideoPlayPause();
|
||||
break;
|
||||
case ACTION_OPEN_DETAIL:
|
||||
onOpenDetail(PopupVideoPlayer.this, playerImpl.getVideoUrl(), playerImpl.getVideoTitle());
|
||||
break;
|
||||
case ACTION_REPEAT:
|
||||
playerImpl.onRepeatClicked();
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
// States
|
||||
//////////////////////////////////////////////////////////////////////////*/
|
||||
@ -483,8 +485,8 @@ public class PopupVideoPlayer extends Service {
|
||||
|
||||
private void onScrollEnd() {
|
||||
if (DEBUG) Log.d(TAG, "onScrollEnd() called");
|
||||
if (playerImpl.isControlsVisible() && playerImpl.getCurrentState() == StateInterface.STATE_PLAYING) {
|
||||
playerImpl.animateView(playerImpl.getControlsRoot(), false, 300, AbstractPlayer.DEFAULT_CONTROLS_HIDE_TIME);
|
||||
if (playerImpl.isControlsVisible() && playerImpl.getCurrentState() == BasePlayer.STATE_PLAYING) {
|
||||
playerImpl.animateView(playerImpl.getControlsRoot(), false, 300, VideoPlayer.DEFAULT_CONTROLS_HIDE_TIME);
|
||||
}
|
||||
}
|
||||
|
||||
@ -516,6 +518,7 @@ public class PopupVideoPlayer extends Service {
|
||||
public void onReceive(StreamInfo info) {
|
||||
playerImpl.setVideoTitle(info.title);
|
||||
playerImpl.setVideoUrl(info.webpage_url);
|
||||
playerImpl.setVideoThumbnailUrl(info.thumbnail_url);
|
||||
playerImpl.setChannelName(info.uploader);
|
||||
|
||||
playerImpl.setVideoStreamsList(Utils.getSortedStreamVideosList(context, info.video_streams, info.video_only_streams, false));
|
||||
@ -537,7 +540,7 @@ public class PopupVideoPlayer extends Service {
|
||||
mainHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
playerImpl.playVideo(playerImpl.getSelectedVideoStream(), true);
|
||||
playerImpl.play(true);
|
||||
}
|
||||
});
|
||||
|
||||
@ -551,7 +554,6 @@ public class PopupVideoPlayer extends Service {
|
||||
playerImpl.setVideoThumbnail(loadedImage);
|
||||
if (loadedImage != null) notRemoteView.setImageViewBitmap(R.id.notificationCover, loadedImage);
|
||||
updateNotification(-1);
|
||||
ActivityCommunicator.getCommunicator().backgroundPlayerThumbnail = loadedImage;
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -619,6 +621,7 @@ public class PopupVideoPlayer extends Service {
|
||||
|
||||
@Override
|
||||
public void onUnrecoverableError(Exception exception) {
|
||||
exception.printStackTrace();
|
||||
stopSelf();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,19 +0,0 @@
|
||||
package org.schabi.newpipe.player;
|
||||
|
||||
public interface StateInterface {
|
||||
int STATE_LOADING = 123;
|
||||
int STATE_PLAYING = 124;
|
||||
int STATE_BUFFERING = 125;
|
||||
int STATE_PAUSED = 126;
|
||||
int STATE_PAUSED_SEEK = 127;
|
||||
int STATE_COMPLETED = 128;
|
||||
|
||||
void changeState(int state);
|
||||
|
||||
void onLoading();
|
||||
void onPlaying();
|
||||
void onBuffering();
|
||||
void onPaused();
|
||||
void onPausedSeek();
|
||||
void onCompleted();
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -8,33 +8,57 @@ import org.schabi.newpipe.MainActivity;
|
||||
import org.schabi.newpipe.R;
|
||||
import org.schabi.newpipe.extractor.NewPipe;
|
||||
import org.schabi.newpipe.extractor.StreamingService;
|
||||
import org.schabi.newpipe.extractor.stream_info.AudioStream;
|
||||
import org.schabi.newpipe.extractor.stream_info.StreamInfo;
|
||||
import org.schabi.newpipe.fragments.OnItemSelectedListener;
|
||||
import org.schabi.newpipe.fragments.detail.VideoDetailFragment;
|
||||
import org.schabi.newpipe.player.AbstractPlayer;
|
||||
import org.schabi.newpipe.player.BackgroundPlayer;
|
||||
import org.schabi.newpipe.player.BasePlayer;
|
||||
import org.schabi.newpipe.player.VideoPlayer;
|
||||
|
||||
@SuppressWarnings({"unused", "WeakerAccess"})
|
||||
public class NavigationHelper {
|
||||
|
||||
public static Intent getOpenPlayerIntent(Context context, Class targetClazz, StreamInfo info, int selectedStreamIndex) {
|
||||
return new Intent(context, targetClazz)
|
||||
.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, selectedStreamIndex)
|
||||
.putExtra(AbstractPlayer.VIDEO_STREAMS_LIST, Utils.getSortedStreamVideosList(context, info.video_streams, info.video_only_streams, false))
|
||||
.putExtra(AbstractPlayer.VIDEO_ONLY_AUDIO_STREAM, Utils.getHighestQualityAudio(info.audio_streams));
|
||||
public static Intent getOpenVideoPlayerIntent(Context context, Class targetClazz, StreamInfo info, int selectedStreamIndex) {
|
||||
Intent mIntent = new Intent(context, targetClazz)
|
||||
.putExtra(BasePlayer.VIDEO_TITLE, info.title)
|
||||
.putExtra(BasePlayer.VIDEO_URL, info.webpage_url)
|
||||
.putExtra(BasePlayer.VIDEO_THUMBNAIL_URL, info.thumbnail_url)
|
||||
.putExtra(BasePlayer.CHANNEL_NAME, info.uploader)
|
||||
.putExtra(VideoPlayer.INDEX_SEL_VIDEO_STREAM, selectedStreamIndex)
|
||||
.putExtra(VideoPlayer.VIDEO_STREAMS_LIST, Utils.getSortedStreamVideosList(context, info.video_streams, info.video_only_streams, false))
|
||||
.putExtra(VideoPlayer.VIDEO_ONLY_AUDIO_STREAM, Utils.getHighestQualityAudio(info.audio_streams));
|
||||
if (info.start_position > 0) mIntent.putExtra(BasePlayer.START_POSITION, info.start_position * 1000);
|
||||
return mIntent;
|
||||
}
|
||||
|
||||
public static Intent getOpenPlayerIntent(Context context, Class targetClazz, AbstractPlayer instance) {
|
||||
|
||||
public static Intent getOpenVideoPlayerIntent(Context context, Class targetClazz, VideoPlayer instance) {
|
||||
return new Intent(context, targetClazz)
|
||||
.putExtra(AbstractPlayer.VIDEO_TITLE, instance.getVideoTitle())
|
||||
.putExtra(AbstractPlayer.VIDEO_URL, instance.getVideoUrl())
|
||||
.putExtra(AbstractPlayer.CHANNEL_NAME, instance.getChannelName())
|
||||
.putExtra(AbstractPlayer.INDEX_SEL_VIDEO_STREAM, instance.getSelectedStreamIndex())
|
||||
.putExtra(AbstractPlayer.VIDEO_STREAMS_LIST, instance.getVideoStreamsList())
|
||||
.putExtra(AbstractPlayer.VIDEO_ONLY_AUDIO_STREAM, instance.getAudioStream())
|
||||
.putExtra(AbstractPlayer.START_POSITION, ((int) instance.getPlayer().getCurrentPosition()));
|
||||
.putExtra(BasePlayer.VIDEO_TITLE, instance.getVideoTitle())
|
||||
.putExtra(BasePlayer.VIDEO_URL, instance.getVideoUrl())
|
||||
.putExtra(BasePlayer.VIDEO_THUMBNAIL_URL, instance.getVideoThumbnailUrl())
|
||||
.putExtra(BasePlayer.CHANNEL_NAME, instance.getChannelName())
|
||||
.putExtra(VideoPlayer.INDEX_SEL_VIDEO_STREAM, instance.getSelectedStreamIndex())
|
||||
.putExtra(VideoPlayer.VIDEO_STREAMS_LIST, instance.getVideoStreamsList())
|
||||
.putExtra(VideoPlayer.VIDEO_ONLY_AUDIO_STREAM, instance.getAudioStream())
|
||||
.putExtra(BasePlayer.START_POSITION, ((int) instance.getPlayer().getCurrentPosition()));
|
||||
}
|
||||
|
||||
public static Intent getOpenBackgroundPlayerIntent(Context context, StreamInfo info) {
|
||||
return getOpenBackgroundPlayerIntent(context, info, info.audio_streams.get(Utils.getPreferredAudioFormat(context, info.audio_streams)));
|
||||
}
|
||||
|
||||
public static Intent getOpenBackgroundPlayerIntent(Context context, StreamInfo info, AudioStream audioStream) {
|
||||
Intent mIntent = new Intent(context, BackgroundPlayer.class)
|
||||
.putExtra(BasePlayer.VIDEO_TITLE, info.title)
|
||||
.putExtra(BasePlayer.VIDEO_URL, info.webpage_url)
|
||||
.putExtra(BasePlayer.VIDEO_THUMBNAIL_URL, info.thumbnail_url)
|
||||
.putExtra(BasePlayer.CHANNEL_NAME, info.uploader)
|
||||
.putExtra(BasePlayer.CHANNEL_NAME, info.uploader)
|
||||
.putExtra(BackgroundPlayer.AUDIO_STREAM, audioStream);
|
||||
if (info.start_position > 0) mIntent.putExtra(BasePlayer.START_POSITION, info.start_position * 1000);
|
||||
return mIntent;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -136,13 +136,19 @@ public class Utils {
|
||||
break;
|
||||
}
|
||||
|
||||
int highestQualityIndex = 0;
|
||||
|
||||
// Try to find a audio stream with the preferred format
|
||||
for (int i = 0; i < audioStreams.size(); i++) if (audioStreams.get(i).format == preferredFormat) highestQualityIndex = i;
|
||||
|
||||
// Try to find a audio stream with the highest bitrate and preferred format
|
||||
for (int i = 0; i < audioStreams.size(); i++) {
|
||||
if (audioStreams.get(i).format == preferredFormat) {
|
||||
return i;
|
||||
}
|
||||
AudioStream audioStream = audioStreams.get(i);
|
||||
if (audioStream.avgBitrate > audioStreams.get(highestQualityIndex).avgBitrate
|
||||
&& audioStream.format == preferredFormat) highestQualityIndex = i;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return highestQualityIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -191,14 +197,13 @@ public class Utils {
|
||||
}
|
||||
return getSortedStreamVideosList(preferredFormat, showHigherResolutions, videoStreams, videoOnlyStreams, ascendingOrder);
|
||||
}
|
||||
//show_higher_resolutions_key
|
||||
|
||||
/**
|
||||
* Join the two lists of video streams (video_only and normal videos), and sort them according with preferred format
|
||||
* chosen by the user
|
||||
*
|
||||
* @param preferredFormat format to give preference
|
||||
* @param showHigherResolutions
|
||||
* @param showHigherResolutions show >1080p resolutions
|
||||
* @param videoStreams normal videos list
|
||||
* @param videoOnlyStreams video only stream list
|
||||
* @param ascendingOrder true -> smallest to greatest | false -> greatest to smallest @return the sorted list
|
||||
|
||||
17
app/src/main/res/drawable/custom_progress_bar.xml
Normal file
17
app/src/main/res/drawable/custom_progress_bar.xml
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:id="@android:id/background">
|
||||
<shape>
|
||||
<solid android:color="@color/gray"/>
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<item android:id="@android:id/progress">
|
||||
<clip>
|
||||
<shape>
|
||||
<solid android:color="@color/middle_gray"/>
|
||||
</shape>
|
||||
</clip>
|
||||
</item>
|
||||
|
||||
</layer-list>
|
||||
@ -1,16 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/notificationContent"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:clickable="true"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:background="@color/background_notification_color">
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="64dp"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/notificationContent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="64dp"
|
||||
android:background="@color/background_notification_color"
|
||||
android:clickable="true"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
@ -18,65 +19,102 @@
|
||||
android:id="@+id/notificationCover"
|
||||
android:layout_width="64dp"
|
||||
android:layout_height="64dp"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@drawable/dummy_thumbnail"
|
||||
android:scaleType="centerCrop"/>
|
||||
tools:ignore="ContentDescription"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical" >
|
||||
android:orientation="vertical"
|
||||
tools:ignore="RtlHardcoded">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/notificationSongName"
|
||||
style="@android:style/TextAppearance.StatusBar.EventContent.Title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:ellipsize="end"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="marquee"
|
||||
android:singleLine="true"
|
||||
android:text="title" />
|
||||
android:maxLines="1"
|
||||
android:textSize="14sp"
|
||||
tools:text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis nec aliquam augue, eget cursus est. Ut id tristique enim, ut scelerisque tellus. Sed ultricies ipsum non mauris ultricies, commodo malesuada velit porta."/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/notificationArtist"
|
||||
android:layout_width="match_parent"
|
||||
style="@android:style/TextAppearance.StatusBar.EventContent"
|
||||
android:layout_width="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="marquee"
|
||||
android:singleLine="true"
|
||||
android:text="artist" />
|
||||
android:maxLines="1"
|
||||
android:textSize="12sp"
|
||||
tools:text="Duis posuere arcu condimentum lobortis mattis."/>
|
||||
</LinearLayout>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/notificationRewind"
|
||||
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_action_av_fast_rewind" />
|
||||
android:padding="5dp"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/ic_repeat_white"
|
||||
tools:ignore="ContentDescription"/>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/notificationFRewind"
|
||||
android:layout_width="45dp"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#00000000"
|
||||
android:clickable="true"
|
||||
android:padding="5dp"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/ic_action_av_fast_rewind"
|
||||
tools:ignore="ContentDescription"/>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/notificationPlayPause"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_margin="5dp"
|
||||
android:background="#00ffffff"
|
||||
android:layout_width="45dp"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#00000000"
|
||||
android:clickable="true"
|
||||
android:scaleType="fitXY"
|
||||
android:src="@drawable/ic_pause_white" />
|
||||
android:src="@drawable/ic_pause_white"
|
||||
tools:ignore="ContentDescription"/>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/notificationFForward"
|
||||
android:layout_width="45dp"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#00000000"
|
||||
android:clickable="true"
|
||||
android:padding="5dp"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/ic_action_av_fast_forward"
|
||||
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" />
|
||||
android:padding="5dp"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/ic_close_white"
|
||||
tools:ignore="ContentDescription,RtlHardcoded"/>
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</RelativeLayout>
|
||||
<ProgressBar
|
||||
android:id="@+id/notificationProgressBar"
|
||||
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="3dp"
|
||||
android:layout_gravity="bottom"
|
||||
android:layout_marginLeft="64dp"
|
||||
android:progressDrawable="@drawable/custom_progress_bar"
|
||||
tools:ignore="RtlHardcoded"
|
||||
tools:progress="52"/>
|
||||
</FrameLayout>
|
||||
@ -1,4 +1,153 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/notificationContent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="128dp"
|
||||
android:background="@color/background_notification_color"
|
||||
android:clickable="true"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/notificationCover"
|
||||
android:layout_width="128dp"
|
||||
android:layout_height="128dp"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@drawable/dummy_thumbnail"
|
||||
tools:ignore="ContentDescription,RtlHardcoded"/>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/notificationStop"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_alignParentRight="true"
|
||||
android:background="#00000000"
|
||||
android:clickable="true"
|
||||
android:padding="8dp"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/ic_close_white"
|
||||
tools:ignore="ContentDescription,RtlHardcoded"/>
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_toLeftOf="@+id/notificationStop"
|
||||
android:layout_toRightOf="@+id/notificationCover"
|
||||
android:orientation="vertical"
|
||||
android:padding="8dp"
|
||||
tools:ignore="RtlHardcoded,RtlSymmetry">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/notificationSongName"
|
||||
style="@android:style/TextAppearance.StatusBar.EventContent.Title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="2"
|
||||
android:textSize="14sp"
|
||||
tools:text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis nec aliquam augue, eget cursus est. Ut id tristique enim, ut scelerisque tellus. Sed ultricies ipsum non mauris ultricies, commodo malesuada velit porta."/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/notificationArtist"
|
||||
style="@android:style/TextAppearance.StatusBar.EventContent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textSize="12sp"
|
||||
tools:text="Duis posuere arcu condimentum lobortis mattis."/>
|
||||
</LinearLayout>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/notificationProgressBar"
|
||||
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="2dp"
|
||||
android:layout_alignTop="@+id/notificationControls"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_toRightOf="@+id/notificationCover"
|
||||
android:progressDrawable="@drawable/custom_progress_bar"
|
||||
tools:ignore="RtlHardcoded"
|
||||
tools:progress="52"/>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/notificationControls"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="60dp"
|
||||
android:paddingTop="10dp"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_toRightOf="@+id/notificationCover"
|
||||
android:orientation="horizontal"
|
||||
tools:ignore="RtlHardcoded">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/notificationRepeat"
|
||||
android:layout_width="45dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:background="#00000000"
|
||||
android:clickable="true"
|
||||
android:paddingBottom="4dp"
|
||||
android:paddingLeft="11dp"
|
||||
android:paddingRight="11dp"
|
||||
android:paddingTop="4dp"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/ic_repeat_white"
|
||||
tools:ignore="ContentDescription"/>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/notificationFRewind"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginRight="5dp"
|
||||
android:layout_toLeftOf="@+id/notificationPlayPause"
|
||||
android:background="#00000000"
|
||||
android:clickable="true"
|
||||
android:padding="2dp"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/ic_action_av_fast_rewind"
|
||||
tools:ignore="ContentDescription"/>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/notificationPlayPause"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginRight="5dp"
|
||||
android:layout_toLeftOf="@+id/notificationFForward"
|
||||
android:background="#00000000"
|
||||
android:padding="2dp"
|
||||
android:clickable="true"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/ic_pause_white"
|
||||
tools:ignore="ContentDescription"/>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/notificationFForward"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginRight="8dp"
|
||||
android:background="#00000000"
|
||||
android:clickable="true"
|
||||
android:padding="2dp"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/ic_action_av_fast_forward"
|
||||
tools:ignore="ContentDescription"/>
|
||||
</RelativeLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
<!--
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/notificationContent"
|
||||
android:layout_width="fill_parent"
|
||||
@ -93,4 +242,4 @@
|
||||
android:layout_alignParentLeft="true" />
|
||||
</RelativeLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
</RelativeLayout>-->
|
||||
@ -29,20 +29,23 @@
|
||||
<TextView
|
||||
android:id="@+id/notificationSongName"
|
||||
style="@android:style/TextAppearance.StatusBar.EventContent.Title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:ellipsize="end"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="marquee"
|
||||
android:maxLines="1"
|
||||
tools:text="a long, long, long, long, long title"/>
|
||||
android:textSize="14sp"
|
||||
tools:text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis nec aliquam augue, eget cursus est. Ut id tristique enim, ut scelerisque tellus. Sed ultricies ipsum non mauris ultricies, commodo malesuada velit porta."/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/notificationArtist"
|
||||
android:layout_width="match_parent"
|
||||
style="@android:style/TextAppearance.StatusBar.EventContent"
|
||||
android:layout_width="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="marquee"
|
||||
android:maxLines="1"
|
||||
tools:text="a long, long artist"/>
|
||||
android:textSize="12sp"
|
||||
tools:text="Duis posuere arcu condimentum lobortis mattis."/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<ImageButton
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user