Merge pull request #6 from chschtsch/master

.
This commit is contained in:
Greg 2015-11-30 23:42:54 +03:00
commit 53f8d09d31
64 changed files with 560 additions and 377 deletions

View File

@ -2,27 +2,29 @@
[![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.5.png)](http://dasochan.nl/newpipe/)
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)
A free lightweight YouTube frontend for Android
[![Screenshot 1](assets/screenshot_1.png)](assets/screenshot_1.png)
[![Screenshot 2](assets/screenshot_2.png)](assets/screenshot_2.png)
## Description ## Description
NewPipe does not use any Google framework libraries, or the YouTube API. It only parses the website in order to gain the information it needs. Therefore this app can be used on devices without G-services installed. Also NewPipe does not store data on the YouTube website (no login), and it's free software. NewPipe does not use any Google framework libraries, or the YouTube API. It only parses the website in order to gain the information it needs. Therefore this app can be used on devices without Google Services installed. Also, you don't need a YouTube account to use NewPipe, and it's FLOSS.
## Features ## Features
* Search videos * Search videos
* Display general information about a video * Display general information about a video
* Watch Youtube videos * Watch YouTube videos
* Listen to Youtube videos (audio only streaming) * Listen to YouTube videos (audio only streaming)
* Select the streaming player to watch the video with * Select the streaming player to watch the video with
* 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 it could be better)
* Open a video in Kodi * Open a video in Kodi
* Show Next/Related videos * Show Next/Related videos
* Search Youtube in a specific language * Search YouTube in a specific language
## Coming Features ## Coming Features
@ -37,10 +39,11 @@ NewPipe does not use any Google framework libraries, or the YouTube API. It only
* Search/Watch Playlists * Search/Watch Playlists
* ... and many more * ... and many more
### Multi service support ## Multiservice support
Generally NewPipe is designed to not only support YouTube, but many more streaming services. However, right now NewPipe is not stable enough to support more than only YouTube. But if all works as planned, NewPipe will get such support by the version 2.0. Although, right now NewPipe supports only YouTube, it's designed to support many more streaming services. The plan is, that NewPipe will get such support by the v2.0.
# Help is always welcome !!!
Whether it's about ideas, translation, design changes, code cleaning, or real heavy code changes. Help is always welcome.
## Help is always welcome!
Whether it's ideas, translation, design changes, code cleaning, or real heavy code changes, help is always welcome.
The more is done the better it gets! The more is done the better it gets!
Join our slack: http://invite.chschtsch.ml/

View File

@ -21,9 +21,9 @@ android {
dependencies { 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.1'
compile 'com.android.support:support-v4:23.1.0' compile 'com.android.support:support-v4:23.1.1'
compile 'com.android.support:design:23.1.0' compile 'com.android.support:design:23.1.1'
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'
} }

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="org.schabi.newpipe" > package="org.schabi.newpipe" >
<uses-permission android:name= "android.permission.INTERNET" /> <uses-permission android:name= "android.permission.INTERNET" />
@ -10,7 +11,8 @@
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
android:logo="@mipmap/ic_launcher" android:logo="@mipmap/ic_launcher"
android:label="@string/app_name" android:label="@string/app_name"
android:theme="@style/AppTheme" > android:theme="@style/AppTheme"
tools:ignore="AllowBackup">
<activity <activity
android:name=".VideoItemListActivity" android:name=".VideoItemListActivity"
android:label="@string/app_name" > android:label="@string/app_name" >
@ -67,9 +69,9 @@
</activity> </activity>
<activity android:name=".PlayVideoActivity" <activity android:name=".PlayVideoActivity"
android:configChanges="orientation|keyboardHidden|screenSize" android:configChanges="orientation|keyboardHidden|screenSize"
android:theme="@style/FullscreenTheme" android:theme="@style/VideoPlayerTheme"
android:parentActivityName=".VideoItemDetailActivity" android:parentActivityName=".VideoItemDetailActivity"
> tools:ignore="UnusedAttribute">
</activity> </activity>
<activity <activity
android:name=".SettingsActivity" android:name=".SettingsActivity"

View File

