Add resolution support up to 4k and 60 fps
- Up to 4k with 60 fps
- Not every device can play in that resolution and bitrate
- Add option to hide these high resolution greater than 1080p (2k,4k) for not clutter the menus
- Add a default resolution for the popup, wil be used when opening in popup mode from another app
This commit is contained in:
parent
e5bf98a741
commit
3b9a477499
17 changed files with 632 additions and 200 deletions
|
|
@ -413,4 +413,9 @@ public class ChannelFragment extends Fragment implements ChannelExtractorWorker.
|
|||
public void onError(int messageId) {
|
||||
Toast.makeText(activity, messageId, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUnrecoverableError(Exception exception) {
|
||||
activity.finish();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ class ActionBarHandler {
|
|||
VideoStream item = videoStreams.get(i);
|
||||
itemArray[i] = MediaFormat.getNameById(item.format) + " " + item.resolution;
|
||||
}
|
||||
int defaultResolution = Utils.getPreferredResolution(activity, videoStreams);
|
||||
int defaultResolution = Utils.getDefaultResolution(activity, videoStreams);
|
||||
|
||||
ArrayAdapter<String> itemAdapter = new ArrayAdapter<>(activity.getBaseContext(),
|
||||
android.R.layout.simple_spinner_dropdown_item, itemArray);
|
||||
|
|
|
|||
|
|
@ -88,6 +88,7 @@ public class VideoDetailFragment extends Fragment implements StreamExtractorWork
|
|||
|
||||
private AppCompatActivity activity;
|
||||
private OnItemSelectedListener onItemSelectedListener;
|
||||
private ArrayList<VideoStream> sortedStreamVideosList;
|
||||
private ActionBarHandler actionBarHandler;
|
||||
|
||||
private InfoItemBuilder infoItemBuilder = null;
|
||||
|
|
@ -98,8 +99,11 @@ public class VideoDetailFragment extends Fragment implements StreamExtractorWork
|
|||
private String videoUrl;
|
||||
private int serviceId = -1;
|
||||
|
||||
private AtomicBoolean wasLoading = new AtomicBoolean(false);
|
||||
private AtomicBoolean isLoading = new AtomicBoolean(false);
|
||||
private boolean needUpdate = false;
|
||||
private static final int RELATED_STREAMS_UPDATE_FLAG = 0x1;
|
||||
private static final int RESOLUTIONS_MENU_UPDATE_FLAG = 0x2;
|
||||
private int updateFlags = 0;
|
||||
|
||||
private boolean autoPlayEnabled;
|
||||
private boolean showRelatedStreams;
|
||||
|
|
@ -203,7 +207,8 @@ public class VideoDetailFragment extends Fragment implements StreamExtractorWork
|
|||
public void onViewCreated(View rootView, Bundle savedInstanceState) {
|
||||
initViews(rootView);
|
||||
initListeners();
|
||||
isLoading.set(true);
|
||||
selectAndLoadVideo(serviceId, videoUrl, videoTitle);
|
||||
wasLoading.set(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -251,19 +256,23 @@ public class VideoDetailFragment extends Fragment implements StreamExtractorWork
|
|||
|
||||
// Currently only used for enable/disable related videos
|
||||
// but can be extended for other live settings changes
|
||||
if (needUpdate) {
|
||||
if (relatedStreamsView != null) initRelatedVideos(currentStreamInfo);
|
||||
needUpdate = false;
|
||||
if (updateFlags != 0) {
|
||||
if (!isLoading.get()) {
|
||||
if ((updateFlags & RELATED_STREAMS_UPDATE_FLAG) != 0) initRelatedVideos(currentStreamInfo);
|
||||
if ((updateFlags & RESOLUTIONS_MENU_UPDATE_FLAG) != 0) setupActionBarHandler(currentStreamInfo);
|
||||
}
|
||||
updateFlags = 0;
|
||||
}
|
||||
|
||||
// Check if it was loading when the activity was stopped/paused,
|
||||
// because when this happen, the curExtractorWorker is cancelled
|
||||
if (isLoading.get()) selectAndLoadVideo(serviceId, videoUrl, videoTitle);
|
||||
if (wasLoading.getAndSet(false)) selectAndLoadVideo(serviceId, videoUrl, videoTitle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
wasLoading.set(curExtractorWorker.isRunning());
|
||||
if (curExtractorWorker != null && curExtractorWorker.isRunning()) curExtractorWorker.cancel();
|
||||
}
|
||||
|
||||
|
|
@ -301,7 +310,11 @@ public class VideoDetailFragment extends Fragment implements StreamExtractorWork
|
|||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
||||
if (key.equals(getString(R.string.show_next_video_key))) {
|
||||
showRelatedStreams = sharedPreferences.getBoolean(key, true);
|
||||
needUpdate = true;
|
||||
updateFlags |= RELATED_STREAMS_UPDATE_FLAG;
|
||||
} else if (key.equals(getString(R.string.preferred_video_format_key))
|
||||
|| key.equals(getString(R.string.default_resolution_key))
|
||||
|| key.equals(getString(R.string.show_higher_resolutions_key))) {
|
||||
updateFlags |= RESOLUTIONS_MENU_UPDATE_FLAG;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -480,7 +493,8 @@ public class VideoDetailFragment extends Fragment implements StreamExtractorWork
|
|||
activity.getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
|
||||
}
|
||||
|
||||
actionBarHandler.setupStreamList(info.video_streams);
|
||||
sortedStreamVideosList = Utils.getSortedStreamVideosList(activity, info.video_streams, info.video_only_streams, false);
|
||||
actionBarHandler.setupStreamList(sortedStreamVideosList);
|
||||
actionBarHandler.setOnShareListener(new ActionBarHandler.OnActionListener() {
|
||||
@Override
|
||||
public void onActionSelected(int selectedStreamId) {
|
||||
|
|
@ -517,15 +531,10 @@ public class VideoDetailFragment extends Fragment implements StreamExtractorWork
|
|||
}
|
||||
if (streamThumbnail != null) ActivityCommunicator.getCommunicator().backgroundPlayerThumbnail = streamThumbnail;
|
||||
|
||||
Intent i = new Intent(activity, PopupVideoPlayer.class);
|
||||
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);
|
||||
Intent mIntent = NavigationHelper.getOpenPlayerIntent(activity, PopupVideoPlayer.class, info, selectedStreamId);
|
||||
if (info.start_position > 0) mIntent.putExtra(AbstractPlayer.START_POSITION, info.start_position * 1000);
|
||||
activity.startService(mIntent);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -586,8 +595,8 @@ public class VideoDetailFragment extends Fragment implements StreamExtractorWork
|
|||
args.putString(DownloadDialog.FILE_SUFFIX_AUDIO, audioSuffix);
|
||||
}
|
||||
|
||||
if (info.video_streams != null) {
|
||||
VideoStream selectedStreamItem = info.video_streams.get(selectedStreamId);
|
||||
if (sortedStreamVideosList != null) {
|
||||
VideoStream selectedStreamItem = sortedStreamVideosList.get(selectedStreamId);
|
||||
String videoSuffix = "." + MediaFormat.getSuffixById(selectedStreamItem.format);
|
||||
args.putString(DownloadDialog.FILE_SUFFIX_VIDEO, videoSuffix);
|
||||
args.putString(DownloadDialog.VIDEO_URL, selectedStreamItem.url);
|
||||
|
|
@ -737,6 +746,7 @@ public class VideoDetailFragment extends Fragment implements StreamExtractorWork
|
|||
}
|
||||
|
||||
public void loadSelectedVideo() {
|
||||
isLoading.set(true);
|
||||
pushToStack(videoUrl, videoTitle);
|
||||
|
||||
if (curExtractorWorker != null && curExtractorWorker.isRunning()) curExtractorWorker.cancel();
|
||||
|
|
@ -753,6 +763,7 @@ public class VideoDetailFragment extends Fragment implements StreamExtractorWork
|
|||
if (scrollY < 30) animateView(videoTitleTextView, false, 200, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (videoTitleTextView == null) return;
|
||||
videoTitleTextView.setText(videoTitle != null ? videoTitle : "");
|
||||
animateView(videoTitleTextView, true, 400, null);
|
||||
}
|
||||
|
|
@ -775,12 +786,11 @@ public class VideoDetailFragment extends Fragment implements StreamExtractorWork
|
|||
|
||||
curExtractorWorker = new StreamExtractorWorker(activity, serviceId, videoUrl, this);
|
||||
curExtractorWorker.start();
|
||||
isLoading.set(true);
|
||||
}
|
||||
|
||||
public void playVideo(StreamInfo info) {
|
||||
// ----------- THE MAGIC MOMENT ---------------
|
||||
VideoStream selectedVideoStream = info.video_streams.get(actionBarHandler.getSelectedVideoStream());
|
||||
VideoStream selectedVideoStream = sortedStreamVideosList.get(actionBarHandler.getSelectedVideoStream());
|
||||
|
||||
if (PreferenceManager.getDefaultSharedPreferences(activity).getBoolean(this.getString(R.string.use_external_video_player_key), false)) {
|
||||
|
||||
|
|
@ -813,30 +823,24 @@ public class VideoDetailFragment extends Fragment implements StreamExtractorWork
|
|||
builder.create().show();
|
||||
}
|
||||
} else {
|
||||
Intent intent;
|
||||
Intent mIntent;
|
||||
boolean useOldPlayer = PreferenceManager.getDefaultSharedPreferences(activity)
|
||||
.getBoolean(getString(R.string.use_old_player_key), false)
|
||||
|| (Build.VERSION.SDK_INT < 16);
|
||||
if (!useOldPlayer) {
|
||||
// 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);
|
||||
mIntent = NavigationHelper.getOpenPlayerIntent(activity, ExoPlayerActivity.class, info, actionBarHandler.getSelectedVideoStream());
|
||||
if (info.start_position > 0) mIntent.putExtra(AbstractPlayer.START_POSITION, info.start_position * 1000);
|
||||
} else {
|
||||
// Internal Player
|
||||
intent = new Intent(activity, PlayVideoActivity.class)
|
||||
mIntent = 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);
|
||||
}
|
||||
//intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
startActivity(intent);
|
||||
startActivity(mIntent);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -928,6 +932,7 @@ public class VideoDetailFragment extends Fragment implements StreamExtractorWork
|
|||
|
||||
// Since newpipe is designed to work even if certain information is not available,
|
||||
// the UI has to react on missing information.
|
||||
videoTitle = info.title;
|
||||
videoTitleTextView.setText(info.title);
|
||||
if (!info.uploader.isEmpty()) uploaderTextView.setText(info.uploader);
|
||||
uploaderTextView.setVisibility(!info.uploader.isEmpty() ? View.VISIBLE : View.GONE);
|
||||
|
|
@ -1031,4 +1036,9 @@ public class VideoDetailFragment extends Fragment implements StreamExtractorWork
|
|||
thumbnailImageView.setImageDrawable(ContextCompat.getDrawable(activity, R.drawable.not_available_monkey));
|
||||
Toast.makeText(activity, R.string.content_not_available, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUnrecoverableError(Exception exception) {
|
||||
activity.finish();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue