mirror of
https://github.com/TeamNewPipe/NewPipe
synced 2024-12-23 08:30:44 +00:00
Merge remote-tracking branch 'upstream/master'
Conflicts: app/src/main/java/org/schabi/newpipe/VideoItemDetailFragment.java -- still used class-based passing app/src/main/java/org/schabi/newpipe/VideoItemListActivity.java -- just some whitespace
This commit is contained in:
commit
c32c267889
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
[![Translation Status](https://hosted.weblate.org/widgets/NewPipe/-/svg-badge.svg)](https://hosted.weblate.org/engage/NewPipe/)
|
[![Translation Status](https://hosted.weblate.org/widgets/NewPipe/-/svg-badge.svg)](https://hosted.weblate.org/engage/NewPipe/)
|
||||||
|
|
||||||
[![NewPipe](https://f-droid.org/repo/icons/org.schabi.newpipe.4.png)](http://dasochan.nl/newpipe/)
|
[![NewPipe](https://f-droid.org/repo/icons/org.schabi.newpipe.5.png)](http://dasochan.nl/newpipe/)
|
||||||
NewPipe: A free lightweight Youtube frontend for Android.
|
NewPipe: A free lightweight Youtube frontend for Android.
|
||||||
|
|
||||||
[![F-Droid](https://f-droid.org/wiki/images/0/06/F-Droid-button_get-it-on.png)](https://f-droid.org/repository/browse/?fdfilter=newpipe&fdid=org.schabi.newpipe)
|
[![F-Droid](https://f-droid.org/wiki/images/0/06/F-Droid-button_get-it-on.png)](https://f-droid.org/repository/browse/?fdfilter=newpipe&fdid=org.schabi.newpipe)
|
||||||
@ -21,10 +21,10 @@ NewPipe does not use any Google framework libraries, or the YouTube API. It only
|
|||||||
* Download videos (working, but it could be better)
|
* Download videos (working, but it could be better)
|
||||||
* Download audio only (working but, but it could be better)
|
* Download audio only (working but, but it could be better)
|
||||||
* Open a video in Kodi
|
* Open a video in Kodi
|
||||||
|
* Show Next/Related videos
|
||||||
|
|
||||||
## Coming Features
|
## Coming Features
|
||||||
|
|
||||||
* Shows Next/Related videos
|
|
||||||
* Improved Downloading
|
* Improved Downloading
|
||||||
* Bookmarks
|
* Bookmarks
|
||||||
* View history
|
* View history
|
||||||
|
@ -23,7 +23,7 @@ dependencies {
|
|||||||
compile fileTree(include: ['*.jar'], dir: 'libs')
|
compile fileTree(include: ['*.jar'], dir: 'libs')
|
||||||
compile 'com.android.support:appcompat-v7:23.1.0'
|
compile 'com.android.support:appcompat-v7:23.1.0'
|
||||||
compile 'com.android.support:support-v4:23.1.0'
|
compile 'com.android.support:support-v4:23.1.0'
|
||||||
|
compile 'com.android.support:design:23.1.0'
|
||||||
compile 'org.jsoup:jsoup:1.8.3'
|
compile 'org.jsoup:jsoup:1.8.3'
|
||||||
compile 'org.mozilla:rhino:1.7.7'
|
compile 'org.mozilla:rhino:1.7.7'
|
||||||
compile 'com.android.support:design:23.1.0'
|
|
||||||
}
|
}
|
||||||
|
@ -69,6 +69,7 @@ public class ActionBarHandler {
|
|||||||
public void setStreams(VideoInfo.VideoStream[] videoStreams, VideoInfo.AudioStream[] audioStreams) {
|
public void setStreams(VideoInfo.VideoStream[] videoStreams, VideoInfo.AudioStream[] audioStreams) {
|
||||||
this.videoStreams = videoStreams;
|
this.videoStreams = videoStreams;
|
||||||
selectedStream = 0;
|
selectedStream = 0;
|
||||||
|
defaultPreferences = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||||
String[] itemArray = new String[videoStreams.length];
|
String[] itemArray = new String[videoStreams.length];
|
||||||
String defaultResolution = defaultPreferences
|
String defaultResolution = defaultPreferences
|
||||||
.getString(activity.getString(R.string.defaultResolutionPreference),
|
.getString(activity.getString(R.string.defaultResolutionPreference),
|
||||||
@ -93,7 +94,7 @@ public class ActionBarHandler {
|
|||||||
|
|
||||||
// set audioStream
|
// set audioStream
|
||||||
audioStream = null;
|
audioStream = null;
|
||||||
String preferedFormat = PreferenceManager.getDefaultSharedPreferences(activity)
|
String preferedFormat = defaultPreferences
|
||||||
.getString(activity.getString(R.string.defaultAudioFormatPreference), "webm");
|
.getString(activity.getString(R.string.defaultAudioFormatPreference), "webm");
|
||||||
if(preferedFormat.equals("webm")) {
|
if(preferedFormat.equals("webm")) {
|
||||||
for(VideoInfo.AudioStream s : audioStreams) {
|
for(VideoInfo.AudioStream s : audioStreams) {
|
||||||
|
@ -143,6 +143,6 @@ public class VideoInfo {
|
|||||||
public VideoStream[] videoStreams = null;
|
public VideoStream[] videoStreams = null;
|
||||||
public AudioStream[] audioStreams = null;
|
public AudioStream[] audioStreams = null;
|
||||||
public VideoInfoItem nextVideo = null;
|
public VideoInfoItem nextVideo = null;
|
||||||
public Vector<VideoInfoItem> relatedVideos = null;
|
public VideoInfoItem[] relatedVideos = null;
|
||||||
public int videoAvailableStatus = VIDEO_AVAILABLE;
|
public int videoAvailableStatus = VIDEO_AVAILABLE;
|
||||||
}
|
}
|
@ -1,6 +1,8 @@
|
|||||||
package org.schabi.newpipe;
|
package org.schabi.newpipe;
|
||||||
|
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Christian Schabesberger on 26.08.15.
|
* Created by Christian Schabesberger on 26.08.15.
|
||||||
@ -22,7 +24,7 @@ import android.graphics.Bitmap;
|
|||||||
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class VideoInfoItem {
|
public class VideoInfoItem implements Parcelable {
|
||||||
public String id = "";
|
public String id = "";
|
||||||
public String title = "";
|
public String title = "";
|
||||||
public String uploader = "";
|
public String uploader = "";
|
||||||
@ -32,4 +34,51 @@ public class VideoInfoItem {
|
|||||||
public String webpage_url = "";
|
public String webpage_url = "";
|
||||||
public String upload_date = "";
|
public String upload_date = "";
|
||||||
public String view_count = "";
|
public String view_count = "";
|
||||||
|
|
||||||
|
protected VideoInfoItem(Parcel in) {
|
||||||
|
id = in.readString();
|
||||||
|
title = in.readString();
|
||||||
|
uploader = in.readString();
|
||||||
|
duration = in.readString();
|
||||||
|
thumbnail_url = in.readString();
|
||||||
|
thumbnail = (Bitmap) in.readValue(Bitmap.class.getClassLoader());
|
||||||
|
webpage_url = in.readString();
|
||||||
|
upload_date = in.readString();
|
||||||
|
view_count = in.readString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public VideoInfoItem() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(Parcel dest, int flags) {
|
||||||
|
dest.writeString(id);
|
||||||
|
dest.writeString(title);
|
||||||
|
dest.writeString(uploader);
|
||||||
|
dest.writeString(duration);
|
||||||
|
dest.writeString(thumbnail_url);
|
||||||
|
dest.writeValue(thumbnail);
|
||||||
|
dest.writeString(webpage_url);
|
||||||
|
dest.writeString(upload_date);
|
||||||
|
dest.writeString(view_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public static final Parcelable.Creator<VideoInfoItem> CREATOR = new Parcelable.Creator<VideoInfoItem>() {
|
||||||
|
@Override
|
||||||
|
public VideoInfoItem createFromParcel(Parcel in) {
|
||||||
|
return new VideoInfoItem(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VideoInfoItem[] newArray(int size) {
|
||||||
|
return new VideoInfoItem[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
@ -38,7 +38,6 @@ public class VideoItemDetailActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
private String videoUrl;
|
private String videoUrl;
|
||||||
private int currentStreamingService = -1;
|
private int currentStreamingService = -1;
|
||||||
private Menu menu = null;
|
|
||||||
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
@ -81,6 +81,7 @@ public class VideoItemDetailFragment extends Fragment {
|
|||||||
private Handler h = new Handler();
|
private Handler h = new Handler();
|
||||||
private Extractor extractor;
|
private Extractor extractor;
|
||||||
private String videoUrl;
|
private String videoUrl;
|
||||||
|
|
||||||
public ExtractorRunnable(String videoUrl, Extractor extractor, VideoItemDetailFragment f) {
|
public ExtractorRunnable(String videoUrl, Extractor extractor, VideoItemDetailFragment f) {
|
||||||
this.extractor = extractor;
|
this.extractor = extractor;
|
||||||
this.videoUrl = videoUrl;
|
this.videoUrl = videoUrl;
|
||||||
@ -95,18 +96,21 @@ public class VideoItemDetailFragment extends Fragment {
|
|||||||
BitmapFactory.decodeStream(
|
BitmapFactory.decodeStream(
|
||||||
new URL(videoInfo.thumbnail_url)
|
new URL(videoInfo.thumbnail_url)
|
||||||
.openConnection()
|
.openConnection()
|
||||||
.getInputStream()), SetThumbnailRunnable.VIDEO_THUMBNAIL));
|
.getInputStream()),
|
||||||
|
SetThumbnailRunnable.VIDEO_THUMBNAIL));
|
||||||
h.post(new SetThumbnailRunnable(
|
h.post(new SetThumbnailRunnable(
|
||||||
BitmapFactory.decodeStream(
|
BitmapFactory.decodeStream(
|
||||||
new URL(videoInfo.uploader_thumbnail_url)
|
new URL(videoInfo.uploader_thumbnail_url)
|
||||||
.openConnection()
|
.openConnection()
|
||||||
.getInputStream()), SetThumbnailRunnable.CHANNEL_THUMBNAIL));
|
.getInputStream()),
|
||||||
|
SetThumbnailRunnable.CHANNEL_THUMBNAIL));
|
||||||
if(showNextVideoItem) {
|
if(showNextVideoItem) {
|
||||||
h.post(new SetThumbnailRunnable(
|
h.post(new SetThumbnailRunnable(
|
||||||
BitmapFactory.decodeStream(
|
BitmapFactory.decodeStream(
|
||||||
new URL(videoInfo.nextVideo.thumbnail_url)
|
new URL(videoInfo.nextVideo.thumbnail_url)
|
||||||
.openConnection()
|
.openConnection()
|
||||||
.getInputStream()), SetThumbnailRunnable.NEXT_VIDEO_THUMBNAIL));
|
.getInputStream()),
|
||||||
|
SetThumbnailRunnable.NEXT_VIDEO_THUMBNAIL));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -175,29 +179,28 @@ public class VideoItemDetailFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void updateInfo(VideoInfo info) {
|
public void updateInfo(VideoInfo info) {
|
||||||
Activity a = getActivity();
|
|
||||||
currentVideoInfo = info;
|
currentVideoInfo = info;
|
||||||
try {
|
try {
|
||||||
VideoInfoItemViewCreator videoItemViewCreator =
|
VideoInfoItemViewCreator videoItemViewCreator =
|
||||||
new VideoInfoItemViewCreator(LayoutInflater.from(getActivity()));
|
new VideoInfoItemViewCreator(LayoutInflater.from(getActivity()));
|
||||||
|
|
||||||
ScrollView contentMainView = (ScrollView) a.findViewById(R.id.detailMainContent);
|
ScrollView contentMainView = (ScrollView) activity.findViewById(R.id.detailMainContent);
|
||||||
ProgressBar progressBar = (ProgressBar) a.findViewById(R.id.detailProgressBar);
|
ProgressBar progressBar = (ProgressBar) activity.findViewById(R.id.detailProgressBar);
|
||||||
TextView videoTitleView = (TextView) a.findViewById(R.id.detailVideoTitleView);
|
TextView videoTitleView = (TextView) activity.findViewById(R.id.detailVideoTitleView);
|
||||||
TextView uploaderView = (TextView) a.findViewById(R.id.detailUploaderView);
|
TextView uploaderView = (TextView) activity.findViewById(R.id.detailUploaderView);
|
||||||
TextView viewCountView = (TextView) a.findViewById(R.id.detailViewCountView);
|
TextView viewCountView = (TextView) activity.findViewById(R.id.detailViewCountView);
|
||||||
TextView thumbsUpView = (TextView) a.findViewById(R.id.detailThumbsUpCountView);
|
TextView thumbsUpView = (TextView) activity.findViewById(R.id.detailThumbsUpCountView);
|
||||||
TextView thumbsDownView = (TextView) a.findViewById(R.id.detailThumbsDownCountView);
|
TextView thumbsDownView = (TextView) activity.findViewById(R.id.detailThumbsDownCountView);
|
||||||
TextView uploadDateView = (TextView) a.findViewById(R.id.detailUploadDateView);
|
TextView uploadDateView = (TextView) activity.findViewById(R.id.detailUploadDateView);
|
||||||
TextView descriptionView = (TextView) a.findViewById(R.id.detailDescriptionView);
|
TextView descriptionView = (TextView) activity.findViewById(R.id.detailDescriptionView);
|
||||||
ImageView thumbnailView = (ImageView) a.findViewById(R.id.detailThumbnailView);
|
ImageView thumbnailView = (ImageView) activity.findViewById(R.id.detailThumbnailView);
|
||||||
FrameLayout nextVideoFrame = (FrameLayout) a.findViewById(R.id.detailNextVideoFrame);
|
FrameLayout nextVideoFrame = (FrameLayout) activity.findViewById(R.id.detailNextVideoFrame);
|
||||||
RelativeLayout nextVideoRootFrame =
|
RelativeLayout nextVideoRootFrame =
|
||||||
(RelativeLayout) a.findViewById(R.id.detailNextVideoRootLayout);
|
(RelativeLayout) activity.findViewById(R.id.detailNextVideoRootLayout);
|
||||||
View nextVideoView = videoItemViewCreator
|
View nextVideoView = videoItemViewCreator
|
||||||
.getViewByVideoInfoItem(null, nextVideoFrame, info.nextVideo);
|
.getViewByVideoInfoItem(null, nextVideoFrame, info.nextVideo);
|
||||||
nextVideoFrame.addView(nextVideoView);
|
nextVideoFrame.addView(nextVideoView);
|
||||||
Button nextVideoButton = (Button) a.findViewById(R.id.detailNextVideoButton);
|
Button nextVideoButton = (Button) activity.findViewById(R.id.detailNextVideoButton);
|
||||||
|
|
||||||
contentMainView.setVisibility(View.VISIBLE);
|
contentMainView.setVisibility(View.VISIBLE);
|
||||||
progressBar.setVisibility(View.GONE);
|
progressBar.setVisibility(View.GONE);
|
||||||
@ -209,10 +212,12 @@ public class VideoItemDetailFragment extends Fragment {
|
|||||||
case VideoInfo.VIDEO_AVAILABLE: {
|
case VideoInfo.VIDEO_AVAILABLE: {
|
||||||
videoTitleView.setText(info.title);
|
videoTitleView.setText(info.title);
|
||||||
uploaderView.setText(info.uploader);
|
uploaderView.setText(info.uploader);
|
||||||
viewCountView.setText(info.view_count + " " + a.getString(R.string.viewSufix));
|
viewCountView.setText(info.view_count
|
||||||
|
+ " " + activity.getString(R.string.viewSufix));
|
||||||
thumbsUpView.setText(info.like_count);
|
thumbsUpView.setText(info.like_count);
|
||||||
thumbsDownView.setText(info.dislike_count);
|
thumbsDownView.setText(info.dislike_count);
|
||||||
uploadDateView.setText(a.getString(R.string.uploadDatePrefix) + " " + info.upload_date);
|
uploadDateView.setText(
|
||||||
|
activity.getString(R.string.uploadDatePrefix) + " " + info.upload_date);
|
||||||
descriptionView.setText(Html.fromHtml(info.description));
|
descriptionView.setText(Html.fromHtml(info.description));
|
||||||
descriptionView.setMovementMethod(LinkMovementMethod.getInstance());
|
descriptionView.setMovementMethod(LinkMovementMethod.getInstance());
|
||||||
|
|
||||||
@ -235,9 +240,12 @@ public class VideoItemDetailFragment extends Fragment {
|
|||||||
nextVideoButton.setOnClickListener(new View.OnClickListener() {
|
nextVideoButton.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
Intent detailIntent = new Intent(getActivity(), VideoItemDetailActivity.class);
|
Intent detailIntent =
|
||||||
detailIntent.putExtra(VideoItemDetailFragment.ARG_ITEM_ID, currentVideoInfo.nextVideo.id);
|
new Intent(getActivity(), VideoItemDetailActivity.class);
|
||||||
detailIntent.putExtra(VideoItemDetailFragment.VIDEO_URL, currentVideoInfo.nextVideo.webpage_url);
|
detailIntent.putExtra(
|
||||||
|
VideoItemDetailFragment.ARG_ITEM_ID, currentVideoInfo.nextVideo.id);
|
||||||
|
detailIntent.putExtra(
|
||||||
|
VideoItemDetailFragment.VIDEO_URL, currentVideoInfo.nextVideo.webpage_url);
|
||||||
//todo: make id dynamic the following line is crap
|
//todo: make id dynamic the following line is crap
|
||||||
detailIntent.putExtra(VideoItemDetailFragment.STREAMING_SERVICE, 0);
|
detailIntent.putExtra(VideoItemDetailFragment.STREAMING_SERVICE, 0);
|
||||||
startActivity(detailIntent);
|
startActivity(detailIntent);
|
||||||
@ -245,10 +253,12 @@ public class VideoItemDetailFragment extends Fragment {
|
|||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case VideoInfo.VIDEO_UNAVAILABLE_GEMA:
|
case VideoInfo.VIDEO_UNAVAILABLE_GEMA:
|
||||||
thumbnailView.setImageBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.gruese_die_gema_unangebracht));
|
thumbnailView.setImageBitmap(BitmapFactory.decodeResource(
|
||||||
|
getResources(), R.drawable.gruese_die_gema_unangebracht));
|
||||||
break;
|
break;
|
||||||
case VideoInfo.VIDEO_UNAVAILABLE:
|
case VideoInfo.VIDEO_UNAVAILABLE:
|
||||||
thumbnailView.setImageBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.not_available_monkey));
|
thumbnailView.setImageBitmap(BitmapFactory.decodeResource(
|
||||||
|
getResources(), R.drawable.not_available_monkey));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Log.e(TAG, "Video Available Status not known.");
|
Log.e(TAG, "Video Available Status not known.");
|
||||||
@ -303,15 +313,19 @@ public class VideoItemDetailFragment extends Fragment {
|
|||||||
@Override
|
@Override
|
||||||
public void onActivityCreated(Bundle savedInstanceBundle) {
|
public void onActivityCreated(Bundle savedInstanceBundle) {
|
||||||
super.onActivityCreated(savedInstanceBundle);
|
super.onActivityCreated(savedInstanceBundle);
|
||||||
FloatingActionButton playVideoButton = (FloatingActionButton) getActivity().findViewById(R.id.playVideoButton);
|
FloatingActionButton playVideoButton =
|
||||||
|
(FloatingActionButton) getActivity().findViewById(R.id.playVideoButton);
|
||||||
|
|
||||||
|
// Sometimes when this fragment is not visible it still gets initiated
|
||||||
|
// then we must not try to access objects of this fragment.
|
||||||
|
// Otherwise the applications would crash.
|
||||||
if(playVideoButton != null) {
|
if(playVideoButton != null) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
StreamingService streamingService = ServiceList.getService(
|
StreamingService streamingService = ServiceList.getService(
|
||||||
getArguments().getInt(STREAMING_SERVICE));
|
getArguments().getInt(STREAMING_SERVICE));
|
||||||
extractorThread = new Thread(new ExtractorRunnable(
|
extractorThread = new Thread(new ExtractorRunnable(
|
||||||
getArguments().getString(VIDEO_URL), streamingService.getExtractorInstance(), this));
|
getArguments().getString(VIDEO_URL), streamingService.getExtractorInstance(), this));
|
||||||
|
|
||||||
autoPlayEnabled = getArguments().getBoolean(AUTO_PLAY);
|
autoPlayEnabled = getArguments().getBoolean(AUTO_PLAY);
|
||||||
extractorThread.start();
|
extractorThread.start();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -320,13 +334,15 @@ public class VideoItemDetailFragment extends Fragment {
|
|||||||
|
|
||||||
if (PreferenceManager.getDefaultSharedPreferences(getActivity())
|
if (PreferenceManager.getDefaultSharedPreferences(getActivity())
|
||||||
.getBoolean(getString(R.string.leftHandLayout), false) && checkIfLandscape()) {
|
.getBoolean(getString(R.string.leftHandLayout), false) && checkIfLandscape()) {
|
||||||
RelativeLayout.LayoutParams oldLayout = (RelativeLayout.LayoutParams) playVideoButton.getLayoutParams();
|
RelativeLayout.LayoutParams oldLayout =
|
||||||
|
(RelativeLayout.LayoutParams) playVideoButton.getLayoutParams();
|
||||||
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
|
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
|
||||||
RelativeLayout.LayoutParams.WRAP_CONTENT,
|
RelativeLayout.LayoutParams.WRAP_CONTENT,
|
||||||
RelativeLayout.LayoutParams.WRAP_CONTENT);
|
RelativeLayout.LayoutParams.WRAP_CONTENT);
|
||||||
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
|
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
|
||||||
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
|
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
|
||||||
layoutParams.setMargins(oldLayout.leftMargin, oldLayout.topMargin, oldLayout.rightMargin, oldLayout.bottomMargin);
|
layoutParams.setMargins(oldLayout.leftMargin, oldLayout.topMargin,
|
||||||
|
oldLayout.rightMargin, oldLayout.bottomMargin);
|
||||||
playVideoButton.setLayoutParams(layoutParams);
|
playVideoButton.setLayoutParams(layoutParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -336,6 +352,16 @@ public class VideoItemDetailFragment extends Fragment {
|
|||||||
actionBarHandler.playVideo();
|
actionBarHandler.playVideo();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Button similarVideosButton = (Button) activity.findViewById(R.id.detailShowSimilarButton);
|
||||||
|
similarVideosButton.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
Intent intent = new Intent(activity, VideoItemListActivity.class);
|
||||||
|
intent.putExtra(VideoItemListActivity.VIDEO_INFO_ITEMS, currentVideoInfo.relatedVideos);
|
||||||
|
activity.startActivity(intent);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,8 +3,12 @@ package org.schabi.newpipe;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
import android.support.v4.app.NavUtils;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.support.v7.widget.SearchView;
|
import android.support.v7.widget.SearchView;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
@ -12,6 +16,8 @@ import android.view.View;
|
|||||||
import android.view.inputmethod.InputMethodManager;
|
import android.view.inputmethod.InputMethodManager;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copyright (C) Christian Schabesberger 2015 <chris.schabesberger@mailbox.org>
|
* Copyright (C) Christian Schabesberger 2015 <chris.schabesberger@mailbox.org>
|
||||||
* VideoItemListActivity.java is part of NewPipe.
|
* VideoItemListActivity.java is part of NewPipe.
|
||||||
@ -34,9 +40,19 @@ public class VideoItemListActivity extends AppCompatActivity
|
|||||||
implements VideoItemListFragment.Callbacks {
|
implements VideoItemListFragment.Callbacks {
|
||||||
|
|
||||||
private static final String TAG = VideoItemListFragment.class.toString();
|
private static final String TAG = VideoItemListFragment.class.toString();
|
||||||
|
|
||||||
|
// arguments to give to this activity
|
||||||
|
public static final String VIDEO_INFO_ITEMS = "video_info_items";
|
||||||
|
|
||||||
|
// savedInstanceBundle arguments
|
||||||
private static final String QUERY = "query";
|
private static final String QUERY = "query";
|
||||||
private static final String STREAMING_SERVICE = "streaming_service";
|
private static final String STREAMING_SERVICE = "streaming_service";
|
||||||
|
|
||||||
|
// activity modes
|
||||||
|
private static final int SEARCH_MODE = 0;
|
||||||
|
private static final int PRESENT_VIDEOS_MODE = 1;
|
||||||
|
|
||||||
|
private int mode = SEARCH_MODE;
|
||||||
private int currentStreamingServiceId = -1;
|
private int currentStreamingServiceId = -1;
|
||||||
private String searchQuery = "";
|
private String searchQuery = "";
|
||||||
|
|
||||||
@ -95,7 +111,22 @@ public class VideoItemListActivity extends AppCompatActivity
|
|||||||
.findFragmentById(R.id.videoitem_list);
|
.findFragmentById(R.id.videoitem_list);
|
||||||
listFragment.setStreamingService(ServiceList.getService(currentStreamingServiceId));
|
listFragment.setStreamingService(ServiceList.getService(currentStreamingServiceId));
|
||||||
|
|
||||||
if(savedInstanceState != null) {
|
Bundle arguments = getIntent().getExtras();
|
||||||
|
|
||||||
|
if(arguments != null) {
|
||||||
|
Parcelable[] p = arguments.getParcelableArray(VIDEO_INFO_ITEMS);
|
||||||
|
if(p != null) {
|
||||||
|
mode = PRESENT_VIDEOS_MODE;
|
||||||
|
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
|
|
||||||
|
//todo: make this more efficient
|
||||||
|
listFragment.present(Arrays.copyOf(p, p.length, VideoInfoItem[].class));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(savedInstanceState != null
|
||||||
|
&& mode != PRESENT_VIDEOS_MODE) {
|
||||||
searchQuery = savedInstanceState.getString(QUERY);
|
searchQuery = savedInstanceState.getString(QUERY);
|
||||||
currentStreamingServiceId = savedInstanceState.getInt(STREAMING_SERVICE);
|
currentStreamingServiceId = savedInstanceState.getInt(STREAMING_SERVICE);
|
||||||
if(!searchQuery.isEmpty()) {
|
if(!searchQuery.isEmpty()) {
|
||||||
@ -118,15 +149,18 @@ public class VideoItemListActivity extends AppCompatActivity
|
|||||||
.setActivateOnItemClick(true);
|
.setActivateOnItemClick(true);
|
||||||
|
|
||||||
SearchView searchView = (SearchView)findViewById(R.id.searchViewTablet);
|
SearchView searchView = (SearchView)findViewById(R.id.searchViewTablet);
|
||||||
|
if(mode != PRESENT_VIDEOS_MODE) {
|
||||||
// Somehow the seticonifiedbydefault property set by the layout xml is not working on
|
// Somehow the seticonifiedbydefault property set by the layout xml is not working on
|
||||||
// the support version on SearchView, so it needs to be set programmatically.
|
// the support version on SearchView, so it needs to be set programmatically.
|
||||||
searchView.setIconifiedByDefault(false);
|
searchView.setIconifiedByDefault(false);
|
||||||
searchView.setIconified(false);
|
searchView.setIconified(false);
|
||||||
searchView.setOnQueryTextListener(new SearchVideoQueryListener());
|
searchView.setOnQueryTextListener(new SearchVideoQueryListener());
|
||||||
|
} else {
|
||||||
|
searchView.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SettingsActivity.initSettings(this);
|
SettingsActivity.initSettings(this);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -176,7 +210,8 @@ public class VideoItemListActivity extends AppCompatActivity
|
|||||||
super.onCreateOptionsMenu(menu);
|
super.onCreateOptionsMenu(menu);
|
||||||
this.menu = menu;
|
this.menu = menu;
|
||||||
MenuInflater inflater = getMenuInflater();
|
MenuInflater inflater = getMenuInflater();
|
||||||
if(findViewById(R.id.videoitem_detail_container) == null) {
|
if(mode != PRESENT_VIDEOS_MODE &&
|
||||||
|
findViewById(R.id.videoitem_detail_container) == null) {
|
||||||
inflater.inflate(R.menu.videoitem_list, menu);
|
inflater.inflate(R.menu.videoitem_list, menu);
|
||||||
MenuItem searchItem = menu.findItem(R.id.action_search);
|
MenuItem searchItem = menu.findItem(R.id.action_search);
|
||||||
SearchView searchView = (SearchView) searchItem.getActionView();
|
SearchView searchView = (SearchView) searchItem.getActionView();
|
||||||
@ -196,14 +231,23 @@ public class VideoItemListActivity extends AppCompatActivity
|
|||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
int id = item.getItemId();
|
int id = item.getItemId();
|
||||||
if(id == R.id.action_settings) {
|
|
||||||
|
switch(id) {
|
||||||
|
case android.R.id.home: {
|
||||||
|
Intent intent = new Intent(this, VideoItemListActivity.class);
|
||||||
|
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||||
|
NavUtils.navigateUpTo(this, intent);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case R.id.action_settings: {
|
||||||
Intent intent = new Intent(this, SettingsActivity.class);
|
Intent intent = new Intent(this, SettingsActivity.class);
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
} else {
|
return true;
|
||||||
|
}
|
||||||
|
default:
|
||||||
return videoFragment.onOptionsItemSelected(item) ||
|
return videoFragment.onOptionsItemSelected(item) ||
|
||||||
super.onOptionsItemSelected(item);
|
super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -13,6 +13,7 @@ import android.widget.ListView;
|
|||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
|
|
||||||
@ -41,6 +42,11 @@ public class VideoItemListFragment extends ListFragment {
|
|||||||
private StreamingService streamingService = null;
|
private StreamingService streamingService = null;
|
||||||
private VideoListAdapter videoListAdapter;
|
private VideoListAdapter videoListAdapter;
|
||||||
|
|
||||||
|
// activity modes
|
||||||
|
private static final int SEARCH_MODE = 0;
|
||||||
|
private static final int PRESENT_VIDEOS_MODE = 1;
|
||||||
|
|
||||||
|
private int mode = SEARCH_MODE;
|
||||||
private String query = "";
|
private String query = "";
|
||||||
private int lastPage = 0;
|
private int lastPage = 0;
|
||||||
|
|
||||||
@ -50,6 +56,7 @@ public class VideoItemListFragment extends ListFragment {
|
|||||||
private LoadThumbsRunnable loadThumbsRunnable = null;
|
private LoadThumbsRunnable loadThumbsRunnable = null;
|
||||||
// used to track down if results posted by threads ar still valid
|
// used to track down if results posted by threads ar still valid
|
||||||
private int currentRequestId = -1;
|
private int currentRequestId = -1;
|
||||||
|
private ListView list;
|
||||||
|
|
||||||
private class ResultRunnable implements Runnable {
|
private class ResultRunnable implements Runnable {
|
||||||
private SearchEngine.Result result;
|
private SearchEngine.Result result;
|
||||||
@ -154,7 +161,18 @@ public class VideoItemListFragment extends ListFragment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void present(VideoInfoItem[] videoList) {
|
||||||
|
mode = PRESENT_VIDEOS_MODE;
|
||||||
|
setListShown(true);
|
||||||
|
getListView().smoothScrollToPosition(0);
|
||||||
|
|
||||||
|
// inefficient like hell i know (welcome to the world of java)
|
||||||
|
//todo: make this more efficient
|
||||||
|
updateList(new Vector<>(Arrays.asList(videoList)));
|
||||||
|
}
|
||||||
|
|
||||||
public void search(String query) {
|
public void search(String query) {
|
||||||
|
mode = SEARCH_MODE;
|
||||||
this.query = query;
|
this.query = query;
|
||||||
this.lastPage = 1;
|
this.lastPage = 1;
|
||||||
videoListAdapter.clearVideoList();
|
videoListAdapter.clearVideoList();
|
||||||
@ -261,6 +279,7 @@ public class VideoItemListFragment extends ListFragment {
|
|||||||
@Override
|
@Override
|
||||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||||
super.onViewCreated(view, savedInstanceState);
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
list = getListView();
|
||||||
videoListAdapter = new VideoListAdapter(getActivity(), this);
|
videoListAdapter = new VideoListAdapter(getActivity(), this);
|
||||||
setListAdapter(videoListAdapter);
|
setListAdapter(videoListAdapter);
|
||||||
|
|
||||||
@ -272,8 +291,6 @@ public class VideoItemListFragment extends ListFragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getListView().setOnScrollListener(new AbsListView.OnScrollListener() {
|
getListView().setOnScrollListener(new AbsListView.OnScrollListener() {
|
||||||
private static final float OVERSCROLL_THRESHOLD_IN_PIXELS = 100;
|
|
||||||
private float downY;
|
|
||||||
long lastScrollDate = 0;
|
long lastScrollDate = 0;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -282,8 +299,8 @@ public class VideoItemListFragment extends ListFragment {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
|
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
|
||||||
ListView list = getListView();
|
if (mode != PRESENT_VIDEOS_MODE
|
||||||
if (list.getChildAt(0) != null
|
&& list.getChildAt(0) != null
|
||||||
&& list.getLastVisiblePosition() == list.getAdapter().getCount() - 1
|
&& list.getLastVisiblePosition() == list.getAdapter().getCount() - 1
|
||||||
&& list.getChildAt(list.getChildCount() - 1).getBottom() <= list.getHeight()) {
|
&& list.getChildAt(list.getChildCount() - 1).getBottom() <= list.getHeight()) {
|
||||||
long time = System.currentTimeMillis();
|
long time = System.currentTimeMillis();
|
||||||
|
@ -233,10 +233,8 @@ public class YoutubeExtractor implements Extractor {
|
|||||||
resolveResolutionString(itag)));
|
resolveResolutionString(itag)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
videoInfo.videoStreams = new VideoInfo.VideoStream[videoStreams.size()];
|
videoInfo.videoStreams =
|
||||||
for(int i = 0; i < videoStreams.size(); i++) {
|
videoStreams.toArray(new VideoInfo.VideoStream[videoStreams.size()]);
|
||||||
videoInfo.videoStreams[i] = videoStreams.get(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@ -310,15 +308,15 @@ public class YoutubeExtractor implements Extractor {
|
|||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
// related videos
|
// related videos
|
||||||
videoInfo.relatedVideos = new Vector<>();
|
Vector<VideoInfoItem> relatedVideos = new Vector<>();
|
||||||
for(Element li : doc.select("ul[id=\"watch-related\"]").first().children()) {
|
for(Element li : doc.select("ul[id=\"watch-related\"]").first().children()) {
|
||||||
// first check if we have a playlist. If so leave them out
|
// first check if we have a playlist. If so leave them out
|
||||||
if(li.select("a[class*=\"content-link\"]").first() != null) {
|
if(li.select("a[class*=\"content-link\"]").first() != null) {
|
||||||
videoInfo.relatedVideos.add(extractVideoInfoItem(li));
|
relatedVideos.add(extractVideoInfoItem(li));
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
videoInfo.relatedVideos = relatedVideos.toArray(new VideoInfoItem[relatedVideos.size()]);
|
||||||
return videoInfo;
|
return videoInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -390,11 +388,7 @@ public class YoutubeExtractor implements Extractor {
|
|||||||
} catch(Exception e) {
|
} catch(Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
VideoInfo.AudioStream[] output = new VideoInfo.AudioStream[audioStreams.size()];
|
return audioStreams.toArray(new VideoInfo.AudioStream[audioStreams.size()]);
|
||||||
for(int i = 0; i < output.length; i++) {
|
|
||||||
output[i] = audioStreams.get(i);
|
|
||||||
}
|
|
||||||
return output;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private VideoInfoItem extractVideoInfoItem(Element li) {
|
private VideoInfoItem extractVideoInfoItem(Element li) {
|
||||||
|
@ -188,10 +188,18 @@
|
|||||||
android:layout_alignParentLeft="true" />
|
android:layout_alignParentLeft="true" />
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<Button android:id="@+id/detailShowSimilarButton"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="6dp"
|
||||||
|
android:layout_marginRight="6dp"
|
||||||
|
android:layout_below="@id/detailNextVideoRootLayout"
|
||||||
|
android:text="@string/showSimilarVideosButtonText"/>
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="90dp"
|
android:layout_height="90dp"
|
||||||
android:layout_below="@id/detailNextVideoRootLayout"/>
|
android:layout_below="@id/detailShowSimilarButton"/>
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
@ -188,10 +188,18 @@
|
|||||||
android:layout_alignParentLeft="true" />
|
android:layout_alignParentLeft="true" />
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<Button android:id="@+id/detailShowSimilarButton"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="6dp"
|
||||||
|
android:layout_marginRight="6dp"
|
||||||
|
android:layout_below="@id/detailNextVideoRootLayout"
|
||||||
|
android:text="@string/showSimilarVideosButtonText"/>
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="90dp"
|
android:layout_height="90dp"
|
||||||
android:layout_below="@id/detailNextVideoRootLayout"/>
|
android:layout_below="@id/detailShowSimilarButton"/>
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
@ -185,13 +185,22 @@
|
|||||||
android:layout_alignParentLeft="true" />
|
android:layout_alignParentLeft="true" />
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<Button android:id="@+id/detailShowSimilarButton"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="6dp"
|
||||||
|
android:layout_marginRight="6dp"
|
||||||
|
android:layout_below="@id/detailNextVideoRootLayout"
|
||||||
|
android:text="@string/showSimilarVideosButtonText"/>
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="90dp"
|
android:layout_height="90dp"
|
||||||
android:layout_below="@id/detailNextVideoRootLayout"/>
|
android:layout_below="@id/detailShowSimilarButton"/>
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
|
||||||
<android.support.design.widget.FloatingActionButton
|
<android.support.design.widget.FloatingActionButton
|
||||||
android:id="@+id/playVideoButton"
|
android:id="@+id/playVideoButton"
|
||||||
android:layout_alignParentBottom="true"
|
android:layout_alignParentBottom="true"
|
||||||
|
@ -48,4 +48,5 @@
|
|||||||
<string name="nextVideoTitle">Nächstes Video</string>
|
<string name="nextVideoTitle">Nächstes Video</string>
|
||||||
<string name="showNextVideoTitle">Zeige \"Nächstes Video\" Auswahl.</string>
|
<string name="showNextVideoTitle">Zeige \"Nächstes Video\" Auswahl.</string>
|
||||||
<string name="urlNotSupportedText">Url wird nicht unterstützt.</string>
|
<string name="urlNotSupportedText">Url wird nicht unterstützt.</string>
|
||||||
|
<string name="showSimilarVideosButtonText">Ähnliche Videos</string>
|
||||||
</resources>
|
</resources>
|
@ -48,4 +48,5 @@
|
|||||||
<string name="nextVideoTitle">Next Video</string>
|
<string name="nextVideoTitle">Next Video</string>
|
||||||
<string name="showNextVideoTitle">Show \"Next video\" item.</string>
|
<string name="showNextVideoTitle">Show \"Next video\" item.</string>
|
||||||
<string name="urlNotSupportedText">Url not Supported.</string>
|
<string name="urlNotSupportedText">Url not Supported.</string>
|
||||||
|
<string name="showSimilarVideosButtonText">Similar Videos</string>
|
||||||
</resources>
|
</resources>
|
Loading…
Reference in New Issue
Block a user