Migrate to fragments and improvements

- Migrate to fragments
- Fix #487
- Don't show "Open in popup mode" to channel links
- New backstack of videos
- Change the subscribers count to format using `NumberFormat`, for example some locales use `.`  others `,`, this handles it automatically (and the old method had a bug for leading zero, e.g. 4.82.125 instead of 4.082.125)
- Add string 'subscribers' for channels with more than 1 subscriber (plural)
- Popup player chooses the default format and resolution based on the new preference (format)
- Fix taskaffinity of the router activities
- Show title before loading, as it is available from the items already loaded
This commit is contained in:
Mauricio Colli 2017-04-09 14:34:00 -03:00
parent 9318bb5306
commit 746c2a15bf
39 changed files with 2026 additions and 1506 deletions

View file

@ -299,7 +299,6 @@ public abstract class AbstractPlayer implements StateInterface, SeekBar.OnSeekBa
return;
}
changeState(STATE_LOADING);
isPrepared = false;
qualityChanged = false;
@ -312,6 +311,7 @@ public abstract class AbstractPlayer implements StateInterface, SeekBar.OnSeekBa
if (videoStartPos > 0) simpleExoPlayer.seekTo(videoStartPos);
simpleExoPlayer.prepare(videoSource);
simpleExoPlayer.setPlayWhenReady(autoPlay);
changeState(STATE_LOADING);
}
public void destroy() {
@ -396,7 +396,6 @@ public abstract class AbstractPlayer implements StateInterface, SeekBar.OnSeekBa
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) playbackSeekBar.getThumb().setColorFilter(Color.RED, PorterDuff.Mode.SRC_IN);
animateView(endScreen, false, 0, 0);
animateView(controlsRoot, false, 0, 0);
loadingPanel.setBackgroundColor(Color.BLACK);
animateView(loadingPanel, true, 0, 0);
animateView(surfaceForeground, true, 100, 0);
@ -408,7 +407,12 @@ public abstract class AbstractPlayer implements StateInterface, SeekBar.OnSeekBa
if (!isProgressLoopRunning.get()) startProgressLoop();
showAndAnimateControl(-1, true);
loadingPanel.setVisibility(View.GONE);
animateView(controlsRoot, false, 500, DEFAULT_CONTROLS_HIDE_TIME, true);
animateView(controlsRoot, true, 500, 0, new Runnable() {
@Override
public void run() {
animateView(controlsRoot, false, 500, DEFAULT_CONTROLS_HIDE_TIME, true);
}
});
animateView(currentDisplaySeek, false, 200, 0);
}
@ -417,7 +421,6 @@ public abstract class AbstractPlayer implements StateInterface, SeekBar.OnSeekBa
if (DEBUG) Log.d(TAG, "onBuffering() called");
loadingPanel.setBackgroundColor(Color.TRANSPARENT);
animateView(loadingPanel, true, 500, 0);
animateView(controlsRoot, false, 0, 0, true);
}
@Override
@ -598,14 +601,12 @@ public abstract class AbstractPlayer implements StateInterface, SeekBar.OnSeekBa
if (DEBUG) Log.d(TAG, "onFastRewind() called");
seekBy(-FAST_FORWARD_REWIND_AMOUNT);
showAndAnimateControl(R.drawable.ic_action_av_fast_rewind, true);
animateView(controlsRoot, false, 100, 0);
}
public void onFastForward() {
if (DEBUG) Log.d(TAG, "onFastForward() called");
seekBy(FAST_FORWARD_REWIND_AMOUNT);
showAndAnimateControl(R.drawable.ic_action_av_fast_forward, true);
animateView(controlsRoot, false, 100, 0);
}
/*//////////////////////////////////////////////////////////////////////////

View file

@ -24,9 +24,10 @@ import android.widget.Toast;
import org.schabi.newpipe.ActivityCommunicator;
import org.schabi.newpipe.BuildConfig;
import org.schabi.newpipe.MainActivity;
import org.schabi.newpipe.R;
import org.schabi.newpipe.detail.VideoItemDetailActivity;
import org.schabi.newpipe.util.NavStack;
import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.util.Constants;
import java.io.IOException;
import java.util.Arrays;
@ -353,10 +354,11 @@ public class BackgroundPlayer extends Service /*implements MediaPlayer.OnPrepare
new Intent(ACTION_REWIND), PendingIntent.FLAG_UPDATE_CURRENT);
//build intent to return to video, on tapping notification
Intent openDetailViewIntent = new Intent(getApplicationContext(),
VideoItemDetailActivity.class);
openDetailViewIntent.putExtra(NavStack.SERVICE_ID, serviceId);
openDetailViewIntent.putExtra(NavStack.URL, webUrl);
Intent openDetailViewIntent = new Intent(getApplicationContext(), MainActivity.class);
openDetailViewIntent.putExtra(Constants.KEY_SERVICE_ID, serviceId);
openDetailViewIntent.putExtra(Constants.KEY_URL, webUrl);
openDetailViewIntent.putExtra(Constants.KEY_TITLE, title);
openDetailViewIntent.putExtra(Constants.KEY_LINK_TYPE, StreamingService.LinkType.STREAM);
openDetailViewIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent openDetailView = PendingIntent.getActivity(owner, noteID,
openDetailViewIntent, PendingIntent.FLAG_UPDATE_CURRENT);

View file

@ -24,7 +24,6 @@ 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;
@ -70,6 +69,7 @@ public class ExoPlayerActivity extends Activity {
return;
}
showSystemUi();
setContentView(R.layout.activity_exo_player);
playerImpl = new AbstractPlayerImpl();
playerImpl.setup(findViewById(android.R.id.content));
@ -88,7 +88,6 @@ public class ExoPlayerActivity extends Activity {
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);
}
@ -340,8 +339,7 @@ public class ExoPlayerActivity extends Activity {
public void onStopTrackingTouch(SeekBar seekBar) {
super.onStopTrackingTouch(seekBar);
if (playerImpl.wasPlaying()) {
hideSystemUi();
playerImpl.getControlsRoot().setVisibility(View.GONE);
animateView(playerImpl.getControlsRoot(), false, 100, 0);
}
}
@ -365,6 +363,13 @@ public class ExoPlayerActivity extends Activity {
public void onLoading() {
super.onLoading();
playPauseButton.setImageResource(R.drawable.ic_pause_white);
animateView(playPauseButton, false, 100, 0);
}
@Override
public void onBuffering() {
super.onBuffering();
animateView(playPauseButton, false, 100, 0);
}
@Override
@ -384,6 +389,7 @@ public class ExoPlayerActivity extends Activity {
public void onPlaying() {
super.onPlaying();
animateView(playPauseButton, true, 500, 0);
showSystemUi();
}
@Override

View file

@ -34,16 +34,17 @@ import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListene
import org.schabi.newpipe.ActivityCommunicator;
import org.schabi.newpipe.BuildConfig;
import org.schabi.newpipe.MainActivity;
import org.schabi.newpipe.R;
import org.schabi.newpipe.detail.VideoItemDetailActivity;
import org.schabi.newpipe.extractor.MediaFormat;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.stream_info.StreamExtractor;
import org.schabi.newpipe.extractor.stream_info.StreamInfo;
import org.schabi.newpipe.extractor.stream_info.VideoStream;
import org.schabi.newpipe.util.NavStack;
import org.schabi.newpipe.util.Constants;
import org.schabi.newpipe.util.ThemeHelper;
import org.schabi.newpipe.util.Utils;
import java.io.IOException;
import java.util.ArrayList;
@ -107,7 +108,7 @@ public class PopupVideoPlayer extends Service {
if (!playerImpl.isPlaying()) playerImpl.getPlayer().setPlayWhenReady(true);
if (imageLoader != null) imageLoader.clearMemoryCache();
if (intent.getStringExtra(NavStack.URL) != null) {
if (intent.getStringExtra(Constants.KEY_URL) != null) {
playerImpl.setStartedFromNewPipe(false);
Thread fetcher = new Thread(new FetcherRunnable(intent));
fetcher.start();
@ -158,7 +159,7 @@ public class PopupVideoPlayer extends Service {
playerImpl.onVideoPlayPause();
break;
case ACTION_OPEN_DETAIL:
onOpenDetail(PopupVideoPlayer.this, playerImpl.getVideoUrl());
onOpenDetail(PopupVideoPlayer.this, playerImpl.getVideoUrl(), playerImpl.getVideoTitle());
break;
case ACTION_REPEAT:
playerImpl.onRepeatClicked();
@ -266,12 +267,14 @@ public class PopupVideoPlayer extends Service {
stopSelf();
}
public void onOpenDetail(Context context, String videoUrl) {
public void onOpenDetail(Context context, String videoUrl, String videoTitle) {
if (DEBUG) Log.d(TAG, "onOpenDetail() called with: context = [" + context + "], videoUrl = [" + videoUrl + "]");
Intent i = new Intent(context, VideoItemDetailActivity.class);
i.putExtra(NavStack.SERVICE_ID, 0)
.putExtra(NavStack.URL, videoUrl)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Intent i = new Intent(context, MainActivity.class);
i.putExtra(Constants.KEY_SERVICE_ID, 0);
i.putExtra(Constants.KEY_URL, videoUrl);
i.putExtra(Constants.KEY_TITLE, videoTitle);
i.putExtra(Constants.KEY_LINK_TYPE, StreamingService.LinkType.STREAM);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
context.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
}
@ -510,8 +513,6 @@ public class PopupVideoPlayer extends Service {
private class FetcherRunnable implements Runnable {
private final Intent intent;
private final Handler mainHandler;
private final boolean printStreams = true;
FetcherRunnable(Intent intent) {
this.intent = intent;
@ -524,48 +525,22 @@ public class PopupVideoPlayer extends Service {
try {
StreamingService service = NewPipe.getService(0);
if (service == null) return;
streamExtractor = service.getExtractorInstance(intent.getStringExtra(NavStack.URL));
streamExtractor = service.getExtractorInstance(intent.getStringExtra(Constants.KEY_URL));
StreamInfo info = StreamInfo.getVideoInfo(streamExtractor);
String defaultResolution = playerImpl.getSharedPreferences().getString(
getResources().getString(R.string.default_resolution_key),
getResources().getString(R.string.default_resolution_value));
VideoStream chosen = null, secondary = null, fallback = null;
playerImpl.setVideoStreamsList(info.video_streams instanceof ArrayList
? (ArrayList<VideoStream>) info.video_streams
: new ArrayList<>(info.video_streams));
for (VideoStream item : info.video_streams) {
if (DEBUG && printStreams) {
Log.d(TAG, "FetcherRunnable.StreamExtractor: current Item"
+ ", item.resolution = " + item.resolution
+ ", item.format = " + item.format
+ ", item.url = " + item.url);
}
if (defaultResolution.equals(item.resolution)) {
if (item.format == MediaFormat.MPEG_4.id) {
chosen = item;
if (DEBUG) Log.d(TAG, "FetcherRunnable.StreamExtractor: CHOSEN item, item.resolution = " + item.resolution + ", item.format = " + item.format + ", item.url = " + item.url);
} else if (item.format == 2) secondary = item;
else fallback = item;
}
int defaultResolution = Utils.getPreferredResolution(PopupVideoPlayer.this, info.video_streams);
playerImpl.setSelectedIndexStream(defaultResolution);
if (DEBUG) {
Log.d(TAG, "FetcherRunnable.StreamExtractor: chosen = "
+ MediaFormat.getNameById(info.video_streams.get(defaultResolution).format) + " "
+ info.video_streams.get(defaultResolution).resolution + " > "
+ info.video_streams.get(defaultResolution).url);
}
int selectedIndexStream;
if (chosen != null) selectedIndexStream = info.video_streams.indexOf(chosen);
else if (secondary != null) selectedIndexStream = info.video_streams.indexOf(secondary);
else if (fallback != null) selectedIndexStream = info.video_streams.indexOf(fallback);
else selectedIndexStream = 0;
playerImpl.setSelectedIndexStream(selectedIndexStream);
if (DEBUG && printStreams) Log.d(TAG, "FetcherRunnable.StreamExtractor: chosen = " + chosen
+ "\n, secondary = " + secondary
+ "\n, fallback = " + fallback
+ "\n, info.video_streams.get(0).url = " + info.video_streams.get(0).url);
playerImpl.setVideoUrl(info.webpage_url);
playerImpl.setVideoTitle(info.title);
playerImpl.setChannelName(info.uploader);
@ -578,6 +553,8 @@ public class PopupVideoPlayer extends Service {
playerImpl.playVideo(playerImpl.getSelectedStreamUri(), true);
}
});
imageLoader.resume();
imageLoader.loadImage(info.thumbnail_url, displayImageOptions, new SimpleImageLoadingListener() {
@Override
public void onLoadingComplete(String imageUri, View view, final Bitmap loadedImage) {