@ -6,7 +6,6 @@ import android.content.SharedPreferences;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBar;
import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
@ -36,7 +35,8 @@ import android.widget.ArrayAdapter;
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>. * along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
*/ */
public class ActionBarHandler {
class ActionBarHandler {
private static final String TAG = ActionBarHandler.class.toString(); private static final String TAG = ActionBarHandler.class.toString();
private static final String KORE_PACKET = "org.xbmc.kore"; private static final String KORE_PACKET = "org.xbmc.kore";
@ -47,10 +47,11 @@ public class ActionBarHandler {
private int selectedStream = -1; private int selectedStream = -1;
private String videoTitle = ""; private String videoTitle = "";
SharedPreferences defaultPreferences = null; private SharedPreferences defaultPreferences = null;
private int startPosition; private int startPosition;
class FormatItemSelectListener implements ActionBar.OnNavigationListener { @SuppressWarnings("deprecation")
private class FormatItemSelectListener implements ActionBar.OnNavigationListener {
@Override @Override
public boolean onNavigationItemSelected(int itemPosition, long itemId) { public boolean onNavigationItemSelected(int itemPosition, long itemId) {
selectFormatItem((int)itemId); selectFormatItem((int)itemId);
@ -62,11 +63,17 @@ public class ActionBarHandler {
this.activity = activity; this.activity = activity;
} }
@SuppressWarnings({"deprecation", "ConstantConditions"})
public void setupNavMenu(AppCompatActivity activity) { public void setupNavMenu(AppCompatActivity activity) {
this.activity = activity; this.activity = activity;
activity.getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_LIST); try {
activity.getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
} catch(NullPointerException e) {
e.printStackTrace();
}
} }
@SuppressWarnings("deprecation")
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;
@ -84,12 +91,14 @@ public class ActionBarHandler {
} }
} }
ArrayAdapter<String> itemAdapter = new ArrayAdapter<String>(activity.getBaseContext(), ArrayAdapter<String> itemAdapter = new ArrayAdapter<>(activity.getBaseContext(),
android.R.layout.simple_spinner_dropdown_item, itemArray); android.R.layout.simple_spinner_dropdown_item, itemArray);
if(activity != null) { if(activity != null) {
ActionBar ab = activity.getSupportActionBar(); ActionBar ab = activity.getSupportActionBar();
ab.setListNavigationCallbacks(itemAdapter assert ab != null : "Could not get actionbar";
,new FormatItemSelectListener()); ab.setListNavigationCallbacks(itemAdapter
, new FormatItemSelectListener());
ab.setSelectedNavigationItem(defaultResolutionPos); ab.setSelectedNavigationItem(defaultResolutionPos);
} }
@ -117,7 +126,7 @@ public class ActionBarHandler {
selectedStream = i; selectedStream = i;
} }
public boolean setupMenu(Menu menu, MenuInflater inflater) { public void setupMenu(Menu menu, MenuInflater inflater) {
// CAUTION set item properties programmatically otherwise it would not be accepted by // CAUTION set item properties programmatically otherwise it would not be accepted by
// appcompat itemsinflater.inflate(R.menu.videoitem_detail, menu); // appcompat itemsinflater.inflate(R.menu.videoitem_detail, menu);
@ -128,8 +137,6 @@ public class ActionBarHandler {
castItem.setVisible(defaultPreferences castItem.setVisible(defaultPreferences
.getBoolean(activity.getString(R.string.showPlayWidthKodiPreference), false)); .getBoolean(activity.getString(R.string.showPlayWidthKodiPreference), false));
return true;
} }
public boolean onItemSelected(MenuItem item) { public boolean onItemSelected(MenuItem item) {
@ -229,7 +236,7 @@ public class ActionBarHandler {
this.startPosition = startPositionSeconds; this.startPosition = startPositionSeconds;
} }
public void downloadVideo() { private void downloadVideo() {
if(!videoTitle.isEmpty()) { if(!videoTitle.isEmpty()) {
String videoSuffix = "." + MediaFormat.getSuffixById(videoStreams[selectedStream].format); String videoSuffix = "." + MediaFormat.getSuffixById(videoStreams[selectedStream].format);
String audioSuffix = "." + MediaFormat.getSuffixById(audioStream.format); String audioSuffix = "." + MediaFormat.getSuffixById(audioStream.format);
@ -245,7 +252,7 @@ public class ActionBarHandler {
} }
} }
public void openInBrowser() { private void openInBrowser() {
if(!videoTitle.isEmpty()) { if(!videoTitle.isEmpty()) {
Intent intent = new Intent(); Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW); intent.setAction(Intent.ACTION_VIEW);
@ -255,7 +262,7 @@ public class ActionBarHandler {
} }
} }
public void playWithKodi() { private void playWithKodi() {
if(!videoTitle.isEmpty()) { if(!videoTitle.isEmpty()) {
try { try {
Intent intent = new Intent(Intent.ACTION_VIEW); Intent intent = new Intent(Intent.ACTION_VIEW);
@ -286,7 +293,7 @@ public class ActionBarHandler {
} }
} }
public void playAudio() { private void playAudio() {
Intent intent = new Intent(); Intent intent = new Intent();
try { try {
intent.setAction(Intent.ACTION_VIEW); intent.setAction(Intent.ACTION_VIEW);

View File

@ -8,6 +8,7 @@ import android.content.SharedPreferences;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment; import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog;
import android.util.Log; import android.util.Log;
@ -42,8 +43,9 @@ public class DownloadDialog extends DialogFragment {
public static final String FILE_SUFFIX_VIDEO = "file_suffix_video"; public static final String FILE_SUFFIX_VIDEO = "file_suffix_video";
public static final String AUDIO_URL = "audio_url"; public static final String AUDIO_URL = "audio_url";
public static final String VIDEO_URL = "video_url"; public static final String VIDEO_URL = "video_url";
Bundle arguments; private Bundle arguments;
@NonNull
@Override @Override
public Dialog onCreateDialog(Bundle savedInstanceState) { public Dialog onCreateDialog(Bundle savedInstanceState) {
arguments = getArguments(); arguments = getArguments();

View File

@ -50,8 +50,8 @@ public class Downloader {
return ret; return ret;
} }
/**Common functionality between download(String url) and download(String url, String language)*/ /**Common functionality between download(String url) and download(String url, String language)*/
private static String dl(HttpURLConnection con) { private static String dl(HttpURLConnection con) throws IOException {
StringBuffer response = new StringBuffer(); StringBuilder response = new StringBuilder();
try { try {
con.setRequestMethod("GET"); con.setRequestMethod("GET");
@ -71,9 +71,7 @@ public class Downloader {
uhe.printStackTrace(); uhe.printStackTrace();
//Toast.makeText(getActivity(), uhe.getMessage(), Toast.LENGTH_LONG).show(); //Toast.makeText(getActivity(), uhe.getMessage(), Toast.LENGTH_LONG).show();
} }
catch (Exception e) {
e.printStackTrace();
}
return response.toString(); return response.toString();
} }

View File

@ -23,6 +23,7 @@ package org.schabi.newpipe;
*/ */
/**Static data about various media formats support by Newpipe, eg mime type, extension*/ /**Static data about various media formats support by Newpipe, eg mime type, extension*/
public enum MediaFormat { public enum MediaFormat {
// id name suffix mime type // id name suffix mime type
MPEG_4 (0x0, "MPEG-4", "mp4", "video/mp4"), MPEG_4 (0x0, "MPEG-4", "mp4", "video/mp4"),
@ -32,7 +33,9 @@ public enum MediaFormat {
WEBMA (0x4, "WebM", "webm", "audio/webm"); WEBMA (0x4, "WebM", "webm", "audio/webm");
public final int id; public final int id;
@SuppressWarnings("WeakerAccess")
public final String name; public final String name;
@SuppressWarnings("WeakerAccess")
public final String suffix; public final String suffix;
public final String mimeType; public final String mimeType;

View File

@ -84,6 +84,7 @@ public class PlayVideoActivity extends AppCompatActivity {
hasSoftKeys = checkIfHasSoftKeys(); hasSoftKeys = checkIfHasSoftKeys();
actionBar = getSupportActionBar(); actionBar = getSupportActionBar();
assert actionBar != null;
actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setDisplayHomeAsUpEnabled(true);
Intent intent = getIntent(); Intent intent = getIntent();
if(mediaController == null) { if(mediaController == null) {
@ -291,11 +292,9 @@ public class PlayVideoActivity extends AppCompatActivity {
} }
private boolean checkIfHasSoftKeys(){ private boolean checkIfHasSoftKeys(){
if(Build.VERSION.SDK_INT >= 17) { return Build.VERSION.SDK_INT >= 17 ||
return getNavigationBarHeight() != 0 || getNavigationBarWidth() != 0; getNavigationBarHeight() != 0 ||
} else { getNavigationBarWidth() != 0;
return true;
}
} }
private int getNavigationBarHeight() { private int getNavigationBarHeight() {
@ -332,7 +331,7 @@ public class PlayVideoActivity extends AppCompatActivity {
} }
} }
public boolean checkIfLandscape() { private boolean checkIfLandscape() {
DisplayMetrics displayMetrics = new DisplayMetrics(); DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
return displayMetrics.heightPixels < displayMetrics.widthPixels; return displayMetrics.heightPixels < displayMetrics.widthPixels;
@ -348,6 +347,6 @@ public class PlayVideoActivity extends AppCompatActivity {
} }
SharedPreferences.Editor editor = prefs.edit(); SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean(PREF_IS_LANDSCAPE, isLandscape); editor.putBoolean(PREF_IS_LANDSCAPE, isLandscape);
editor.commit(); editor.apply();
} }
} }

View File

@ -9,10 +9,9 @@ import android.preference.PreferenceActivity;
import android.preference.PreferenceFragment; import android.preference.PreferenceFragment;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.support.annotation.LayoutRes; import android.support.annotation.LayoutRes;
import android.support.annotation.Nullable; import android.support.annotation.NonNull;
import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatDelegate; import android.support.v7.app.AppCompatDelegate;
import android.support.v7.widget.Toolbar;
import android.view.MenuInflater; import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
@ -70,14 +69,11 @@ public class SettingsActivity extends PreferenceActivity {
getDelegate().onPostCreate(savedInstanceState); getDelegate().onPostCreate(savedInstanceState);
} }
public ActionBar getSupportActionBar() { private ActionBar getSupportActionBar() {
return getDelegate().getSupportActionBar(); return getDelegate().getSupportActionBar();
} }
public void setSupportActionBar(@Nullable Toolbar toolbar) { @NonNull
getDelegate().setSupportActionBar(toolbar);
}
@Override @Override
public MenuInflater getMenuInflater() { public MenuInflater getMenuInflater() {
return getDelegate().getMenuInflater(); return getDelegate().getMenuInflater();
@ -162,7 +158,7 @@ public class SettingsActivity extends PreferenceActivity {
Environment.getExternalStorageDirectory().getAbsolutePath() + "/NewPipe"; Environment.getExternalStorageDirectory().getAbsolutePath() + "/NewPipe";
spEditor.putString(context.getString(R.string.downloadPathPreference) spEditor.putString(context.getString(R.string.downloadPathPreference)
, newPipeDownloadStorage); , newPipeDownloadStorage);
spEditor.commit(); spEditor.apply();
} }
} }
} }

View File

@ -2,6 +2,8 @@ package org.schabi.newpipe;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import org.schabi.newpipe.services.AbstractVideoInfo;
import java.util.List; import java.util.List;
/** /**
@ -56,6 +58,7 @@ public class VideoInfo extends AbstractVideoInfo {
/**Creates a new VideoInfo object from an existing AbstractVideoInfo. /**Creates a new VideoInfo object from an existing AbstractVideoInfo.
* All the shared properties are copied to the new VideoInfo.*/ * All the shared properties are copied to the new VideoInfo.*/
@SuppressWarnings("WeakerAccess")
public VideoInfo(AbstractVideoInfo avi) { public VideoInfo(AbstractVideoInfo avi) {
this.id = avi.id; this.id = avi.id;
this.title = avi.title; this.title = avi.title;
@ -74,7 +77,6 @@ public class VideoInfo extends AbstractVideoInfo {
int seconds = Integer.parseInt(dur.substring(dur.indexOf(":")+1, dur.length())); int seconds = Integer.parseInt(dur.substring(dur.indexOf(":")+1, dur.length()));
this.duration = (minutes*60)+seconds; this.duration = (minutes*60)+seconds;
} }
} }
public static class VideoStream { public static class VideoStream {

View File

@ -26,10 +26,10 @@ import android.widget.TextView;
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>. * along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
*/ */
public class VideoInfoItemViewCreator { class VideoInfoItemViewCreator {
private static final String TAG = VideoInfoItemViewCreator.class.toString(); private static final String TAG = VideoInfoItemViewCreator.class.toString();
LayoutInflater inflater; private final LayoutInflater inflater;
public VideoInfoItemViewCreator(LayoutInflater inflater) { public VideoInfoItemViewCreator(LayoutInflater inflater) {
this.inflater = inflater; this.inflater = inflater;
@ -57,12 +57,12 @@ public class VideoInfoItemViewCreator {
} }
holder.itemVideoTitleView.setText(info.title); holder.itemVideoTitleView.setText(info.title);
holder.itemUploaderView.setText(info.uploader); holder.itemUploaderView.setText(info.uploader);
holder.itemDurationView.setText(""+info.duration); holder.itemDurationView.setText(info.duration);
if(!info.upload_date.isEmpty()) { if(!info.upload_date.isEmpty()) {
holder.itemUploadDateView.setText(info.upload_date); holder.itemUploadDateView.setText(info.upload_date);
} else { } else {
//tweak if necessary: This is a hack to prevent having white space in the layout :P //tweak if necessary: This is a hack to prevent having white space in the layout :P
holder.itemUploadDateView.setText(""+info.view_count); holder.itemUploadDateView.setText(String.format("%d", info.view_count));
} }
return convertView; return convertView;

View File

@ -10,7 +10,6 @@ import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.widget.Toast; import android.widget.Toast;
import org.schabi.newpipe.services.Extractor;
import org.schabi.newpipe.services.ServiceList; import org.schabi.newpipe.services.ServiceList;
import org.schabi.newpipe.services.StreamingService; import org.schabi.newpipe.services.StreamingService;
@ -37,7 +36,7 @@ public class VideoItemDetailActivity extends AppCompatActivity {
private static final String TAG = VideoItemDetailActivity.class.toString(); private static final String TAG = VideoItemDetailActivity.class.toString();
VideoItemDetailFragment fragment; private VideoItemDetailFragment fragment;
private String videoUrl; private String videoUrl;
private int currentStreamingService = -1; private int currentStreamingService = -1;
@ -47,7 +46,13 @@ public class VideoItemDetailActivity extends AppCompatActivity {
setContentView(R.layout.activity_videoitem_detail); setContentView(R.layout.activity_videoitem_detail);
// Show the Up button in the action bar. // Show the Up button in the action bar.
getSupportActionBar().setDisplayHomeAsUpEnabled(true); try {
//noinspection ConstantConditions
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
} catch(Exception e) {
Log.d(TAG, "Could not get SupportActionBar");
e.printStackTrace();
}
// savedInstanceState is non-null when there is fragment state // savedInstanceState is non-null when there is fragment state
// saved from previous configurations of this activity // saved from previous configurations of this activity
@ -64,14 +69,13 @@ public class VideoItemDetailActivity extends AppCompatActivity {
// this means the video was called though another app // this means the video was called though another app
if (getIntent().getData() != null) { if (getIntent().getData() != null) {
videoUrl = getIntent().getData().toString(); videoUrl = getIntent().getData().toString();
//Log.i(TAG, "video URL passed:\"" + videoUrl + "\"");
StreamingService[] serviceList = ServiceList.getServices(); StreamingService[] serviceList = ServiceList.getServices();
Extractor extractor = null; //VideoExtractor videoExtractor = null;
for (int i = 0; i < serviceList.length; i++) { for (int i = 0; i < serviceList.length; i++) {
if (serviceList[i].acceptUrl(videoUrl)) { if (serviceList[i].acceptUrl(videoUrl)) {
arguments.putInt(VideoItemDetailFragment.STREAMING_SERVICE, i); arguments.putInt(VideoItemDetailFragment.STREAMING_SERVICE, i);
currentStreamingService = i; currentStreamingService = i;
//extractor = ServiceList.getService(i).getExtractorInstance(); //videoExtractor = ServiceList.getService(i).getExtractorInstance();
break; break;
} }
} }
@ -80,7 +84,7 @@ public class VideoItemDetailActivity extends AppCompatActivity {
.show(); .show();
} }
//arguments.putString(VideoItemDetailFragment.VIDEO_URL, //arguments.putString(VideoItemDetailFragment.VIDEO_URL,
// extractor.getVideoUrl(extractor.getVideoId(videoUrl)));//cleans URL // videoExtractor.getVideoUrl(videoExtractor.getVideoId(videoUrl)));//cleans URL
arguments.putString(VideoItemDetailFragment.VIDEO_URL, videoUrl); arguments.putString(VideoItemDetailFragment.VIDEO_URL, videoUrl);
arguments.putBoolean(VideoItemDetailFragment.AUTO_PLAY, arguments.putBoolean(VideoItemDetailFragment.AUTO_PLAY,

View File

@ -1,8 +1,10 @@
package org.schabi.newpipe; package org.schabi.newpipe;
import android.annotation.SuppressLint;
import android.app.Activity; import android.app.Activity;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.os.Bundle; import android.os.Bundle;
@ -39,7 +41,7 @@ import java.util.Date;
import java.util.Locale; import java.util.Locale;
import java.util.Vector; import java.util.Vector;
import org.schabi.newpipe.services.Extractor; import org.schabi.newpipe.services.VideoExtractor;
import org.schabi.newpipe.services.ServiceList; import org.schabi.newpipe.services.ServiceList;
import org.schabi.newpipe.services.StreamingService; import org.schabi.newpipe.services.StreamingService;
@ -79,7 +81,6 @@ public class VideoItemDetailFragment extends Fragment {
private ActionBarHandler actionBarHandler; private ActionBarHandler actionBarHandler;
private boolean autoPlayEnabled = false; private boolean autoPlayEnabled = false;
private Thread extractorThread = null;
private VideoInfo currentVideoInfo = null; private VideoInfo currentVideoInfo = null;
private boolean showNextVideoItem = false; private boolean showNextVideoItem = false;
@ -89,21 +90,21 @@ public class VideoItemDetailFragment extends Fragment {
private OnInvokeCreateOptionsMenuListener onInvokeCreateOptionsMenuListener = null; private OnInvokeCreateOptionsMenuListener onInvokeCreateOptionsMenuListener = null;
private class ExtractorRunnable implements Runnable { private class VideoExtractorRunnable implements Runnable {
private Handler h = new Handler(); private final Handler h = new Handler();
private Extractor extractor; private VideoExtractor videoExtractor;
private StreamingService service; private final StreamingService service;
private String videoUrl; private final String videoUrl;
public ExtractorRunnable(String videoUrl, StreamingService service, VideoItemDetailFragment f) { public VideoExtractorRunnable(String videoUrl, StreamingService service) {
this.service = service; this.service = service;
this.videoUrl = videoUrl; this.videoUrl = videoUrl;
} }
@Override @Override
public void run() { public void run() {
try { try {
this.extractor = service.getExtractorInstance(videoUrl); this.videoExtractor = service.getExtractorInstance(videoUrl);
VideoInfo videoInfo = extractor.getVideoInfo(); VideoInfo videoInfo = videoExtractor.getVideoInfo();
h.post(new VideoResultReturnedRunnable(videoInfo)); h.post(new VideoResultReturnedRunnable(videoInfo));
if (videoInfo.videoAvailableStatus == VideoInfo.VIDEO_AVAILABLE) { if (videoInfo.videoAvailableStatus == VideoInfo.VIDEO_AVAILABLE) {
h.post(new SetThumbnailRunnable( h.post(new SetThumbnailRunnable(
@ -135,7 +136,7 @@ public class VideoItemDetailFragment extends Fragment {
} }
private class VideoResultReturnedRunnable implements Runnable { private class VideoResultReturnedRunnable implements Runnable {
private VideoInfo videoInfo; private final VideoInfo videoInfo;
public VideoResultReturnedRunnable(VideoInfo videoInfo) { public VideoResultReturnedRunnable(VideoInfo videoInfo) {
this.videoInfo = videoInfo; this.videoInfo = videoInfo;
} }
@ -151,8 +152,8 @@ public class VideoItemDetailFragment extends Fragment {
public static final int VIDEO_THUMBNAIL = 1; public static final int VIDEO_THUMBNAIL = 1;
public static final int CHANNEL_THUMBNAIL = 2; public static final int CHANNEL_THUMBNAIL = 2;
public static final int NEXT_VIDEO_THUMBNAIL = 3; public static final int NEXT_VIDEO_THUMBNAIL = 3;
private Bitmap thumbnail; private final Bitmap thumbnail;
private int thumbnailId; private final int thumbnailId;
public SetThumbnailRunnable(Bitmap thumbnail, int id) { public SetThumbnailRunnable(Bitmap thumbnail, int id) {
this.thumbnail = thumbnail; this.thumbnail = thumbnail;
this.thumbnailId = id; this.thumbnailId = id;
@ -163,9 +164,9 @@ public class VideoItemDetailFragment extends Fragment {
} }
} }
public void updateThumbnail(Bitmap thumbnail, int id) { private void updateThumbnail(Bitmap thumbnail, int id) {
Activity a = getActivity(); Activity a = getActivity();
ImageView thumbnailView = null; ImageView thumbnailView;
try { try {
switch (id) { switch (id) {
case SetThumbnailRunnable.VIDEO_THUMBNAIL: case SetThumbnailRunnable.VIDEO_THUMBNAIL:
@ -194,8 +195,9 @@ public class VideoItemDetailFragment extends Fragment {
} }
} }
public void updateInfo(VideoInfo info) { private void updateInfo(VideoInfo info) {
currentVideoInfo = info; currentVideoInfo = info;
Resources res = activity.getResources();
try { try {
VideoInfoItemViewCreator videoItemViewCreator = VideoInfoItemViewCreator videoItemViewCreator =
new VideoInfoItemViewCreator(LayoutInflater.from(getActivity())); new VideoInfoItemViewCreator(LayoutInflater.from(getActivity()));
@ -234,13 +236,17 @@ public class VideoItemDetailFragment extends Fragment {
Locale locale = getPreferredLocale(); Locale locale = getPreferredLocale();
NumberFormat nf = NumberFormat.getInstance(locale); NumberFormat nf = NumberFormat.getInstance(locale);
String localisedViewCount = nf.format(info.view_count); String localisedViewCount = nf.format(info.view_count);
viewCountView.setText(localisedViewCount viewCountView.setText(
+ " " + activity.getString(R.string.viewSufix)); String.format(
res.getString(R.string.viewCountText), localisedViewCount));
/*viewCountView.setText(localisedViewCount
+ " " + activity.getString(R.string.viewSufix)); */
thumbsUpView.setText(nf.format(info.like_count)); thumbsUpView.setText(nf.format(info.like_count));
thumbsDownView.setText(nf.format(info.dislike_count)); thumbsDownView.setText(nf.format(info.dislike_count));
@SuppressLint("SimpleDateFormat")
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
Date datum = null; Date datum = null;
try { try {
@ -253,7 +259,7 @@ public class VideoItemDetailFragment extends Fragment {
String localisedDate = df.format(datum); String localisedDate = df.format(datum);
uploadDateView.setText( uploadDateView.setText(
activity.getString(R.string.uploadDatePrefix) + " " + localisedDate); String.format(res.getString(R.string.uploadDateText), localisedDate));
descriptionView.setText(Html.fromHtml(info.description)); descriptionView.setText(Html.fromHtml(info.description));
descriptionView.setMovementMethod(LinkMovementMethod.getInstance()); descriptionView.setMovementMethod(LinkMovementMethod.getInstance());
@ -323,8 +329,6 @@ public class VideoItemDetailFragment extends Fragment {
* Mandatory empty constructor for the fragment manager to instantiate the * Mandatory empty constructor for the fragment manager to instantiate the
* fragment (e.g. upon screen orientation changes). * fragment (e.g. upon screen orientation changes).
*/ */
public VideoItemDetailFragment() {
}
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
@ -360,11 +364,11 @@ public class VideoItemDetailFragment extends Fragment {
try { try {
StreamingService streamingService = ServiceList.getService( StreamingService streamingService = ServiceList.getService(
getArguments().getInt(STREAMING_SERVICE)); getArguments().getInt(STREAMING_SERVICE));
extractorThread = new Thread(new ExtractorRunnable( Thread videoExtractorThread = new Thread(new VideoExtractorRunnable(
getArguments().getString(VIDEO_URL), streamingService, this)); getArguments().getString(VIDEO_URL), streamingService));
autoPlayEnabled = getArguments().getBoolean(AUTO_PLAY); autoPlayEnabled = getArguments().getBoolean(AUTO_PLAY);
extractorThread.start(); videoExtractorThread.start();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -409,10 +413,12 @@ public class VideoItemDetailFragment extends Fragment {
/**Returns the java.util.Locale object which corresponds to the locale set in NewPipe's preferences. /**Returns the java.util.Locale object which corresponds to the locale set in NewPipe's preferences.
* Currently not affected by the device's locale.*/ * Currently not affected by the device's locale.*/
public Locale getPreferredLocale() { private Locale getPreferredLocale() {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
String languageKey = getContext().getString(R.string.searchLanguage); String languageKey = getContext().getString(R.string.searchLanguage);
String languageCode = "en";//i know the following line defaults languageCode to "en", but java is picky about uninitialised values //i know the following line defaults languageCode to "en", but java is picky about uninitialised values
// Schabi: well lint tels me the value is redundant. I'll suppress it for now.
@SuppressWarnings("UnusedAssignment") String languageCode = "en";
languageCode = sp.getString(languageKey, "en"); languageCode = sp.getString(languageKey, "en");
if(languageCode.length() == 2) { if(languageCode.length() == 2) {
@ -426,7 +432,7 @@ public class VideoItemDetailFragment extends Fragment {
return Locale.getDefault(); return Locale.getDefault();
} }
public boolean checkIfLandscape() { private boolean checkIfLandscape() {
DisplayMetrics displayMetrics = new DisplayMetrics(); DisplayMetrics displayMetrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); getActivity().getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
return displayMetrics.heightPixels < displayMetrics.widthPixels; return displayMetrics.heightPixels < displayMetrics.widthPixels;

View File

@ -6,6 +6,7 @@ import android.os.Bundle;
import android.support.v4.app.NavUtils; 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;
@ -56,9 +57,9 @@ public class VideoItemListActivity extends AppCompatActivity
private VideoItemListFragment listFragment; private VideoItemListFragment listFragment;
private VideoItemDetailFragment videoFragment = null; private VideoItemDetailFragment videoFragment = null;
Menu menu = null; private Menu menu = null;
public class SearchVideoQueryListener implements SearchView.OnQueryTextListener { private class SearchVideoQueryListener implements SearchView.OnQueryTextListener {
@Override @Override
public boolean onQueryTextSubmit(String query) { public boolean onQueryTextSubmit(String query) {
@ -69,8 +70,14 @@ public class VideoItemListActivity extends AppCompatActivity
// hide virtual keyboard // hide virtual keyboard
InputMethodManager inputManager = InputMethodManager inputManager =
(InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow( try {
getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); //noinspection ConstantConditions
inputManager.hideSoftInputFromWindow(
getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
} catch(NullPointerException e) {
Log.e(TAG, "Could not get widget with focus");
e.printStackTrace();
}
// clear focus // clear focus
// 1. to not open up the keyboard after switching back to this // 1. to not open up the keyboard after switching back to this
// 2. It's a workaround to a seeming bug by the Android OS it self, causing // 2. It's a workaround to a seeming bug by the Android OS it self, causing
@ -116,7 +123,13 @@ public class VideoItemListActivity extends AppCompatActivity
ArrayList<VideoPreviewInfo> p = arguments.getParcelableArrayList(VIDEO_INFO_ITEMS); ArrayList<VideoPreviewInfo> p = arguments.getParcelableArrayList(VIDEO_INFO_ITEMS);
if(p != null) { if(p != null) {
mode = PRESENT_VIDEOS_MODE; mode = PRESENT_VIDEOS_MODE;
getSupportActionBar().setDisplayHomeAsUpEnabled(true); try {
//noinspection ConstantConditions
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
} catch (NullPointerException e) {
Log.e(TAG, "Could not get SupportActionBar");
e.printStackTrace();
}
listFragment.present(p); listFragment.present(p);
} }

View File

@ -64,8 +64,8 @@ public class VideoItemListFragment extends ListFragment {
private ListView list; private ListView list;
private class ResultRunnable implements Runnable { private class ResultRunnable implements Runnable {
private SearchEngine.Result result; private final SearchEngine.Result result;
private int requestId; private final int requestId;
public ResultRunnable(SearchEngine.Result result, int requestId) { public ResultRunnable(SearchEngine.Result result, int requestId) {
this.result = result; this.result = result;
this.requestId = requestId; this.requestId = requestId;
@ -77,12 +77,12 @@ public class VideoItemListFragment extends ListFragment {
} }
private class SearchRunnable implements Runnable { private class SearchRunnable implements Runnable {
private SearchEngine engine; private final SearchEngine engine;
private String query; private final String query;
private int page; private final int page;
Handler h = new Handler(); final Handler h = new Handler();
private volatile boolean run = true; private volatile boolean run = true;
private int requestId; private final int requestId;
public SearchRunnable(SearchEngine engine, String query, int page, int requestId) { public SearchRunnable(SearchEngine engine, String query, int page, int requestId) {
this.engine = engine; this.engine = engine;
this.query = query; this.query = query;
@ -116,11 +116,11 @@ public class VideoItemListFragment extends ListFragment {
} }
private class LoadThumbsRunnable implements Runnable { private class LoadThumbsRunnable implements Runnable {
private Vector<String> thumbnailUrlList = new Vector<>(); private final Vector<String> thumbnailUrlList = new Vector<>();
private Vector<Boolean> downloadedList; private final Vector<Boolean> downloadedList;
Handler h = new Handler(); final Handler h = new Handler();
private volatile boolean run = true; private volatile boolean run = true;
private int requestId; private final int requestId;
public LoadThumbsRunnable(Vector<VideoPreviewInfo> videoList, public LoadThumbsRunnable(Vector<VideoPreviewInfo> videoList,
Vector<Boolean> downloadedList, int requestId) { Vector<Boolean> downloadedList, int requestId) {
for(VideoPreviewInfo item : videoList) { for(VideoPreviewInfo item : videoList) {
@ -139,7 +139,7 @@ public class VideoItemListFragment extends ListFragment {
public void run() { public void run() {
for(int i = 0; i < thumbnailUrlList.size() && run; i++) { for(int i = 0; i < thumbnailUrlList.size() && run; i++) {
if(!downloadedList.get(i)) { if(!downloadedList.get(i)) {
Bitmap thumbnail = null; Bitmap thumbnail;
try { try {
thumbnail = BitmapFactory.decodeStream( thumbnail = BitmapFactory.decodeStream(
new URL(thumbnailUrlList.get(i)).openConnection().getInputStream()); new URL(thumbnailUrlList.get(i)).openConnection().getInputStream());
@ -153,9 +153,9 @@ public class VideoItemListFragment extends ListFragment {
} }
private class SetThumbnailRunnable implements Runnable { private class SetThumbnailRunnable implements Runnable {
private int index; private final int index;
private Bitmap thumbnail; private final Bitmap thumbnail;
private int requestId; private final int requestId;
public SetThumbnailRunnable(int index, Bitmap thumbnail, int requestId) { public SetThumbnailRunnable(int index, Bitmap thumbnail, int requestId) {
this.index = index; this.index = index;
this.thumbnail = thumbnail; this.thumbnail = thumbnail;
@ -164,7 +164,7 @@ public class VideoItemListFragment extends ListFragment {
@Override @Override
public void run() { public void run() {
if(requestId == currentRequestId) { if(requestId == currentRequestId) {
videoListAdapter.updateDownloadedThumbnailList(index, true); videoListAdapter.updateDownloadedThumbnailList(index);
videoListAdapter.setThumbnail(index, thumbnail); videoListAdapter.setThumbnail(index, thumbnail);
} }
} }
@ -188,7 +188,7 @@ public class VideoItemListFragment extends ListFragment {
getListView().smoothScrollToPosition(0); getListView().smoothScrollToPosition(0);
} }
public void nextPage() { private void nextPage() {
lastPage++; lastPage++;
Log.d(TAG, getString(R.string.searchPage) + Integer.toString(lastPage)); Log.d(TAG, getString(R.string.searchPage) + Integer.toString(lastPage));
startSearch(query, lastPage); startSearch(query, lastPage);
@ -207,7 +207,7 @@ public class VideoItemListFragment extends ListFragment {
this.streamingService = streamingService; this.streamingService = streamingService;
} }
public void updateListOnResult(SearchEngine.Result result, int requestId) { private void updateListOnResult(SearchEngine.Result result, int requestId) {
if(requestId == currentRequestId) { if(requestId == currentRequestId) {
setListShown(true); setListShown(true);
if (result.resultList.isEmpty()) { if (result.resultList.isEmpty()) {
@ -237,7 +237,7 @@ public class VideoItemListFragment extends ListFragment {
} }
} }
public void terminateThreads() { private void terminateThreads() {
if(loadThumbsRunnable != null && loadThumbsRunnable.isRunning()) { if(loadThumbsRunnable != null && loadThumbsRunnable.isRunning()) {
loadThumbsRunnable.terminate(); loadThumbsRunnable.terminate();
try { try {
@ -276,12 +276,7 @@ public class VideoItemListFragment extends ListFragment {
void onItemSelected(String id); void onItemSelected(String id);
} }
Callbacks mCallbacks = null; private Callbacks mCallbacks = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override @Override
public void onViewCreated(View view, Bundle savedInstanceState) { public void onViewCreated(View view, Bundle savedInstanceState) {
@ -333,11 +328,6 @@ public class VideoItemListFragment extends ListFragment {
mCallbacks = (Callbacks) context; mCallbacks = (Callbacks) context;
} }
@Override
public void onDetach() {
super.onDetach();
}
@Override @Override
public void onListItemClick(ListView listView, View view, int position, long id) { public void onListItemClick(ListView listView, View view, int position, long id) {
super.onListItemClick(listView, view, position, id); super.onListItemClick(listView, view, position, id);
@ -345,22 +335,11 @@ public class VideoItemListFragment extends ListFragment {
mCallbacks.onItemSelected(Long.toString(id)); mCallbacks.onItemSelected(Long.toString(id));
} }
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
/*
if (mActivatedPosition != ListView.INVALID_POSITION) {
// Serialize and persist the activated item position.
outState.putInt(STATE_ACTIVATED_POSITION, mActivatedPosition);
}
*/
}
/** /**
* Turns on activate-on-click mode. When this mode is on, list items will be * Turns on activate-on-click mode. When this mode is on, list items will be
* given the 'activated' state when touched. * given the 'activated' state when touched.
*/ */
public void setActivateOnItemClick(boolean activateOnItemClick) { public void setActivateOnItemClick(@SuppressWarnings("SameParameterValue") boolean activateOnItemClick) {
// When setting CHOICE_MODE_SINGLE, ListView will automatically // When setting CHOICE_MODE_SINGLE, ListView will automatically
// give items the 'activated' state when touched. // give items the 'activated' state when touched.
getListView().setChoiceMode(activateOnItemClick getListView().setChoiceMode(activateOnItemClick

View File

@ -32,19 +32,17 @@ import java.util.Vector;
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>. * along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
*/ */
public class VideoListAdapter extends BaseAdapter { class VideoListAdapter extends BaseAdapter {
private static final String TAG = VideoListAdapter.class.toString(); private static final String TAG = VideoListAdapter.class.toString();
private Context context; private final Context context;
private VideoInfoItemViewCreator viewCreator; private final VideoInfoItemViewCreator viewCreator;
private Vector<VideoPreviewInfo> videoList = new Vector<>(); private Vector<VideoPreviewInfo> videoList = new Vector<>();
private Vector<Boolean> downloadedThumbnailList = new Vector<>(); private Vector<Boolean> downloadedThumbnailList = new Vector<>();
VideoItemListFragment videoListFragment; private final ListView listView;
ListView listView;
public VideoListAdapter(Context context, VideoItemListFragment videoListFragment) { public VideoListAdapter(Context context, VideoItemListFragment videoListFragment) {
viewCreator = new VideoInfoItemViewCreator(LayoutInflater.from(context)); viewCreator = new VideoInfoItemViewCreator(LayoutInflater.from(context));
this.videoListFragment = videoListFragment;
this.listView = videoListFragment.getListView(); this.listView = videoListFragment.getListView();
this.context = context; this.context = context;
} }
@ -67,8 +65,8 @@ public class VideoListAdapter extends BaseAdapter {
return videoList; return videoList;
} }
public void updateDownloadedThumbnailList(int index, boolean val) { public void updateDownloadedThumbnailList(int index) {
downloadedThumbnailList.set(index, val); downloadedThumbnailList.set(index, true);
} }
public Vector<Boolean> getDownloadedThumbnailList() { public Vector<Boolean> getDownloadedThumbnailList() {

View File

@ -4,6 +4,8 @@ import android.graphics.Bitmap;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import org.schabi.newpipe.services.AbstractVideoInfo;
/** /**
* Created by Christian Schabesberger on 26.08.15. * Created by Christian Schabesberger on 26.08.15.
* *
@ -27,6 +29,7 @@ import android.os.Parcelable;
/**Info object for previews of unopened videos, eg search results, related videos*/ /**Info object for previews of unopened videos, eg search results, related videos*/
public class VideoPreviewInfo extends AbstractVideoInfo implements Parcelable { public class VideoPreviewInfo extends AbstractVideoInfo implements Parcelable {
public String duration = ""; public String duration = "";
@SuppressWarnings("WeakerAccess")
protected VideoPreviewInfo(Parcel in) { protected VideoPreviewInfo(Parcel in) {
id = in.readString(); id = in.readString();
title = in.readString(); title = in.readString();

View File

@ -1,4 +1,4 @@
package org.schabi.newpipe; package org.schabi.newpipe.services;
import android.graphics.Bitmap; import android.graphics.Bitmap;

View File

@ -31,7 +31,7 @@ public interface SearchEngine {
class Result { class Result {
public String errorMessage = ""; public String errorMessage = "";
public String suggestion = ""; public String suggestion = "";
public Vector<VideoPreviewInfo> resultList = new Vector<>(); public final Vector<VideoPreviewInfo> resultList = new Vector<>();
} }
ArrayList<String> suggestionList(String query); ArrayList<String> suggestionList(String query);

View File

@ -42,7 +42,7 @@ public class ServiceList {
} }
public static int getIdOfService(String serviceName) { public static int getIdOfService(String serviceName) {
for(int i = 0; i < services.length; i++) { for(int i = 0; i < services.length; i++) {
if(services[i].getServiceInfo().name == serviceName) { if(services[i].getServiceInfo().name.equals(serviceName)) {
return i; return i;
} }
} }

View File

@ -25,7 +25,7 @@ public interface StreamingService {
public String name = ""; public String name = "";
} }
ServiceInfo getServiceInfo(); ServiceInfo getServiceInfo();
Extractor getExtractorInstance(String url); VideoExtractor getExtractorInstance(String url);
SearchEngine getSearchEngineInstance(); SearchEngine getSearchEngineInstance();
/**When a VIEW_ACTION is caught this function will test if the url delivered within the calling /**When a VIEW_ACTION is caught this function will test if the url delivered within the calling

View File

@ -4,7 +4,7 @@ package org.schabi.newpipe.services;
* Created by Christian Schabesberger on 10.08.15. * Created by Christian Schabesberger on 10.08.15.
* *
* Copyright (C) Christian Schabesberger 2015 <chris.schabesberger@mailbox.org> * Copyright (C) Christian Schabesberger 2015 <chris.schabesberger@mailbox.org>
* Extractor.java is part of NewPipe. * VideoExtractor.java is part of NewPipe.
* *
* NewPipe is free software: you can redistribute it and/or modify * NewPipe is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -23,11 +23,12 @@ package org.schabi.newpipe.services;
import org.schabi.newpipe.VideoInfo; import org.schabi.newpipe.VideoInfo;
/**Scrapes information from a video streaming service (eg, YouTube).*/ /**Scrapes information from a video streaming service (eg, YouTube).*/
public abstract class Extractor { public abstract class VideoExtractor {
public String pageUrl; protected final String pageUrl;
public VideoInfo videoInfo; protected VideoInfo videoInfo;
public Extractor(String url) { @SuppressWarnings("WeakerAccess")
public VideoExtractor(String url) {
this.pageUrl = url; this.pageUrl = url;
} }
@ -99,17 +100,17 @@ public abstract class Extractor {
return videoInfo; return videoInfo;
} }
public abstract String getVideoUrl(String videoId); protected abstract String getVideoUrl(String videoId);
public abstract String getVideoId(String siteUrl); protected abstract String getVideoId(String siteUrl);
public abstract int getTimeStamp(); protected abstract int getTimeStamp();
public abstract String getTitle(); protected abstract String getTitle();
public abstract String getDescription(); protected abstract String getDescription();
public abstract String getUploader(); protected abstract String getUploader();
public abstract int getLength(); protected abstract int getLength();
public abstract int getViews(); protected abstract int getViews();
public abstract String getUploadDate(); protected abstract String getUploadDate();
public abstract String getThumbnailUrl(); protected abstract String getThumbnailUrl();
public abstract String getUploaderThumbnailUrl(); protected abstract String getUploaderThumbnailUrl();
public abstract VideoInfo.AudioStream[] getAudioStreams(); protected abstract VideoInfo.AudioStream[] getAudioStreams();
public abstract VideoInfo.VideoStream[] getVideoStreams(); protected abstract VideoInfo.VideoStream[] getVideoStreams();
} }

View File

@ -95,20 +95,18 @@ public class YoutubeSearchEngine implements SearchEngine {
// both types of spell correction item // both types of spell correction item
if(!((el = item.select("div[class*=\"spell-correction\"]").first()) == null)) { if(!((el = item.select("div[class*=\"spell-correction\"]").first()) == null)) {
result.suggestion = el.select("a").first().text(); result.suggestion = el.select("a").first().text();
// search message item // search message item
} else if(!((el = item.select("div[class*=\"search-message\"]").first()) == null)) { } else if(!((el = item.select("div[class*=\"search-message\"]").first()) == null)) {
result.errorMessage = el.text(); result.errorMessage = el.text();
// video item type // video item type
} else if(!((el = item.select("div[class*=\"yt-lockup-video\"").first()) == null)) { } else if(!((el = item.select("div[class*=\"yt-lockup-video\"").first()) == null)) {
//todo: de-duplicate this with YoutubeExtractor.getVideoPreviewInfo()
VideoPreviewInfo resultItem = new VideoPreviewInfo(); VideoPreviewInfo resultItem = new VideoPreviewInfo();
Element dl = el.select("h3").first().select("a").first(); Element dl = el.select("h3").first().select("a").first();
resultItem.webpage_url = dl.attr("abs:href"); resultItem.webpage_url = dl.attr("abs:href");
try { try {
Pattern p = Pattern.compile("v=([0-9a-zA-Z-]*)"); Pattern p = Pattern.compile("v=([0-9a-zA-Z-]*)");
Matcher m = p.matcher(resultItem.webpage_url); Matcher m = p.matcher(resultItem.webpage_url);
m.find();
resultItem.id=m.group(1); resultItem.id=m.group(1);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
@ -134,6 +132,7 @@ public class YoutubeSearchEngine implements SearchEngine {
} }
result.resultList.add(resultItem); result.resultList.add(resultItem);
} else { } else {
//noinspection ConstantConditions
Log.e(TAG, "unexpected element found:\""+el+"\""); Log.e(TAG, "unexpected element found:\""+el+"\"");
} }
} }

View File

@ -1,7 +1,7 @@
package org.schabi.newpipe.services.youtube; package org.schabi.newpipe.services.youtube;
import org.schabi.newpipe.services.StreamingService; import org.schabi.newpipe.services.StreamingService;
import org.schabi.newpipe.services.Extractor; import org.schabi.newpipe.services.VideoExtractor;
import org.schabi.newpipe.services.SearchEngine; import org.schabi.newpipe.services.SearchEngine;
@ -33,9 +33,9 @@ public class YoutubeService implements StreamingService {
return serviceInfo; return serviceInfo;
} }
@Override @Override
public Extractor getExtractorInstance(String url) { public VideoExtractor getExtractorInstance(String url) {
if(acceptUrl(url)) { if(acceptUrl(url)) {
return new YoutubeExtractor(url); return new YoutubeVideoExtractor(url);
} }
else { else {
throw new IllegalArgumentException("supplied String is not a valid Youtube URL"); throw new IllegalArgumentException("supplied String is not a valid Youtube URL");

View File

@ -13,7 +13,7 @@ import org.mozilla.javascript.Context;
import org.mozilla.javascript.Function; import org.mozilla.javascript.Function;
import org.mozilla.javascript.ScriptableObject; import org.mozilla.javascript.ScriptableObject;
import org.schabi.newpipe.Downloader; import org.schabi.newpipe.Downloader;
import org.schabi.newpipe.services.Extractor; import org.schabi.newpipe.services.VideoExtractor;
import org.schabi.newpipe.MediaFormat; import org.schabi.newpipe.MediaFormat;
import org.schabi.newpipe.VideoInfo; import org.schabi.newpipe.VideoInfo;
import org.schabi.newpipe.VideoPreviewInfo; import org.schabi.newpipe.VideoPreviewInfo;
@ -31,7 +31,7 @@ import java.util.regex.Pattern;
* Created by Christian Schabesberger on 06.08.15. * Created by Christian Schabesberger on 06.08.15.
* *
* Copyright (C) Christian Schabesberger 2015 <chris.schabesberger@mailbox.org> * Copyright (C) Christian Schabesberger 2015 <chris.schabesberger@mailbox.org>
* YoutubeExtractor.java is part of NewPipe. * YoutubeVideoExtractor.java is part of NewPipe.
* *
* NewPipe is free software: you can redistribute it and/or modify * NewPipe is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -47,11 +47,10 @@ import java.util.regex.Pattern;
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>. * along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
*/ */
public class YoutubeExtractor extends Extractor { public class YoutubeVideoExtractor extends VideoExtractor {
private static final String TAG = YoutubeExtractor.class.toString(); private static final String TAG = YoutubeVideoExtractor.class.toString();
private String pageContents; private final Document doc;
private Document doc;
private JSONObject jsonObj; private JSONObject jsonObj;
private JSONObject playerArgs; private JSONObject playerArgs;
@ -62,9 +61,9 @@ public class YoutubeExtractor extends Extractor {
private static volatile String decryptionCode = ""; private static volatile String decryptionCode = "";
public YoutubeExtractor(String pageUrl) { public YoutubeVideoExtractor(String pageUrl) {
super(pageUrl);//most common videoInfo fields are now set in our superclass, for all services super(pageUrl);//most common videoInfo fields are now set in our superclass, for all services
pageContents = Downloader.download(cleanUrl(pageUrl)); String pageContents = Downloader.download(cleanUrl(pageUrl));
doc = Jsoup.parse(pageContents, pageUrl); doc = Jsoup.parse(pageContents, pageUrl);
//attempt to load the youtube js player JSON arguments //attempt to load the youtube js player JSON arguments
@ -266,6 +265,8 @@ public class YoutubeExtractor extends Extractor {
/**These lists only contain itag formats that are supported by the common Android Video player. /**These lists only contain itag formats that are supported by the common Android Video player.
However if you are looking for a list showing all itag formats, look at However if you are looking for a list showing all itag formats, look at
https://github.com/rg3/youtube-dl/issues/1687 */ https://github.com/rg3/youtube-dl/issues/1687 */
@SuppressWarnings("WeakerAccess")
public static int resolveFormat(int itag) { public static int resolveFormat(int itag) {
switch(itag) { switch(itag) {
// video // video
@ -285,6 +286,7 @@ public class YoutubeExtractor extends Extractor {
} }
} }
@SuppressWarnings("WeakerAccess")
public static String resolveResolutionString(int itag) { public static String resolveResolutionString(int itag) {
switch(itag) { switch(itag) {
case 17: return "144p"; case 17: return "144p";
@ -303,6 +305,7 @@ public class YoutubeExtractor extends Extractor {
} }
} }
@SuppressWarnings("WeakerAccess")
@Override @Override
public String getVideoId(String url) { public String getVideoId(String url) {
String id; String id;
@ -327,6 +330,7 @@ public class YoutubeExtractor extends Extractor {
return ""; return "";
} }
@SuppressWarnings("WeakerAccess")
@Override @Override
public String getVideoUrl(String videoId) { public String getVideoUrl(String videoId) {
return "https://www.youtube.com/watch?v=" + videoId; return "https://www.youtube.com/watch?v=" + videoId;
@ -579,7 +583,10 @@ public class YoutubeExtractor extends Extractor {
e.printStackTrace(); e.printStackTrace();
} }
Context.exit(); Context.exit();
return result.toString(); if(result != null)
return result.toString();
else
return "";
} }
private String cleanUrl(String complexUrl) { private String cleanUrl(String complexUrl) {

View File

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

Before

Width:  |  Height:  |  Size: 869 B

After

Width:  |  Height:  |  Size: 869 B

View File

Before

Width:  |  Height:  |  Size: 209 B

After

Width:  |  Height:  |  Size: 209 B

View File

Before

Width:  |  Height:  |  Size: 786 B

After

Width:  |  Height:  |  Size: 786 B

View File

Before

Width:  |  Height:  |  Size: 320 B

After

Width:  |  Height:  |  Size: 320 B

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 888 B

After

Width:  |  Height:  |  Size: 888 B

View File

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 75 KiB

View File

Before

Width:  |  Height:  |  Size: 870 B

After

Width:  |  Height:  |  Size: 870 B

View File

Before

Width:  |  Height:  |  Size: 783 B

After

Width:  |  Height:  |  Size: 783 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 236 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 938 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 KiB

View File

@ -31,10 +31,12 @@
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<ImageView android:id="@+id/detailThumbnailView" <ImageView android:id="@+id/detailThumbnailView"
android:contentDescription="@string/detailThumbnailViewDescription"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:scaleType="centerInside" android:scaleType="centerInside"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
android:adjustViewBounds="true" android:adjustViewBounds="true"
android:src="@drawable/dummy_thumbnail"/> android:src="@drawable/dummy_thumbnail"/>
@ -52,17 +54,19 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:textStyle="bold" android:textStyle="bold"
android:paddingBottom="5dp" android:paddingBottom="5dp"
android:textSize="@dimen/text_video_title_land_size" android:textSize="@dimen/text_video_title_land_size"
android:textAppearance="?android:attr/textAppearanceLarge" android:textAppearance="?android:attr/textAppearanceLarge"/>
android:text="Video title placeholder"/>
<ImageView android:id="@+id/detailUploaderThumbnailView" <ImageView android:id="@+id/detailUploaderThumbnailView"
android:contentDescription="@string/detailUploaderThumbnailViewDescription"
android:layout_width="100dp" android:layout_width="100dp"
android:layout_height="100dp" android:layout_height="100dp"
android:layout_below="@id/detailVideoTitleView" android:layout_below="@id/detailVideoTitleView"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:src="@drawable/buddy" /> android:src="@drawable/buddy" />
<TextView android:id="@+id/detailUploaderView" <TextView android:id="@+id/detailUploaderView"
@ -70,10 +74,10 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/detailUploaderThumbnailView" android:layout_below="@id/detailUploaderThumbnailView"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:textStyle="bold" android:textStyle="bold"
android:textSize="@dimen/text_video_uploader_land_size" android:textSize="@dimen/text_video_uploader_land_size"
android:textAppearance="?android:attr/textAppearanceLarge" android:textAppearance="?android:attr/textAppearanceLarge" />
android:text="username" />
<TextView android:id="@+id/detailViewCountView" <TextView android:id="@+id/detailViewCountView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -81,25 +85,30 @@
android:paddingBottom="5dp" android:paddingBottom="5dp"
android:layout_below="@id/detailVideoTitleView" android:layout_below="@id/detailVideoTitleView"
android:layout_alignParentRight="true" android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:textSize="@dimen/text_video_views_land_size" android:textSize="@dimen/text_video_views_land_size"
android:textAppearance="?android:attr/textAppearanceLarge" android:textAppearance="?android:attr/textAppearanceLarge"/>
android:text="81,754 views" />
<TextView android:id="@+id/detailThumbsDownCountView" <TextView android:id="@+id/detailThumbsDownCountView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/detailViewCountView" android:layout_below="@id/detailViewCountView"
android:layout_alignParentRight="true" android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:textSize="@dimen/text_video_like_land_size" android:textSize="@dimen/text_video_like_land_size"
android:textAppearance="?android:attr/textAppearanceMedium" android:paddingRight="5dp"
android:text="1,000" /> android:paddingLeft="5dp"
android:textAppearance="?android:attr/textAppearanceMedium" />
<ImageView android:id="@+id/detailThumbsDownImgView" <ImageView android:id="@+id/detailThumbsDownImgView"
android:contentDescription="@string/detailThumbsDownImgViewDescription"
android:layout_width="40dp" android:layout_width="40dp"
android:layout_height="20dp" android:layout_height="20dp"
android:layout_below="@id/detailViewCountView" android:layout_below="@id/detailViewCountView"
android:layout_toLeftOf="@id/detailThumbsDownCountView" android:layout_toLeftOf="@id/detailThumbsDownCountView"
android:paddingRight="10dp" android:layout_toStartOf="@id/detailThumbsDownCountView"
android:paddingRight="5dp"
android:paddingLeft="5dp"
android:src="@drawable/thumbs_down" /> android:src="@drawable/thumbs_down" />
<TextView android:id="@+id/detailThumbsUpCountView" <TextView android:id="@+id/detailThumbsUpCountView"
@ -107,17 +116,21 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/detailViewCountView" android:layout_below="@id/detailViewCountView"
android:layout_toLeftOf="@id/detailThumbsDownImgView" android:layout_toLeftOf="@id/detailThumbsDownImgView"
android:paddingRight="10dp" android:layout_toStartOf="@id/detailThumbsDownImgView"
android:paddingRight="5dp"
android:paddingLeft="5dp"
android:textSize="@dimen/text_video_like_land_size" android:textSize="@dimen/text_video_like_land_size"
android:textAppearance="?android:attr/textAppearanceMedium" android:textAppearance="?android:attr/textAppearanceMedium" />
android:text="200" />
<ImageView android:id="@+id/detailThumbsUpImgView" <ImageView android:id="@+id/detailThumbsUpImgView"
android:contentDescription="@string/detailThumbsUpImgViewDescription"
android:layout_width="40dp" android:layout_width="40dp"
android:layout_height="20dp" android:layout_height="20dp"
android:layout_below="@id/detailViewCountView" android:layout_below="@id/detailViewCountView"
android:paddingRight="10dp" android:paddingRight="5dp"
android:paddingLeft="5dp"
android:layout_toLeftOf="@id/detailThumbsUpCountView" android:layout_toLeftOf="@id/detailThumbsUpCountView"
android:layout_toStartOf="@id/detailThumbsUpImgView"
android:src="@drawable/thumbs_up" /> android:src="@drawable/thumbs_up" />
<TextView android:id="@+id/detailUploadDateView" <TextView android:id="@+id/detailUploadDateView"
@ -125,19 +138,18 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/detailUploaderView" android:layout_below="@id/detailUploaderView"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:textSize="@dimen/text_video_upload_date_land_size" android:textSize="@dimen/text_video_upload_date_land_size"
android:textAppearance="?android:attr/textAppearanceLarge" android:textAppearance="?android:attr/textAppearanceLarge" />
android:text="Uploaded at Jan 01 1975" />
<TextView android:id="@+id/detailDescriptionView" <TextView android:id="@+id/detailDescriptionView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/detailUploadDateView" android:layout_below="@id/detailUploadDateView"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:textSize="@dimen/text_video_description_land_size" android:textSize="@dimen/text_video_description_land_size"
android:textAppearance="?android:attr/textAppearanceMedium" android:textAppearance="?android:attr/textAppearanceMedium" />
android:text="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmodtempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. "
/>
</RelativeLayout> </RelativeLayout>
</RelativeLayout> </RelativeLayout>
@ -150,6 +162,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:paddingLeft="6dp" android:paddingLeft="6dp"
android:paddingRight="6dp" android:paddingRight="6dp"
android:paddingTop="20dp" android:paddingTop="20dp"
@ -191,6 +204,7 @@
<android.support.design.widget.FloatingActionButton <android.support.design.widget.FloatingActionButton
android:id="@+id/playVideoButton" android:id="@+id/playVideoButton"
android:layout_alignParentRight="true" android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View File

@ -25,7 +25,8 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:iconifiedByDefault="false" android:iconifiedByDefault="false"
android:focusable="false"/> android:focusable="false"
tools:ignore="InconsistentLayout" />
<fragment android:id="@+id/videoitem_list" <fragment android:id="@+id/videoitem_list"
android:name="org.schabi.newpipe.VideoItemListFragment" android:name="org.schabi.newpipe.VideoItemListFragment"
@ -44,7 +45,8 @@
<FrameLayout android:id="@+id/videoitem_detail_container" <FrameLayout android:id="@+id/videoitem_detail_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent"
tools:ignore="InconsistentLayout" />
</LinearLayout> </LinearLayout>

View File

@ -31,10 +31,12 @@
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<ImageView android:id="@+id/detailThumbnailView" <ImageView android:id="@+id/detailThumbnailView"
android:contentDescription="@string/detailThumbnailViewDescription"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:scaleType="centerInside" android:scaleType="centerInside"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
android:adjustViewBounds="true" android:adjustViewBounds="true"
android:src="@drawable/dummy_thumbnail"/> android:src="@drawable/dummy_thumbnail"/>
@ -52,17 +54,19 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:textStyle="bold" android:textStyle="bold"
android:paddingBottom="5dp" android:paddingBottom="5dp"
android:textSize="@dimen/text_video_title_sw600dp_size" android:textSize="@dimen/text_video_title_sw600dp_size"
android:textAppearance="?android:attr/textAppearanceLarge" android:textAppearance="?android:attr/textAppearanceLarge"/>
android:text="Video title placeholder"/>
<ImageView android:id="@+id/detailUploaderThumbnailView" <ImageView android:id="@+id/detailUploaderThumbnailView"
android:contentDescription="@string/detailUploaderThumbnailViewDescription"
android:layout_width="100dp" android:layout_width="100dp"
android:layout_height="100dp" android:layout_height="100dp"
android:layout_below="@id/detailVideoTitleView" android:layout_below="@id/detailVideoTitleView"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:src="@drawable/buddy" /> android:src="@drawable/buddy" />
<TextView android:id="@+id/detailUploaderView" <TextView android:id="@+id/detailUploaderView"
@ -70,10 +74,10 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/detailUploaderThumbnailView" android:layout_below="@id/detailUploaderThumbnailView"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:textStyle="bold" android:textStyle="bold"
android:textSize="@dimen/text_video_uploader_sw600dp_size" android:textSize="@dimen/text_video_uploader_sw600dp_size"
android:textAppearance="?android:attr/textAppearanceLarge" android:textAppearance="?android:attr/textAppearanceLarge"/>
android:text="username" />
<TextView android:id="@+id/detailViewCountView" <TextView android:id="@+id/detailViewCountView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -81,25 +85,30 @@
android:paddingBottom="5dp" android:paddingBottom="5dp"
android:layout_below="@id/detailVideoTitleView" android:layout_below="@id/detailVideoTitleView"
android:layout_alignParentRight="true" android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:textSize="@dimen/text_video_views_sw600dp_size" android:textSize="@dimen/text_video_views_sw600dp_size"
android:textAppearance="?android:attr/textAppearanceLarge" android:textAppearance="?android:attr/textAppearanceLarge"/>
android:text="81,754 views" />
<TextView android:id="@+id/detailThumbsDownCountView" <TextView android:id="@+id/detailThumbsDownCountView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/detailViewCountView" android:layout_below="@id/detailViewCountView"
android:layout_alignParentRight="true" android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:textSize="@dimen/text_video_like_sw600dp_size" android:textSize="@dimen/text_video_like_sw600dp_size"
android:textAppearance="?android:attr/textAppearanceMedium" android:paddingRight="5dp"
android:text="1,000" /> android:paddingLeft="5dp"
android:textAppearance="?android:attr/textAppearanceMedium"/>
<ImageView android:id="@+id/detailThumbsDownImgView" <ImageView android:id="@+id/detailThumbsDownImgView"
android:contentDescription="@string/detailThumbsDownImgViewDescription"
android:layout_width="40dp" android:layout_width="40dp"
android:layout_height="20dp" android:layout_height="20dp"
android:layout_below="@id/detailViewCountView" android:layout_below="@id/detailViewCountView"
android:layout_toLeftOf="@id/detailThumbsDownCountView" android:layout_toLeftOf="@id/detailThumbsDownCountView"
android:paddingRight="10dp" android:layout_toStartOf="@id/detailThumbsDownCountView"
android:paddingRight="5dp"
android:paddingLeft="5dp"
android:src="@drawable/thumbs_down" /> android:src="@drawable/thumbs_down" />
<TextView android:id="@+id/detailThumbsUpCountView" <TextView android:id="@+id/detailThumbsUpCountView"
@ -107,17 +116,21 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/detailViewCountView" android:layout_below="@id/detailViewCountView"
android:layout_toLeftOf="@id/detailThumbsDownImgView" android:layout_toLeftOf="@id/detailThumbsDownImgView"
android:paddingRight="10dp" android:layout_toStartOf="@id/detailThumbsDownImgView"
android:paddingRight="5dp"
android:paddingLeft="5dp"
android:textSize="@dimen/text_video_like_sw600dp_size" android:textSize="@dimen/text_video_like_sw600dp_size"
android:textAppearance="?android:attr/textAppearanceMedium" android:textAppearance="?android:attr/textAppearanceMedium" />
android:text="200" />
<ImageView android:id="@+id/detailThumbsUpImgView" <ImageView android:id="@+id/detailThumbsUpImgView"
android:contentDescription="@string/detailThumbsUpImgViewDescription"
android:layout_width="40dp" android:layout_width="40dp"
android:layout_height="20dp" android:layout_height="20dp"
android:layout_below="@id/detailViewCountView" android:layout_below="@id/detailViewCountView"
android:paddingRight="10dp" android:paddingRight="5dp"
android:paddingLeft="5dp"
android:layout_toLeftOf="@id/detailThumbsUpCountView" android:layout_toLeftOf="@id/detailThumbsUpCountView"
android:layout_toStartOf="@id/detailThumbsUpImgView"
android:src="@drawable/thumbs_up" /> android:src="@drawable/thumbs_up" />
<TextView android:id="@+id/detailUploadDateView" <TextView android:id="@+id/detailUploadDateView"
@ -125,19 +138,18 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/detailUploaderView" android:layout_below="@id/detailUploaderView"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:textSize="@dimen/text_video_upload_date_sw600dp_size" android:textSize="@dimen/text_video_upload_date_sw600dp_size"
android:textAppearance="?android:attr/textAppearanceLarge" android:textAppearance="?android:attr/textAppearanceLarge" />
android:text="Uploaded at Jan 01 1975" />
<TextView android:id="@+id/detailDescriptionView" <TextView android:id="@+id/detailDescriptionView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/detailUploadDateView" android:layout_below="@id/detailUploadDateView"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:textSize="@dimen/text_video_description_sw600dp_size" android:textSize="@dimen/text_video_description_sw600dp_size"
android:textAppearance="?android:attr/textAppearanceMedium" android:textAppearance="?android:attr/textAppearanceMedium" />
android:text="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmodtempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. "
/>
</RelativeLayout> </RelativeLayout>
</RelativeLayout> </RelativeLayout>
@ -150,6 +162,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:paddingLeft="6dp" android:paddingLeft="6dp"
android:paddingRight="6dp" android:paddingRight="6dp"
android:paddingTop="20dp" android:paddingTop="20dp"
@ -190,6 +203,7 @@
<android.support.design.widget.FloatingActionButton <android.support.design.widget.FloatingActionButton
android:id="@+id/playVideoButton" android:id="@+id/playVideoButton"
android:layout_alignParentRight="true" android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View File

@ -1,8 +1,7 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="@android:color/black"
tools:context="org.schabi.newpipe.PlayVideoActivity" tools:context="org.schabi.newpipe.PlayVideoActivity"
android:gravity="center"> android:gravity="center">
@ -25,4 +24,4 @@
android:layout_gravity="center" android:layout_gravity="center"
android:focusable="false"/> android:focusable="false"/>
</FrameLayout> </merge>

View File

@ -31,10 +31,12 @@
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<ImageView android:id="@+id/detailThumbnailView" <ImageView android:id="@+id/detailThumbnailView"
android:contentDescription="@string/detailThumbnailViewDescription"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:scaleType="centerInside" android:scaleType="centerInside"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
android:adjustViewBounds="true" android:adjustViewBounds="true"
android:src="@drawable/dummy_thumbnail"/> android:src="@drawable/dummy_thumbnail"/>
@ -52,17 +54,19 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:textStyle="bold" android:textStyle="bold"
android:paddingBottom="3dp" android:paddingBottom="3dp"
android:textSize="@dimen/text_video_title_size" android:textSize="@dimen/text_video_title_size"
android:textAppearance="?android:attr/textAppearanceLarge" android:textAppearance="?android:attr/textAppearanceLarge"/>
android:text="Video title placeholder"/>
<ImageView android:id="@+id/detailUploaderThumbnailView" <ImageView android:id="@+id/detailUploaderThumbnailView"
android:contentDescription="@string/detailUploaderThumbnailViewDescription"
android:layout_width="80dp" android:layout_width="80dp"
android:layout_height="80dp" android:layout_height="80dp"
android:layout_below="@id/detailVideoTitleView" android:layout_below="@id/detailVideoTitleView"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:src="@drawable/buddy" /> android:src="@drawable/buddy" />
<TextView android:id="@+id/detailUploaderView" <TextView android:id="@+id/detailUploaderView"
@ -70,10 +74,10 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/detailUploaderThumbnailView" android:layout_below="@id/detailUploaderThumbnailView"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:textStyle="bold" android:textStyle="bold"
android:textSize="@dimen/text_video_uploader_size" android:textSize="@dimen/text_video_uploader_size"
android:textAppearance="?android:attr/textAppearanceLarge" android:textAppearance="?android:attr/textAppearanceLarge" />
android:text="username" />
<TextView android:id="@+id/detailViewCountView" <TextView android:id="@+id/detailViewCountView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -81,25 +85,30 @@
android:paddingBottom="3dp" android:paddingBottom="3dp"
android:layout_below="@id/detailVideoTitleView" android:layout_below="@id/detailVideoTitleView"
android:layout_alignParentRight="true" android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:textSize="@dimen/text_video_views_size" android:textSize="@dimen/text_video_views_size"
android:textAppearance="?android:attr/textAppearanceLarge" android:textAppearance="?android:attr/textAppearanceLarge" />
android:text="81,754 views" />
<TextView android:id="@+id/detailThumbsDownCountView" <TextView android:id="@+id/detailThumbsDownCountView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/detailViewCountView" android:layout_below="@id/detailViewCountView"
android:layout_alignParentRight="true" android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:textSize="@dimen/text_video_like_size" android:textSize="@dimen/text_video_like_size"
android:textAppearance="?android:attr/textAppearanceMedium" android:paddingRight="5dp"
android:text="1,000" /> android:paddingLeft="5dp"
android:textAppearance="?android:attr/textAppearanceMedium" />
<ImageView android:id="@+id/detailThumbsDownImgView" <ImageView android:id="@+id/detailThumbsDownImgView"
android:contentDescription="@string/detailThumbsDownImgViewDescription"
android:layout_width="30dp" android:layout_width="30dp"
android:layout_height="15dp" android:layout_height="15dp"
android:layout_below="@id/detailViewCountView" android:layout_below="@id/detailViewCountView"
android:layout_toLeftOf="@id/detailThumbsDownCountView" android:layout_toLeftOf="@id/detailThumbsDownCountView"
android:layout_toStartOf="@id/detailThumbsDownCountView"
android:paddingRight="5dp" android:paddingRight="5dp"
android:paddingLeft="5dp"
android:src="@drawable/thumbs_down" /> android:src="@drawable/thumbs_down" />
<TextView android:id="@+id/detailThumbsUpCountView" <TextView android:id="@+id/detailThumbsUpCountView"
@ -107,17 +116,21 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/detailViewCountView" android:layout_below="@id/detailViewCountView"
android:layout_toLeftOf="@id/detailThumbsDownImgView" android:layout_toLeftOf="@id/detailThumbsDownImgView"
android:layout_toStartOf="@id/detailThumbsDownImgView"
android:paddingRight="5dp" android:paddingRight="5dp"
android:paddingLeft="5dp"
android:textSize="@dimen/text_video_like_size" android:textSize="@dimen/text_video_like_size"
android:textAppearance="?android:attr/textAppearanceMedium" android:textAppearance="?android:attr/textAppearanceMedium"/>
android:text="200" />
<ImageView android:id="@+id/detailThumbsUpImgView" <ImageView android:id="@+id/detailThumbsUpImgView"
android:contentDescription="@string/detailThumbsUpImgViewDescription"
android:layout_width="30dp" android:layout_width="30dp"
android:layout_height="15dp" android:layout_height="15dp"
android:layout_below="@id/detailViewCountView" android:layout_below="@id/detailViewCountView"
android:layout_toLeftOf="@id/detailThumbsUpCountView" android:layout_toLeftOf="@id/detailThumbsUpCountView"
android:layout_toStartOf="@id/detailThumbsUpImgView"
android:paddingRight="5dp" android:paddingRight="5dp"
android:paddingLeft="5dp"
android:src="@drawable/thumbs_up" /> android:src="@drawable/thumbs_up" />
<TextView android:id="@+id/detailUploadDateView" <TextView android:id="@+id/detailUploadDateView"
@ -125,19 +138,18 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/detailUploaderView" android:layout_below="@id/detailUploaderView"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:textSize="@dimen/text_video_upload_date_size" android:textSize="@dimen/text_video_upload_date_size"
android:textAppearance="?android:attr/textAppearanceLarge" android:textAppearance="?android:attr/textAppearanceLarge" />
android:text="Uploaded at Jan 01 1975" />
<TextView android:id="@+id/detailDescriptionView" <TextView android:id="@+id/detailDescriptionView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/detailUploadDateView" android:layout_below="@id/detailUploadDateView"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:textSize="@dimen/text_video_description_size" android:textSize="@dimen/text_video_description_size"
android:textAppearance="?android:attr/textAppearanceMedium" android:textAppearance="?android:attr/textAppearanceMedium" />
android:text="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmodtempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. "
/>
</RelativeLayout> </RelativeLayout>
</RelativeLayout> </RelativeLayout>
@ -155,6 +167,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:textSize="@dimen/text_video_upload_date_size" android:textSize="@dimen/text_video_upload_date_size"
android:textAppearance="?android:attr/textAppearanceMedium" android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@android:color/black" android:textColor="@android:color/black"

View File

@ -7,11 +7,14 @@
android:padding="6dp"> android:padding="6dp">
<ImageView android:id="@+id/itemThumbnailView" <ImageView android:id="@+id/itemThumbnailView"
android:contentDescription="@string/itemThumbnailViewDescription"
android:layout_width="142dp" android:layout_width="142dp"
android:layout_height="80dp" android:layout_height="80dp"
android:layout_marginEnd="6dp"
android:layout_marginRight="6dp" android:layout_marginRight="6dp"
android:scaleType="centerCrop" android:scaleType="centerCrop"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
android:src="@drawable/dummy_thumbnail"/> android:src="@drawable/dummy_thumbnail"/>
@ -19,26 +22,25 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="36dp" android:layout_height="36dp"
android:layout_toRightOf="@id/itemThumbnailView" android:layout_toRightOf="@id/itemThumbnailView"
android:layout_toEndOf="@id/itemThumbnailView"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
android:textAppearance="?android:attr/textAppearanceLarge" android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="@dimen/text_search_title_size" android:textSize="@dimen/text_search_title_size"/>
android:text="title"
/>
<TextView android:id="@+id/itemUploaderView" <TextView android:id="@+id/itemUploaderView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="18dp" android:layout_height="18dp"
android:layout_toRightOf="@id/itemThumbnailView" android:layout_toRightOf="@id/itemThumbnailView"
android:layout_toEndOf="@id/itemThumbnailView"
android:layout_below="@id/itemVideoTitleView" android:layout_below="@id/itemVideoTitleView"
android:textAppearance="?android:attr/textAppearanceSmall" android:textAppearance="?android:attr/textAppearanceSmall"
android:textSize="@dimen/text_search_uploader_size" android:textSize="@dimen/text_search_uploader_size"/>
android:text="uploader"/>
<TextView android:id="@+id/itemUploadDateView" <TextView android:id="@+id/itemUploadDateView"
android:text="itemUploadDateView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_toRightOf="@id/itemThumbnailView" android:layout_toRightOf="@id/itemThumbnailView"
android:layout_toEndOf="@id/itemThumbnailView"
android:layout_below="@id/itemUploaderView" android:layout_below="@id/itemUploaderView"
android:textAppearance="?android:attr/textAppearanceSmall" android:textAppearance="?android:attr/textAppearanceSmall"
android:textSize="@dimen/text_search_uploadtime_size" android:textSize="@dimen/text_search_uploadtime_size"
@ -49,7 +51,9 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignBottom="@id/itemThumbnailView" android:layout_alignBottom="@id/itemThumbnailView"
android:layout_alignRight="@id/itemThumbnailView" android:layout_alignRight="@id/itemThumbnailView"
android:layout_alignEnd="@id/itemThumbnailView"
android:layout_marginRight="2dp" android:layout_marginRight="2dp"
android:layout_marginEnd="2dp"
android:layout_marginBottom="2dp" android:layout_marginBottom="2dp"
android:paddingTop="1dp" android:paddingTop="1dp"
android:paddingBottom="1dp" android:paddingBottom="1dp"
@ -58,8 +62,6 @@
android:textAppearance="?android:attr/textAppearanceSmall" android:textAppearance="?android:attr/textAppearanceSmall"
android:textSize="@dimen/text_search_duration_size" android:textSize="@dimen/text_search_duration_size"
android:background="@color/durationBackground" android:background="@color/durationBackground"
android:textColor="@color/durationText" android:textColor="@color/durationText"/>
android:text="duration"
/>
</RelativeLayout> </RelativeLayout>

View File

@ -3,7 +3,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto"> xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/action_search" <item android:id="@+id/action_search"
android:icon="@android:drawable/ic_menu_search" android:icon="@android:drawable/ic_menu_search"
app:showAsAction="always" app:showAsAction="ifRoom"
android:title="@string/search" android:title="@string/search"
app:actionViewClass="android.support.v7.widget.SearchView" /> app:actionViewClass="android.support.v7.widget.SearchView" />

View File

@ -2,20 +2,17 @@
<resources> <resources>
<string name="app_name">NewPipe</string> <string name="app_name">NewPipe</string>
<string name="title_videoitem_detail">NewPipe</string> <string name="title_videoitem_detail">NewPipe</string>
<string name="nothingFound">Nichts gefunden</string> <string name="viewCountText">%1$s Aufrufe</string>
<string name="viewSufix">Aufrufe</string> <string name="uploadDateText">Hochgeladen am %1$s</string>
<string name="uploadDatePrefix">Hochgeladen am </string>
<string name="noPlayerFound">Keinen Streamplayer gefunden. Vielleicht möchtest du einen installieren.</string> <string name="noPlayerFound">Keinen Streamplayer gefunden. Vielleicht möchtest du einen installieren.</string>
<string name="installStreamPlayer">Jetzt installieren</string> <string name="installStreamPlayer">Jetzt installieren</string>
<string name="cancel">Abbrechen</string> <string name="cancel">Abbrechen</string>
<string name="fdroidVLCurl">https://f-droid.org/repository/browse/?fdfilter=vlc&amp;fdid=org.videolan.vlc</string> <string name="fdroidVLCurl">https://f-droid.org/repository/browse/?fdfilter=vlc&amp;fdid=org.videolan.vlc</string>
<string name="open_in_browser">In Browser öffnen</string> <string name="open_in_browser">In Browser öffnen</string>
<string name="share">Teilen</string> <string name="share">Teilen</string>
<string name="play">Play</string>
<string name="download">Download</string> <string name="download">Download</string>
<string name="search">Suchen</string> <string name="search">Suchen</string>
<string name="settings">Einstellungen</string> <string name="settings">Einstellungen</string>
<string name="sendWith">Senden mit</string>
<string name="didYouMean">Meintest du: </string> <string name="didYouMean">Meintest du: </string>
<string name="searchPage">Suchseite: </string> <string name="searchPage">Suchseite: </string>
<string name="shareDialogTitle">Teilen mit:</string> <string name="shareDialogTitle">Teilen mit:</string>
@ -23,10 +20,10 @@
<string name="screenRotation">Rotation</string> <string name="screenRotation">Rotation</string>
<string name="title_activity_settings">Einstellungen</string> <string name="title_activity_settings">Einstellungen</string>
<string name="useExternalPlayerTitle">Externen Player benutzen</string> <string name="useExternalPlayerTitle">Externen Player benutzen</string>
<string name="downloadLocation">Download Verzeichnis</string> <string name="downloadLocation">Downloadverzeichnis</string>
<string name="downloadLocationSummary">Verzeichnis in dem heruntergeladene Videos gespeichert werden.</string> <string name="downloadLocationSummary">Verzeichnis in dem heruntergeladene Videos gespeichert werden.</string>
<string name="downloadLocationDialogTitle">Download Verzeichnis eingeben</string> <string name="downloadLocationDialogTitle">Download Verzeichnis eingeben</string>
<string name="autoPlayThroughIntentTitle">Automatisches abspielen durch Intent</string> <string name="autoPlayThroughIntentTitle">Automatisches Abspielen durch Intent</string>
<string name="autoPlayThroughIntentSummary">Startet ein Video automatisch wenn es von einer anderen App aufgerufen wurde.</string> <string name="autoPlayThroughIntentSummary">Startet ein Video automatisch wenn es von einer anderen App aufgerufen wurde.</string>
<string name="defaultResolutionPreferenceTitle">Standard Auflösung</string> <string name="defaultResolutionPreferenceTitle">Standard Auflösung</string>
<string name="playWithKodiTitle">Mit Kodi abspielen</string> <string name="playWithKodiTitle">Mit Kodi abspielen</string>
@ -46,7 +43,11 @@
<item>Audio</item> <item>Audio</item>
</string-array> </string-array>
<string name="nextVideoTitle">Nächstes Video</string> <string name="nextVideoTitle">Nächstes Video</string>
<string name="showNextAndSimilarTitle">Zeige nächstes und änliche Videos</string> <string name="showNextAndSimilarTitle">Zeige nächstes und ähnliche Videos</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> <string name="showSimilarVideosButtonText">Ähnliche Videos</string>
</resources> <string name="settingsCategoryVideoAudioTitle">VIDEO &amp; AUDIO</string>
<string name="settingsCategoryVideoInfoTittle">INFO</string>
<string name="settingsCategoryEtcTitle">ETC</string>
<string name="searchLanguageTitle">Bevorzugte Sprache</string>
</resources>

View File

@ -2,20 +2,17 @@
<resources> <resources>
<string name="app_name">NewPipe</string> <string name="app_name">NewPipe</string>
<string name="title_videoitem_detail">NewPipe</string> <string name="title_videoitem_detail">NewPipe</string>
<string name="nothingFound">No se ha encontrado nada</string> <string name="viewCountText">%1$s visitas</string>
<string name="viewSufix">visitas</string> <string name="uploadDateText">Subido el %1$s</string>
<string name="uploadDatePrefix">Subido el </string>
<string name="noPlayerFound">No se ha encontrado ningún reproductor de vídeo. Quizás quieras instalar alguno.</string> <string name="noPlayerFound">No se ha encontrado ningún reproductor de vídeo. Quizás quieras instalar alguno.</string>
<string name="installStreamPlayer">Instalarlo</string> <string name="installStreamPlayer">Instalarlo</string>
<string name="cancel">Cancelar</string> <string name="cancel">Cancelar</string>
<string name="fdroidVLCurl">https://f-droid.org/repository/browse/?fdfilter=vlc&amp;fdid=org.videolan.vlc</string> <string name="fdroidVLCurl">https://f-droid.org/repository/browse/?fdfilter=vlc&amp;fdid=org.videolan.vlc</string>
<string name="open_in_browser">Abrir en el navegador</string> <string name="open_in_browser">Abrir en el navegador</string>
<string name="share">Compartir</string> <string name="share">Compartir</string>
<string name="play">Reproducir</string>
<string name="download">Descargar</string> <string name="download">Descargar</string>
<string name="search">Buscar</string> <string name="search">Buscar</string>
<string name="settings">Ajustes</string> <string name="settings">Ajustes</string>
<string name="sendWith">Enviar con</string>
<string name="didYouMean">"¿Querías decir?: "</string> <string name="didYouMean">"¿Querías decir?: "</string>
<string name="searchPage">Buscar página: </string> <string name="searchPage">Buscar página: </string>
<string name="shareDialogTitle">Compartir con:</string> <string name="shareDialogTitle">Compartir con:</string>
@ -23,7 +20,7 @@
<string name="screenRotation">rotación</string> <string name="screenRotation">rotación</string>
<string name="title_activity_settings">Ajustes</string> <string name="title_activity_settings">Ajustes</string>
<string name="useExternalPlayerTitle">Usar reproductor externo</string> <string name="useExternalPlayerTitle">Usar reproductor externo</string>
<string name="downloadLocation">Descargar en...</string> <string name="downloadLocation">Descargar en&#8230;</string>
<string name="downloadLocationSummary">Ruta donde guardar los vídeos descargados.</string> <string name="downloadLocationSummary">Ruta donde guardar los vídeos descargados.</string>
<string name="downloadLocationDialogTitle">Localización del directorio de descargas</string> <string name="downloadLocationDialogTitle">Localización del directorio de descargas</string>
<string name="autoPlayThroughIntentTitle">Reproducción automática</string> <string name="autoPlayThroughIntentTitle">Reproducción automática</string>
@ -42,8 +39,6 @@
<string name="m4aAudioDescription">m4a - mejor calidad</string> <string name="m4aAudioDescription">m4a - mejor calidad</string>
<string name="downloadDialogTitle">Descargar</string> <string name="downloadDialogTitle">Descargar</string>
<string name="nextVideoTitle">Siguiente vídeo</string> <string name="nextVideoTitle">Siguiente vídeo</string>
<string name="showNextVideoTitle">Mostrar la opción \"Siguiente vídeo\".</string>
<string name="urlNotSupportedText">URL no soportada.</string> <string name="urlNotSupportedText">URL no soportada.</string>
<string name="showSimilarVideosButtonText">Vídeos similares</string> <string name="showSimilarVideosButtonText">Vídeos similares</string>
<string name="contentCountryTitle">País del contenido del vídeo</string>
</resources> </resources>

View File

@ -2,20 +2,17 @@
<resources> <resources>
<string name="app_name">NewPipe</string> <string name="app_name">NewPipe</string>
<string name="title_videoitem_detail">NewPipe</string> <string name="title_videoitem_detail">NewPipe</string>
<string name="nothingFound">چیزی پیدا نشد</string> <string name="viewCountText">%1$s نماها</string>
<string name="viewSufix">نماها</string> <string name="uploadDateText">بارگذاری‌شده در: %1$s</string>
<string name="uploadDatePrefix">بارگذاری‌شده در: </string>
<string name="noPlayerFound">هیچ پخش‌کننده‌ی جریانی یافت نشد. ممکن است بخواهید یکی نصب کنید.</string> <string name="noPlayerFound">هیچ پخش‌کننده‌ی جریانی یافت نشد. ممکن است بخواهید یکی نصب کنید.</string>
<string name="installStreamPlayer">نصب کنید</string> <string name="installStreamPlayer">نصب کنید</string>
<string name="cancel">انصراف</string> <string name="cancel">انصراف</string>
<string name="fdroidVLCurl">https://f-droid.org/repository/browse/?fdfilter=vlc&amp;fdid=org.videolan.vlc</string> <string name="fdroidVLCurl">https://f-droid.org/repository/browse/?fdfilter=vlc&amp;fdid=org.videolan.vlc</string>
<string name="open_in_browser">بازکردن در مرورگر</string> <string name="open_in_browser">بازکردن در مرورگر</string>
<string name="share">هم‌رسانی</string> <string name="share">هم‌رسانی</string>
<string name="play">پخش</string>
<string name="download">بارگیری</string> <string name="download">بارگیری</string>
<string name="search">جستجو</string> <string name="search">جستجو</string>
<string name="settings">تنظیمات</string> <string name="settings">تنظیمات</string>
<string name="sendWith">فرستادن با</string>
<string name="didYouMean">منظورتان این است: </string> <string name="didYouMean">منظورتان این است: </string>
<string name="searchPage">صفحه‌ی جستجو: </string> <string name="searchPage">صفحه‌ی جستجو: </string>
<string name="shareDialogTitle">هم‌رسانی با:</string> <string name="shareDialogTitle">هم‌رسانی با:</string>
@ -46,6 +43,5 @@
<item>صدا</item> <item>صدا</item>
</string-array> </string-array>
<string name="nextVideoTitle">ویدئوی بعدی</string> <string name="nextVideoTitle">ویدئوی بعدی</string>
<string name="showNextVideoTitle">نمایش گزینه‌ی «ویدئوی بعدی».</string>
<string name="urlNotSupportedText">پیوند پشتیبانی نمی‌شود.</string> <string name="urlNotSupportedText">پیوند پشتیبانی نمی‌شود.</string>
</resources> </resources>

View File

@ -16,15 +16,12 @@
<string name="installeKore">Installer Kore</string> <string name="installeKore">Installer Kore</string>
<string name="koreNotFound">L\'application Kore est introuvable. Kore est nécessaire afin de lire des vidéos dans Kodi media center.</string> <string name="koreNotFound">L\'application Kore est introuvable. Kore est nécessaire afin de lire des vidéos dans Kodi media center.</string>
<string name="noPlayerFound">Aucun lecteur de streaming détecté. Vous devriez en installer un.</string> <string name="noPlayerFound">Aucun lecteur de streaming détecté. Vous devriez en installer un.</string>
<string name="nothingFound">Aucun résultat</string>
<string name="open_in_browser">Ouvrir dans le navigateur</string> <string name="open_in_browser">Ouvrir dans le navigateur</string>
<string name="play">Lire</string>
<string name="autoPlayThroughIntentTitle">Lecture automatique via Intent</string> <string name="autoPlayThroughIntentTitle">Lecture automatique via Intent</string>
<string name="playWithKodiTitle">Lire avec Kodi</string> <string name="playWithKodiTitle">Lire avec Kodi</string>
<string name="screenRotation">rotation</string> <string name="screenRotation">rotation</string>
<string name="search">Chercher</string> <string name="search">Chercher</string>
<string name="searchPage">Chercher dans la page:</string> <string name="searchPage">Chercher dans la page:</string>
<string name="sendWith">Envoyer avec</string>
<string name="settings">Paramètres</string> <string name="settings">Paramètres</string>
<string name="share">Partager</string> <string name="share">Partager</string>
<string name="shareDialogTitle">Partager avec:</string> <string name="shareDialogTitle">Partager avec:</string>
@ -32,7 +29,17 @@
<string name="showPlayWithKodiTitle">Afficher l\'option \"Lire avec Kodi\"</string> <string name="showPlayWithKodiTitle">Afficher l\'option \"Lire avec Kodi\"</string>
<string name="title_activity_settings">Paramètres</string> <string name="title_activity_settings">Paramètres</string>
<string name="title_videoitem_detail">NewPipe</string> <string name="title_videoitem_detail">NewPipe</string>
<string name="uploadDatePrefix">Mise en ligne le </string> <string name="uploadDateText">Mise en ligne le %1$s</string>
<string name="useExternalPlayerTitle">Utiliser un lecteur externe</string> <string name="useExternalPlayerTitle">Utiliser un lecteur externe</string>
<string name="viewSufix">vues</string> <string name="viewCountText">%1$s vues</string>
</resources> <string name="leftPlayButtonTitle">Afficher le bouton de lecture sur la gauche.</string>
<string name="playAudio">Audio</string>
<string name="defaultAudioFormatTitle">Format audio par défaut</string>
<string name="webMAudioDescription">WebM- format libre</string>
<string name="m4aAudioDescription">m4a - meilleur qualité</string>
<string name="downloadDialogTitle">Télécharger</string>
<string name="nextVideoTitle">Vidéo suivante</string>
<string name="showNextAndSimilarTitle">Afficher les vidéos suivantes et similaires</string>
<string name="urlNotSupportedText">URL non supportée.</string>
<string name="showSimilarVideosButtonText">Vidéos similaires</string>
</resources>

View File

@ -2,20 +2,17 @@
<resources> <resources>
<string name="app_name">NewPipe</string> <string name="app_name">NewPipe</string>
<string name="title_videoitem_detail">NewPipe</string> <string name="title_videoitem_detail">NewPipe</string>
<string name="nothingFound">Nincs találat</string> <string name="viewCountText">%1$s megtekintés</string>
<string name="viewSufix">megtekintés</string> <string name="uploadDateText">Feltöltve: %1$s</string>
<string name="uploadDatePrefix">Feltöltve: </string>
<string name="noPlayerFound">Nem található lejátszó. Telepítsen egyet!</string> <string name="noPlayerFound">Nem található lejátszó. Telepítsen egyet!</string>
<string name="installStreamPlayer">Telepítsen egyet</string> <string name="installStreamPlayer">Telepítsen egyet</string>
<string name="cancel">Mégse</string> <string name="cancel">Mégse</string>
<string name="fdroidVLCurl">https://f-droid.org/repository/browse/?fdfilter=vlc&amp;fdid=org.videolan.vlc</string> <string name="fdroidVLCurl">https://f-droid.org/repository/browse/?fdfilter=vlc&amp;fdid=org.videolan.vlc</string>
<string name="open_in_browser">Megnyitás böngészőben</string> <string name="open_in_browser">Megnyitás böngészőben</string>
<string name="share">Megosztás</string> <string name="share">Megosztás</string>
<string name="play">Lejátszás</string>
<string name="download">Letöltés</string> <string name="download">Letöltés</string>
<string name="search">Keresés</string> <string name="search">Keresés</string>
<string name="settings">Beállítások</string> <string name="settings">Beállítások</string>
<string name="sendWith">Küldés ezzel:</string>
<string name="didYouMean">Erre gondolt: </string> <string name="didYouMean">Erre gondolt: </string>
<string name="searchPage">Keresési lap: </string> <string name="searchPage">Keresési lap: </string>
<string name="shareDialogTitle">Megosztás ezzel:</string> <string name="shareDialogTitle">Megosztás ezzel:</string>
@ -46,7 +43,6 @@
<item>Hang</item> <item>Hang</item>
</string-array> </string-array>
<string name="nextVideoTitle">Következő videó</string> <string name="nextVideoTitle">Következő videó</string>
<string name="showNextVideoTitle">\"Következő videó\" elem mutatása</string>
<string name="urlNotSupportedText">A webcím nem támogatott.</string> <string name="urlNotSupportedText">A webcím nem támogatott.</string>
<string name="showSimilarVideosButtonText">Hasonló videók</string> <string name="showSimilarVideosButtonText">Hasonló videók</string>
</resources> </resources>

View File

@ -0,0 +1,52 @@
<?xml version='1.0' encoding='utf-8'?>
<resources><string name="app_name">NewPipe</string>
<string name="title_videoitem_detail">NewPipe</string>
<string name="nothingFound">何も見つかりません</string>
<string name="viewSufix">表示</string>
<string name="uploadDateText">"アップロード: "%1$s</string>
<string name="noPlayerFound">StreamPlayer が見つかりませんでした。インストールが必要になるかもしれません。</string>
<string name="installStreamPlayer">インストール</string>
<string name="cancel">取り消し</string>
<string name="fdroidVLCurl">https://f-droid.org/repository/browse/?fdfilter=vlc&amp;fdid=org.videolan.vlc</string>
<string name="open_in_browser">ブラウザーで開く</string>
<string name="share">共有</string>
<string name="play">再生</string>
<string name="download">ダウンロード</string>
<string name="search">検索</string>
<string name="settings">設定</string>
<string name="sendWith">送信</string>
<string name="didYouMean">"この意味ですか: "</string>
<string name="searchPage">"検索ページ: "</string>
<string name="shareDialogTitle">…共有:</string>
<string name="chooseBrowser">ブラウザーを選択:</string>
<string name="screenRotation">回転</string>
<string name="title_activity_settings">設定</string>
<string name="useExternalPlayerTitle">外部プレーヤーを使用する</string>
<string name="downloadLocation">ダウンロードする場所</string>
<string name="downloadLocationSummary">ダウンロードした動画を保存する場所のパス。</string>
<string name="downloadLocationDialogTitle">ダウンロードのパスを入力してください。</string>
<string name="autoPlayThroughIntentTitle">インテントで自動再生</string>
<string name="autoPlayThroughIntentSummary">他のアプリケーションから呼び出されたとき、自動的に動画再生を開始します。</string>
<string name="defaultResolutionPreferenceTitle">基本の解像度</string>
<string name="playWithKodiTitle">Kodi で再生</string>
<string name="koreNotFound">Kore アプリが見つかりません。 Kodi メディアセンターで動画を再生するには、 Kore が必要です。</string>
<string name="installeKore">Kore をインストール</string>
<string name="fdroidKoreUrl">https://f-droid.org/repository/browse/?fdfilter=Kore&amp;fdid=org.xbmc.kore</string>
<string name="showPlayWithKodiTitle">\"Kodi で再生\" 設定を表示</string>
<string name="showPlayWithKodiSummary">Kodi メディアセンター経由で動画を再生するための設定を表示します.</string>
<string name="leftPlayButtonTitle">左側に再生ボタンを表示.</string>
<string name="playAudio">オーディオ</string>
<string name="defaultAudioFormatTitle">基本のオーディオフォーマット</string>
<string name="webMAudioDescription">.WebM - フリーフォーマット</string>
<string name="m4aAudioDescription">.m4a - より良い品質</string>
<string name="downloadDialogTitle">ダウンロード</string>
<string name="nextVideoTitle">次の動画</string>
<string name="showNextAndSimilarTitle">次の同様の動画を表示します。</string>
<string name="urlNotSupportedText">URL は使用できません。</string>
<string name="showSimilarVideosButtonText">同様の動画</string>
<string name="searchLanguageTitle">優先される言語</string>
<string name="settingsCategoryVideoAudioTitle">動画とオーディオ</string>
<string name="settingsCategoryVideoInfoTittle">情報</string>
<string name="settingsCategoryEtcTitle">その他</string>
</resources>

View File

@ -2,20 +2,17 @@
<resources> <resources>
<string name="app_name">NewPipe</string> <string name="app_name">NewPipe</string>
<string name="title_videoitem_detail">NewPipe</string> <string name="title_videoitem_detail">NewPipe</string>
<string name="nothingFound">Geen resultaten</string> <string name="viewCountText">%1$s keer bekeken</string>
<string name="viewSufix">keer bekeken</string> <string name="uploadDateText">Geüpload op %1$s</string>
<string name="uploadDatePrefix">Geüpload op </string>
<string name="noPlayerFound">Geen speler met streaming ondersteuning gevonden. Misschien wil je er een installeren.</string> <string name="noPlayerFound">Geen speler met streaming ondersteuning gevonden. Misschien wil je er een installeren.</string>
<string name="installStreamPlayer">Installeer speler</string> <string name="installStreamPlayer">Installeer speler</string>
<string name="cancel">Annuleer</string> <string name="cancel">Annuleer</string>
<string name="fdroidVLCurl">https://f-droid.org/repository/browse/?fdfilter=vlc&amp;fdid=org.videolan.vlc</string> <string name="fdroidVLCurl">https://f-droid.org/repository/browse/?fdfilter=vlc&amp;fdid=org.videolan.vlc</string>
<string name="open_in_browser">Open in browser</string> <string name="open_in_browser">Open in browser</string>
<string name="share">Deel</string> <string name="share">Deel</string>
<string name="play">Speel af</string>
<string name="download">Download</string> <string name="download">Download</string>
<string name="search">Zoek</string> <string name="search">Zoek</string>
<string name="settings">Instellingen</string> <string name="settings">Instellingen</string>
<string name="sendWith">Verstuur met</string>
<string name="didYouMean">Bedoelde je: </string> <string name="didYouMean">Bedoelde je: </string>
<string name="searchPage">Zoekpagina: </string> <string name="searchPage">Zoekpagina: </string>
<string name="shareDialogTitle">Deel met:</string> <string name="shareDialogTitle">Deel met:</string>
@ -35,16 +32,15 @@
<string name="fdroidKoreUrl">https://f-droid.org/repository/browse/?fdfilter=Kore&amp;fdid=org.xbmc.kore</string> <string name="fdroidKoreUrl">https://f-droid.org/repository/browse/?fdfilter=Kore&amp;fdid=org.xbmc.kore</string>
<string name="showPlayWithKodiTitle">Toon \"Speel af met Kodi\" optie</string> <string name="showPlayWithKodiTitle">Toon \"Speel af met Kodi\" optie</string>
<string name="showPlayWithKodiSummary">Toont een optie om een video op een Kodi media center af te spelen.</string> <string name="showPlayWithKodiSummary">Toont een optie om een video op een Kodi media center af te spelen.</string>
<string name="contentCountryTitle">Video inhoud land</string> <string name="leftPlayButtonTitle">Afspeel knop aan de linker kant weergeven.</string>
<string name="leftPlayButtonTitle">Afspeel knop aan de linker kant weergeven.</string>
<string name="playAudio">Audio</string> <string name="playAudio">Audio</string>
<string name="defaultAudioFormatTitle">Standaard audio formaat</string> <string name="defaultAudioFormatTitle">Standaard audio formaat</string>
<string name="webMAudioDescription">Webam - open formaat</string> <string name="webMAudioDescription">Webam - open formaat</string>
<string name="m4aAudioDescription">m4a - betere kwaliteit</string> <string name="m4aAudioDescription">m4a - betere kwaliteit</string>
<string name="downloadDialogTitle">Download</string> <string name="downloadDialogTitle">Download</string>
<string name="nextVideoTitle">Volgende video</string> <string name="nextVideoTitle">Volgende video</string>
<string name="showNextVideoTitle">\"Volgende video\" weergeven</string>
<string name="urlNotSupportedText">URL wordt niet ondersteund.</string> <string name="urlNotSupportedText">URL wordt niet ondersteund.</string>
<string name="showSimilarVideosButtonText">Vergelijkbare videos</string> <string name="showSimilarVideosButtonText">Vergelijkbare videos</string>
<string name="showNextAndSimilarTitle">Laat volgende en vergelijkbare videos zien</string> <string name="showNextAndSimilarTitle">Laat volgende en vergelijkbare videos zien</string>
</resources> <string name="searchLanguageTitle">Voorkeurs content taal</string>
</resources>

View File

@ -0,0 +1,49 @@
<?xml version='1.0' encoding='utf-8'?>
<resources><string name="app_name">NewPipe</string>
<string name="title_videoitem_detail">NewPipe</string>
<string name="nothingFound">Brak wyników</string>
<string name="viewSufix">wyświetleń</string>
<string name="uploadDatePrefix">"Opublikowany "</string>
<string name="noPlayerFound">Nie znaleziono odtwarzacza strumieniowego.</string>
<string name="installStreamPlayer">Zainstaluj</string>
<string name="cancel">Anuluj</string>
<string name="open_in_browser">Otwórz w przeglądarce</string>
<string name="share">Udostępnij</string>
<string name="play">Odtwórz</string>
<string name="download">Pobierz</string>
<string name="search">Szukaj</string>
<string name="settings">Ustawienia</string>
<string name="sendWith">Wyślij za pośrednictwem</string>
<string name="didYouMean">"Czy chodziło Ci o: "</string>
<string name="shareDialogTitle">Udostępnij za pośrednictwem:</string>
<string name="chooseBrowser">Wybierz przeglądarkę:</string>
<string name="screenRotation">obrót</string>
<string name="title_activity_settings">Ustawienia</string>
<string name="useExternalPlayerTitle">Użyj zewnętrznego odtwarzacza</string>
<string name="downloadLocation">Miejsce zapisu pobieranych plików</string>
<string name="downloadLocationSummary">Ścieżka folderu do zapisywania pobieranego wideo.</string>
<string name="downloadLocationDialogTitle">Wprowadź ścieżkę folderu dla pobieranych plików</string>
<string name="autoPlayThroughIntentTitle">Automatycznie odtwarzaj przez Intent</string>
<string name="autoPlayThroughIntentSummary">Automatycznie odtwarza wideo po wywołaniu z innej aplikacji.</string>
<string name="defaultResolutionPreferenceTitle">Domyślna rozdzielczość</string>
<string name="playWithKodiTitle">Odtwarzaj za pośrednictwem Kodi</string>
<string name="koreNotFound">Aplikacja Kode nie została znaleziona. Wymagana jest do odtwarzania w Kodi.</string>
<string name="installeKore">Zainstaluj Kore</string>
<string name="showPlayWithKodiTitle">Wyświetlaj opcję \"Odtwarzaj za pośrednictwem Kodi\"</string>
<string name="showPlayWithKodiSummary">Wyświetla opcję do odtwarzania wideo przez aplikację Kodi.</string>
<string name="leftPlayButtonTitle">Wyświetl przycisk odtwarzania po lewej stronie.</string>
<string name="playAudio">Dźwięk</string>
<string name="defaultAudioFormatTitle">Domyślny format dźwięku</string>
<string name="webMAudioDescription">WebM - otwarty format</string>
<string name="m4aAudioDescription">m4a - lepsza jakość</string>
<string name="downloadDialogTitle">Pobierz</string>
<string name="nextVideoTitle">Następne wideo</string>
<string name="showNextAndSimilarTitle">Wyświetl następne i podobne wideo</string>
<string name="urlNotSupportedText">Niewspierany URL.</string>
<string name="showSimilarVideosButtonText">Podobne wideo</string>
<string name="searchLanguageTitle">Preferowany język zawartości</string>
<string name="settingsCategoryVideoAudioTitle">WIDEO &amp; DŹWIĘK</string>
<string name="settingsCategoryVideoInfoTittle">INFO</string>
<string name="settingsCategoryEtcTitle">INNE</string>
<string name="searchPage">"Szukaj strony: "</string>
</resources>

View File

@ -2,20 +2,17 @@
<resources> <resources>
<string name="app_name">NewPipe</string> <string name="app_name">NewPipe</string>
<string name="title_videoitem_detail">NewPipe</string> <string name="title_videoitem_detail">NewPipe</string>
<string name="nothingFound">Ничего не найдено</string> <string name="viewCountText">%1$s просмотров</string>
<string name="viewSufix">просмотров</string> <string name="uploadDateText">Опубликовано: %1$s</string>
<string name="uploadDatePrefix">Опубликовано: </string>
<string name="noPlayerFound">Ни одного потокового проигрывателя не было найдено. Установить?</string> <string name="noPlayerFound">Ни одного потокового проигрывателя не было найдено. Установить?</string>
<string name="installStreamPlayer">Установить</string> <string name="installStreamPlayer">Установить</string>
<string name="cancel">Отмена</string> <string name="cancel">Отмена</string>
<string name="fdroidVLCurl">https://f-droid.org/repository/browse/?fdfilter=vlc&amp;fdid=org.videolan.vlc</string> <string name="fdroidVLCurl">https://f-droid.org/repository/browse/?fdfilter=vlc&amp;fdid=org.videolan.vlc</string>
<string name="open_in_browser">Открыть в браузере</string> <string name="open_in_browser">Открыть в браузере</string>
<string name="share">Поделиться</string> <string name="share">Поделиться</string>
<string name="play">Воспроизвести</string>
<string name="download">Скачать</string> <string name="download">Скачать</string>
<string name="search">Найти</string> <string name="search">Найти</string>
<string name="settings">Настройки</string> <string name="settings">Настройки</string>
<string name="sendWith">Отправить с помощью</string>
<string name="didYouMean">Возможно, вы имели в виду: </string> <string name="didYouMean">Возможно, вы имели в виду: </string>
<string name="searchPage">Страница поиска: </string> <string name="searchPage">Страница поиска: </string>
<string name="shareDialogTitle">Поделиться с помощью:</string> <string name="shareDialogTitle">Поделиться с помощью:</string>
@ -46,9 +43,8 @@
<item>Аудио</item> <item>Аудио</item>
</string-array> </string-array>
<string name="nextVideoTitle">Следующее видео</string> <string name="nextVideoTitle">Следующее видео</string>
<string name="showNextVideoTitle">Показать \"Следующее видео\".</string>
<string name="urlNotSupportedText">URL не поддерживается.</string> <string name="urlNotSupportedText">URL не поддерживается.</string>
<string name="showSimilarVideosButtonText">Похожие видео</string> <string name="showSimilarVideosButtonText">Похожие видео</string>
<string name="showNextAndSimilarTitle">Показывать следующее и предложенные видео</string> <string name="showNextAndSimilarTitle">Показывать следующее и предложенные видео</string>
<string name="searchLanguageTitle">Предпочитаемый язык контента</string> <string name="searchLanguageTitle">Предпочитаемый язык контента</string>
</resources> </resources>

View File

@ -2,20 +2,17 @@
<resources> <resources>
<string name="app_name">Јутјуб цев</string> <string name="app_name">Јутјуб цев</string>
<string name="title_videoitem_detail">Јутјуб цев</string> <string name="title_videoitem_detail">Јутјуб цев</string>
<string name="nothingFound">Ништа није нађено</string> <string name="viewCountText">%1$s приказа</string>
<string name="viewSufix">приказа</string> <string name="uploadDateText">"Отпремљен "%1$s</string>
<string name="uploadDatePrefix">"Отпремљено "</string>
<string name="noPlayerFound">Нема плејера токова. Можда желите да га инсталирате.</string> <string name="noPlayerFound">Нема плејера токова. Можда желите да га инсталирате.</string>
<string name="installStreamPlayer">Инсталирај</string> <string name="installStreamPlayer">Инсталирај</string>
<string name="cancel">Одустани</string> <string name="cancel">Одустани</string>
<string name="fdroidVLCurl">https://f-droid.org/repository/browse/?fdfilter=vlc&amp;fdid=org.videolan.vlc</string> <string name="fdroidVLCurl">https://f-droid.org/repository/browse/?fdfilter=vlc&amp;fdid=org.videolan.vlc</string>
<string name="open_in_browser">Отвори у прегледачу</string> <string name="open_in_browser">Отвори у прегледачу</string>
<string name="share">Дели</string> <string name="share">Дели</string>
<string name="play">Пусти</string>
<string name="download">Преузми</string> <string name="download">Преузми</string>
<string name="search">Тражи</string> <string name="search">Тражи</string>
<string name="settings">Поставке</string> <string name="settings">Поставке</string>
<string name="sendWith">Пошаљи помоћу</string>
<string name="didYouMean">Да ли сте мислили: </string> <string name="didYouMean">Да ли сте мислили: </string>
<string name="searchPage">Страница претраге: </string> <string name="searchPage">Страница претраге: </string>
<string name="shareDialogTitle">Подели помоћу:</string> <string name="shareDialogTitle">Подели помоћу:</string>
@ -45,10 +42,12 @@
<item>Видео</item> <item>Видео</item>
<item>Аудио</item> <item>Аудио</item>
</string-array> </string-array>
<string name="nextVideoTitle">Следећи видео</string> <string name="nextVideoTitle">Следећи видео</string>
<string name="showNextVideoTitle">Приказ ставке „Следећи видео“.</string>
<string name="urlNotSupportedText">УРЛ није подржан.</string> <string name="urlNotSupportedText">УРЛ није подржан.</string>
<string name="showNextAndSimilarTitle">Прикажи следећи и слични видео</string> <string name="showNextAndSimilarTitle">Прикажи следећи и слични видео</string>
<string name="showSimilarVideosButtonText">Слични видео</string> <string name="showSimilarVideosButtonText">Слични видео</string>
<string name="searchLanguageTitle">Пожељни језик садржаја</string> <string name="searchLanguageTitle">Пожељни језик садржаја</string>
<string name="settingsCategoryVideoAudioTitle">ВИДЕО И АУДИО</string>
<string name="settingsCategoryVideoInfoTittle">ПОДАЦИ</string>
<string name="settingsCategoryEtcTitle">ОСТАЛО</string>
</resources> </resources>

View File

@ -16,17 +16,18 @@
<item name="background">@color/primaryColorYoutube</item> <item name="background">@color/primaryColorYoutube</item>
</style> </style>
<style name="FullscreenTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <style name="VideoPlayerTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="android:windowFullscreen">false</item> <item name="android:windowFullscreen">false</item>
<item name="android:windowActionBarOverlay">true</item> <item name="android:windowActionBarOverlay">true</item>
<item name="windowActionBarOverlay">true</item> <item name="windowActionBarOverlay">true</item>
<item name="android:actionBarStyle">@style/NewPipePlayerActionBarTheme</item> <item name="android:actionBarStyle">@style/VideoPlayerActionBarTheme</item>
<item name="actionBarStyle">@style/NewPipePlayerActionBarTheme</item> <item name="actionBarStyle">@style/VideoPlayerActionBarTheme</item>
<item name="colorAccent">@color/primaryColorYoutube</item> <item name="colorAccent">@color/primaryColorYoutube</item>
<item name="android:colorAccent">@color/primaryColorYoutube</item> <item name="android:colorAccent">@color/primaryColorYoutube</item>
<item name="android:windowBackground">@android:color/black</item>
</style> </style>
<style name="NewPipePlayerActionBarTheme" parent="Widget.AppCompat.Light.ActionBar.Solid.Inverse" > <style name="VideoPlayerActionBarTheme" parent="Widget.AppCompat.Light.ActionBar.Solid.Inverse" >
<item name="android:displayOptions">showHome</item> <item name="android:displayOptions">showHome</item>
<item name="displayOptions">showHome</item> <item name="displayOptions">showHome</item>
<item name="android:background">@color/black_overlay</item> <item name="android:background">@color/black_overlay</item>

View File

@ -1,5 +1,10 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<!-- Categories -->
<string name="settingsCategoryVideoAudio">settings_categoery_video_audio</string>
<string name="settingsCategoryVideoInfo">settings_category_video_info</string>
<string name="settingsCategoryEtc">settings_category_etc</string>
<!-- Key values -->
<string name="downloadPathPreference">download_path_preference</string> <string name="downloadPathPreference">download_path_preference</string>
<string name="useExternalPlayer">use_external_player</string> <string name="useExternalPlayer">use_external_player</string>
<string name="autoPlayThroughIntent">autoplay_through_intent</string> <string name="autoPlayThroughIntent">autoplay_through_intent</string>

View File

@ -1,21 +1,18 @@
<?xml version='1.0' encoding='utf-8'?> <?xml version='1.0' encoding='utf-8'?>
<resources> <resources>
<string name="app_name">NewPipe</string> <string name="app_name" translatable="false">NewPipe</string>
<string name="title_videoitem_detail">NewPipe</string> <string name="title_videoitem_detail" translatable="false">NewPipe</string>
<string name="nothingFound">Nothing found</string> <string name="viewCountText">%1$s views</string>
<string name="viewSufix">views</string> <string name="uploadDateText">Uploaded on %1$s</string>
<string name="uploadDatePrefix">Uploaded on </string>
<string name="noPlayerFound">No stream player found. You may want to install one.</string> <string name="noPlayerFound">No stream player found. You may want to install one.</string>
<string name="installStreamPlayer">Install</string> <string name="installStreamPlayer">Install</string>
<string name="cancel">Cancel</string> <string name="cancel">Cancel</string>
<string name="fdroidVLCurl">https://f-droid.org/repository/browse/?fdfilter=vlc&amp;fdid=org.videolan.vlc</string> <string name="fdroidVLCurl" translatable="false">https://f-droid.org/repository/browse/?fdfilter=vlc&amp;fdid=org.videolan.vlc</string>
<string name="open_in_browser">Open in browser</string> <string name="open_in_browser">Open in browser</string>
<string name="share">Share</string> <string name="share">Share</string>
<string name="play">Play</string>
<string name="download">Download</string> <string name="download">Download</string>
<string name="search">Search</string> <string name="search">Search</string>
<string name="settings">Settings</string> <string name="settings">Settings</string>
<string name="sendWith">Send with</string>
<string name="didYouMean">Did you mean: </string> <string name="didYouMean">Did you mean: </string>
<string name="searchPage">Search page: </string> <string name="searchPage">Search page: </string>
<string name="shareDialogTitle">Share with:</string> <string name="shareDialogTitle">Share with:</string>
@ -32,7 +29,7 @@
<string name="playWithKodiTitle">Play with Kodi</string> <string name="playWithKodiTitle">Play with Kodi</string>
<string name="koreNotFound">Kore app not found. Kore is needed to play videos with Kodi media center.</string> <string name="koreNotFound">Kore app not found. Kore is needed to play videos with Kodi media center.</string>
<string name="installeKore">Install Kore</string> <string name="installeKore">Install Kore</string>
<string name="fdroidKoreUrl">https://f-droid.org/repository/browse/?fdfilter=Kore&amp;fdid=org.xbmc.kore</string> <string name="fdroidKoreUrl" translatable="false">https://f-droid.org/repository/browse/?fdfilter=Kore&amp;fdid=org.xbmc.kore</string>
<string name="showPlayWithKodiTitle">Show \"Play with Kodi\" option</string> <string name="showPlayWithKodiTitle">Show \"Play with Kodi\" option</string>
<string name="showPlayWithKodiSummary">Displays an option to play a video via Kodi media center.</string> <string name="showPlayWithKodiSummary">Displays an option to play a video via Kodi media center.</string>
<string name="leftPlayButtonTitle">Show play button on the left side.</string> <string name="leftPlayButtonTitle">Show play button on the left side.</string>
@ -50,4 +47,14 @@
<string name="urlNotSupportedText">URL not supported.</string> <string name="urlNotSupportedText">URL not supported.</string>
<string name="showSimilarVideosButtonText">Similar videos</string> <string name="showSimilarVideosButtonText">Similar videos</string>
<string name="searchLanguageTitle">Preferable content language</string> <string name="searchLanguageTitle">Preferable content language</string>
<string name="settingsCategoryVideoAudioTitle">VIDEO &amp; AUDIO</string>
<string name="settingsCategoryVideoInfoTittle">INFO</string>
<string name="settingsCategoryEtcTitle">ETC</string>
<!-- Content descriptions (for better accessibility) -->
<string name="itemThumbnailViewDescription">Video preview thumbnail</string>
<string name="detailThumbnailViewDescription">Video preview thumbnail</string>
<string name="detailUploaderThumbnailViewDescription">Uploader thumbnail</string>
<string name="detailThumbsDownImgViewDescription">Unlikes</string>
<string name="detailThumbsUpImgViewDescription">Likes</string>
</resources> </resources>

View File

@ -15,16 +15,17 @@
<item name="background">@color/primaryColorYoutube</item> <item name="background">@color/primaryColorYoutube</item>
</style> </style>
<style name="FullscreenTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <style name="VideoPlayerTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="android:windowFullscreen">false</item> <item name="android:windowFullscreen">false</item>
<item name="android:windowActionBarOverlay">true</item> <item name="android:windowActionBarOverlay">true</item>
<item name="windowActionBarOverlay">true</item> <item name="windowActionBarOverlay">true</item>
<item name="android:actionBarStyle">@style/NewPipePlayerActionBarTheme</item> <item name="android:actionBarStyle">@style/VideoPlayerActionBarTheme</item>
<item name="actionBarStyle">@style/NewPipePlayerActionBarTheme</item> <item name="actionBarStyle">@style/VideoPlayerActionBarTheme</item>
<item name="colorAccent">@color/primaryColorYoutube</item> <item name="colorAccent">@color/primaryColorYoutube</item>
<item name="android:windowBackground">@android:color/black</item>
</style> </style>
<style name="NewPipePlayerActionBarTheme" parent="Widget.AppCompat.Light.ActionBar.Solid.Inverse" > <style name="VideoPlayerActionBarTheme" parent="Widget.AppCompat.Light.ActionBar.Solid.Inverse" >
<item name="android:displayOptions">showHome</item> <item name="android:displayOptions">showHome</item>
<item name="displayOptions">showHome</item> <item name="displayOptions">showHome</item>
<item name="android:background">@color/black_overlay</item> <item name="android:background">@color/black_overlay</item>

View File

@ -3,59 +3,75 @@
android:title="@string/title_activity_settings" android:title="@string/title_activity_settings"
android:key="general_preferences"> android:key="general_preferences">
<CheckBoxPreference <PreferenceCategory
android:key="@string/useExternalPlayer" android:key="@string/settingsCategoryVideoAudio"
android:title="@string/useExternalPlayerTitle" android:title="@string/settingsCategoryVideoAudioTitle">
android:defaultValue="false"/>
<EditTextPreference <CheckBoxPreference
android:key="@string/downloadPathPreference" android:key="@string/useExternalPlayer"
android:title="@string/downloadLocation" android:title="@string/useExternalPlayerTitle"
android:summary="@string/downloadLocationSummary" android:defaultValue="false"/>
android:dialogTitle="@string/downloadLocationDialogTitle"
android:defaultValue=""/>
<CheckBoxPreference <ListPreference
android:key="@string/autoPlayThroughIntent" android:key="@string/defaultResolutionPreference"
android:title="@string/autoPlayThroughIntentTitle" android:title="@string/defaultResolutionPreferenceTitle"
android:summary="@string/autoPlayThroughIntentSummary" android:entries="@array/resolutionList"
android:defaultValue="false" /> android:entryValues="@array/resolutionList"
android:defaultValue="@string/defaultResolutionListItem"/>
<ListPreference <ListPreference
android:key="@string/defaultResolutionPreference" android:key="@string/defaultAudioFormatPreference"
android:title="@string/defaultResolutionPreferenceTitle" android:title="@string/defaultAudioFormatTitle"
android:entries="@array/resolutionList" android:entries="@array/audioFormatDescriptionList"
android:entryValues="@array/resolutionList" android:entryValues="@array/audioFormatList"
android:defaultValue="@string/defaultResolutionListItem"/> android:defaultValue="@string/defaultAudioFormat"/>
<CheckBoxPreference </PreferenceCategory>
android:key="@string/showPlayWidthKodiPreference" <PreferenceCategory
android:title="@string/showPlayWithKodiTitle" android:key="@string/settingsCategoryVideoInfo"
android:summary="@string/showPlayWithKodiSummary" android:title="@string/settingsCategoryVideoInfoTittle">
android:defaultValue="false" />
<CheckBoxPreference <CheckBoxPreference
android:key="@string/leftHandLayout" android:key="@string/showPlayWidthKodiPreference"
android:title="@string/leftPlayButtonTitle" android:title="@string/showPlayWithKodiTitle"
android:defaultValue="false" /> android:summary="@string/showPlayWithKodiSummary"
android:defaultValue="false" />
<ListPreference <CheckBoxPreference
android:key="@string/defaultAudioFormatPreference" android:key="@string/leftHandLayout"
android:title="@string/defaultAudioFormatTitle" android:title="@string/leftPlayButtonTitle"
android:entries="@array/audioFormatDescriptionList" android:defaultValue="false" />
android:entryValues="@array/audioFormatList"
android:defaultValue="@string/defaultAudioFormat"/>
<CheckBoxPreference <ListPreference
android:key="@string/showNextVideo" android:key="@string/searchLanguage"
android:title="@string/showNextAndSimilarTitle" android:title="@string/searchLanguageTitle"
android:defaultValue="true" /> android:entries="@array/languageNames"
android:entryValues="@array/languageCodes"
android:defaultValue="en" />
<ListPreference <CheckBoxPreference
android:key="@string/searchLanguage" android:key="@string/showNextVideo"
android:title="@string/searchLanguageTitle" android:title="@string/showNextAndSimilarTitle"
android:entries="@array/languageNames" android:defaultValue="true" />
android:entryValues="@array/languageCodes"
android:defaultValue="en" /> </PreferenceCategory>
<PreferenceCategory
android:key="@string/settingsCategoryEtc"
android:title="@string/settingsCategoryEtcTitle">
<EditTextPreference
android:key="@string/downloadPathPreference"
android:title="@string/downloadLocation"
android:summary="@string/downloadLocationSummary"
android:dialogTitle="@string/downloadLocationDialogTitle"
android:defaultValue=""/>
<CheckBoxPreference
android:key="@string/autoPlayThroughIntent"
android:title="@string/autoPlayThroughIntentTitle"
android:summary="@string/autoPlayThroughIntentSummary"
android:defaultValue="false" />
</PreferenceCategory>
</PreferenceScreen> </PreferenceScreen>

View File

@ -5,7 +5,7 @@ buildscript {
jcenter() jcenter()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:1.3.0' classpath 'com.android.tools.build:gradle:1.5.0'
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files // in the individual module build.gradle files