1
0
mirror of https://github.com/TeamNewPipe/NewPipe synced 2026-01-15 05:58:02 +00:00

Compare commits

..

105 Commits

Author SHA1 Message Date
Christian Schabesberger
f451f1f65d resolve conflict 2018-01-20 18:06:34 +01:00
Christian Schabesberger
4d12e71fba move on to v0.11.5 2018-01-20 16:00:39 +01:00
Christian Schabesberger
66fde7a212 fix loop in channel 2018-01-20 15:59:34 +01:00
Christian Schabesberger
86eccf219d refactore some more lambda functions 2018-01-20 15:24:45 +01:00
Christian Schabesberger
677865f347 player popup menu icons for white theme 2018-01-20 14:46:10 +01:00
Christian Schabesberger
eb4b3810e9 refactor ExtractionHelper using lambda expression 2018-01-20 13:57:31 +01:00
Christian Schabesberger
5f26501ddf fix triangle play button when returning to app 2018-01-20 13:39:06 +01:00
Emanuele Petriglia
b33a72f864 Translated using Weblate (Italian)
Currently translated at 100.0% (249 of 249 strings)
2018-01-19 20:07:50 +01:00
Freddy Morán Jr
675f43b968 Translated using Weblate (Spanish)
Currently translated at 100.0% (249 of 249 strings)
2018-01-19 01:24:52 +01:00
M2ck
9f117a2e59 Translated using Weblate (French)
Currently translated at 100.0% (249 of 249 strings)
2018-01-19 00:33:40 +01:00
Yann Hodiesne
a0844229a3 Translated using Weblate (French)
Currently translated at 97.9% (244 of 249 strings)
2018-01-19 00:23:06 +01:00
M2ck
114fcc144c Translated using Weblate (French)
Currently translated at 97.9% (244 of 249 strings)
2018-01-19 00:19:11 +01:00
Weblate
43372ff648 Merge remote-tracking branch 'origin/dev' into dev 2018-01-19 00:17:53 +01:00
ScratchBuild
b8ebbc5404 Translated using Weblate (Japanese)
Currently translated at 79.5% (194 of 244 strings)
2018-01-19 00:17:51 +01:00
M2ck
28309f82f3 Translated using Weblate (French)
Currently translated at 100.0% (244 of 244 strings)
2018-01-19 00:17:45 +01:00
Christian Schabesberger
c70fa391b6 fix conflict with weblate 2018-01-18 20:43:30 +01:00
nautilusx
caab589dce Translated using Weblate (German)
Currently translated at 99.5% (243 of 244 strings)
2018-01-18 08:18:08 +01:00
maruyuki
20370054e7 Translated using Weblate (Japanese)
Currently translated at 56.9% (139 of 244 strings)
2018-01-18 08:18:04 +01:00
f1882cb1e1 Translated using Weblate (German)
Currently translated at 97.5% (238 of 244 strings)
2018-01-12 19:37:15 +01:00
Nick Undnick
2ed149852d Translated using Weblate (German)
Currently translated at 97.5% (238 of 244 strings)
2018-01-10 18:22:38 +01:00
Coffeemaker
ac7226a0df Translated using Weblate (German)
Currently translated at 97.5% (238 of 244 strings)
2018-01-10 18:22:00 +01:00
Coffeemaker
5705650ca8 Translated using Weblate (Telugu)
Currently translated at 53.6% (131 of 244 strings)
2018-01-09 17:53:16 +01:00
Coffeemaker
60855ca7c5 Translated using Weblate (Tamil)
Currently translated at 5.7% (14 of 244 strings)
2018-01-09 17:53:16 +01:00
Coffeemaker
b8d8d181f3 Translated using Weblate (Slovak)
Currently translated at 70.0% (171 of 244 strings)
2018-01-09 17:53:16 +01:00
Thomas Lavend'Homme
6309160fc6 Translated using Weblate (French)
Currently translated at 100.0% (244 of 244 strings)
2018-01-09 17:53:14 +01:00
ButterflyOfFire
fc0e6ed273 Translated using Weblate (Arabic)
Currently translated at 100.0% (244 of 244 strings)
2018-01-09 17:53:04 +01:00
Christian Schabesberger
ada0cee656 move on to v0.11.4 2018-01-09 14:11:37 +01:00
Christian Schabesberger
6dde524d2c Merge branch 'dev' of github.com:teamnewpipe/NewPipe into dev 2018-01-09 14:02:39 +01:00
Christian Schabesberger
6a631e1915 forece select activity when opening with browser 2018-01-09 14:02:32 +01:00
Christian Schabesberger
bb6fa343cf Merge pull request #976 from coffeemakr/feature-share-subject
Add subject to shared URL's (fixes #975)
2018-01-09 13:53:29 +01:00
Christian Schabesberger
7557acde6c Merge pull request #977 from TobiGr/TranslationChecker-Fix
Fix crash due to no "other" item in plurals
2018-01-09 13:51:14 +01:00
TobiGr
25ed8952f9 Fix crash due to no "other" item in plurals 2018-01-09 13:24:50 +01:00
Coffeemakr
b93d94b0bd Add subject to shared URL's (fixes #975) 2018-01-09 12:41:30 +01:00
Christian Schabesberger
33d75fd2fb switch languageCode to content country 2018-01-09 12:25:40 +01:00
Christian Schabesberger
28a9855fd2 add countrycodes 2018-01-09 11:33:17 +01:00
Christian Schabesberger
9aad07621c fix many/other problem 2018-01-09 10:28:28 +01:00
Christian Schabesberger
384cde6eaa fix weblate merge failure 2018-01-08 13:29:25 +01:00
Sebastian Rasmussen
5ae98661ad Translated using Weblate (Swedish)
Currently translated at 100.0% (244 of 244 strings)
2018-01-08 13:21:19 +01:00
Alberto Moshpirit
8f4d9ceca9 Translated using Weblate (Spanish)
Currently translated at 100.0% (244 of 244 strings)
2018-01-08 13:21:15 +01:00
Christian Schabesberger
83d9a1233e horrible hack for fixing channel load next page foo 2018-01-06 20:39:33 +01:00
thami simo
522a287d79 Translated using Weblate (Arabic)
Currently translated at 96.3% (235 of 244 strings)
2018-01-06 17:21:06 +01:00
Sebastian Rasmussen
e052d4660d Translated using Weblate (Swedish)
Currently translated at 100.0% (244 of 244 strings)
2018-01-06 17:21:03 +01:00
John Zhen Mo
39b0b2f032 -Added player conversion to background and popup players.
-[#919] Fixed custom notification does not trigger unlocking on lockscreen.
-[#947] Fixes player crashing on internet outage, issue partially addressed.
-Fixed main player losing state after destroy while in background.
-Fixed main player controls not hiding automatically after orientation change.
-Fixed dialog uploader not marqueeing when too long.
-Fixed popup permission throwing NPE on BaseList.
-Refactored popup permissions to start in NavigationHelper.
-Extracted hardcoded string for player menus.
-Bump Java version to 1.8.
-Some lambda conversions.
2018-01-03 22:53:38 -08:00
Christian Schabesberger
0223d6d200 moved on to v0.11.3 2018-01-04 05:34:19 +01:00
Christian Schabesberger
808ce72078 fix share menu for playlists 2018-01-04 05:28:01 +01:00
Christian Schabesberger
3a84c47176 hopefully fix plurals 2018-01-04 04:56:45 +01:00
Weblate
20c2426128 Merge remote-tracking branch 'origin/dev' into dev 2017-12-30 19:06:47 +01:00
Phạm Nguyễn Hoàng
bf11d4c9fa Translated using Weblate (Vietnamese)
Currently translated at 59.0% (144 of 244 strings)
2017-12-30 19:06:47 +01:00
Matej U
783c0f79d7 Translated using Weblate (Slovenian)
Currently translated at 91.8% (224 of 244 strings)
2017-12-30 19:06:46 +01:00
Ivan Krušlin
98b94bd9c4 Translated using Weblate (Croatian)
Currently translated at 97.1% (237 of 244 strings)
2017-12-30 19:06:44 +01:00
Rex_sa
ff0178f965 Translated using Weblate (Arabic)
Currently translated at 91.8% (224 of 244 strings)
2017-12-30 19:06:41 +01:00
Schabi
7f88c3d0a9 roleback wrong fix 2017-12-30 00:27:29 +01:00
Schabi
11e8e38f2c setup context for making notifications open via setContextIntent() 2017-12-29 17:29:15 +01:00
Schabi
50c5314eaf fix yt trending content language 2017-12-29 15:02:23 +01:00
Schabi
a7a76d4f58 add beta 2 logo 2017-12-26 14:48:06 +01:00
Schabi
4df4f68fe1 Merge branch 'dev' 2017-12-24 12:17:55 +01:00
Schabi
7db8d37137 update extractor and move on to version v0.11.2 2017-12-24 12:17:41 +01:00
Christian Schabesberger
b7503a7d81 Merge pull request #936 from TobiGr/readme-website
Add website, blog and press kit to README.MD
2017-12-23 17:47:59 +01:00
Schabi
9f5d4034e3 fix fullscreen button on popup 2017-12-23 17:34:47 +01:00
Tobias Groza
3c941f6c4b Add website, blog and press kit to README.MD 2017-12-23 16:35:40 +01:00
Christian Schabesberger
ec8fff421a fix avatar not vissible on info screen bug 2017-12-22 16:53:43 +01:00
Christian Schabesberger
a47a0b5432 Merge pull request #904 from Jawnnypoo/tweaks
Pull up support lib version so all always match
2017-12-22 15:25:33 +01:00
Christian Schabesberger
96ba46f21d Merge pull request #931 from TobiGr/notification-icon
Change notification bar icon for popup and background player
2017-12-21 16:03:15 +01:00
Ariel Shulman
90f48d5817 Translated using Weblate (Hebrew)
Currently translated at 100.0% (244 of 244 strings)
2017-12-20 23:47:19 +01:00
Jonas
7288dd097a Translated using Weblate (Spanish)
Currently translated at 100.0% (244 of 244 strings)
2017-12-20 17:02:16 +01:00
TobiGr
0119d62a35 change notification bar icon for popup and background player 2017-12-20 16:29:32 +01:00
Kompiuterių meistras +37060040
4d6ab73fa9 Translated using Weblate (Lithuanian)
Currently translated at 100.0% (244 of 244 strings)
2017-12-20 13:06:09 +01:00
f58c95840a Translated using Weblate (Lithuanian)
Currently translated at 60.6% (148 of 244 strings)
2017-12-20 11:04:43 +01:00
Weblate
ecf24f81ec Merge remote-tracking branch 'origin/dev' into dev 2017-12-18 14:15:55 +01:00
Rex_sa
dd3306a940 Translated using Weblate (Arabic)
Currently translated at 91.3% (223 of 244 strings)
2017-12-18 14:15:52 +01:00
Claudio Maradonna
bbb2b98f27 Translated using Weblate (Italian)
Currently translated at 100.0% (244 of 244 strings)
2017-12-18 14:15:32 +01:00
Christian Schabesberger
bc7332780d fix show rending before page was loaded 2017-12-17 12:55:30 +01:00
Joseph Kim
6f3bc3ac8f Translated using Weblate (Korean)
Currently translated at 99.5% (243 of 244 strings)
2017-12-14 11:48:42 +01:00
Weblate
cd04d869b7 Merge remote-tracking branch 'origin/dev' into dev 2017-12-12 15:49:41 +01:00
Eduardo Caron
909e15cbdd Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (244 of 244 strings)
2017-12-12 15:49:31 +01:00
Christian Schabesberger
33fa30ab78 Merge branch 'feature-small-code-improvements' of https://github.com/coffeemakr/NewPipe into coffe 2017-12-11 18:06:38 +01:00
Anthony MARGERAND
44933ac17a Translated using Weblate (French)
Currently translated at 100.0% (244 of 244 strings)
2017-12-10 16:35:06 +01:00
Coffeemakr
bb2af96deb Use getters for extractor items 2017-12-10 11:07:51 +01:00
Coffeemakr
1fe6da14ea Small code improvements 2017-12-10 11:07:08 +01:00
Weblate
b7b9653c21 Merge remote-tracking branch 'origin/dev' into dev 2017-12-09 18:07:20 +01:00
alekksander
8adc5918f8 Translated using Weblate (Polish)
Currently translated at 100.0% (244 of 244 strings)
2017-12-09 18:07:19 +01:00
Tobias Groza
0db593b1bb Translated using Weblate (German)
Currently translated at 100.0% (244 of 244 strings)
2017-12-09 18:07:10 +01:00
Christian Schabesberger
a0c9dbeb78 Merge pull request #910 from coffeemakr/bugfix-integrate-extractor
Fix failing test
2017-12-09 17:36:13 +01:00
Nathan Follens
61d5546d89 Translated using Weblate (Dutch)
Currently translated at 100.0% (244 of 244 strings)
2017-12-09 14:30:18 +01:00
alekksander
f97b7c943b Translated using Weblate (Polish)
Currently translated at 100.0% (244 of 244 strings)
2017-12-09 13:58:19 +01:00
Duppadaadadii
97549b633b Translated using Weblate (Finnish)
Currently translated at 100.0% (244 of 244 strings)
2017-12-09 10:54:55 +01:00
Sérgio Marques
1949e4a9d4 Translated using Weblate (Portuguese)
Currently translated at 93.4% (228 of 244 strings)
2017-12-09 02:49:06 +01:00
Coffeemakr
ecb5f7a5ba Try Travis' solution 2017-12-08 20:26:44 +01:00
Emanuele Petriglia
6021f72cf0 Translated using Weblate (Italian)
Currently translated at 99.1% (242 of 244 strings)
2017-12-08 16:49:42 +01:00
nailyk
c00ef74f96 Translated using Weblate (French)
Currently translated at 99.5% (243 of 244 strings)
2017-12-08 14:46:23 +01:00
Coffeemakr
962e070150 Use Mediaformat objects instead of ids for tests 2017-12-08 13:57:44 +01:00
r2308145
221cbf5e07 Translated using Weblate (Czech)
Currently translated at 100.0% (244 of 244 strings)
2017-12-08 13:45:20 +01:00
John
91ff301d53 Pull up support lib version so all always match 2017-12-06 18:19:56 -06:00
wb9688
f5f8371865 Remove setting 2017-11-20 19:31:33 +01:00
wb9688
1191455d37 Show selected service 2017-11-20 16:04:18 +01:00
wb9688
011e151c91 Merge branch 'dev' into multiple-services 2017-11-19 17:41:57 +01:00
wb9688
54aa40eac1 Add simple drawer for selecting service 2017-11-19 17:21:46 +01:00
wb9688
621a1909ec Merge remote-tracking branch 'origin/dev' into multiple-services 2017-11-11 13:18:26 +01:00
Christian Schabesberger
c485e7e167 merge master 2017-11-05 21:00:05 +01:00
Christian Schabesberger
71a8361580 merge dev 2017-11-05 20:59:17 +01:00
Christian Schabesberger
3d1cc348c8 fix getUploaderName() and move on to v0.10.2 2017-10-31 19:47:46 +01:00
wb9688
25db3c2940 Update NewPipeExtractor 2017-09-16 10:25:54 +02:00
wb9688
442290d7f0 Hide spinner 2017-09-14 11:43:30 +02:00
wb9688
a6eb871f5e Change layout for audio-only streams 2017-09-14 10:49:39 +02:00
wb9688
b500c3f526 Add service setting 2017-09-14 09:31:01 +02:00
100 changed files with 3348 additions and 946 deletions

1
.gitignore vendored
View File

@@ -10,3 +10,4 @@
gradle.properties
*~
.weblate
*.class

View File

@@ -10,6 +10,8 @@ android:
# The SDK version used to compile NewPipe
- android-27
before_install:
- yes | sdkmanager "platforms;android-27"
script: ./gradlew -Dorg.gradle.jvmargs=-Xmx1536m assembleDebug lintDebug testDebugUnitTest
licenses:

170
CheckTranslations.java Normal file
View File

@@ -0,0 +1,170 @@
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.regex.*;
import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;
import java.nio.file.Files;
import java.nio.charset.Charset;
public final class CheckTranslations {
private static boolean debug = false;
private static boolean plurals = false;
private static boolean empty = false;
private static boolean remove = false;
private static int checks = 0;
private static int matches = 0;
private static int changes = 0;
private static Pattern p, pb, pe, e, o;
/**
* Search translated strings.xml files for empty item / plural tags
* and remove them.
* @param args directories which contain string.xml files (in any subdirectory)
* -e option to find all empty string tags
* -p option to find all empty plurals and item tags
* -r option to remove all occurrences from the files
* -d option to see more details
*/
public static void main(String[] args) {
if (args.length < 1 || (args[0].equals("-d") && args.length < 2)) {
System.out.println("Not enough arguments");
return;
}
for (int i = 0; i < args.length; i++) {
switch (args[i]) {
case "-d":
debug = true;
break;
case "-p":
plurals = true;
break;
case "-e":
empty = true;
break;
case "-r":
remove = true;
break;
}
}
if (!plurals && !empty) {
plurals = true;
empty = true;
}
p = Pattern.compile("(<item quantity=\")(zero|one|two|three|few|many|other)(\"></item>|\"/>)");
pb = Pattern.compile("(<plurals[\\sa-zA-Z=\"]*>)");
pe = Pattern.compile("(</plurals>)");
e = Pattern.compile("(<string[\\sa-z_\\\"=]*)((><\\/string>|\\/>){1})");
o = Pattern.compile("(<item quantity=\"other\">)[^</>]*(<\\/item>)");
for (int i = 0; i < args.length; i++) {
if (!args[i].equals("-d") && !args[i].equals("-p") && !args[i].equals("-e") && !args[i].equals("-r")) {
File f = new File(args[i]);
if (f.exists() && !f.isDirectory()) {
checkFile(f);
} else if (f.isDirectory()) {
checkFiles(f.listFiles());
} else {
System.out.println("'" + args[i] + "' does not exist!");
}
}
}
System.out.println(checks + " files were checked.");
System.out.println(matches + " corrupt lines detected.");
if (remove) {
System.out.println(matches + " corrupt lines removed and " + changes + " lines fixed.");
}
}
private static void checkFiles(File[] f) {
for (int i = 0; i < f.length; i++) {
if (f[i].exists() && !f[i].isDirectory()) {
if (f[i].toString().contains("strings.xml")) {
checkFile(f[i]);
}
} else if (f[i].isDirectory()) {
checkFiles(f[i].listFiles());
}
}
}
private static void checkFile(File f) {
// Do not check our original English strings to cause no unwanted changes
// Btw. there should not be empty plural/item tags
if (f.toString().contains("values/strings.xml")) {
return;
}
if (debug) System.out.println("Checking " + f.toString());
checks++;
List<String> lines = new ArrayList<String>();
boolean checkFailed = false;
boolean otherDetected = false;
boolean inPlurals = false;
try (BufferedReader br = new BufferedReader(new FileReader(f))) {
String line;
int ln = 0;
while ((line = br.readLine()) != null) {
ln++;
if (plurals && p.matcher(line).find()) {
matches++;
if (debug) System.out.println(" Line " + ln + " was " + ((remove) ? "removed" : "detected") + ": '" + line + "'");
checkFailed = true;
} else if (empty && e.matcher(line).find()) {
matches++;
checkFailed = true;
if (debug) System.out.println(" Line " + ln + " was " + ((remove) ? "removed" : "detected") + ": '" + line + "'");
} else {
if (remove) lines.add(line);
}
}
br.close();
int pluralsLine = 0;
for (int i = 0; i < lines.size(); i++) {
if (o.matcher(lines.get(i)).find()) {
otherDetected = true;
}
if (plurals && pb.matcher(lines.get(i)).find()) {
inPlurals = true;
pluralsLine = i;
} else if (plurals && pe.matcher(lines.get(i)).find()) {
inPlurals = false;
if (!otherDetected) {
boolean b = false;
check: for(int j = pluralsLine; j < i; j++) {
if (lines.get(j).contains("many")) {
b = true;
pluralsLine = j;
break check;
}
}
if (remove && b) {
if (debug) System.out.println(" Line " + (pluralsLine + 1) + " was " + ((remove) ? "changed" : "detected") + ": '" + lines.get(pluralsLine) + "'");
lines.set(pluralsLine, lines.get(pluralsLine).replace("many", "other"));
changes++;
checkFailed = true;
} else if (debug) {
if (debug) System.out.println(" WARNING: Line " + (i + 1) + " - No <item quantity=\"other\"> found!");
}
}
otherDetected = false;
}
}
if (remove && checkFailed) {
Files.write(f.toPath(), lines, Charset.forName("UTF-8"));
}
} catch (IOException e) {
System.out.println(e);
}
}
}

View File

@@ -13,6 +13,7 @@
</p>
<hr />
<p align="center"><a href="#screenshots">Screenshots</a> &bull; <a href="#description">Description</a> &bull; <a href="#features">Features</a> &bull; <a href="#contribution">Contribution</a> &bull; <a href="#donate">Donate</a> &bull; <a href="#license">License</a></p>
<p align="center"><a href="https://newpipe.schabi.org">Website</a> &bull; <a href="https://newpipe.schabi.org/blog/">Blog</a> &bull; <a href="https://newpipe.schabi.org/press/">Press</a></p>
<hr />
WARNING: PUTTING NEWPIPE OR ANY FORK OF IT INTO GOOGLE PLAYSTORE VIOLATES THEIR TERMS OF CONDITIONS.

View File

@@ -8,8 +8,8 @@ android {
applicationId "org.schabi.newpipe"
minSdkVersion 15
targetSdkVersion 27
versionCode 42
versionName "0.11.1"
versionCode 46
versionName "0.11.5"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
@@ -42,26 +42,29 @@ android {
abortOnError false
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
ext {
supportLibVersion = '27.0.2'
}
dependencies {
androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2') {
exclude module: 'support-annotations'
}
implementation 'com.github.TeamNewPipe:NewPipeExtractor:17ce9f537e8df'
implementation 'com.github.TeamNewPipe:NewPipeExtractor:1c97da8b51b3610'
testImplementation 'junit:junit:4.12'
testImplementation 'org.mockito:mockito-core:1.10.19'
implementation 'com.android.support:appcompat-v7:27.0.1'
implementation 'com.android.support:support-v4:27.0.1'
implementation 'com.android.support:design:27.0.1'
implementation 'com.android.support:recyclerview-v7:27.0.1'
implementation 'com.android.support:preference-v14:27.0.1'
implementation "com.android.support:appcompat-v7:$supportLibVersion"
implementation "com.android.support:support-v4:$supportLibVersion"
implementation "com.android.support:design:$supportLibVersion"
implementation "com.android.support:recyclerview-v7:$supportLibVersion"
implementation "com.android.support:preference-v14:$supportLibVersion"
implementation 'com.google.code.gson:gson:2.8.2'
implementation 'ch.acra:acra:4.9.2'
@@ -76,7 +79,7 @@ dependencies {
debugImplementation 'com.facebook.stetho:stetho-urlconnection:1.5.0'
debugImplementation 'com.android.support:multidex:1.0.2'
implementation 'io.reactivex.rxjava2:rxjava:2.1.6'
implementation 'io.reactivex.rxjava2:rxjava:2.1.7'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
implementation 'com.jakewharton.rxbinding2:rxbinding:2.0.0'

View File

@@ -28,8 +28,13 @@ import android.os.Looper;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.NavigationView;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
@@ -45,6 +50,7 @@ import org.schabi.newpipe.database.history.dao.WatchHistoryDAO;
import org.schabi.newpipe.database.history.model.HistoryEntry;
import org.schabi.newpipe.database.history.model.SearchHistoryEntry;
import org.schabi.newpipe.database.history.model.WatchHistoryEntry;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.stream.AudioStream;
import org.schabi.newpipe.extractor.stream.StreamInfo;
@@ -69,6 +75,7 @@ public class MainActivity extends AppCompatActivity implements HistoryListener {
private static final String TAG = "MainActivity";
public static final boolean DEBUG = false;
private SharedPreferences sharedPreferences;
private ActionBarDrawerToggle toggle = null;
/*//////////////////////////////////////////////////////////////////////////
// Activity's LifeCycle
@@ -76,7 +83,8 @@ public class MainActivity extends AppCompatActivity implements HistoryListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
if (DEBUG) Log.d(TAG, "onCreate() called with: savedInstanceState = [" + savedInstanceState + "]");
if (DEBUG)
Log.d(TAG, "onCreate() called with: savedInstanceState = [" + savedInstanceState + "]");
ThemeHelper.setTheme(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
@@ -85,8 +93,59 @@ public class MainActivity extends AppCompatActivity implements HistoryListener {
initFragments();
}
Toolbar toolbar = findViewById(R.id.toolbar);
final Toolbar toolbar = findViewById(R.id.toolbar);
final DrawerLayout drawer = findViewById(R.id.drawer_layout);
final NavigationView drawerItems = findViewById(R.id.navigation);
setSupportActionBar(toolbar);
drawerItems.getMenu().getItem(NewPipe.getIdOfService(PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getString("service", "YouTube"))).setChecked(true);
if (!BuildConfig.BUILD_TYPE.equals("release")) {
toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.drawer_open, R.string.drawer_close);
toggle.syncState();
drawer.addDrawerListener(toggle);
drawerItems.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
drawerItems.getMenu().getItem(NewPipe.getIdOfService(PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getString("service", "YouTube"))).setChecked(false);
SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).edit();
editor.putString("service", item.getTitle().toString());
editor.apply();
drawer.closeDrawers();
drawerItems.getMenu().getItem(NewPipe.getIdOfService(PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getString("service", "YouTube"))).setChecked(true);
return true;
}
});
} else {
drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
}
getSupportFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
@Override
public void onBackStackChanged() {
if (getSupportFragmentManager().getBackStackEntryCount() > 1) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onBackPressed();
}
});
} else {
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
if (toggle != null) {
toggle.syncState();
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
drawer.openDrawer(GravityCompat.START);
}
});
}
}
}
});
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
initHistory();

View File

@@ -18,9 +18,8 @@ public class RouterPopupActivity extends RouterActivity {
@Override
protected void handleUrl(String url) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
&& !PermissionHelper.checkSystemAlertWindowPermission(this)) {
Toast.makeText(this, R.string.msg_popup_permission, Toast.LENGTH_LONG).show();
if (!PermissionHelper.isPopupEnabled(this)) {
PermissionHelper.showPopupEnablementToast(this);
finish();
return;
}

View File

@@ -48,7 +48,7 @@ public class WatchHistoryEntry extends HistoryEntry {
}
public WatchHistoryEntry(StreamInfo streamInfo) {
this(new Date(), streamInfo.service_id, streamInfo.name, streamInfo.url,
this(new Date(), streamInfo.getServiceId(), streamInfo.getName(), streamInfo.getUrl(),
streamInfo.id, streamInfo.thumbnail_url, streamInfo.uploader_name, streamInfo.duration);
}

View File

@@ -108,8 +108,8 @@ public class DownloadDialog extends DialogFragment implements RadioGroup.OnCheck
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
nameEditText = view.findViewById(R.id.file_name);
nameEditText.setText(FilenameUtils.createFilename(getContext(), currentInfo.name));
selectedAudioIndex = ListHelper.getDefaultAudioFormat(getContext(), currentInfo.audio_streams);
nameEditText.setText(FilenameUtils.createFilename(getContext(), currentInfo.getName()));
selectedAudioIndex = ListHelper.getDefaultAudioFormat(getContext(), currentInfo.getAudioStreams());
streamsSpinner = view.findViewById(R.id.quality_spinner);
streamsSpinner.setOnItemSelectedListener(this);
@@ -183,7 +183,7 @@ public class DownloadDialog extends DialogFragment implements RadioGroup.OnCheck
String[] items = new String[audioStreams.size()];
for (int i = 0; i < audioStreams.size(); i++) {
AudioStream audioStream = audioStreams.get(i);
items[i] = MediaFormat.getNameById(audioStream.format) + " " + audioStream.average_bitrate + "kbps";
items[i] = audioStream.getFormat().getName() + " " + audioStream.getAverageBitrate() + "kbps";
}
ArrayAdapter<String> itemAdapter = new ArrayAdapter<>(getContext(), android.R.layout.simple_spinner_dropdown_item, items);
@@ -242,7 +242,7 @@ public class DownloadDialog extends DialogFragment implements RadioGroup.OnCheck
RadioButton audioButton = view.findViewById(R.id.audio_button);
RadioButton videoButton = view.findViewById(R.id.video_button);
if (currentInfo.audio_streams == null || currentInfo.audio_streams.size() == 0) {
if (currentInfo.getAudioStreams() == null || currentInfo.getAudioStreams().size() == 0) {
audioButton.setVisibility(View.GONE);
videoButton.setChecked(true);
} else if (sortedStreamVideosList == null || sortedStreamVideosList.size() == 0) {
@@ -256,14 +256,18 @@ public class DownloadDialog extends DialogFragment implements RadioGroup.OnCheck
String url, location;
String fileName = nameEditText.getText().toString().trim();
if (fileName.isEmpty()) fileName = FilenameUtils.createFilename(getContext(), currentInfo.name);
if (fileName.isEmpty()) fileName = FilenameUtils.createFilename(getContext(), currentInfo.getName());
boolean isAudio = radioVideoAudioGroup.getCheckedRadioButtonId() == R.id.audio_button;
url = isAudio ? currentInfo.audio_streams.get(selectedAudioIndex).url : sortedStreamVideosList.get(selectedVideoIndex).url;
location = isAudio ? NewPipeSettings.getAudioDownloadPath(getContext()) : NewPipeSettings.getVideoDownloadPath(getContext());
if (isAudio) fileName += "." + MediaFormat.getSuffixById(currentInfo.audio_streams.get(selectedAudioIndex).format);
else fileName += "." + MediaFormat.getSuffixById(sortedStreamVideosList.get(selectedVideoIndex).format);
if (isAudio) {
url = currentInfo.getAudioStreams().get(selectedAudioIndex).getUrl();
location = NewPipeSettings.getAudioDownloadPath(getContext());
fileName += "." + currentInfo.getAudioStreams().get(selectedAudioIndex).getFormat().getSuffix();
} else {
url = sortedStreamVideosList.get(selectedVideoIndex).getUrl();
location = NewPipeSettings.getVideoDownloadPath(getContext());
fileName += "." + sortedStreamVideosList.get(selectedVideoIndex).getFormat().getSuffix();
}
DownloadManagerService.startMission(getContext(), url, location, fileName, isAudio, threadsSeekBar.getProgress() + 1);
getDialog().dismiss();

View File

@@ -1,6 +1,7 @@
package org.schabi.newpipe.fragments;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
@@ -18,6 +19,7 @@ import org.schabi.newpipe.MainActivity;
import org.schabi.newpipe.R;
import org.schabi.newpipe.ReCaptchaActivity;
import org.schabi.newpipe.extractor.exceptions.ReCaptchaException;
import org.schabi.newpipe.extractor.stream.StreamInfo;
import org.schabi.newpipe.report.ErrorActivity;
import org.schabi.newpipe.report.UserAction;
import org.schabi.newpipe.util.ExtractorHelper;
@@ -219,6 +221,7 @@ public abstract class BaseStateFragment<I> extends BaseFragment implements ViewC
if (serviceName == null) serviceName = "none";
if (request == null) request = "none";
ErrorActivity.reportError(getContext(), exception, MainActivity.class, null, ErrorActivity.ErrorInfo.make(userAction, serviceName, request, errorId));
}
@@ -239,4 +242,22 @@ public abstract class BaseStateFragment<I> extends BaseFragment implements ViewC
ErrorActivity.reportError(getContext(), exception, MainActivity.class, rootView, ErrorActivity.ErrorInfo.make(userAction, serviceName, request, errorId));
}
/*//////////////////////////////////////////////////////////////////////////
// Utils
//////////////////////////////////////////////////////////////////////////*/
protected void openUrlInBrowser(String url) {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(Intent.createChooser(intent, activity.getString(R.string.share_dialog_title)));
}
protected void shareUrl(String subject, String url) {
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_SUBJECT, subject);
intent.putExtra(Intent.EXTRA_TEXT, url);
startActivity(Intent.createChooser(intent, getString(R.string.share_dialog_title)));
}
}

View File

@@ -2,6 +2,7 @@ package org.schabi.newpipe.fragments;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
@@ -30,30 +31,28 @@ import org.schabi.newpipe.fragments.list.kiosk.KioskFragment;
import org.schabi.newpipe.fragments.subscription.SubscriptionFragment;
import org.schabi.newpipe.report.ErrorActivity;
import org.schabi.newpipe.report.UserAction;
import org.schabi.newpipe.util.Constants;
import org.schabi.newpipe.util.KioskTranslator;
import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.ThemeHelper;
import java.util.concurrent.ExecutionException;
public class MainFragment extends BaseFragment implements TabLayout.OnTabSelectedListener {
private ViewPager viewPager;
private boolean showBlankTab = false;
private static final int FALLBACK_SERVICE_ID = 0; // Youtbe
public int currentServiceId = -1;
/*//////////////////////////////////////////////////////////////////////////
// Constants
//////////////////////////////////////////////////////////////////////////*/
private static final int FALLBACK_SERVICE_ID = 0; // Youtube
private static final String FALLBACK_CHANNEL_URL =
"https://www.youtube.com/channel/UC-9-kyTW8ZkZNDHQJ6FgpwQ";
private static final String FALLBACK_CHANNEL_NAME = "Music";
private static final String FALLBACK_KIOSK_ID = "Trending";
public int currentServiceId = -1;
/*//////////////////////////////////////////////////////////////////////////
// Konst
//////////////////////////////////////////////////////////////////////////*/
private static final int KIOSK_MENU_OFFSETT = 2000;
private static final int KIOSK_MENU_OFFSET = 2000;
/*//////////////////////////////////////////////////////////////////////////
// Fragment's LifeCycle
@@ -66,7 +65,7 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte
}
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
currentServiceId = Integer.parseInt(PreferenceManager.getDefaultSharedPreferences(getActivity())
.getString(getString(R.string.current_service_key), "0"));
return inflater.inflate(R.layout.fragment_main, container, false);
@@ -86,27 +85,27 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte
tabLayout.setupWithViewPager(viewPager);
if(ThemeHelper.isLightThemeSelected(getActivity())) {
int channelIcon;
int whatsHotIcon;
if (ThemeHelper.isLightThemeSelected(getActivity())) {
tabLayout.setBackgroundColor(getResources().getColor(R.color.light_youtube_primary_color));
channelIcon = R.drawable.ic_channel_black_24dp;
whatsHotIcon = R.drawable.ic_whatshot_black_24dp;
} else {
channelIcon = R.drawable.ic_channel_white_24dp;
whatsHotIcon = R.drawable.ic_whatshot_white_24dp;
}
if(PreferenceManager.getDefaultSharedPreferences(getActivity())
if (PreferenceManager.getDefaultSharedPreferences(getActivity())
.getString(getString(R.string.main_page_content_key), getString(R.string.blank_page_key))
.equals(getString(R.string.subscription_page_key))) {
if(ThemeHelper.isLightThemeSelected(getActivity())) {
tabLayout.getTabAt(0).setIcon(R.drawable.ic_channel_black_24dp);
} else{
tabLayout.getTabAt(0).setIcon(R.drawable.ic_channel_white_24dp);
}
} else {
if(ThemeHelper.isLightThemeSelected(getActivity())) {
tabLayout.getTabAt(0).setIcon(R.drawable.ic_whatshot_black_24dp);
tabLayout.getTabAt(1).setIcon(R.drawable.ic_channel_black_24dp);
} else {
tabLayout.getTabAt(0).setIcon(R.drawable.ic_whatshot_white_24dp);
tabLayout.getTabAt(1).setIcon(R.drawable.ic_channel_white_24dp);
}
}
tabLayout.getTabAt(0).setIcon(channelIcon);
} else {
tabLayout.getTabAt(0).setIcon(whatsHotIcon);
tabLayout.getTabAt(1).setIcon(channelIcon);
}
}
/*//////////////////////////////////////////////////////////////////////////
@@ -139,7 +138,7 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_search:
NavigationHelper.openSearchFragment(getFragmentManager(), 0, "");
NavigationHelper.openSearchFragment(getFragmentManager(), NewPipe.getIdOfService(PreferenceManager.getDefaultSharedPreferences(getActivity()).getString("service", "YouTube")), "");
return true;
}
return super.onOptionsItemSelected(item);
@@ -182,7 +181,7 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte
.equals(getString(R.string.subscription_page_key))) {
return new SubscriptionFragment();
} else {
return getMainPageFramgent();
return getMainPageFragment();
}
case 1:
return new SubscriptionFragment();
@@ -213,7 +212,7 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte
// Main page content
//////////////////////////////////////////////////////////////////////////*/
private Fragment getMainPageFramgent() {
private Fragment getMainPageFragment() {
try {
SharedPreferences preferences =
PreferenceManager.getDefaultSharedPreferences(getActivity());
@@ -268,7 +267,7 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte
KioskList kl = service.getKioskList();
int i = 0;
for(final String ks : kl.getAvailableKiosks()) {
menu.add(0, KIOSK_MENU_OFFSETT + i, Menu.NONE,
menu.add(0, KIOSK_MENU_OFFSET + i, Menu.NONE,
KioskTranslator.getTranslatedKioskName(ks, getContext()))
.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override

View File

@@ -60,7 +60,7 @@ public class SpinnerToolbarAdapter extends BaseAdapter {
ImageView woSoundIcon = convertView.findViewById(R.id.wo_sound_icon);
TextView text = convertView.findViewById(android.R.id.text1);
VideoStream item = (VideoStream) getItem(position);
text.setText(MediaFormat.getNameById(item.format) + " " + item.resolution);
text.setText(item.getFormat().getName() + " " + item.getResolution());
int visibility = !showIconNoAudio ? View.GONE
: item.isVideoOnly ? View.VISIBLE

View File

@@ -4,7 +4,8 @@ import java.io.Serializable;
class StackItem implements Serializable {
private int serviceId;
private String title, url;
private String title;
private String url;
StackItem(int serviceId, String url, String title) {
this.serviceId = serviceId;

View File

@@ -13,6 +13,7 @@ import android.support.annotation.DrawableRes;
import android.support.annotation.FloatRange;
import android.support.annotation.NonNull;
import android.support.v4.content.ContextCompat;
import android.support.v4.text.TextUtilsCompat;
import android.support.v4.view.animation.FastOutSlowInInterpolator;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AlertDialog;
@@ -283,7 +284,7 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
// Check if the next video label and video is visible,
// if it is, include the two elements in the next check
int nextCount = currentInfo != null && currentInfo.next_video != null ? 2 : 0;
int nextCount = currentInfo != null && currentInfo.getNextVideo() != null ? 2 : 0;
if (relatedStreamsView != null && relatedStreamsView.getChildCount() > INITIAL_RELATED_VIDEOS + nextCount) {
outState.putSerializable(WAS_RELATED_EXPANDED_KEY, true);
}
@@ -330,14 +331,22 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
openPopupPlayer(false);
break;
case R.id.detail_uploader_root_layout:
if (currentInfo.uploader_url == null || currentInfo.uploader_url.isEmpty()) {
if (TextUtils.isEmpty(currentInfo.getUploaderUrl())) {
Log.w(TAG, "Can't open channel because we got no channel URL");
} else {
NavigationHelper.openChannelFragment(getFragmentManager(), currentInfo.service_id, currentInfo.uploader_url, currentInfo.uploader_name);
NavigationHelper.openChannelFragment(
getFragmentManager(),
currentInfo.getServiceId(),
currentInfo.getUploaderUrl(),
currentInfo.getUploaderName());
}
break;
case R.id.detail_thumbnail_root_layout:
openVideoPlayer();
if (currentInfo.video_streams.isEmpty() && currentInfo.video_only_streams.isEmpty()) {
openBackgroundPlayer(false);
} else {
openVideoPlayer();
}
break;
case R.id.detail_title_root_layout:
toggleTitleAndDescription();
@@ -380,7 +389,7 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
if (DEBUG) Log.d(TAG, "toggleExpandRelatedVideos() called with: info = [" + info + "]");
if (!showRelatedStreams) return;
int nextCount = info.next_video != null ? 2 : 0;
int nextCount = info.getNextVideo() != null ? 2 : 0;
int initialCount = INITIAL_RELATED_VIDEOS + nextCount;
if (relatedStreamsView.getChildCount() > initialCount) {
@@ -390,8 +399,8 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
}
//Log.d(TAG, "toggleExpandRelatedVideos() called with: info = [" + info + "], from = [" + INITIAL_RELATED_VIDEOS + "]");
for (int i = INITIAL_RELATED_VIDEOS; i < info.related_streams.size(); i++) {
InfoItem item = info.related_streams.get(i);
for (int i = INITIAL_RELATED_VIDEOS; i < info.getRelatedStreams().size(); i++) {
InfoItem item = info.getRelatedStreams().get(i);
//Log.d(TAG, "i = " + i);
relatedStreamsView.addView(infoItemBuilder.buildView(relatedStreamsView, item));
}
@@ -459,7 +468,7 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
infoItemBuilder.setOnStreamSelectedListener(new InfoItemBuilder.OnInfoItemSelectedListener<StreamInfoItem>() {
@Override
public void selected(StreamInfoItem selectedItem) {
selectAndLoadVideo(selectedItem.service_id, selectedItem.url, selectedItem.name);
selectAndLoadVideo(selectedItem.getServiceId(), selectedItem.getUrl(), selectedItem.getName());
}
@Override
@@ -500,7 +509,7 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
NavigationHelper.enqueueOnBackgroundPlayer(context, new SinglePlayQueue(item));
break;
case 1:
NavigationHelper.enqueueOnPopupPlayer(context, new SinglePlayQueue(item));
NavigationHelper.enqueueOnPopupPlayer(getActivity(), new SinglePlayQueue(item));
break;
default:
break;
@@ -532,35 +541,35 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
private void initThumbnailViews(StreamInfo info) {
thumbnailImageView.setImageResource(R.drawable.dummy_thumbnail_dark);
if (info.thumbnail_url != null && !info.thumbnail_url.isEmpty()) {
imageLoader.displayImage(info.thumbnail_url, thumbnailImageView, DISPLAY_THUMBNAIL_OPTIONS, new SimpleImageLoadingListener() {
if (!TextUtils.isEmpty(info.getThumbnailUrl())) {
imageLoader.displayImage(info.getThumbnailUrl(), thumbnailImageView, DISPLAY_THUMBNAIL_OPTIONS, new SimpleImageLoadingListener() {
@Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
ErrorActivity.reportError(activity, failReason.getCause(), null, activity.findViewById(android.R.id.content), ErrorActivity.ErrorInfo.make(UserAction.LOAD_IMAGE, NewPipe.getNameOfService(currentInfo.service_id), imageUri, R.string.could_not_load_thumbnails));
ErrorActivity.reportError(activity, failReason.getCause(), null, activity.findViewById(android.R.id.content), ErrorActivity.ErrorInfo.make(UserAction.LOAD_IMAGE, NewPipe.getNameOfService(currentInfo.getServiceId()), imageUri, R.string.could_not_load_thumbnails));
}
});
}
if (info.uploader_avatar_url != null && !info.uploader_avatar_url.isEmpty()) {
imageLoader.displayImage(info.uploader_avatar_url, uploaderThumb, DISPLAY_AVATAR_OPTIONS);
if (!TextUtils.isEmpty(info.getUploaderAvatarUrl())) {
imageLoader.displayImage(info.getUploaderAvatarUrl(), uploaderThumb, DISPLAY_AVATAR_OPTIONS);
}
}
private void initRelatedVideos(StreamInfo info) {
if (relatedStreamsView.getChildCount() > 0) relatedStreamsView.removeAllViews();
if (info.next_video != null && showRelatedStreams) {
if (info.getNextVideo() != null && showRelatedStreams) {
nextStreamTitle.setVisibility(View.VISIBLE);
relatedStreamsView.addView(infoItemBuilder.buildView(relatedStreamsView, info.next_video));
relatedStreamsView.addView(infoItemBuilder.buildView(relatedStreamsView, info.getNextVideo()));
relatedStreamsView.addView(getSeparatorView());
relatedStreamRootLayout.setVisibility(View.VISIBLE);
} else nextStreamTitle.setVisibility(View.GONE);
if (info.related_streams != null && !info.related_streams.isEmpty() && showRelatedStreams) {
//long first = System.nanoTime(), each;
int to = info.related_streams.size() >= INITIAL_RELATED_VIDEOS ? INITIAL_RELATED_VIDEOS : info.related_streams.size();
int to = info.getRelatedStreams().size() >= INITIAL_RELATED_VIDEOS ? INITIAL_RELATED_VIDEOS : info.getRelatedStreams().size();
for (int i = 0; i < to; i++) {
InfoItem item = info.related_streams.get(i);
InfoItem item = info.getRelatedStreams().get(i);
//each = System.nanoTime();
relatedStreamsView.addView(infoItemBuilder.buildView(relatedStreamsView, item));
//if (DEBUG) Log.d(TAG, "each took " + ((System.nanoTime() - each) / 1000000L) + "ms");
@@ -572,7 +581,7 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
relatedStreamExpandButton.setImageDrawable(ContextCompat.getDrawable(activity, resolveResourceIdFromAttr(R.attr.expand)));
} else {
if (info.next_video == null) relatedStreamRootLayout.setVisibility(View.GONE);
if (info.getNextVideo() == null) relatedStreamRootLayout.setVisibility(View.GONE);
relatedStreamExpandButton.setVisibility(View.GONE);
}
}
@@ -616,26 +625,14 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
private void setupActionBarHandler(final StreamInfo info) {
if (DEBUG) Log.d(TAG, "setupActionBarHandler() called with: info = [" + info + "]");
sortedStreamVideosList = new ArrayList<>(ListHelper.getSortedStreamVideosList(activity, info.video_streams, info.video_only_streams, false));
sortedStreamVideosList = new ArrayList<>(ListHelper.getSortedStreamVideosList(activity, info.getVideoStreams(), info.getVideoOnlyStreams(), false));
actionBarHandler.setupStreamList(sortedStreamVideosList, spinnerToolbar);
actionBarHandler.setOnShareListener(new ActionBarHandler.OnActionListener() {
@Override
public void onActionSelected(int selectedStreamId) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_TEXT, info.url);
intent.setType("text/plain");
startActivity(Intent.createChooser(intent, activity.getString(R.string.share_dialog_title)));
}
});
actionBarHandler.setOnShareListener(selectedStreamId -> shareUrl(info.name, info.url));
actionBarHandler.setOnOpenInBrowserListener(new ActionBarHandler.OnActionListener() {
@Override
public void onActionSelected(int selectedStreamId) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setData(Uri.parse(info.url));
startActivity(Intent.createChooser(intent, activity.getString(R.string.choose_browser)));
openUrlInBrowser(info.getUrl());
}
});
@@ -643,7 +640,7 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
@Override
public void onActionSelected(int selectedStreamId) {
try {
NavigationHelper.playWithKore(activity, Uri.parse(info.url.replace("https", "http")));
NavigationHelper.playWithKore(activity, Uri.parse(info.getUrl().replace("https", "http")));
if(activity instanceof HistoryListener) {
((HistoryListener) activity).onVideoPlayed(info, null);
}
@@ -742,7 +739,7 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
public void prepareAndHandleInfo(final StreamInfo info, boolean scrollToTop) {
if (DEBUG) Log.d(TAG, "prepareAndHandleInfo() called with: info = [" + info + "], scrollToTop = [" + scrollToTop + "]");
setInitialData(info.service_id, info.url, info.name);
setInitialData(info.getServiceId(), info.getUrl(), info.getName());
pushToStack(serviceId, url, name);
showLoading();
@@ -798,7 +795,7 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
//////////////////////////////////////////////////////////////////////////*/
private void openBackgroundPlayer(final boolean append) {
AudioStream audioStream = currentInfo.audio_streams.get(ListHelper.getDefaultAudioFormat(activity, currentInfo.audio_streams));
AudioStream audioStream = currentInfo.getAudioStreams().get(ListHelper.getDefaultAudioFormat(activity, currentInfo.getAudioStreams()));
if (activity instanceof HistoryListener) {
((HistoryListener) activity).onAudioPlayed(currentInfo, audioStream);
@@ -815,11 +812,8 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
}
private void openPopupPlayer(final boolean append) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !PermissionHelper.checkSystemAlertWindowPermission(activity)) {
Toast toast = Toast.makeText(activity, R.string.msg_popup_permission, Toast.LENGTH_LONG);
TextView messageView = toast.getView().findViewById(android.R.id.message);
if (messageView != null) messageView.setGravity(Gravity.CENTER);
toast.show();
if (!PermissionHelper.isPopupEnabled(activity)) {
PermissionHelper.showPopupEnablementToast(activity);
return;
}
@@ -868,9 +862,9 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
intent = new Intent();
try {
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse(audioStream.url), MediaFormat.getMimeById(audioStream.format));
intent.putExtra(Intent.EXTRA_TITLE, currentInfo.name);
intent.putExtra("title", currentInfo.name);
intent.setDataAndType(Uri.parse(audioStream.getUrl()), audioStream.getFormat().getMimeType());
intent.putExtra(Intent.EXTRA_TITLE, currentInfo.getName());
intent.putExtra("title", currentInfo.getName());
activity.startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
@@ -903,14 +897,14 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
if (!useOldPlayer) {
// ExoPlayer
final PlayQueue playQueue = new SinglePlayQueue(currentInfo);
mIntent = NavigationHelper.getPlayerIntent(activity, MainVideoPlayer.class, playQueue, getSelectedVideoStream().resolution);
mIntent = NavigationHelper.getPlayerIntent(activity, MainVideoPlayer.class, playQueue, getSelectedVideoStream().getResolution());
} else {
// Internal Player
mIntent = new Intent(activity, PlayVideoActivity.class)
.putExtra(PlayVideoActivity.VIDEO_TITLE, currentInfo.name)
.putExtra(PlayVideoActivity.STREAM_URL, selectedVideoStream.url)
.putExtra(PlayVideoActivity.VIDEO_URL, currentInfo.url)
.putExtra(PlayVideoActivity.START_POSITION, currentInfo.start_position);
.putExtra(PlayVideoActivity.VIDEO_TITLE, currentInfo.getName())
.putExtra(PlayVideoActivity.STREAM_URL, selectedVideoStream.getUrl())
.putExtra(PlayVideoActivity.VIDEO_URL, currentInfo.getUrl())
.putExtra(PlayVideoActivity.START_POSITION, currentInfo.getStartPosition());
}
startActivity(mIntent);
}
@@ -920,9 +914,9 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
Intent intent = new Intent();
try {
intent.setAction(Intent.ACTION_VIEW)
.setDataAndType(Uri.parse(selectedVideoStream.url), MediaFormat.getMimeById(selectedVideoStream.format))
.putExtra(Intent.EXTRA_TITLE, currentInfo.name)
.putExtra("title", currentInfo.name);
.setDataAndType(Uri.parse(selectedVideoStream.getUrl()), selectedVideoStream.getFormat().getMimeType())
.putExtra(Intent.EXTRA_TITLE, currentInfo.getName())
.putExtra("title", currentInfo.getName());
this.startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
@@ -1095,20 +1089,28 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
public void handleResult(@NonNull StreamInfo info) {
super.handleResult(info);
setInitialData(info.service_id, info.url, info.name);
setInitialData(info.getServiceId(), info.getUrl(), info.getName());
pushToStack(serviceId, url, name);
animateView(thumbnailPlayButton, true, 200);
videoTitleTextView.setText(name);
if (!TextUtils.isEmpty(info.uploader_name)) uploaderTextView.setText(info.uploader_name);
uploaderTextView.setVisibility(!TextUtils.isEmpty(info.uploader_name) ? View.VISIBLE : View.GONE);
if (!TextUtils.isEmpty(info.getUploaderName())) {
uploaderTextView.setText(info.getUploaderName());
uploaderTextView.setVisibility(View.VISIBLE);
} else {
uploaderTextView.setVisibility(View.GONE);
}
uploaderThumb.setImageDrawable(ContextCompat.getDrawable(activity, R.drawable.buddy));
if (info.view_count >= 0) videoCountView.setText(Localization.localizeViewCount(activity, info.view_count));
videoCountView.setVisibility(info.view_count >= 0 ? View.VISIBLE : View.GONE);
if (info.getViewCount() >= 0) {
videoCountView.setText(Localization.localizeViewCount(activity, info.getViewCount()));
videoCountView.setVisibility(View.VISIBLE);
} else {
videoCountView.setVisibility(View.GONE);
}
if (info.dislike_count == -1 && info.like_count == -1) {
if (info.getDislikeCount() == -1 && info.getLikeCount() == -1) {
thumbsDownImageView.setVisibility(View.VISIBLE);
thumbsUpImageView.setVisibility(View.VISIBLE);
thumbsUpTextView.setVisibility(View.GONE);
@@ -1116,14 +1118,23 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
thumbsDisabledTextView.setVisibility(View.VISIBLE);
} else {
if (info.dislike_count >= 0) thumbsDownTextView.setText(Localization.shortCount(activity, info.dislike_count));
thumbsDownTextView.setVisibility(info.dislike_count >= 0 ? View.VISIBLE : View.GONE);
thumbsDownImageView.setVisibility(info.dislike_count >= 0 ? View.VISIBLE : View.GONE);
if (info.like_count >= 0) thumbsUpTextView.setText(Localization.shortCount(activity, info.like_count));
thumbsUpTextView.setVisibility(info.like_count >= 0 ? View.VISIBLE : View.GONE);
thumbsUpImageView.setVisibility(info.like_count >= 0 ? View.VISIBLE : View.GONE);
if (info.getDislikeCount() >= 0) {
thumbsDownTextView.setText(Localization.shortCount(activity, info.getDislikeCount()));
thumbsDownTextView.setVisibility(View.VISIBLE);
thumbsDownImageView.setVisibility(View.VISIBLE);
} else {
thumbsDownTextView.setVisibility(View.GONE);
thumbsDownImageView.setVisibility(View.GONE);
}
if (info.getLikeCount() >= 0) {
thumbsUpTextView.setText(Localization.shortCount(activity, info.getLikeCount()));
thumbsUpTextView.setVisibility(View.VISIBLE);
thumbsUpImageView.setVisibility(View.VISIBLE);
} else {
thumbsUpTextView.setVisibility(View.GONE);
thumbsUpImageView.setVisibility(View.GONE);
}
thumbsDisabledTextView.setVisibility(View.GONE);
}
@@ -1132,10 +1143,10 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
videoTitleToggleArrow.setImageResource(R.drawable.arrow_down);
videoDescriptionView.setVisibility(View.GONE);
videoDescriptionRootLayout.setVisibility(View.GONE);
if (!TextUtils.isEmpty(info.upload_date)) {
videoUploadDateView.setText(Localization.localizeDate(activity, info.upload_date));
if (!TextUtils.isEmpty(info.getUploadDate())) {
videoUploadDateView.setText(Localization.localizeDate(activity, info.getUploadDate()));
}
prepareDescription(info.description);
prepareDescription(info.getDescription());
animateView(spinnerToolbar, true, 500);
setupActionBarHandler(info);
@@ -1145,10 +1156,17 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
toggleExpandRelatedVideos(currentInfo);
wasRelatedStreamsExpanded = false;
}
setTitleToUrl(info.service_id, info.url, info.name);
setTitleToUrl(info.getServiceId(), info.getUrl(), info.getName());
if (!info.errors.isEmpty()) {
showSnackBarError(info.errors, UserAction.REQUESTED_STREAM, NewPipe.getNameOfService(info.service_id), info.url, 0);
if (!info.getErrors().isEmpty()) {
showSnackBarError(info.getErrors(), UserAction.REQUESTED_STREAM, NewPipe.getNameOfService(info.getServiceId()), info.getUrl(), 0);
}
if (info.video_streams.isEmpty() && info.video_only_streams.isEmpty()) {
detailControlsBackground.setVisibility(View.GONE);
detailControlsPopup.setVisibility(View.GONE);
spinnerToolbar.setVisibility(View.GONE);
thumbnailPlayButton.setImageResource(R.drawable.ic_headset_white_24dp);
}
if (autoPlayEnabled) {
@@ -1194,4 +1212,4 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
showError(getString(R.string.blocked_by_gema), false, R.drawable.gruese_die_gema);
}
}
}

View File

@@ -1,16 +1,21 @@
package org.schabi.newpipe.fragments.list;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.ActionBar;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import org.schabi.newpipe.R;
import org.schabi.newpipe.extractor.InfoItem;
@@ -24,6 +29,7 @@ import org.schabi.newpipe.info_list.InfoItemDialog;
import org.schabi.newpipe.info_list.InfoListAdapter;
import org.schabi.newpipe.playlist.SinglePlayQueue;
import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.PermissionHelper;
import org.schabi.newpipe.util.StateSaver;
import java.util.List;
@@ -140,7 +146,7 @@ public abstract class BaseListFragment<I, N> extends BaseStateFragment<I> implem
onItemSelected(selectedItem);
NavigationHelper.openVideoDetailFragment(
useAsFrontPage?getParentFragment().getFragmentManager():getFragmentManager(),
selectedItem.service_id, selectedItem.url, selectedItem.name);
selectedItem.getServiceId(), selectedItem.getUrl(), selectedItem.getName());
}
@Override
@@ -155,7 +161,7 @@ public abstract class BaseListFragment<I, N> extends BaseStateFragment<I> implem
onItemSelected(selectedItem);
NavigationHelper.openChannelFragment(
useAsFrontPage?getParentFragment().getFragmentManager():getFragmentManager(),
selectedItem.service_id, selectedItem.url, selectedItem.name);
selectedItem.getServiceId(), selectedItem.getUrl(), selectedItem.getName());
}
@Override
@@ -168,7 +174,7 @@ public abstract class BaseListFragment<I, N> extends BaseStateFragment<I> implem
onItemSelected(selectedItem);
NavigationHelper.openPlaylistFragment(
useAsFrontPage?getParentFragment().getFragmentManager():getFragmentManager(),
selectedItem.service_id, selectedItem.url, selectedItem.name);
selectedItem.getServiceId(), selectedItem.getUrl(), selectedItem.getName());
}
@Override
@@ -192,6 +198,7 @@ public abstract class BaseListFragment<I, N> extends BaseStateFragment<I> implem
protected void showStreamDialog(final StreamInfoItem item) {
final Context context = getContext();
final Activity activity = getActivity();
if (context == null || context.getResources() == null || getActivity() == null) return;
final String[] commands = new String[]{
@@ -207,7 +214,7 @@ public abstract class BaseListFragment<I, N> extends BaseStateFragment<I> implem
NavigationHelper.enqueueOnBackgroundPlayer(context, new SinglePlayQueue(item));
break;
case 1:
NavigationHelper.enqueueOnPopupPlayer(context, new SinglePlayQueue(item));
NavigationHelper.enqueueOnPopupPlayer(activity, new SinglePlayQueue(item));
break;
default:
break;

View File

@@ -124,20 +124,12 @@ public abstract class BaseListInfoFragment<I extends ListInfo> extends BaseListF
currentWorker = loadResult(forceLoad)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<I>() {
@Override
public void accept(@NonNull I result) throws Exception {
isLoading.set(false);
currentInfo = result;
currentNextItemsUrl = result.next_streams_url;
handleResult(result);
}
}, new Consumer<Throwable>() {
@Override
public void accept(@NonNull Throwable throwable) throws Exception {
onError(throwable);
}
});
.subscribe((@NonNull I result) -> {
isLoading.set(false);
currentInfo = result;
currentNextItemsUrl = result.next_streams_url;
handleResult(result);
}, (@NonNull Throwable throwable) -> onError(throwable));
}
/**
@@ -153,18 +145,12 @@ public abstract class BaseListInfoFragment<I extends ListInfo> extends BaseListF
currentWorker = loadMoreItemsLogic()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<ListExtractor.NextItemsResult>() {
@Override
public void accept(@io.reactivex.annotations.NonNull ListExtractor.NextItemsResult nextItemsResult) throws Exception {
isLoading.set(false);
handleNextItems(nextItemsResult);
}
}, new Consumer<Throwable>() {
@Override
public void accept(@io.reactivex.annotations.NonNull Throwable throwable) throws Exception {
isLoading.set(false);
onError(throwable);
}
.subscribe((@io.reactivex.annotations.NonNull ListExtractor.NextItemsResult nextItemsResult) -> {
isLoading.set(false);
handleNextItems(nextItemsResult);
}, (@io.reactivex.annotations.NonNull Throwable throwable) -> {
isLoading.set(false);
onError(throwable);
});
}
@@ -190,8 +176,8 @@ public abstract class BaseListInfoFragment<I extends ListInfo> extends BaseListF
public void handleResult(@NonNull I result) {
super.handleResult(result);
url = result.url;
name = result.name;
url = result.getUrl();
name = result.getName();
setTitle(name);
if (infoListAdapter.getItemsList().size() == 0) {

View File

@@ -1,10 +1,10 @@
package org.schabi.newpipe.fragments.list.channel;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
@@ -12,7 +12,6 @@ import android.support.v4.content.ContextCompat;
import android.support.v7.app.ActionBar;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
@@ -23,7 +22,6 @@ import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.jakewharton.rxbinding2.view.RxView;
@@ -105,7 +103,7 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
&& useAsFrontPage
&& isVisibleToUser) {
try {
activity.getSupportActionBar().setTitle(currentInfo.name);
activity.getSupportActionBar().setTitle(currentInfo.getName());
} catch (Exception e) {
onError(e);
}
@@ -153,6 +151,7 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
@Override
protected void showStreamDialog(final StreamInfoItem item) {
final Activity activity = getActivity();
final Context context = getContext();
if (context == null || context.getResources() == null || getActivity() == null) return;
@@ -173,7 +172,7 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
NavigationHelper.enqueueOnBackgroundPlayer(context, new SinglePlayQueue(item));
break;
case 1:
NavigationHelper.enqueueOnPopupPlayer(context, new SinglePlayQueue(item));
NavigationHelper.enqueueOnPopupPlayer(activity, new SinglePlayQueue(item));
break;
case 2:
NavigationHelper.playOnMainPlayer(context, getPlayQueue(index));
@@ -182,7 +181,7 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
NavigationHelper.playOnBackgroundPlayer(context, getPlayQueue(index));
break;
case 4:
NavigationHelper.playOnPopupPlayer(context, getPlayQueue(index));
NavigationHelper.playOnPopupPlayer(activity, getPlayQueue(index));
break;
default:
break;
@@ -208,7 +207,7 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
if (DEBUG) Log.d(TAG, "onCreateOptionsMenu() called with: menu = [" + menu + "], inflater = [" + inflater + "]");
menuRssButton = menu.findItem(R.id.menu_item_rss);
if (currentInfo != null) {
menuRssButton.setVisible(!TextUtils.isEmpty(currentInfo.feed_url));
menuRssButton.setVisible(!TextUtils.isEmpty(currentInfo.getFeedUrl()));
}
}
@@ -217,23 +216,11 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
private void openRssFeed() {
final ChannelInfo info = currentInfo;
if(info != null) {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(info.feed_url));
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(info.getFeedUrl()));
startActivity(intent);
}
}
private void openChannelUriInBrowser() {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(intent);
}
private void shareChannelUri() {
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, url);
startActivity(Intent.createChooser(intent, getString(R.string.share_dialog_title)));
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
@@ -241,10 +228,10 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
openRssFeed();
break;
case R.id.menu_item_openInBrowser:
openChannelUriInBrowser();
openUrlInBrowser(url);
break;
case R.id.menu_item_share: {
shareChannelUri();
shareUrl(name, url);
break;
}
default:
@@ -264,12 +251,12 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
@Override
public void accept(Throwable throwable) throws Exception {
animateView(headerSubscribeButton, false, 100);
showSnackBarError(throwable, UserAction.SUBSCRIPTION, NewPipe.getNameOfService(currentInfo.service_id), "Get subscription status", 0);
showSnackBarError(throwable, UserAction.SUBSCRIPTION, NewPipe.getNameOfService(currentInfo.getServiceId()), "Get subscription status", 0);
}
};
final Observable<List<SubscriptionEntity>> observable = subscriptionService.subscriptionTable()
.getSubscription(info.service_id, info.url)
.getSubscription(info.getServiceId(), info.getUrl())
.toObservable();
disposables.add(observable
@@ -315,14 +302,14 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
final Action onComplete = new Action() {
@Override
public void run() throws Exception {
if (DEBUG) Log.d(TAG, "Updated subscription: " + info.url);
if (DEBUG) Log.d(TAG, "Updated subscription: " + info.getUrl());
}
};
final Consumer<Throwable> onError = new Consumer<Throwable>() {
@Override
public void accept(@NonNull Throwable throwable) throws Exception {
onUnrecoverableError(throwable, UserAction.SUBSCRIPTION, NewPipe.getNameOfService(info.service_id), "Updating Subscription for " + info.url, R.string.subscription_update_failed);
onUnrecoverableError(throwable, UserAction.SUBSCRIPTION, NewPipe.getNameOfService(info.getServiceId()), "Updating Subscription for " + info.getUrl(), R.string.subscription_update_failed);
}
};
@@ -343,7 +330,7 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
final Consumer<Throwable> onError = new Consumer<Throwable>() {
@Override
public void accept(@NonNull Throwable throwable) throws Exception {
onUnrecoverableError(throwable, UserAction.SUBSCRIPTION, NewPipe.getNameOfService(currentInfo.service_id), "Subscription Change", R.string.subscription_change_failed);
onUnrecoverableError(throwable, UserAction.SUBSCRIPTION, NewPipe.getNameOfService(currentInfo.getServiceId()), "Subscription Change", R.string.subscription_change_failed);
}
};
@@ -367,9 +354,9 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
if (subscriptionEntities.isEmpty()) {
if (DEBUG) Log.d(TAG, "No subscription to this channel!");
SubscriptionEntity channel = new SubscriptionEntity();
channel.setServiceId(info.service_id);
channel.setUrl(info.url);
channel.setData(info.name, info.avatar_url, info.description, info.subscriber_count);
channel.setServiceId(info.getServiceId());
channel.setUrl(info.getUrl());
channel.setData(info.getName(), info.getAvatarUrl(), info.getDescription(), info.getSubscriberCount());
subscribeButtonMonitor = monitorSubscribeButton(headerSubscribeButton, mapOnSubscribe(channel));
} else {
if (DEBUG) Log.d(TAG, "Found subscription to this channel!");
@@ -440,16 +427,16 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
imageLoader.displayImage(result.banner_url, headerChannelBanner, DISPLAY_BANNER_OPTIONS);
imageLoader.displayImage(result.avatar_url, headerAvatarView, DISPLAY_AVATAR_OPTIONS);
if (result.subscriber_count != -1) {
headerSubscribersTextView.setText(Localization.localizeSubscribersCount(activity, result.subscriber_count));
if (result.getSubscriberCount() != -1) {
headerSubscribersTextView.setText(Localization.localizeSubscribersCount(activity, result.getSubscriberCount()));
headerSubscribersTextView.setVisibility(View.VISIBLE);
} else headerSubscribersTextView.setVisibility(View.GONE);
if (menuRssButton != null) menuRssButton.setVisible(!TextUtils.isEmpty(result.feed_url));
if (menuRssButton != null) menuRssButton.setVisible(!TextUtils.isEmpty(result.getFeedUrl()));
playlistCtrl.setVisibility(View.VISIBLE);
if (!result.errors.isEmpty()) {
showSnackBarError(result.errors, UserAction.REQUESTED_CHANNEL, NewPipe.getNameOfService(result.service_id), result.url, 0);
showSnackBarError(result.errors, UserAction.REQUESTED_CHANNEL, NewPipe.getNameOfService(result.getServiceId()), result.getUrl(), 0);
}
if (disposables != null) disposables.clear();
@@ -466,13 +453,6 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
headerPopupButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !PermissionHelper.checkSystemAlertWindowPermission(activity)) {
Toast toast = Toast.makeText(activity, R.string.msg_popup_permission, Toast.LENGTH_LONG);
TextView messageView = toast.getView().findViewById(android.R.id.message);
if (messageView != null) messageView.setGravity(Gravity.CENTER);
toast.show();
return;
}
NavigationHelper.playOnPopupPlayer(activity, getPlayQueue());
}
});
@@ -490,9 +470,9 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
private PlayQueue getPlayQueue(final int index) {
return new ChannelPlayQueue(
currentInfo.service_id,
currentInfo.url,
currentInfo.next_streams_url,
currentInfo.getServiceId(),
currentInfo.getUrl(),
currentInfo.getNextStreamsUrl(),
infoListAdapter.getItemsList(),
index
);
@@ -502,8 +482,8 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
public void handleNextItems(ListExtractor.NextItemsResult result) {
super.handleNextItems(result);
if (!result.errors.isEmpty()) {
showSnackBarError(result.errors, UserAction.REQUESTED_CHANNEL, NewPipe.getNameOfService(serviceId),
if (!result.getErrors().isEmpty()) {
showSnackBarError(result.getErrors(), UserAction.REQUESTED_CHANNEL, NewPipe.getNameOfService(serviceId),
"Get next page of: " + url, R.string.general_error);
}
}

View File

@@ -297,12 +297,12 @@ public class FeedFragment extends BaseListFragment<List<SubscriptionEntity>, Voi
// Called only when response is non-empty
@Override
public void onSuccess(final ChannelInfo channelInfo) {
if (infoListAdapter == null || channelInfo.related_streams.isEmpty()) {
if (infoListAdapter == null || channelInfo.getRelatedStreams().isEmpty()) {
onDone();
return;
}
final InfoItem item = channelInfo.related_streams.get(0);
final InfoItem item = channelInfo.getRelatedStreams().get(0);
// Keep requesting new items if the current one already exists
boolean itemExists = doesItemExist(infoListAdapter.getItemsList(), item);
if (!itemExists) {
@@ -412,9 +412,9 @@ public class FeedFragment extends BaseListFragment<List<SubscriptionEntity>, Voi
private boolean doesItemExist(final List<InfoItem> items, final InfoItem item) {
for (final InfoItem existingItem : items) {
if (existingItem.info_type == item.info_type &&
existingItem.service_id == item.service_id &&
existingItem.name.equals(item.name) &&
existingItem.url.equals(item.url)) return true;
existingItem.getServiceId() == item.getServiceId() &&
existingItem.getName().equals(item.getName()) &&
existingItem.getUrl().equals(item.getUrl())) return true;
}
return false;
}

View File

@@ -5,6 +5,7 @@ import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.ActionBar;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
@@ -57,14 +58,10 @@ public class KioskFragment extends BaseListInfoFragment<KioskInfo> {
@State
protected String kioskId = "";
/*//////////////////////////////////////////////////////////////////////////
// Views
//////////////////////////////////////////////////////////////////////////*/
private View headerRootLayout;
private TextView headerTitleView;
public static KioskFragment getInstance(int serviceId)
throws ExtractionException {
return getInstance(serviceId, NewPipe.getService(serviceId)
@@ -89,21 +86,40 @@ public class KioskFragment extends BaseListInfoFragment<KioskInfo> {
// LifeCycle
//////////////////////////////////////////////////////////////////////////*/
@Override
public void onActivityCreated(Bundle savedState) {
super.onActivityCreated(savedState);
try {
activity.getSupportActionBar()
.setTitle(KioskTranslator.getTranslatedKioskName(kioskId, getActivity()));
} catch (Exception e) {
onUnrecoverableError(e, UserAction.UI_ERROR,
"none",
"none", R.string.app_ui_crash);
}
}
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if(useAsFrontPage && isVisibleToUser) {
if(useAsFrontPage && isVisibleToUser && activity != null) {
try {
activity.getSupportActionBar().setTitle(KioskTranslator.getTranslatedKioskName(kioskId, getActivity()));
activity.getSupportActionBar()
.setTitle(KioskTranslator.getTranslatedKioskName(kioskId, getActivity()));
} catch (Exception e) {
onError(e);
onUnrecoverableError(e, UserAction.UI_ERROR,
"none",
"none", R.string.app_ui_crash);
}
}
}
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_kiosk, container, false);
View view = inflater.inflate(R.layout.fragment_kiosk, container, false);
activity.getSupportActionBar()
.setTitle(KioskTranslator.getTranslatedKioskName(kioskId, getActivity()));
return view;
}
/*//////////////////////////////////////////////////////////////////////////
@@ -127,14 +143,18 @@ public class KioskFragment extends BaseListInfoFragment<KioskInfo> {
public Single<KioskInfo> loadResult(boolean forceReload) {
String contentCountry = PreferenceManager
.getDefaultSharedPreferences(activity)
.getString(getString(R.string.search_language_key),
getString(R.string.default_language_value));
.getString(getString(R.string.content_country_key),
getString(R.string.default_country_value));
return ExtractorHelper.getKioskInfo(serviceId, url, contentCountry, forceReload);
}
@Override
public Single<ListExtractor.NextItemsResult> loadMoreItemsLogic() {
return ExtractorHelper.getMoreKioskItems(serviceId, url, currentNextItemsUrl);
String contentCountry = PreferenceManager
.getDefaultSharedPreferences(activity)
.getString(getString(R.string.content_country_key),
getString(R.string.default_country_value));
return ExtractorHelper.getMoreKioskItems(serviceId, url, currentNextItemsUrl, contentCountry);
}
/*//////////////////////////////////////////////////////////////////////////
@@ -155,10 +175,10 @@ public class KioskFragment extends BaseListInfoFragment<KioskInfo> {
ActionBar supportActionBar = activity.getSupportActionBar();
supportActionBar.setTitle(title);
if (!result.errors.isEmpty()) {
showSnackBarError(result.errors,
if (!result.getErrors().isEmpty()) {
showSnackBarError(result.getErrors(),
UserAction.REQUESTED_PLAYLIST,
NewPipe.getNameOfService(result.service_id), result.url, 0);
NewPipe.getNameOfService(result.getServiceId()), result.getUrl(), 0);
}
}
@@ -166,8 +186,8 @@ public class KioskFragment extends BaseListInfoFragment<KioskInfo> {
public void handleNextItems(ListExtractor.NextItemsResult result) {
super.handleNextItems(result);
if (!result.errors.isEmpty()) {
showSnackBarError(result.errors,
if (!result.getErrors().isEmpty()) {
showSnackBarError(result.getErrors(),
UserAction.REQUESTED_PLAYLIST, NewPipe.getNameOfService(serviceId)
, "Get next page of: " + url, 0);
}

View File

@@ -1,22 +1,21 @@
package org.schabi.newpipe.fragments.list.playlist;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import org.schabi.newpipe.R;
import org.schabi.newpipe.extractor.ListExtractor;
@@ -32,7 +31,6 @@ import org.schabi.newpipe.playlist.SinglePlayQueue;
import org.schabi.newpipe.report.UserAction;
import org.schabi.newpipe.util.ExtractorHelper;
import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.PermissionHelper;
import io.reactivex.Single;
@@ -98,16 +96,10 @@ public class PlaylistFragment extends BaseListInfoFragment<PlaylistInfo> {
infoListAdapter.useMiniItemVariants(true);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
if (DEBUG) Log.d(TAG, "onCreateOptionsMenu() called with: menu = [" + menu + "], inflater = [" + inflater + "]");
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.menu_playlist, menu);
}
@Override
protected void showStreamDialog(final StreamInfoItem item) {
final Context context = getContext();
final Activity activity = getActivity();
if (context == null || context.getResources() == null || getActivity() == null) return;
final String[] commands = new String[]{
@@ -127,7 +119,7 @@ public class PlaylistFragment extends BaseListInfoFragment<PlaylistInfo> {
NavigationHelper.enqueueOnBackgroundPlayer(context, new SinglePlayQueue(item));
break;
case 1:
NavigationHelper.enqueueOnPopupPlayer(context, new SinglePlayQueue(item));
NavigationHelper.enqueueOnPopupPlayer(activity, new SinglePlayQueue(item));
break;
case 2:
NavigationHelper.playOnMainPlayer(context, getPlayQueue(index));
@@ -136,7 +128,7 @@ public class PlaylistFragment extends BaseListInfoFragment<PlaylistInfo> {
NavigationHelper.playOnBackgroundPlayer(context, getPlayQueue(index));
break;
case 4:
NavigationHelper.playOnPopupPlayer(context, getPlayQueue(index));
NavigationHelper.playOnPopupPlayer(activity, getPlayQueue(index));
break;
default:
break;
@@ -146,6 +138,14 @@ public class PlaylistFragment extends BaseListInfoFragment<PlaylistInfo> {
new InfoItemDialog(getActivity(), item, commands, actions).show();
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
if (DEBUG) Log.d(TAG, "onCreateOptionsMenu() called with: menu = [" + menu + "], inflater = [" + inflater + "]");
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.menu_playlist, menu);
}
/*//////////////////////////////////////////////////////////////////////////
// Load and handle
//////////////////////////////////////////////////////////////////////////*/
@@ -160,6 +160,23 @@ public class PlaylistFragment extends BaseListInfoFragment<PlaylistInfo> {
return ExtractorHelper.getPlaylistInfo(serviceId, url, forceLoad);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_item_openInBrowser:
openUrlInBrowser(url);
break;
case R.id.menu_item_share: {
shareUrl(name, url);
break;
}
default:
return super.onOptionsItemSelected(item);
}
return true;
}
/*//////////////////////////////////////////////////////////////////////////
// Contract
//////////////////////////////////////////////////////////////////////////*/
@@ -181,13 +198,13 @@ public class PlaylistFragment extends BaseListInfoFragment<PlaylistInfo> {
animateView(headerRootLayout, true, 100);
animateView(headerUploaderLayout, true, 300);
headerUploaderLayout.setOnClickListener(null);
if (!TextUtils.isEmpty(result.uploader_name)) {
headerUploaderName.setText(result.uploader_name);
if (!TextUtils.isEmpty(result.uploader_url)) {
if (!TextUtils.isEmpty(result.getUploaderName())) {
headerUploaderName.setText(result.getUploaderName());
if (!TextUtils.isEmpty(result.getUploaderUrl())) {
headerUploaderLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
NavigationHelper.openChannelFragment(getFragmentManager(), result.service_id, result.uploader_url, result.uploader_name);
NavigationHelper.openChannelFragment(getFragmentManager(), result.getServiceId(), result.getUploaderUrl(), result.getUploaderName());
}
});
}
@@ -195,11 +212,11 @@ public class PlaylistFragment extends BaseListInfoFragment<PlaylistInfo> {
playlistCtrl.setVisibility(View.VISIBLE);
imageLoader.displayImage(result.uploader_avatar_url, headerUploaderAvatar, DISPLAY_AVATAR_OPTIONS);
imageLoader.displayImage(result.getUploaderAvatarUrl(), headerUploaderAvatar, DISPLAY_AVATAR_OPTIONS);
headerStreamCount.setText(getResources().getQuantityString(R.plurals.videos, (int) result.stream_count, (int) result.stream_count));
if (!result.errors.isEmpty()) {
showSnackBarError(result.errors, UserAction.REQUESTED_PLAYLIST, NewPipe.getNameOfService(result.service_id), result.url, 0);
if (!result.getErrors().isEmpty()) {
showSnackBarError(result.getErrors(), UserAction.REQUESTED_PLAYLIST, NewPipe.getNameOfService(result.getServiceId()), result.getUrl(), 0);
}
headerPlayAllButton.setOnClickListener(new View.OnClickListener() {
@@ -211,13 +228,6 @@ public class PlaylistFragment extends BaseListInfoFragment<PlaylistInfo> {
headerPopupButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !PermissionHelper.checkSystemAlertWindowPermission(activity)) {
Toast toast = Toast.makeText(activity, R.string.msg_popup_permission, Toast.LENGTH_LONG);
TextView messageView = toast.getView().findViewById(android.R.id.message);
if (messageView != null) messageView.setGravity(Gravity.CENTER);
toast.show();
return;
}
NavigationHelper.playOnPopupPlayer(activity, getPlayQueue());
}
});
@@ -235,9 +245,9 @@ public class PlaylistFragment extends BaseListInfoFragment<PlaylistInfo> {
private PlayQueue getPlayQueue(final int index) {
return new PlaylistPlayQueue(
currentInfo.service_id,
currentInfo.url,
currentInfo.next_streams_url,
currentInfo.getServiceId(),
currentInfo.getUrl(),
currentInfo.getNextStreamsUrl(),
infoListAdapter.getItemsList(),
index
);
@@ -247,8 +257,8 @@ public class PlaylistFragment extends BaseListInfoFragment<PlaylistInfo> {
public void handleNextItems(ListExtractor.NextItemsResult result) {
super.handleNextItems(result);
if (!result.errors.isEmpty()) {
showSnackBarError(result.errors, UserAction.REQUESTED_PLAYLIST, NewPipe.getNameOfService(serviceId)
if (!result.getErrors().isEmpty()) {
showSnackBarError(result.getErrors(), UserAction.REQUESTED_PLAYLIST, NewPipe.getNameOfService(serviceId)
, "Get next page of: " + url, 0);
}
}

View File

@@ -111,7 +111,7 @@ public class SearchFragment extends BaseListFragment<SearchResult, ListExtractor
private int currentPage = 0;
private int currentNextPage = 0;
private String searchLanguage;
private String contentCountry;
private boolean isSuggestionsEnabled = true;
private boolean isSearchHistoryEnabled = true;
@@ -176,7 +176,7 @@ public class SearchFragment extends BaseListFragment<SearchResult, ListExtractor
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity);
isSuggestionsEnabled = preferences.getBoolean(getString(R.string.show_search_suggestions_key), true);
searchLanguage = preferences.getString(getString(R.string.search_language_key), getString(R.string.default_language_value));
contentCountry = preferences.getString(getString(R.string.content_country_key), getString(R.string.default_country_value));
}
@Override
@@ -619,7 +619,7 @@ public class SearchFragment extends BaseListFragment<SearchResult, ListExtractor
return local.materialize();
}
final Observable<List<SuggestionItem>> network = ExtractorHelper.suggestionsFor(serviceId, query, searchLanguage).toObservable()
final Observable<List<SuggestionItem>> network = ExtractorHelper.suggestionsFor(serviceId, query, contentCountry).toObservable()
.map(new Function<List<String>, List<SuggestionItem>>() {
@Override
public List<SuggestionItem> apply(@io.reactivex.annotations.NonNull List<String> strings) throws Exception {
@@ -731,7 +731,7 @@ public class SearchFragment extends BaseListFragment<SearchResult, ListExtractor
super.startLoading(forceLoad);
if (disposables != null) disposables.clear();
if (searchDisposable != null) searchDisposable.dispose();
searchDisposable = ExtractorHelper.searchFor(serviceId, searchQuery, currentPage, searchLanguage, filter)
searchDisposable = ExtractorHelper.searchFor(serviceId, searchQuery, currentPage, contentCountry, filter)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<SearchResult>() {
@@ -755,7 +755,7 @@ public class SearchFragment extends BaseListFragment<SearchResult, ListExtractor
showListFooter(true);
if (searchDisposable != null) searchDisposable.dispose();
currentNextPage = currentPage + 1;
searchDisposable = ExtractorHelper.getMoreSearchItems(serviceId, searchQuery, currentNextPage, searchLanguage, filter)
searchDisposable = ExtractorHelper.getMoreSearchItems(serviceId, searchQuery, currentNextPage, contentCountry, filter)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<ListExtractor.NextItemsResult>() {
@@ -861,8 +861,8 @@ public class SearchFragment extends BaseListFragment<SearchResult, ListExtractor
lastSearchedQuery = searchQuery;
if (infoListAdapter.getItemsList().size() == 0) {
if (result.resultList.size() > 0) {
infoListAdapter.addInfoItemList(result.resultList);
if (!result.getResults().isEmpty()) {
infoListAdapter.addInfoItemList(result.getResults());
} else {
infoListAdapter.clearStreamItemList();
showEmptyState();
@@ -876,11 +876,11 @@ public class SearchFragment extends BaseListFragment<SearchResult, ListExtractor
@Override
public void handleNextItems(ListExtractor.NextItemsResult result) {
showListFooter(false);
currentPage = Integer.parseInt(result.nextItemsUrl);
infoListAdapter.addInfoItemList(result.nextItemsList);
currentPage = Integer.parseInt(result.getNextItemsUrl());
infoListAdapter.addInfoItemList(result.getNextItemsList());
if (!result.errors.isEmpty()) {
showSnackBarError(result.errors, UserAction.SEARCHED, NewPipe.getNameOfService(serviceId)
if (!result.getErrors().isEmpty()) {
showSnackBarError(result.getErrors(), UserAction.SEARCHED, NewPipe.getNameOfService(serviceId)
, "\"" + searchQuery + "\" → page " + currentPage, 0);
}
super.handleNextItems(result);

View File

@@ -129,7 +129,7 @@ public class SubscriptionFragment extends BaseStateFragment<List<SubscriptionEnt
@Override
public void selected(ChannelInfoItem selectedItem) {
// Requires the parent fragment to find holder for fragment replacement
NavigationHelper.openChannelFragment(getParentFragment().getFragmentManager(), selectedItem.service_id, selectedItem.url, selectedItem.name);
NavigationHelper.openChannelFragment(getParentFragment().getFragmentManager(), selectedItem.getServiceId(), selectedItem.url, selectedItem.getName());
}

View File

@@ -112,7 +112,7 @@ public class SubscriptionService {
// Subscriber count changes very often, making this check almost unnecessary.
// Consider removing it later.
if (!isSubscriptionUpToDate(info, subscription)) {
subscription.setData(info.name, info.avatar_url, info.description, info.subscriber_count);
subscription.setData(info.getName(), info.getAvatarUrl(), info.getDescription(), info.getSubscriberCount());
return update(subscription);
}
@@ -122,7 +122,7 @@ public class SubscriptionService {
}
};
return subscriptionTable().getSubscription(info.service_id, info.url)
return subscriptionTable().getSubscription(info.getServiceId(), info.getUrl())
.firstOrError()
.flatMapCompletable(update);
}
@@ -137,11 +137,11 @@ public class SubscriptionService {
}
private boolean isSubscriptionUpToDate(final ChannelInfo info, final SubscriptionEntity entity) {
return info.url.equals(entity.getUrl()) &&
info.service_id == entity.getServiceId() &&
info.name.equals(entity.getName()) &&
info.avatar_url.equals(entity.getAvatarUrl()) &&
info.description.equals(entity.getDescription()) &&
info.subscriber_count == entity.getSubscriberCount();
return info.getUrl().equals(entity.getUrl()) &&
info.getServiceId() == entity.getServiceId() &&
info.getName().equals(entity.getName()) &&
info.getAvatarUrl().equals(entity.getAvatarUrl()) &&
info.getDescription().equals(entity.getDescription()) &&
info.getSubscriberCount() == entity.getSubscriberCount();
}
}

View File

@@ -19,7 +19,7 @@ public class InfoItemDialog {
@NonNull final StreamInfoItem info,
@NonNull final String[] commands,
@NonNull final DialogInterface.OnClickListener actions) {
this(activity, commands, actions, info.name, info.uploader_name);
this(activity, commands, actions, info.getName(), info.uploader_name);
}
public InfoItemDialog(@NonNull final Activity activity,

View File

@@ -36,7 +36,7 @@ public class ChannelMiniInfoItemHolder extends InfoItemHolder {
if (!(infoItem instanceof ChannelInfoItem)) return;
final ChannelInfoItem item = (ChannelInfoItem) infoItem;
itemTitleView.setText(item.name);
itemTitleView.setText(item.getName());
itemAdditionalDetailView.setText(getDetailLine(item));
itemBuilder.getImageLoader()

View File

@@ -32,7 +32,7 @@ public class PlaylistInfoItemHolder extends InfoItemHolder {
if (!(infoItem instanceof PlaylistInfoItem)) return;
final PlaylistInfoItem item = (PlaylistInfoItem) infoItem;
itemTitleView.setText(item.name);
itemTitleView.setText(item.getName());
itemStreamCountView.setText(item.stream_count + "");
itemUploaderView.setText(item.uploader_name);

View File

@@ -40,7 +40,7 @@ public class StreamMiniInfoItemHolder extends InfoItemHolder {
if (!(infoItem instanceof StreamInfoItem)) return;
final StreamInfoItem item = (StreamInfoItem) infoItem;
itemVideoTitleView.setText(item.name);
itemVideoTitleView.setText(item.getName());
itemUploaderView.setText(item.uploader_name);
if (item.duration > 0) {

View File

@@ -65,7 +65,6 @@ public final class BackgroundPlayer extends Service {
public static final String ACTION_CLOSE = "org.schabi.newpipe.player.BackgroundPlayer.CLOSE";
public static final String ACTION_PLAY_PAUSE = "org.schabi.newpipe.player.BackgroundPlayer.PLAY_PAUSE";
public static final String ACTION_OPEN_CONTROLS = "org.schabi.newpipe.player.BackgroundPlayer.OPEN_CONTROLS";
public static final String ACTION_REPEAT = "org.schabi.newpipe.player.BackgroundPlayer.REPEAT";
public static final String ACTION_PLAY_NEXT = "org.schabi.newpipe.player.BackgroundPlayer.ACTION_PLAY_NEXT";
public static final String ACTION_PLAY_PREVIOUS = "org.schabi.newpipe.player.BackgroundPlayer.ACTION_PLAY_PREVIOUS";
@@ -177,7 +176,7 @@ public final class BackgroundPlayer extends Service {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, getString(R.string.notification_channel_id))
.setOngoing(true)
.setSmallIcon(R.drawable.ic_play_circle_filled_white_24dp)
.setSmallIcon(R.drawable.ic_newpipe_triangle_white)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setCustomContentView(notRemoteView)
.setCustomBigContentView(bigNotRemoteView);
@@ -195,11 +194,14 @@ public final class BackgroundPlayer extends Service {
PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_PLAY_PAUSE), PendingIntent.FLAG_UPDATE_CURRENT));
remoteViews.setOnClickPendingIntent(R.id.notificationStop,
PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_CLOSE), PendingIntent.FLAG_UPDATE_CURRENT));
remoteViews.setOnClickPendingIntent(R.id.notificationContent,
PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_OPEN_CONTROLS), PendingIntent.FLAG_UPDATE_CURRENT));
remoteViews.setOnClickPendingIntent(R.id.notificationRepeat,
PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_REPEAT), PendingIntent.FLAG_UPDATE_CURRENT));
// Starts background player activity -- attempts to unlock lockscreen
final Intent intent = NavigationHelper.getBackgroundPlayerActivityIntent(this);
remoteViews.setOnClickPendingIntent(R.id.notificationContent,
PendingIntent.getActivity(this, NOTIFICATION_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT));
if (basePlayerImpl.playQueue != null && basePlayerImpl.playQueue.size() > 1) {
remoteViews.setInt(R.id.notificationFRewind, SET_IMAGE_RESOURCE_METHOD, R.drawable.exo_controls_previous);
remoteViews.setInt(R.id.notificationFForward, SET_IMAGE_RESOURCE_METHOD, R.drawable.exo_controls_next);
@@ -393,7 +395,7 @@ public final class BackgroundPlayer extends Service {
if (index < 0 || index >= info.audio_streams.size()) return null;
final AudioStream audio = info.audio_streams.get(index);
return buildMediaSource(audio.url, MediaFormat.getSuffixById(audio.format));
return buildMediaSource(audio.getUrl(), MediaFormat.getSuffixById(audio.getFormatId()));
}
@Override
@@ -453,7 +455,6 @@ public final class BackgroundPlayer extends Service {
super.setupBroadcastReceiver(intentFilter);
intentFilter.addAction(ACTION_CLOSE);
intentFilter.addAction(ACTION_PLAY_PAUSE);
intentFilter.addAction(ACTION_OPEN_CONTROLS);
intentFilter.addAction(ACTION_REPEAT);
intentFilter.addAction(ACTION_PLAY_PREVIOUS);
intentFilter.addAction(ACTION_PLAY_NEXT);
@@ -478,9 +479,6 @@ public final class BackgroundPlayer extends Service {
case ACTION_PLAY_PAUSE:
onVideoPlayPause();
break;
case ACTION_OPEN_CONTROLS:
NavigationHelper.openBackgroundPlayerControl(getApplicationContext());
break;
case ACTION_REPEAT:
onRepeatClicked();
break;

View File

@@ -1,9 +1,12 @@
package org.schabi.newpipe.player;
import android.content.Intent;
import android.view.MenuItem;
import org.schabi.newpipe.R;
import static org.schabi.newpipe.player.BackgroundPlayer.ACTION_CLOSE;
public final class BackgroundPlayerActivity extends ServicePlayerActivity {
private static final String TAG = "BackgroundPlayerActivity";
@@ -36,4 +39,25 @@ public final class BackgroundPlayerActivity extends ServicePlayerActivity {
((BackgroundPlayer.BasePlayerImpl) player).removeActivityListener(this);
}
}
@Override
public int getPlayerOptionMenuResource() {
return R.menu.menu_play_queue_bg;
}
@Override
public boolean onPlayerOptionSelected(MenuItem item) {
if (item.getItemId() == R.id.action_switch_popup) {
this.player.setRecovery();
getApplicationContext().sendBroadcast(getPlayerShutdownIntent());
getApplicationContext().startService(getSwitchIntent(PopupVideoPlayer.class));
return true;
}
return false;
}
@Override
public Intent getPlayerShutdownIntent() {
return new Intent(ACTION_CLOSE);
}
}

View File

@@ -25,6 +25,7 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Color;
import android.media.AudioManager;
import android.os.Build;
@@ -37,7 +38,6 @@ import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
@@ -62,6 +62,7 @@ import org.schabi.newpipe.util.AnimationUtils;
import org.schabi.newpipe.util.ListHelper;
import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.PermissionHelper;
import org.schabi.newpipe.util.PopupMenuIconHacker;
import org.schabi.newpipe.util.ThemeHelper;
import java.lang.reflect.Field;
@@ -78,6 +79,7 @@ import static org.schabi.newpipe.util.AnimationUtils.animateView;
public final class MainVideoPlayer extends Activity {
private static final String TAG = ".MainVideoPlayer";
private static final boolean DEBUG = BasePlayer.DEBUG;
private static final String PLAYER_STATE_INTENT = "player_state_intent";
private GestureDetector gestureDetector;
@@ -99,19 +101,41 @@ public final class MainVideoPlayer extends Activity {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) getWindow().setStatusBarColor(Color.BLACK);
setVolumeControlStream(AudioManager.STREAM_MUSIC);
if (getIntent() == null) {
final Intent intent;
if (savedInstanceState != null && savedInstanceState.getParcelable(PLAYER_STATE_INTENT) != null) {
intent = savedInstanceState.getParcelable(PLAYER_STATE_INTENT);
} else {
intent = getIntent();
}
if (intent == null) {
Toast.makeText(this, R.string.general_error, Toast.LENGTH_SHORT).show();
finish();
return;
}
showSystemUi();
setContentView(R.layout.activity_main_player);
playerImpl = new VideoPlayerImpl(this);
playerImpl.setup(findViewById(android.R.id.content));
playerImpl.handleIntent(getIntent());
playerImpl.handleIntent(intent);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (this.playerImpl == null) return;
final Intent intent = NavigationHelper.getPlayerIntent(
getApplicationContext(),
this.getClass(),
this.playerImpl.getPlayQueue(),
this.playerImpl.getRepeatMode(),
this.playerImpl.getPlaybackSpeed(),
this.playerImpl.getPlaybackPitch(),
this.playerImpl.getPlaybackQuality()
);
outState.putParcelable(PLAYER_STATE_INTENT, intent);
}
@Override
@@ -303,7 +327,7 @@ public final class MainVideoPlayer extends Activity {
this.playNextButton = rootView.findViewById(R.id.playNextButton);
this.moreOptionsButton = rootView.findViewById(R.id.moreOptionsButton);
this.moreOptionsPopupMenu = new PopupMenu(context, moreOptionsButton);
this.moreOptionsPopupMenu.getMenuInflater().inflate(R.menu.menu_videooptions, moreOptionsPopupMenu.getMenu());
buildMoreOptionsMenu();
titleTextView.setSelected(true);
channelTextView.setSelected(true);
@@ -356,7 +380,7 @@ public final class MainVideoPlayer extends Activity {
titleTextView.setText(getVideoTitle());
channelTextView.setText(getUploaderName());
playPauseButton.setImageResource(R.drawable.ic_pause_white);
//playPauseButton.setImageResource(R.drawable.ic_pause_white);
}
@Override
@@ -448,12 +472,9 @@ public final class MainVideoPlayer extends Activity {
if (getCurrentState() != STATE_COMPLETED) {
getControlsVisibilityHandler().removeCallbacksAndMessages(null);
animateView(getControlsRoot(), true, 300, 0, new Runnable() {
@Override
public void run() {
if (getCurrentState() == STATE_PLAYING && !isSomePopupMenuVisible()) {
hideControls(300, DEFAULT_CONTROLS_HIDE_TIME);
}
animateView(getControlsRoot(), true, 300, 0, () -> {
if (getCurrentState() == STATE_PLAYING && !isSomePopupMenuVisible()) {
hideControls(300, DEFAULT_CONTROLS_HIDE_TIME);
}
});
}
@@ -479,25 +500,7 @@ public final class MainVideoPlayer extends Activity {
private void onMoreOptionsClicked() {
if (DEBUG) Log.d(TAG, "onMoreOptionsClicked() called");
buildMoreOptionsMenu();
try {
Field[] fields = moreOptionsPopupMenu.getClass().getDeclaredFields();
for (Field field : fields) {
if ("mPopup".equals(field.getName())) {
field.setAccessible(true);
Object menuPopupHelper = field.get(moreOptionsPopupMenu);
Class<?> classPopupHelper = Class.forName(menuPopupHelper
.getClass().getName());
Method setForceIcons = classPopupHelper.getMethod(
"setForceShowIcon", boolean.class);
setForceIcons.invoke(menuPopupHelper, true);
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
moreOptionsPopupMenu.show();
isSomePopupMenuVisible = true;
showControls(300);
@@ -506,6 +509,7 @@ public final class MainVideoPlayer extends Activity {
private void onScreenRotationClicked() {
if (DEBUG) Log.d(TAG, "onScreenRotationClicked() called");
toggleOrientation();
showControlsThenHide();
}
@Override
@@ -561,12 +565,9 @@ public final class MainVideoPlayer extends Activity {
@Override
public void onPlaying() {
super.onPlaying();
animateView(playPauseButton, AnimationUtils.Type.SCALE_AND_ALPHA, false, 80, 0, new Runnable() {
@Override
public void run() {
playPauseButton.setImageResource(R.drawable.ic_pause_white);
animatePlayButtons(true, 200);
}
animateView(playPauseButton, AnimationUtils.Type.SCALE_AND_ALPHA, false, 80, 0, () -> {
playPauseButton.setImageResource(R.drawable.ic_pause_white);
animatePlayButtons(true, 200);
});
showSystemUi();
getRootView().setKeepScreenOn(true);
@@ -575,12 +576,9 @@ public final class MainVideoPlayer extends Activity {
@Override
public void onPaused() {
super.onPaused();
animateView(playPauseButton, AnimationUtils.Type.SCALE_AND_ALPHA, false, 80, 0, new Runnable() {
@Override
public void run() {
playPauseButton.setImageResource(R.drawable.ic_play_arrow_white);
animatePlayButtons(true, 200);
}
animateView(playPauseButton, AnimationUtils.Type.SCALE_AND_ALPHA, false, 80, 0, () -> {
playPauseButton.setImageResource(R.drawable.ic_play_arrow_white);
animatePlayButtons(true, 200);
});
showSystemUi();
@@ -598,12 +596,9 @@ public final class MainVideoPlayer extends Activity {
@Override
public void onCompleted() {
showSystemUi();
animateView(playPauseButton, AnimationUtils.Type.SCALE_AND_ALPHA, false, 0, 0, new Runnable() {
@Override
public void run() {
playPauseButton.setImageResource(R.drawable.ic_replay_white);
animatePlayButtons(true, 300);
}
animateView(playPauseButton, AnimationUtils.Type.SCALE_AND_ALPHA, false, 0, 0, () -> {
playPauseButton.setImageResource(R.drawable.ic_replay_white);
animatePlayButtons(true, 300);
});
getRootView().setKeepScreenOn(false);
@@ -632,17 +627,10 @@ public final class MainVideoPlayer extends Activity {
public void hideControls(final long duration, long delay) {
if (DEBUG) Log.d(TAG, "hideControls() called with: delay = [" + delay + "]");
getControlsVisibilityHandler().removeCallbacksAndMessages(null);
getControlsVisibilityHandler().postDelayed(new Runnable() {
@Override
public void run() {
animateView(getControlsRoot(), false, duration, 0, new Runnable() {
@Override
public void run() {
hideSystemUi();
}
});
}
}, delay);
getControlsVisibilityHandler().postDelayed(() ->
animateView(getControlsRoot(), false, duration, 0, MainVideoPlayer.this::hideSystemUi),
delay
);
}
private void updatePlaybackButtons() {
@@ -654,24 +642,39 @@ public final class MainVideoPlayer extends Activity {
}
private void buildMoreOptionsMenu() {
if (moreOptionsPopupMenu == null) return;
moreOptionsPopupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.toggleOrientation:
onScreenRotationClicked();
break;
case R.id.switchPopup:
onFullScreenButtonClicked();
break;
case R.id.switchBackground:
onPlayBackgroundButtonClicked();
break;
}
return false;
this.moreOptionsPopupMenu.getMenuInflater().inflate(R.menu.menu_videooptions,
moreOptionsPopupMenu.getMenu());
moreOptionsPopupMenu.setOnMenuItemClickListener(menuItem -> {
switch (menuItem.getItemId()) {
case R.id.toggleOrientation:
onScreenRotationClicked();
break;
case R.id.switchPopup:
onFullScreenButtonClicked();
break;
case R.id.switchBackground:
onPlayBackgroundButtonClicked();
break;
}
return false;
});
try {
PopupMenuIconHacker.setShowPopupIcon(moreOptionsPopupMenu);
} catch (Exception e) {
e.printStackTrace();
}
// fix icon theme
if(ThemeHelper.isLightThemeSelected(MainVideoPlayer.this)) {
moreOptionsPopupMenu.getMenu()
.findItem(R.id.toggleOrientation)
.setIcon(R.drawable.ic_screen_rotation_black_24dp);
moreOptionsPopupMenu.getMenu()
.findItem(R.id.switchPopup)
.setIcon(R.drawable.ic_fullscreen_exit_black_24dp);
}
}
private void buildQueue() {
@@ -692,12 +695,7 @@ public final class MainVideoPlayer extends Activity {
playQueueAdapter.setSelectedListener(getOnSelectedListener());
itemsListCloseButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
onQueueClosed();
}
});
itemsListCloseButton.setOnClickListener(view -> onQueueClosed());
}
private OnScrollBelowItemsListener getQueueScrollListener() {

View File

@@ -44,6 +44,7 @@ import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageButton;
import android.widget.PopupMenu;
import android.widget.RemoteViews;
import android.widget.SeekBar;
@@ -65,9 +66,9 @@ import org.schabi.newpipe.extractor.services.youtube.YoutubeStreamExtractor;
import org.schabi.newpipe.extractor.stream.StreamInfo;
import org.schabi.newpipe.extractor.stream.VideoStream;
import org.schabi.newpipe.player.event.PlayerEventListener;
import org.schabi.newpipe.player.helper.LockManager;
import org.schabi.newpipe.player.helper.PlayerHelper;
import org.schabi.newpipe.player.old.PlayVideoActivity;
import org.schabi.newpipe.player.helper.LockManager;
import org.schabi.newpipe.playlist.PlayQueueItem;
import org.schabi.newpipe.playlist.SinglePlayQueue;
import org.schabi.newpipe.report.ErrorActivity;
@@ -83,7 +84,6 @@ import java.util.List;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;
import static org.schabi.newpipe.player.helper.PlayerHelper.isUsingOldPlayer;
@@ -101,7 +101,6 @@ public final class PopupVideoPlayer extends Service {
private static final int NOTIFICATION_ID = 40028922;
public static final String ACTION_CLOSE = "org.schabi.newpipe.player.PopupVideoPlayer.CLOSE";
public static final String ACTION_PLAY_PAUSE = "org.schabi.newpipe.player.PopupVideoPlayer.PLAY_PAUSE";
public static final String ACTION_OPEN_CONTROLS = "org.schabi.newpipe.player.PopupVideoPlayer.OPEN_CONTROLS";
public static final String ACTION_REPEAT = "org.schabi.newpipe.player.PopupVideoPlayer.REPEAT";
private static final String POPUP_SAVED_WIDTH = "popup_saved_width";
@@ -168,17 +167,7 @@ public final class PopupVideoPlayer extends Service {
currentWorker = ExtractorHelper.getStreamInfo(serviceId,url,false)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<StreamInfo>() {
@Override
public void accept(@NonNull StreamInfo info) throws Exception {
fetcherRunnable.onReceive(info);
}
}, new Consumer<Throwable>() {
@Override
public void accept(@NonNull Throwable throwable) throws Exception {
fetcherRunnable.onError(throwable);
}
});
.subscribe(fetcherRunnable::onReceive, fetcherRunnable::onError);
} else {
playerImpl.setStartedFromNewPipe(true);
playerImpl.handleIntent(intent);
@@ -266,16 +255,19 @@ public final class PopupVideoPlayer extends Service {
PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_PLAY_PAUSE), PendingIntent.FLAG_UPDATE_CURRENT));
notRemoteView.setOnClickPendingIntent(R.id.notificationStop,
PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_CLOSE), PendingIntent.FLAG_UPDATE_CURRENT));
notRemoteView.setOnClickPendingIntent(R.id.notificationContent,
PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_OPEN_CONTROLS), PendingIntent.FLAG_UPDATE_CURRENT));
notRemoteView.setOnClickPendingIntent(R.id.notificationRepeat,
PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_REPEAT), PendingIntent.FLAG_UPDATE_CURRENT));
// Starts popup player activity -- attempts to unlock lockscreen
final Intent intent = NavigationHelper.getPopupPlayerActivityIntent(this);
notRemoteView.setOnClickPendingIntent(R.id.notificationContent,
PendingIntent.getActivity(this, NOTIFICATION_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT));
setRepeatModeRemote(notRemoteView, playerImpl.getRepeatMode());
return new NotificationCompat.Builder(this, getString(R.string.notification_channel_id))
.setOngoing(true)
.setSmallIcon(R.drawable.ic_play_arrow_white)
.setSmallIcon(R.drawable.ic_newpipe_triangle_white)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setContent(notRemoteView);
}
@@ -401,6 +393,7 @@ public final class PopupVideoPlayer extends Service {
protected class VideoPlayerImpl extends VideoPlayer {
private TextView resizingIndicator;
private ImageButton fullScreenButton;
@Override
public void handleIntent(Intent intent) {
@@ -418,6 +411,8 @@ public final class PopupVideoPlayer extends Service {
public void initViews(View rootView) {
super.initViews(rootView);
resizingIndicator = rootView.findViewById(R.id.resizing_indicator);
fullScreenButton = rootView.findViewById(R.id.fullScreenButton);
fullScreenButton.setOnClickListener(v -> onFullScreenButtonClicked());
}
@Override
@@ -462,7 +457,7 @@ public final class PopupVideoPlayer extends Service {
} else {
intent = new Intent(PopupVideoPlayer.this, PlayVideoActivity.class)
.putExtra(PlayVideoActivity.VIDEO_TITLE, getVideoTitle())
.putExtra(PlayVideoActivity.STREAM_URL, getSelectedVideoStream().url)
.putExtra(PlayVideoActivity.STREAM_URL, getSelectedVideoStream().getUrl())
.putExtra(PlayVideoActivity.VIDEO_URL, getVideoUrl())
.putExtra(PlayVideoActivity.START_POSITION, Math.round(getPlayer().getCurrentPosition() / 1000f));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
@@ -595,7 +590,6 @@ public final class PopupVideoPlayer extends Service {
if (DEBUG) Log.d(TAG, "setupBroadcastReceiver() called with: intentFilter = [" + intentFilter + "]");
intentFilter.addAction(ACTION_CLOSE);
intentFilter.addAction(ACTION_PLAY_PAUSE);
intentFilter.addAction(ACTION_OPEN_CONTROLS);
intentFilter.addAction(ACTION_REPEAT);
intentFilter.addAction(Intent.ACTION_SCREEN_ON);
@@ -614,9 +608,6 @@ public final class PopupVideoPlayer extends Service {
case ACTION_PLAY_PAUSE:
onVideoPlayPause();
break;
case ACTION_OPEN_CONTROLS:
NavigationHelper.openPopupPlayerControl(getApplicationContext());
break;
case ACTION_REPEAT:
onRepeatClicked();
break;
@@ -890,37 +881,31 @@ public final class PopupVideoPlayer extends Service {
}
private void onReceive(final StreamInfo info) {
mainHandler.post(new Runnable() {
@Override
public void run() {
final Intent intent = NavigationHelper.getPlayerIntent(getApplicationContext(),
PopupVideoPlayer.class, new SinglePlayQueue(info));
playerImpl.handleIntent(intent);
}
mainHandler.post(() -> {
final Intent intent = NavigationHelper.getPlayerIntent(getApplicationContext(),
PopupVideoPlayer.class, new SinglePlayQueue(info));
playerImpl.handleIntent(intent);
});
}
private void onError(final Throwable exception) {
if (DEBUG) Log.d(TAG, "onError() called with: exception = [" + exception + "]");
exception.printStackTrace();
mainHandler.post(new Runnable() {
@Override
public void run() {
if (exception instanceof ReCaptchaException) {
onReCaptchaException();
} else if (exception instanceof IOException) {
Toast.makeText(context, R.string.network_error, Toast.LENGTH_LONG).show();
} else if (exception instanceof YoutubeStreamExtractor.GemaException) {
Toast.makeText(context, R.string.blocked_by_gema, Toast.LENGTH_LONG).show();
} else if (exception instanceof YoutubeStreamExtractor.LiveStreamException) {
Toast.makeText(context, R.string.live_streams_not_supported, Toast.LENGTH_LONG).show();
} else if (exception instanceof ContentNotAvailableException) {
Toast.makeText(context, R.string.content_not_available, Toast.LENGTH_LONG).show();
} else {
int errorId = exception instanceof YoutubeStreamExtractor.DecryptException ? R.string.youtube_signature_decryption_error :
exception instanceof ParsingException ? R.string.parsing_error : R.string.general_error;
ErrorActivity.reportError(mainHandler, context, exception, MainActivity.class, null, ErrorActivity.ErrorInfo.make(UserAction.REQUESTED_STREAM, NewPipe.getNameOfService(serviceId), url, errorId));
}
mainHandler.post(() -> {
if (exception instanceof ReCaptchaException) {
onReCaptchaException();
} else if (exception instanceof IOException) {
Toast.makeText(context, R.string.network_error, Toast.LENGTH_LONG).show();
} else if (exception instanceof YoutubeStreamExtractor.GemaException) {
Toast.makeText(context, R.string.blocked_by_gema, Toast.LENGTH_LONG).show();
} else if (exception instanceof YoutubeStreamExtractor.LiveStreamException) {
Toast.makeText(context, R.string.live_streams_not_supported, Toast.LENGTH_LONG).show();
} else if (exception instanceof ContentNotAvailableException) {
Toast.makeText(context, R.string.content_not_available, Toast.LENGTH_LONG).show();
} else {
int errorId = exception instanceof YoutubeStreamExtractor.DecryptException ? R.string.youtube_signature_decryption_error :
exception instanceof ParsingException ? R.string.parsing_error : R.string.general_error;
ErrorActivity.reportError(mainHandler, context, exception, MainActivity.class, null, ErrorActivity.ErrorInfo.make(UserAction.REQUESTED_STREAM, NewPipe.getNameOfService(serviceId), url, errorId));
}
});
stopSelf();

View File

@@ -1,9 +1,12 @@
package org.schabi.newpipe.player;
import android.content.Intent;
import android.view.MenuItem;
import org.schabi.newpipe.R;
import static org.schabi.newpipe.player.PopupVideoPlayer.ACTION_CLOSE;
public final class PopupVideoPlayerActivity extends ServicePlayerActivity {
private static final String TAG = "PopupVideoPlayerActivity";
@@ -36,4 +39,25 @@ public final class PopupVideoPlayerActivity extends ServicePlayerActivity {
((PopupVideoPlayer.VideoPlayerImpl) player).removeActivityListener(this);
}
}
@Override
public int getPlayerOptionMenuResource() {
return R.menu.menu_play_queue_popup;
}
@Override
public boolean onPlayerOptionSelected(MenuItem item) {
if (item.getItemId() == R.id.action_switch_background) {
this.player.setRecovery();
getApplicationContext().sendBroadcast(getPlayerShutdownIntent());
getApplicationContext().startService(getSwitchIntent(BackgroundPlayer.class));
return true;
}
return false;
}
@Override
public Intent getPlayerShutdownIntent() {
return new Intent(ACTION_CLOSE);
}
}

View File

@@ -100,6 +100,11 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
public abstract void stopPlayerListener();
public abstract int getPlayerOptionMenuResource();
public abstract boolean onPlayerOptionSelected(MenuItem item);
public abstract Intent getPlayerShutdownIntent();
////////////////////////////////////////////////////////////////////////////
// Activity Lifecycle
////////////////////////////////////////////////////////////////////////////
@@ -134,6 +139,7 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_play_queue, menu);
getMenuInflater().inflate(getPlayerOptionMenuResource(), menu);
return true;
}
@@ -153,8 +159,13 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
case R.id.action_system_audio:
startActivity(new Intent(Settings.ACTION_SOUND_SETTINGS));
return true;
case R.id.action_switch_main:
this.player.setRecovery();
getApplicationContext().sendBroadcast(getPlayerShutdownIntent());
getApplicationContext().startActivity(getSwitchIntent(MainVideoPlayer.class));
return true;
}
return super.onOptionsItemSelected(item);
return onPlayerOptionSelected(item) || super.onOptionsItemSelected(item);
}
@Override
@@ -163,6 +174,17 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
unbind();
}
protected Intent getSwitchIntent(final Class clazz) {
return NavigationHelper.getPlayerIntent(
getApplicationContext(),
clazz,
this.player.getPlayQueue(),
this.player.getRepeatMode(),
this.player.getPlaybackSpeed(),
this.player.getPlaybackPitch(),
null
);
}
////////////////////////////////////////////////////////////////////////////
// Service Connection
////////////////////////////////////////////////////////////////////////////
@@ -288,14 +310,11 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
final float playbackSpeed = BasePlayer.PLAYBACK_SPEEDS[i];
final String formattedSpeed = formatSpeed(playbackSpeed);
final MenuItem item = playbackSpeedPopupMenu.getMenu().add(PLAYBACK_SPEED_POPUP_MENU_GROUP_ID, i, Menu.NONE, formattedSpeed);
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem menuItem) {
if (player == null) return false;
item.setOnMenuItemClickListener(menuItem -> {
if (player == null) return false;
player.setPlaybackSpeed(playbackSpeed);
return true;
}
player.setPlaybackSpeed(playbackSpeed);
return true;
});
}
}
@@ -308,14 +327,11 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
final float playbackPitch = BasePlayer.PLAYBACK_PITCHES[i];
final String formattedPitch = formatPitch(playbackPitch);
final MenuItem item = playbackPitchPopupMenu.getMenu().add(PLAYBACK_PITCH_POPUP_MENU_GROUP_ID, i, Menu.NONE, formattedPitch);
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem menuItem) {
if (player == null) return false;
item.setOnMenuItemClickListener(menuItem -> {
if (player == null) return false;
player.setPlaybackPitch(playbackPitch);
return true;
}
player.setPlaybackPitch(playbackPitch);
return true;
});
}
}
@@ -323,24 +339,18 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
private void buildItemPopupMenu(final PlayQueueItem item, final View view) {
final PopupMenu menu = new PopupMenu(this, view);
final MenuItem remove = menu.getMenu().add(RECYCLER_ITEM_POPUP_MENU_GROUP_ID, 0, Menu.NONE, R.string.play_queue_remove);
remove.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem menuItem) {
if (player == null) return false;
remove.setOnMenuItemClickListener(menuItem -> {
if (player == null) return false;
final int index = player.getPlayQueue().indexOf(item);
if (index != -1) player.getPlayQueue().remove(index);
return true;
}
final int index = player.getPlayQueue().indexOf(item);
if (index != -1) player.getPlayQueue().remove(index);
return true;
});
final MenuItem detail = menu.getMenu().add(RECYCLER_ITEM_POPUP_MENU_GROUP_ID, 1, Menu.NONE, R.string.play_queue_stream_detail);
detail.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem menuItem) {
onOpenDetail(item.getServiceId(), item.getUrl(), item.getTitle());
return true;
}
detail.setOnMenuItemClickListener(menuItem -> {
onOpenDetail(item.getServiceId(), item.getUrl(), item.getTitle());
return true;
});
menu.show();
@@ -529,7 +539,7 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
@Override
public void onMetadataUpdate(StreamInfo info) {
if (info != null) {
metadataTitle.setText(info.name);
metadataTitle.setText(info.getName());
metadataArtist.setText(info.uploader_name);
scrollToSelected();
}

View File

@@ -75,7 +75,13 @@ import static org.schabi.newpipe.util.AnimationUtils.animateView;
* @author mauriciocolli
*/
@SuppressWarnings({"WeakerAccess", "unused"})
public abstract class VideoPlayer extends BasePlayer implements SimpleExoPlayer.VideoListener, SeekBar.OnSeekBarChangeListener, View.OnClickListener, Player.EventListener, PopupMenu.OnMenuItemClickListener, PopupMenu.OnDismissListener {
public abstract class VideoPlayer extends BasePlayer
implements SimpleExoPlayer.VideoListener,
SeekBar.OnSeekBarChangeListener,
View.OnClickListener,
Player.EventListener,
PopupMenu.OnMenuItemClickListener,
PopupMenu.OnDismissListener {
public static final boolean DEBUG = BasePlayer.DEBUG;
public final String TAG;
@@ -282,12 +288,12 @@ public abstract class VideoPlayer extends BasePlayer implements SimpleExoPlayer.
if (index < 0 || index >= videos.size()) return null;
final VideoStream video = videos.get(index);
final MediaSource streamSource = buildMediaSource(video.url, MediaFormat.getSuffixById(video.format));
final MediaSource streamSource = buildMediaSource(video.getUrl(), MediaFormat.getSuffixById(video.format));
final AudioStream audio = ListHelper.getHighestQualityAudio(info.audio_streams);
if (!video.isVideoOnly || audio == null) return streamSource;
// Merge with audio stream in case if video does not contain audio
final MediaSource audioSource = buildMediaSource(audio.url, MediaFormat.getSuffixById(audio.format));
final MediaSource audioSource = buildMediaSource(audio.getUrl(), MediaFormat.getSuffixById(audio.format));
return new MergingMediaSource(streamSource, audioSource);
}

View File

@@ -26,7 +26,7 @@ abstract class AbstractInfoPlayQueue<T extends ListInfo, U extends InfoItem> ext
transient Disposable fetchReactor;
AbstractInfoPlayQueue(final U item) {
this(item.service_id, item.url, null, Collections.<InfoItem>emptyList(), 0);
this(item.getServiceId(), item.getUrl(), null, Collections.<InfoItem>emptyList(), 0);
}
AbstractInfoPlayQueue(final int serviceId,

View File

@@ -30,12 +30,12 @@ public class PlayQueueItem implements Serializable {
private transient Single<StreamInfo> stream;
PlayQueueItem(@NonNull final StreamInfo info) {
this(info.name, info.url, info.service_id, info.duration, info.thumbnail_url, info.uploader_name);
this(info.getName(), info.getUrl(), info.getServiceId(), info.duration, info.thumbnail_url, info.uploader_name);
this.stream = Single.just(info);
}
PlayQueueItem(@NonNull final StreamInfoItem item) {
this(item.name, item.url, item.service_id, item.duration, item.thumbnail_url, item.uploader_name);
this(item.getName(), item.getUrl(), item.getServiceId(), item.duration, item.thumbnail_url, item.uploader_name);
}
private PlayQueueItem(final String name, final String url, final int serviceId,

View File

@@ -382,7 +382,7 @@ public class ErrorActivity extends AppCompatActivity {
private String getContentLangString() {
return PreferenceManager.getDefaultSharedPreferences(this)
.getString(this.getString(R.string.search_language_key), "none");
.getString(this.getString(R.string.content_country_key), "none");
}
private String getOsString() {

View File

@@ -57,104 +57,96 @@ public final class ExtractorHelper {
}
}
public static Single<SearchResult> searchFor(final int serviceId, final String query, final int pageNumber, final String searchLanguage, final SearchEngine.Filter filter) {
public static Single<SearchResult> searchFor(final int serviceId,
final String query,
final int pageNumber,
final String contentCountry,
final SearchEngine.Filter filter) {
checkServiceId(serviceId);
return Single.fromCallable(new Callable<SearchResult>() {
@Override
public SearchResult call() throws Exception {
return SearchResult.getSearchResult(NewPipe.getService(serviceId).getSearchEngine(),
query, pageNumber, searchLanguage, filter);
}
});
return Single.fromCallable(() ->
SearchResult.getSearchResult(NewPipe.getService(serviceId).getSearchEngine(),
query, pageNumber, contentCountry, filter)
);
}
public static Single<NextItemsResult> getMoreSearchItems(final int serviceId, final String query, final int nextPageNumber, final String searchLanguage, final SearchEngine.Filter filter) {
public static Single<NextItemsResult> getMoreSearchItems(final int serviceId,
final String query,
final int nextPageNumber,
final String searchLanguage,
final SearchEngine.Filter filter) {
checkServiceId(serviceId);
return searchFor(serviceId, query, nextPageNumber, searchLanguage, filter)
.map(new Function<SearchResult, NextItemsResult>() {
@Override
public NextItemsResult apply(@NonNull SearchResult searchResult) throws Exception {
return new NextItemsResult(searchResult.resultList, nextPageNumber + "", searchResult.errors);
}
});
.map((@NonNull SearchResult searchResult) ->
new NextItemsResult(searchResult.resultList,
nextPageNumber + "",
searchResult.errors));
}
public static Single<List<String>> suggestionsFor(final int serviceId, final String query, final String searchLanguage) {
public static Single<List<String>> suggestionsFor(final int serviceId,
final String query,
final String contentCountry) {
checkServiceId(serviceId);
return Single.fromCallable(new Callable<List<String>>() {
@Override
public List<String> call() throws Exception {
return NewPipe.getService(serviceId).getSuggestionExtractor().suggestionList(query, searchLanguage);
}
});
return Single.fromCallable(() ->
NewPipe.getService(serviceId)
.getSuggestionExtractor()
.suggestionList(query, contentCountry));
}
public static Single<StreamInfo> getStreamInfo(final int serviceId, final String url, boolean forceLoad) {
public static Single<StreamInfo> getStreamInfo(final int serviceId,
final String url,
boolean forceLoad) {
checkServiceId(serviceId);
return checkCache(forceLoad, serviceId, url, Single.fromCallable(new Callable<StreamInfo>() {
@Override
public StreamInfo call() throws Exception {
return StreamInfo.getInfo(NewPipe.getService(serviceId), url);
}
}));
return checkCache(forceLoad, serviceId, url, Single.fromCallable(() ->
StreamInfo.getInfo(NewPipe.getService(serviceId), url)));
}
public static Single<ChannelInfo> getChannelInfo(final int serviceId, final String url, boolean forceLoad) {
public static Single<ChannelInfo> getChannelInfo(final int serviceId,
final String url,
boolean forceLoad) {
checkServiceId(serviceId);
return checkCache(forceLoad, serviceId, url, Single.fromCallable(new Callable<ChannelInfo>() {
@Override
public ChannelInfo call() throws Exception {
return ChannelInfo.getInfo(NewPipe.getService(serviceId), url);
}
}));
return checkCache(forceLoad, serviceId, url, Single.fromCallable(() ->
ChannelInfo.getInfo(NewPipe.getService(serviceId), url)));
}
public static Single<NextItemsResult> getMoreChannelItems(final int serviceId, final String url, final String nextStreamsUrl) {
public static Single<NextItemsResult> getMoreChannelItems(final int serviceId,
final String url,
final String nextStreamsUrl) {
checkServiceId(serviceId);
return Single.fromCallable(new Callable<NextItemsResult>() {
@Override
public NextItemsResult call() throws Exception {
return ChannelInfo.getMoreItems(NewPipe.getService(serviceId), url, nextStreamsUrl);
}
});
return Single.fromCallable(() ->
ChannelInfo.getMoreItems(NewPipe.getService(serviceId), url, nextStreamsUrl));
}
public static Single<PlaylistInfo> getPlaylistInfo(final int serviceId, final String url, boolean forceLoad) {
public static Single<PlaylistInfo> getPlaylistInfo(final int serviceId,
final String url,
boolean forceLoad) {
checkServiceId(serviceId);
return checkCache(forceLoad, serviceId, url, Single.fromCallable(new Callable<PlaylistInfo>() {
@Override
public PlaylistInfo call() throws Exception {
return PlaylistInfo.getInfo(NewPipe.getService(serviceId), url);
}
}));
return checkCache(forceLoad, serviceId, url, Single.fromCallable(() ->
PlaylistInfo.getInfo(NewPipe.getService(serviceId), url)));
}
public static Single<NextItemsResult> getMorePlaylistItems(final int serviceId, final String url, final String nextStreamsUrl) {
public static Single<NextItemsResult> getMorePlaylistItems(final int serviceId,
final String url,
final String nextStreamsUrl) {
checkServiceId(serviceId);
return Single.fromCallable(new Callable<NextItemsResult>() {
@Override
public NextItemsResult call() throws Exception {
return PlaylistInfo.getMoreItems(NewPipe.getService(serviceId), url, nextStreamsUrl);
}
});
return Single.fromCallable(() ->
PlaylistInfo.getMoreItems(NewPipe.getService(serviceId), url, nextStreamsUrl));
}
public static Single<KioskInfo> getKioskInfo(final int serviceId, final String url, final String contentCountry, boolean forceLoad) {
return checkCache(forceLoad, serviceId, url, Single.fromCallable(new Callable<KioskInfo>() {
@Override
public KioskInfo call() throws Exception {
return KioskInfo.getInfo(NewPipe.getService(serviceId), url, contentCountry);
}
}));
public static Single<KioskInfo> getKioskInfo(final int serviceId,
final String url,
final String contentCountry,
boolean forceLoad) {
return checkCache(forceLoad, serviceId, url, Single.fromCallable(() ->
KioskInfo.getInfo(NewPipe.getService(serviceId), url, contentCountry)));
}
public static Single<NextItemsResult> getMoreKioskItems(final int serviceId, final String url, final String nextStreamsUrl) {
return Single.fromCallable(new Callable<NextItemsResult>() {
@Override
public NextItemsResult call() throws Exception {
return KioskInfo.getMoreItems(NewPipe.getService(serviceId), url, nextStreamsUrl);
}
});
public static Single<NextItemsResult> getMoreKioskItems(final int serviceId,
final String url,
final String nextStreamsUrl,
final String contentCountry) {
return Single.fromCallable(() ->
KioskInfo.getMoreItems(NewPipe.getService(serviceId),
url, nextStreamsUrl, contentCountry));
}
/*//////////////////////////////////////////////////////////////////////////
@@ -162,24 +154,24 @@ public final class ExtractorHelper {
//////////////////////////////////////////////////////////////////////////*/
/**
* Check if we can load it from the cache (forceLoad parameter), if we can't, load from the network (Single loadFromNetwork)
* Check if we can load it from the cache (forceLoad parameter), if we can't,
* load from the network (Single loadFromNetwork)
* and put the results in the cache.
*/
private static <I extends Info> Single<I> checkCache(boolean forceLoad, int serviceId, String url, Single<I> loadFromNetwork) {
private static <I extends Info> Single<I> checkCache(boolean forceLoad,
int serviceId,
String url,
Single<I> loadFromNetwork) {
checkServiceId(serviceId);
loadFromNetwork = loadFromNetwork.doOnSuccess(new Consumer<I>() {
@Override
public void accept(@NonNull I i) throws Exception {
cache.putInfo(i);
}
});
loadFromNetwork = loadFromNetwork.doOnSuccess((@NonNull I i) -> cache.putInfo(i));
Single<I> load;
if (forceLoad) {
cache.removeInfo(serviceId, url);
load = loadFromNetwork;
} else {
load = Maybe.concat(ExtractorHelper.<I>loadFromCache(serviceId, url), loadFromNetwork.toMaybe())
load = Maybe.concat(ExtractorHelper.<I>loadFromCache(serviceId, url),
loadFromNetwork.toMaybe())
.firstElement() //Take the first valid
.toSingle();
}
@@ -192,9 +184,7 @@ public final class ExtractorHelper {
*/
public static <I extends Info> Maybe<I> loadFromCache(final int serviceId, final String url) {
checkServiceId(serviceId);
return Maybe.defer(new Callable<MaybeSource<? extends I>>() {
@Override
public MaybeSource<? extends I> call() throws Exception {
return Maybe.defer(() -> {
//noinspection unchecked
I info = (I) cache.getFromKey(serviceId, url);
if (MainActivity.DEBUG) Log.d(TAG, "loadFromCache() called, info > " + info);
@@ -205,8 +195,7 @@ public final class ExtractorHelper {
}
return Maybe.empty();
}
});
});
}
/**
@@ -214,21 +203,26 @@ public final class ExtractorHelper {
*
* @see Class#isAssignableFrom(Class)
*/
public static boolean hasAssignableCauseThrowable(Throwable throwable, Class<?>... causesToCheck) {
public static boolean hasAssignableCauseThrowable(Throwable throwable,
Class<?>... causesToCheck) {
// Check if getCause is not the same as cause (the getCause is already the root),
// as it will cause a infinite loop if it is
Throwable cause, getCause = throwable;
// Check if throwable is a subclass of any of the filtered classes
final Class throwableClass = throwable.getClass();
for (Class<?> causesEl : causesToCheck) {
if (throwable.getClass().isAssignableFrom(causesEl)) {
if (causesEl.isAssignableFrom(throwableClass)) {
return true;
}
}
// Iteratively checks if the root cause of the throwable is a subclass of the filtered class
while ((cause = throwable.getCause()) != null && getCause != cause) {
getCause = cause;
final Class causeClass = cause.getClass();
for (Class<?> causesEl : causesToCheck) {
if (cause.getClass().isAssignableFrom(causesEl)) {
if (causesEl.isAssignableFrom(causeClass)) {
return true;
}
}
@@ -265,6 +259,21 @@ public final class ExtractorHelper {
* Check if throwable have Interrupted* exception as one of its causes.
*/
public static boolean isInterruptedCaused(Throwable throwable) {
return ExtractorHelper.hasExactCauseThrowable(throwable, InterruptedIOException.class, InterruptedException.class);
return ExtractorHelper.hasExactCauseThrowable(throwable,
InterruptedIOException.class,
InterruptedException.class);
}
public static String toUpperCase(String value) {
StringBuilder sb = new StringBuilder(value);
for (int index = 0; index < sb.length(); index++) {
char c = sb.charAt(index);
if (Character.isLowerCase(c)) {
sb.setCharAt(index, Character.toUpperCase(c));
} else {
sb.setCharAt(index, Character.toLowerCase(c));
}
}
return sb.toString();
}
}

View File

@@ -1,4 +1,4 @@
/*
/**
* Copyright 2017 Mauricio Colli <mauriciocolli@outlook.com>
* InfoCache.java is part of NewPipe
*
@@ -103,7 +103,7 @@ public final class InfoCache {
}
private static String keyOf(@NonNull final Info info) {
return keyOf(info.service_id, info.url);
return keyOf(info.getServiceId(), info.getUrl());
}
private static String keyOf(final int serviceId, @NonNull final String url) {

View File

@@ -95,7 +95,7 @@ public final class ListHelper {
int highestQualityIndex = 0;
if (audioStreams.size() > 1) for (int i = 1; i < audioStreams.size(); i++) {
AudioStream audioStream = audioStreams.get(i);
if (audioStream.average_bitrate >= audioStreams.get(highestQualityIndex).average_bitrate) highestQualityIndex = i;
if (audioStream.getAverageBitrate() >= audioStreams.get(highestQualityIndex).getAverageBitrate()) highestQualityIndex = i;
}
return highestQualityIndex;
}
@@ -124,10 +124,10 @@ public final class ListHelper {
int highestQualityIndex = -1;
for (int i = 0; i < audioStreams.size(); i++) {
AudioStream audioStream = audioStreams.get(i);
if (highestQualityIndex == -1 && audioStream.format == defaultFormat.id) highestQualityIndex = i;
if (highestQualityIndex == -1 && audioStream.getFormat() == defaultFormat) highestQualityIndex = i;
if (highestQualityIndex != -1 && audioStream.format == defaultFormat.id
&& audioStream.average_bitrate > audioStreams.get(highestQualityIndex).average_bitrate) {
if (highestQualityIndex != -1 && audioStream.getFormat() == defaultFormat
&& audioStream.getAverageBitrate() > audioStreams.get(highestQualityIndex).getAverageBitrate()) {
highestQualityIndex = i;
}
}
@@ -171,23 +171,23 @@ public final class ListHelper {
if (videoOnlyStreams != null) {
for (VideoStream stream : videoOnlyStreams) {
if (!showHigherResolutions && HIGH_RESOLUTION_LIST.contains(stream.resolution)) continue;
if (!showHigherResolutions && HIGH_RESOLUTION_LIST.contains(stream.getResolution())) continue;
retList.add(stream);
}
}
if (videoStreams != null) {
for (VideoStream stream : videoStreams) {
if (!showHigherResolutions && HIGH_RESOLUTION_LIST.contains(stream.resolution)) continue;
if (!showHigherResolutions && HIGH_RESOLUTION_LIST.contains(stream.getResolution())) continue;
retList.add(stream);
}
}
// Add all to the hashmap
for (VideoStream videoStream : retList) hashMap.put(videoStream.resolution, videoStream);
for (VideoStream videoStream : retList) hashMap.put(videoStream.getResolution(), videoStream);
// Override the values when the key == resolution, with the defaultFormat
for (VideoStream videoStream : retList) {
if (videoStream.format == defaultFormat.id) hashMap.put(videoStream.resolution, videoStream);
if (videoStream.getFormat() == defaultFormat) hashMap.put(videoStream.getResolution(), videoStream);
}
retList.clear();
@@ -219,8 +219,8 @@ public final class ListHelper {
Collections.sort(videoStreams, new Comparator<VideoStream>() {
@Override
public int compare(VideoStream o1, VideoStream o2) {
int res1 = Integer.parseInt(o1.resolution.replace("0p60", "1").replaceAll("[^\\d.]", ""));
int res2 = Integer.parseInt(o2.resolution.replace("0p60", "1").replaceAll("[^\\d.]", ""));
int res1 = Integer.parseInt(o1.getResolution().replace("0p60", "1").replaceAll("[^\\d.]", ""));
int res2 = Integer.parseInt(o2.getResolution().replace("0p60", "1").replaceAll("[^\\d.]", ""));
return ascendingOrder ? res1 - res2 : res2 - res1;
}
@@ -235,9 +235,9 @@ public final class ListHelper {
int defaultStreamIndex = -1;
for (int i = 0; i < videoStreams.size(); i++) {
VideoStream stream = videoStreams.get(i);
if (defaultStreamIndex == -1 && stream.resolution.equals(defaultResolution)) defaultStreamIndex = i;
if (defaultStreamIndex == -1 && stream.getResolution().equals(defaultResolution)) defaultStreamIndex = i;
if (stream.format == defaultFormat.id && stream.resolution.equals(defaultResolution)) {
if (stream.getFormat() == defaultFormat && stream.getResolution().equals(defaultResolution)) {
return i;
}
}

View File

@@ -87,9 +87,13 @@ public class NavigationHelper {
context.startActivity(getPlayerIntent(context, MainVideoPlayer.class, queue));
}
public static void playOnPopupPlayer(final Context context, final PlayQueue queue) {
Toast.makeText(context, R.string.popup_playing_toast, Toast.LENGTH_SHORT).show();
context.startService(getPlayerIntent(context, PopupVideoPlayer.class, queue));
public static void playOnPopupPlayer(final Activity activity, final PlayQueue queue) {
if (!PermissionHelper.isPopupEnabled(activity)) {
PermissionHelper.showPopupEnablementToast(activity);
return;
}
Toast.makeText(activity, R.string.popup_playing_toast, Toast.LENGTH_SHORT).show();
activity.startService(getPlayerIntent(activity, PopupVideoPlayer.class, queue));
}
public static void playOnBackgroundPlayer(final Context context, final PlayQueue queue) {
@@ -97,9 +101,13 @@ public class NavigationHelper {
context.startService(getPlayerIntent(context, BackgroundPlayer.class, queue));
}
public static void enqueueOnPopupPlayer(final Context context, final PlayQueue queue) {
Toast.makeText(context, R.string.popup_playing_append, Toast.LENGTH_SHORT).show();
context.startService(getPlayerEnqueueIntent(context, PopupVideoPlayer.class, queue));
public static void enqueueOnPopupPlayer(final Activity activity, final PlayQueue queue) {
if (!PermissionHelper.isPopupEnabled(activity)) {
PermissionHelper.showPopupEnablementToast(activity);
return;
}
Toast.makeText(activity, R.string.popup_playing_append, Toast.LENGTH_SHORT).show();
activity.startService(getPlayerEnqueueIntent(activity, PopupVideoPlayer.class, queue));
}
public static void enqueueOnBackgroundPlayer(final Context context, final PlayQueue queue) {
@@ -259,23 +267,22 @@ public class NavigationHelper {
return true;
}
public static void openBackgroundPlayerControl(final Context context) {
openServicePlayerControl(context, BackgroundPlayerActivity.class);
public static Intent getBackgroundPlayerActivityIntent(final Context context) {
return getServicePlayerActivityIntent(context, BackgroundPlayerActivity.class);
}
public static void openPopupPlayerControl(final Context context) {
openServicePlayerControl(context, PopupVideoPlayerActivity.class);
public static Intent getPopupPlayerActivityIntent(final Context context) {
return getServicePlayerActivityIntent(context, PopupVideoPlayerActivity.class);
}
private static void openServicePlayerControl(final Context context, final Class clazz) {
final Intent intent = new Intent(context, clazz);
private static Intent getServicePlayerActivityIntent(final Context context,
final Class activityClass) {
Intent intent = new Intent(context, activityClass);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
context.startActivity(intent);
context.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
return intent;
}
/*//////////////////////////////////////////////////////////////////////////
// Link handling
//////////////////////////////////////////////////////////////////////////*/

View File

@@ -11,6 +11,11 @@ import android.provider.Settings;
import android.support.annotation.RequiresApi;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.view.Gravity;
import android.widget.TextView;
import android.widget.Toast;
import org.schabi.newpipe.R;
public class PermissionHelper {
public static final int PERMISSION_WRITE_STORAGE = 778;
@@ -92,4 +97,16 @@ public class PermissionHelper {
return false;
}else return true;
}
public static boolean isPopupEnabled(Activity activity) {
return Build.VERSION.SDK_INT < Build.VERSION_CODES.M ||
PermissionHelper.checkSystemAlertWindowPermission(activity);
}
public static void showPopupEnablementToast(Context context) {
Toast toast = Toast.makeText(context, R.string.msg_popup_permission, Toast.LENGTH_LONG);
TextView messageView = toast.getView().findViewById(android.R.id.message);
if (messageView != null) messageView.setGravity(Gravity.CENTER);
toast.show();
}
}

View File

@@ -0,0 +1,48 @@
package org.schabi.newpipe.util;
import android.widget.PopupMenu;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* Created by Christian Schabesberger on 20.01.18.
* Copyright 2018 Christian Schabesberger <chris.schabesberger@mailbox.org>
* PopupMenuIconHacker.java is part of NewPipe
*
* License: GPL-3.0+
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
public class PopupMenuIconHacker {
public static void setShowPopupIcon(PopupMenu menu) throws Exception {
try {
Field[] fields = menu.getClass().getDeclaredFields();
for (Field field : fields) {
if ("mPopup".equals(field.getName())) {
field.setAccessible(true);
Object menuPopupHelper = field.get(menu);
Class<?> classPopupHelper = Class.forName(menuPopupHelper
.getClass().getName());
Method setForceIcons = classPopupHelper.getMethod(
"setForceShowIcon", boolean.class);
setForceIcons.invoke(menuPopupHelper, true);
break;
}
}
} catch (Exception e) {
throw new Exception("Could not make Popup menu show Icons", e);
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 570 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 478 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 328 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 628 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 645 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 916 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -1,18 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<merge
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="org.schabi.newpipe.MainActivity">
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/fragment_holder"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize"/>
android:orientation="vertical"
tools:context="org.schabi.newpipe.MainActivity">
<FrameLayout
android:id="@+id/fragment_holder"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize" />
<include layout="@layout/toolbar_layout"/>
<include layout="@layout/toolbar_layout" />
</FrameLayout>
</merge>
<android.support.design.widget.NavigationView
android:id="@+id/navigation"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:menu="@menu/drawer_items" />
</android.support.v4.widget.DrawerLayout>

View File

@@ -244,7 +244,7 @@
android:clickable="true"
android:focusable="true"
android:scaleType="fitXY"
android:src="?attr/options"
android:src="@drawable/ic_more_vert_white_24dp"
tools:ignore="ContentDescription,RtlHardcoded"/>
</RelativeLayout>

View File

@@ -31,10 +31,14 @@
android:layout_below="@+id/itemTitleView"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:ellipsize="marquee"
android:fadingEdge="horizontal"
android:marqueeRepeatLimit="marquee_forever"
android:scrollHorizontally="true"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textSize="@dimen/video_item_search_uploader_text_size"
android:visibility="gone"
tools:visibility="visible"
tools:text="TYPE" />
tools:text="UPLOADER" />
</RelativeLayout>

View File

@@ -273,7 +273,7 @@
android:paddingBottom="6dp"
android:paddingTop="6dp"
android:text="@string/controls_background_title"
android:textSize="12sp"/>
android:textSize="12sp" />
</RelativeLayout>
<!--UPLOADER-->

View File

@@ -11,8 +11,6 @@
android:layout_width="match_parent"
android:layout_height="64dp"
android:background="@color/background_notification_color"
android:clickable="true"
android:focusable="true"
android:gravity="center_vertical"
android:orientation="horizontal">

View File

@@ -6,8 +6,6 @@
android:layout_width="match_parent"
android:layout_height="128dp"
android:background="@color/background_notification_color"
android:clickable="true"
android:focusable="true"
android:gravity="center_vertical"
android:orientation="horizontal">

View File

@@ -92,6 +92,7 @@
android:layout_alignParentRight="true"
android:background="#00ffffff"
android:clickable="true"
android:focusable="true"
android:scaleType="fitCenter"
android:src="@drawable/ic_fullscreen_white"
tools:ignore="ContentDescription,RtlHardcoded"/>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:title="@string/youtube" />
<item android:title="@string/soundcloud" />
</menu>

View File

@@ -17,4 +17,9 @@
android:orderInCategory="996"
android:title="@string/play_queue_audio_settings"
app:showAsAction="never"/>
<item android:id="@+id/action_switch_main"
android:orderInCategory="999"
android:title="@string/switch_to_main"
app:showAsAction="never"/>
</menu>

View File

@@ -0,0 +1,10 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="org.schabi.newpipe.history.HistoryActivity">
<item android:id="@+id/action_switch_popup"
android:orderInCategory="1999"
android:title="@string/switch_to_popup"
app:showAsAction="never"/>
</menu>

View File

@@ -0,0 +1,10 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="org.schabi.newpipe.history.HistoryActivity">
<item android:id="@+id/action_switch_background"
android:orderInCategory="1999"
android:title="@string/switch_to_background"
app:showAsAction="never"/>
</menu>

View File

@@ -4,18 +4,19 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:icon="@drawable/ic_screen_rotation_white"
android:id="@+id/toggleOrientation"
android:title="Toggle orientation"
android:icon="@drawable/ic_screen_rotation_white"
android:title="@string/toggle_orientation"
app:showAsAction="always|withText" />
<item
android:icon="@drawable/ic_fullscreen_exit_white"
android:id="@+id/switchPopup"
android:title="Switch to popup"
android:icon="@drawable/ic_fullscreen_exit_white"
android:title="@string/switch_to_popup"
app:showAsAction="always|withText" />
<item android:icon="?audio"
<item
android:id="@+id/switchBackground"
android:title="Switch to background"
android:icon="?audio"
android:title="@string/switch_to_background"
app:showAsAction="always|withText" />
</menu>

View File

@@ -9,8 +9,8 @@
<string name="detail_dislikes_img_view_description">عدم الإعجاب</string>
<string name="detail_likes_img_view_description">الإعجابات</string>
<string name="detail_thumbnail_view_description">صور معاينة الفيديو</string>
<string name="detail_uploader_thumbnail_view_description">"Uploader's userpic thumbnail"</string>
<string name="did_you_mean">هل تقصد : %1$s ؟</string>
<string name="detail_uploader_thumbnail_view_description">الصورة المصغرة الشخصية</string>
<string name="did_you_mean">هل تقصد : %1$s ?</string>
<string name="download">تنزيل</string>
<string name="download_dialog_title">تنزيل</string>
<string name="download_path_audio_dialog_title">أدخل مسار لتنزيل الملفات الصوتية.</string>
@@ -22,46 +22,46 @@
<string name="err_dir_create">"لا يمكن إنشاء مجلد للتنزيلات في '%1$s'"</string>
<string name="info_dir_created">"تم إنشاء مجلد تنزيلات في '%1$s'"</string>
<string name="install">تثبيت</string>
<string name="kore_not_found">تطبيق Kore غير موجود. هل تريد تثبيته؟</string>
<string name="kore_not_found">تطبيق Kore غير موجود. هل تريد تثبيته ؟</string>
<string name="light_theme_title">مضيء</string>
<string name="list_thumbnail_view_description">صور معاينة الفيديو</string>
<string name="m4a_description">m4a — جودة أفضل</string>
<string name="m4a_description">M4A — جودة أفضل</string>
<string name="network_error">خطأ في الشبكة</string>
<string name="next_video_title">الفيديو التالي</string>
<string name="no_player_found">لا يوجد مشغل فيديو. هل تريد تثبيت VLC ؟</string>
<string name="open_in_browser">فتح في المتصفح</string>
<string name="play_audio">صوت</string>
<string name="open_in_browser">إفتح في متصفح</string>
<string name="play_audio">الصوت</string>
<string name="play_btn_text">تشغيل</string>
<string name="play_with_kodi_title">تشغيل بواسطة Kodi</string>
<string name="screen_rotation">تدوير</string>
<string name="screen_rotation">التدوير</string>
<string name="search">بحث</string>
<string name="search_language_title">لغة المحتوى المفضل</string>
<string name="search_language_title">اللغة الإفتراضية للمحتوى</string>
<string name="settings">الإعدادات</string>
<string name="settings_category_appearance_title">المظهر</string>
<string name="settings_category_other_title">تعريب JetSub مدونة درويديات</string>
<string name="settings_category_other_title">أخرئ</string>
<string name="settings_category_video_audio_title">الفيديو والصوتيات</string>
<string name="share">مشاركة</string>
<string name="share_dialog_title">مشاركة بواسطة</string>
<string name="show_next_and_similar_title">عرض التالي والفيديوهات المشابهة</string>
<string name="show_play_with_kodi_summary">عرض خيار لتشغيل الفيديو بواسطة Kodi Media Center.</string>
<string name="show_play_with_kodi_title">عرض خيار التشغيل بواسطة Kodi.</string>
<string name="show_play_with_kodi_summary">عرض خيار لتشغيل الفيديو بواسطة Kodi Media Center</string>
<string name="show_play_with_kodi_title">عرض خيار التشغيل بواسطة Kodi</string>
<string name="theme_title">السمة</string>
<string name="upload_date_text">تم نشرها في %1$s</string>
<string name="upload_date_text">نُشِرت في %1$s</string>
<string name="url_not_supported_toast">الرابط غير مدعوم</string>
<string name="use_external_audio_player_title">استخدام مشغل صوتيات خارجي</string>
<string name="use_external_audio_player_title">استخدام مشغل صوت خارجي</string>
<string name="use_external_video_player_title">استخدام مشغل فيديو خارجي</string>
<string name="use_tor_summary">إجراء التنزيلات من خلال استخدام بروكسي Tor لزيادة الخصوصية ( تشغيل الفيديو المباشر غير مدعوم حتى الأن )</string>
<string name="use_tor_summary">(إختبارية) إجراء التنزيلات من خلال استخدام بروكسي Tor لزيادة الخصوصية ( تشغيل الفيديو المباشر غير مدعوم حتى الأن ).</string>
<string name="use_tor_title">استخدام Tor</string>
<string name="view_count_text">%1$s المشاهدات</string>
<string name="webm_description">WebM</string>
<string name="blocked_by_gema">Blocked by GEMA.</string>
<string name="content_not_available">المحتوى غير متاح.</string>
<string name="view_count_text">%1$s مشاهدات</string>
<string name="webm_description">WebM—صيغة حرة</string>
<string name="blocked_by_gema">تم حجبه بواسطة GEMA</string>
<string name="content_not_available">المحتوى غير متاح</string>
<string name="could_not_load_thumbnails">لم يتمكن من تحميل كل صور المعاينة</string>
<string name="general_error">خطأ</string>
<string name="parsing_error">لا يمكن تحليل الموقع.</string>
<string name="youtube_signature_decryption_error">لا يمكن فك تشفير توقيع رابط الفيديو.</string>
<string name="main_bg_subtitle">إضغط على البحث للمواصلة</string>
<string name="subscribe_button_title">إشترك</string>
<string name="parsing_error">تعذرت عملية تحليل الموقع</string>
<string name="youtube_signature_decryption_error">تعذر فك تشفير توقيع رابط الفيديو</string>
<string name="main_bg_subtitle">انقر على البحث للبدء</string>
<string name="subscribe_button_title">إشتراك</string>
<string name="subscribed_button_title">مشترك</string>
<string name="tab_main">الرئيسية</string>
<string name="tab_subscriptions">الإشتراكات</string>
@@ -71,8 +71,8 @@
<string name="controls_background_title">الخلفية</string>
<string name="autoplay_by_calling_app_title">التشغيل التلقائي</string>
<string name="black_theme_title">أسود</string>
<string name="enable_watch_history_title">التأريخ</string>
<string name="settings_category_history_title">التأريخ</string>
<string name="enable_watch_history_title">التاريخ</string>
<string name="settings_category_history_title">التاريخ</string>
<string name="content">المحتوى</string>
<string name="downloads">التنزيلات</string>
<string name="downloads_title">التنزيلات</string>
@@ -84,29 +84,212 @@
<string name="tab_about">عن التطبيق</string>
<string name="title_activity_history">التأريخ</string>
<string name="action_history">التأريخ</string>
<string name="open_in_popup_mode">فتح في نوافذ</string>
<string name="use_external_video_player_summary">بعض خيارات الجودة لن يكون الصوت عند تمكين هذا الخيار</string>
<string name="popup_mode_share_menu_title">NewPipe وضع النافذة</string>
<string name="open_in_popup_mode">إفتح في نافذة منبثقه</string>
<string name="use_external_video_player_summary">عند تمكين هذا الخيار لن يكون هنالك صوت في بعض خيارات الجودة</string>
<string name="popup_mode_share_menu_title">وضع النافذة NewPipe المنبثقة</string>
<string name="channel_unsubscribed">تم إلغاء اشتراك القناة</string>
<string name="subscription_change_failed">تعذر تغيير في الاشتراك</string>
<string name="subscription_update_failed">تعذر تحديث الاشتراك</string>
<string name="controls_popup_title">نافذة</string>
<string name="autoplay_by_calling_app_summary">تشغيل الفيديو تلقائيا عند استدعاء نيوبيب من تطبيق آخر</string>
<string name="default_popup_resolution_title">جودة النوافذ الافتراضية</string>
<string name="autoplay_by_calling_app_summary">تشغيل الفيديو تلقائيا عند استدعاء NewPipe من تطبيق آخر</string>
<string name="default_popup_resolution_title">الجودة الافتراضية للنوافذ المنبثقة</string>
<string name="show_higher_resolutions_title">إظهار جودة أعلى</string>
<string name="show_higher_resolutions_summary">فقط بعض الأجهزة تدعم تشغيل فيديوهات 2K / 4K</string>
<string name="default_video_format_title">تنسيق الفيديو الافتراضي</string>
<string name="popup_remember_size_pos_title">تذكر حجم النافذة و وضعها</string>
<string name="popup_remember_size_pos_summary">تذكر آخر حجم ومكان النافذة</string>
<string name="player_gesture_controls_title">ضوابط إشارة المشغل</string>
<string name="player_gesture_controls_summary">استخدم الإشارات للتحكم في سطوع وحجم المشغل</string>
<string name="player_gesture_controls_title">اعدادات إيماءة المشغل</string>
<string name="player_gesture_controls_summary">استخدم إيماءات للتحكم في سطوع وحجم المشغل</string>
<string name="show_search_suggestions_title">اقتراحات البحث</string>
<string name="show_search_suggestions_summary">عرض الاقتراحات عند البحث</string>
<string name="enable_search_history_title">سجل البحث</string>
<string name="enable_search_history_summary">تخزين طلبات البحث محليا</string>
<string name="enable_watch_history_summary">تتبع مقاطع الفيديو التي تمت مشاهدتها</string>
<string name="resume_on_audio_focus_gain_title">استئناف عند اكساب التركيز</string>
<string name="resume_on_audio_focus_gain_summary">متابعة اللعب بعد المقاطعات (مثل المكالمات الهاتفية)</string>
</resources>
<string name="resume_on_audio_focus_gain_summary">متابعة التشغيل بعد المقاطعات (مثل المكالمات الهاتفية)</string>
<string name="show_hold_to_append_title">إظهار تعليق لإلحاق تلميح</string>
<string name="show_hold_to_append_summary">عرض تلميح أو زر منبثق عند الضغط على خلفية على صفحة تفاصيل الفيديو</string>
<string name="settings_category_player_title">المشغل</string>
<string name="settings_category_player_behavior_title">السلوك</string>
<string name="settings_category_popup_title">المنبثق</string>
<string name="popup_playing_toast">التشغيل في الوضع المنبثق</string>
<string name="background_player_append">تم وضعه على قائمة الانتظار في مشغل الخلفية</string>
<string name="popup_playing_append">تم وضعه على قائمة الانتظار في مشغل النافذة المنبثقة</string>
<string name="show_age_restricted_content_title">عرض المحتوى المقيد بحسب العمر</string>
<string name="video_is_age_restricted">فيديو مقيد بحسب العمر. السماح بهذه المحتوى ممكن من الإعدادات.</string>
<string name="duration_live">مباشر</string>
<string name="error_report_title">تقرير الخطأ</string>
<string name="playlist">قائمة التشغيل</string>
<string name="yes">نعم</string>
<string name="later">فيما بعد</string>
<string name="disabled">معطل</string>
<string name="filter">فلتر</string>
<string name="refresh">تحديث</string>
<string name="clear">تنظيف</string>
<string name="popup_resizing_indicator_title">تغيير الحجم</string>
<string name="best_resolution">أفضل دقة</string>
<string name="undo">تراجع</string>
<string name="play_all">تشغيل الكل</string>
<string name="notification_channel_name">تنبيهات NewPipe</string>
<string name="notification_channel_description">التنبيهات لمشغل NewPipe للخلفية والنوافذ المنبثقة</string>
<string name="unknown_content">[غير معروف]</string>
<string name="light_parsing_error">لايمكن تحليل الموقع بشكل كلي</string>
<string name="could_not_setup_download_menu">يتعذر إعداد قائمة التنزيل</string>
<string name="live_streams_not_supported">هذا هو بث مباشر ، وهو غير معتمد حتى الآن.</string>
<string name="could_not_get_stream">يتعذر الحصول على أي بث</string>
<string name="could_not_load_image">تعذر تحميل الصورة</string>
<string name="app_ui_crash">تعطل التطبيق / واجهة المستخدم</string>
<string name="player_stream_failure">أخفق تشغيل هذا البث</string>
<string name="player_unrecoverable_failure">حدث خطأ المشغل غير قابل للاسترداد</string>
<string name="player_recoverable_failure">استرداد المشغل من الخطأ</string>
<string name="sorry_string">عذرا، لا ينبغي أن يحدث ذلك.</string>
<string name="error_report_button_text">الإبلاغ عن خطأ عبر البريد الإلكتروني</string>
<string name="error_snackbar_message">عذرا، حدثت بعض الأخطاء.</string>
<string name="error_snackbar_action">تقرير</string>
<string name="what_device_headline">معلومات:</string>
<string name="what_happened_headline">ماذا حدث:</string>
<string name="info_labels">What:\\nRequest:\\nContent Lang:\\nService:\\nGMT Time:\\nPackage:\\nVersion:\\nOS version:\\nGlob. IP range:</string>
<string name="your_comment">تعليقك (باللغة الإنجليزية):</string>
<string name="error_details_headline">تفاصيل:</string>
<string name="report_error">الإبلاغ عن خطأ</string>
<string name="user_report">تقرير المستخدم</string>
<string name="search_no_results">لم يتم العثور على نتائج</string>
<string name="empty_subscription_feed_subtitle">لا شيء هنا غير صراصير الليل</string>
<string name="audio">الصوت</string>
<string name="retry">إعادة المحاولة</string>
<string name="storage_permission_denied">تم رفض إذن الوصول إلى التخزين</string>
<string name="use_old_player_title">استخدام المشغل القديم</string>
<string name="use_old_player_summary">المشغل القديم المدمج في إطار Mediaframework</string>
<string name="short_thousand">ك</string>
<string name="short_million">م</string>
<string name="short_billion">ب</string>
<string name="no_subscribers">صفر لا تقم با الإختيار (في بعض اللغات) لأنها ليست \"حالة خاصة\" للأندرويد</string>
<plurals name="subscribers">
<item quantity="zero">صفر</item>
<item quantity="one">واحد</item>
<item quantity="two">اثنان</item>
<item quantity="few">قليل</item>
<item quantity="many">كثير</item>
<item quantity="other">أخرى</item>
</plurals>
<string name="no_views">لاتوجد مشاهدات</string>
<string name="no_videos">لاتوجد فديوهات</string>
<string name="start">بداية</string>
<string name="pause">إيقاف</string>
<string name="view">شغل</string>
<string name="delete">حذف</string>
<string name="checksum">التوقيع</string>
<string name="add">قطعة</string>
<string name="finish">حسنا</string>
<string name="msg_name">اسم الملف</string>
<string name="msg_threads">العمليات</string>
<string name="msg_error">الخطأ</string>
<string name="msg_server_unsupported">الخادم غير معتمد</string>
<string name="msg_exists">الملف موجود مسبقا</string>
<string name="msg_url_malform">العنوان غير صحيح أو ان الإنترنت غير متوفر</string>
<string name="msg_running">NewPipe يقوم بالتحميل</string>
<string name="msg_running_detail">انقر للحصول على التفاصيل</string>
<string name="msg_wait">أرجو الإنتظار…</string>
<string name="msg_copied">نسخ إلى الحافظة</string>
<string name="no_available_dir">الرجاء تحديد مجلد لحفظ التنزيلات</string>
<string name="msg_popup_permission">هذا الإذن مطلوب
\nللفتح في وضع النافذة المنبثقة</string>
<string name="reCaptchaActivity">اختبار reCAPTCHA</string>
<string name="settings_file_charset_title">الأحرف المسموح بها في أسماء الملفات</string>
<string name="settings_file_replacement_character_summary">يتم استبدال الأحرف غير الصالحة بهذه القيمة</string>
<string name="settings_file_replacement_character_title">استبدال الحرف</string>
<string name="charset_letters_and_digits">الحروف والأرقام</string>
<string name="charset_most_special_characters">معظم الأحرف الخاصة</string>
<string name="title_activity_about">معلومات عن NewPipe</string>
<string name="action_settings">الإعدادات</string>
<string name="title_licenses">تراخيص الجهات الخارجية</string>
<string name="error_unable_to_load_license">تعذر تحميل الترخيص</string>
<string name="action_open_website">فتح الموقع</string>
<string name="tab_contributors">المساهمون</string>
<string name="tab_licenses">التراخيص</string>
<string name="app_description">واجهة أمامية لليوتوب مجانية مفتوحة المصدر و خفيفة الوزن لنظام التشغيل أندرويد.</string>
<string name="contribution_title">ساهم</string>
<string name="contribution_encouragement">إذا كان لديك أفكار؛ او ترجمة، او تغييرات على التصميم، او تنظيف وتحسين الكود البرمجي ، أو تغييرات ثقيلة على الكود البرمجي، مساعدتك دائما موضع ترحيب. وكلما تم ذلك كلما كان ذلك أفضل!</string>
<string name="view_on_github">عرض على GitHub</string>
<string name="donation_title">تبرع</string>
<string name="donation_encouragement">يتم تطوير NewPipe من قبل المتطوعين الذين يقضون وقت فراغهم لتقديم أفضل تجربة لك. الآن حان الوقت لإعطاء مرة أخرى للتأكد من المطورين لدينا يمكن أن تجعل NewPipe أكثر و أفضل بينما نتمتع بكوب من جافا!</string>
<string name="give_back">تبرع</string>
<string name="website_title">الموقع</string>
<string name="website_encouragement">للحصول على مزيد من المعلومات وآخر الأخبار حول NewPipe الرجاء زيارة موقعنا على الانترنت.</string>
<string name="app_license_title">تراخيص NewPipe</string>
<string name="read_full_license">قراءة الترخيص</string>
<string name="title_history_search">البحث</string>
<string name="title_history_view">شاهد</string>
<string name="history_disabled">تم تعطيل السجل</string>
<string name="history_empty">التاريخ فارغ</string>
<string name="history_cleared">تم تنظيف التاريخ</string>
<string name="item_deleted">تم حذف العنصر</string>
<string name="delete_item_search_history">هل تريد حذف هذا العنصر من سجل البحث؟</string>
<string name="main_page_content">المحتوى</string>
<string name="blank_page_summary">صفحة فارغة</string>
<string name="subscription_page_summary">صفحة الاشتراك</string>
<string name="feed_page_summary">صفحة الخلاصة</string>
<string name="channel_page_summary">صفحة القناة</string>
<string name="select_a_channel">حدد قناة</string>
<string name="no_channel_subscribed_yet">لم يتم الاشتراك في القناة بعد</string>
<string name="trending">الترند</string>
<string name="top_50">أفضل 50</string>
<string name="new_and_hot">جديد &amp; وساخن</string>
<string name="title_activity_background_player">مشغل الخلفية</string>
<string name="title_activity_popup_player">المشغل المنبثق</string>
<string name="play_queue_remove">حذف</string>
<string name="play_queue_stream_detail">تفاصيل</string>
<string name="play_queue_audio_settings">إعدادات الصوت</string>
<string name="start_here_on_main">بدء التشغيل هنا</string>
<string name="start_here_on_popup">تشغيل هنا في وضع النافذة المنبثقة</string>
<string name="reCaptcha_title">تحدي ريكابتشا</string>
<string name="hold_to_append">اضغط للإدراج بقائمة الانتظار</string>
<plurals name="views">
<item quantity="zero">صفر</item>
<item quantity="one">واحد</item>
<item quantity="two">اثنان</item>
<item quantity="few">قليل</item>
<item quantity="many">كثير</item>
<item quantity="other">أخرى</item>
</plurals>
<plurals name="videos">
<item quantity="zero">صفر</item>
<item quantity="one">واحد</item>
<item quantity="two">اثنان</item>
<item quantity="few">قليل</item>
<item quantity="many">كثير</item>
<item quantity="other">أخرى</item>
</plurals>
<string name="recaptcha_request_toast">إعادة طلب كلمة التحقق</string>
<string name="copyright" formatted="true">© %1$sبواسطة%2$sتحت%3$s</string>
<string name="kiosk_page_summary">صفحة الكشك</string>
<string name="select_a_kiosk">حدد كشك</string>
<string name="kiosk">كشك</string>
<string name="enqueue_on_background">إدراج بقائمة الانتظار على خلفية</string>
<string name="enqueue_on_popup">إدراج بقائمة الانتظار على المنبثقة</string>
<string name="start_here_on_background">ابدأ هنا على خلفية المصدر</string>
</resources>

View File

@@ -39,7 +39,7 @@
<string name="light_theme_title">Světlé</string>
<string name="download_dialog_title">Stáhnout</string>
<string name="next_video_title">Další video</string>
<string name="next_video_title">Další videa</string>
<string name="show_next_and_similar_title">Zobrazovat další a podobná videa</string>
<string name="url_not_supported_toast">URL není podporováno</string>
<string name="search_language_title">Preferovaný jazyk obsahu</string>
@@ -204,8 +204,7 @@ otevření ve vyskakovacím okně</string>
<plurals name="subscribers">
<item quantity="one">%s odběratel</item>
<item quantity="few">%s odběratelé</item>
<item quantity="many">%s odběratelů</item>
<item quantity="other"/>
<item quantity="other">%s odběratelů</item>
</plurals>
<string name="no_views">Žádná zhlédnutí</string>
@@ -219,8 +218,7 @@ otevření ve vyskakovacím okně</string>
<plurals name="videos">
<item quantity="one">%s video</item>
<item quantity="few">%s videa</item>
<item quantity="many">%s videí</item>
<item quantity="other"/>
<item quantity="other">%s videí</item>
</plurals>
<string name="settings_category_downloads_title">Stahování</string>
@@ -254,10 +252,10 @@ otevření ve vyskakovacím okně</string>
<string name="history_disabled">Historie je vypnutá</string>
<string name="action_history">Historie</string>
<string name="history_empty">Historie je prázdná</string>
<string name="history_cleared">Historie smazána</string>
<string name="history_cleared">Historie vymazána</string>
<string name="item_deleted">Položka byla odstraněna</string>
<string name="show_hold_to_append_title">Zobrazovat tip \"Podrž pro přidání\"</string>
<string name="show_hold_to_append_summary">Zobrazí se po stisku tlačítka přehrát na pozadí nebo přehrát v okně na stránce videa</string>
<string name="show_hold_to_append_summary">Zobrazí se po stisku tlačítek přehrát na pozadí nebo přehrát v okně na stránce s videem</string>
<string name="background_player_append">Ve frontě přehrávače na pozadí</string>
<string name="popup_playing_append">Ve frontě přehrávače v okně</string>
<string name="play_all">Přehrát vše</string>

View File

@@ -145,31 +145,30 @@
<string name="disabled">Deaktiviert</string>
<string name="use_old_player_title">Benutze den alten Player</string>
<string name="open_in_popup_mode">Im Popup-Modus öffnen</string>
<string name="open_in_popup_mode">Im Pop-up Modus öffnen</string>
<string name="default_video_format_title">Bevorzugtes Videoformat</string>
<string name="popup_playing_toast">Spiele im Popup-Modus ab</string>
<string name="popup_mode_share_menu_title">NewPipe Popup-Modus</string>
<string name="popup_playing_toast">Spiele im Pop-up Modus ab</string>
<string name="popup_mode_share_menu_title">NewPipe Pop-up Modus</string>
<string name="msg_popup_permission">Diese Berechtigung ist für das
Öffnen im Popup-Modus erforderlich</string>
<string name="msg_popup_permission">Diese Berechtigung ist für das Öffnen im Pop-up Modus erforderlich</string>
<string name="use_old_player_summary">Alter eingebauter Mediaframework-Player</string>
<string name="default_popup_resolution_title">Standardauflösung des Popups</string>
<string name="default_popup_resolution_title">Standardauflösung des Pop-ups</string>
<string name="show_higher_resolutions_title">Zeige höhere Auflösungen an</string>
<string name="show_higher_resolutions_summary">Nur einige Geräte unterstützen das Abspielen von 2K-/4K-Videos</string>
<string name="show_higher_resolutions_summary">Nur manche Geräte unterstützen das Abspielen von 2K-/4K-Videos</string>
<string name="controls_background_title">Hintergrund</string>
<string name="controls_popup_title">Popup</string>
<string name="controls_popup_title">Pop-up</string>
<string name="popup_remember_size_pos_title">Größe und Position des Popups merken</string>
<string name="popup_remember_size_pos_title">Größe und Position des Pop-ups merken</string>
<string name="use_external_video_player_summary">Manche Auflösungen werden KEINE Tonspur haben, wenn diese Option eingeschaltet ist</string>
<string name="popup_remember_size_pos_summary">Letzte Größe und Position des Popups merken</string>
<string name="popup_remember_size_pos_summary">Letzte Größe und Position des Pop-ups merken</string>
<string name="player_gesture_controls_title">Gestensteuerung</string>
<string name="player_gesture_controls_summary">Helligkeit und Lautstärke des Players mit Gesten steuern</string>
<string name="player_gesture_controls_summary">Benutze Gesten um Helligkeit und Lautstärke zu justieren</string>
<string name="show_search_suggestions_title">Durchsuche Vorschläge</string>
<string name="show_search_suggestions_summary">Zeige Vorschläge beim Suchen</string>
<string name="settings_category_popup_title">Popup</string>
<string name="settings_category_popup_title">Pop-up</string>
<string name="filter">Filter</string>
<string name="refresh">Aktualisieren</string>
<string name="clear">Leeren</string>
@@ -224,9 +223,9 @@
<string name="notification_channel_name">NewPipe Benachrichtigung</string>
<string name="notification_channel_description">Benachrichtigungen für NewPipe Hintergrund- und Popup-Player</string>
<string name="notification_channel_description">Benachrichtigungen für NewPipe Hintergrund- und Pop-up Player</string>
<string name="tab_main">Übersicht</string>
<string name="tab_main">Main</string>
<string name="settings_category_player_behavior_title">Verhalten</string>
<string name="settings_category_history_title">Verlauf</string>
<string name="playlist">Playlist</string>
@@ -263,7 +262,7 @@
<string name="select_a_channel">Wähle einen Kanal aus</string>
<string name="no_channel_subscribed_yet">Noch kein Kanal abonniert</string>
<string name="trending">Trends</string>
<string name="popup_playing_append">In der Warteschlange des Popup-Players</string>
<string name="popup_playing_append">In der Warteschlange des Pop-up Players</string>
<string name="play_all">Alles abspielen</string>
<string name="play_queue_remove">Entfernen</string>
@@ -274,7 +273,7 @@
<string name="feed_page_summary">Feed-Seite</string>
<string name="channel_page_summary">Kanal-Seite</string>
<string name="title_activity_background_player">Hintergrund-Player</string>
<string name="title_activity_popup_player">Popup-Player</string>
<string name="title_activity_popup_player">Pop-up Player</string>
<string name="play_queue_stream_detail">Details</string>
<string name="top_50">Top 50</string>
<string name="player_unrecoverable_failure">Nicht behebbarer Wiedergabefehler aufgetreten</string>
@@ -284,7 +283,7 @@
<string name="select_a_kiosk">Kiosk auswählen</string>
<string name="kiosk">Kiosk</string>
<string name="show_hold_to_append_summary">Tipp anzeigen, wenn der Hintergrundwiedergabe- oder Pop-up-Button auf der Videodetailseite gedrücktgehalten wird</string>
<string name="show_hold_to_append_summary">Tipp anzeigen, wenn der Hintergrundwiedergabe- oder Pop-up-Button auf der Videodetailseite gedrückt gehalten wird</string>
<string name="background_player_append">In der Warteschlange der Hintergrundwiedergabe</string>
<string name="new_and_hot">Neu und brandheiß</string>
<string name="hold_to_append">Halten zum Hinzufügen zur Warteschleife</string>
@@ -300,4 +299,5 @@
<string name="give_back">Zurückgeben</string>
<string name="website_title">Website</string>
<string name="website_encouragement">Um mehr Informationen und die aktuellsten Nachrichten über NewPipe zu bekommen, besuche unsere Website.</string>
<string name="donation_encouragement">NewPipe wird von Freiwilligen entwickelt, die ihre Freizeit damit verbringen, dir das beste Erlebnis zu bieten. Jetzt ist es an der Zeit, etwas zurückzugeben, um sicherzustellen, dass unsere Entwickler NewPipe noch besser machen können, während sie eine Tasse Java genießen!</string>
</resources>

View File

@@ -34,7 +34,7 @@
<string name="theme_title">Tema</string>
<string name="dark_theme_title">Oscuro</string>
<string name="light_theme_title">Ligero</string>
<string name="light_theme_title">Claro</string>
<string name="settings_category_appearance_title">Apariencia</string>
<string name="settings_category_other_title">Otros</string>
@@ -127,7 +127,7 @@
<string name="app_ui_crash">La interfaz de la app dejó de funcionar</string>
<string name="info_labels">Lo sucedido:\\nSolicitud:\\nIdioma del contenido:\\nServicio:\\nHora GMT:\\nPaquete:\\nVersión:\\nVersión del S.O:\\nRango global de la IP:</string>
<string name="black_theme_title">Oscuro</string>
<string name="black_theme_title">Negro</string>
<string name="all">Todo</string>
<string name="channel">Canal</string>
@@ -193,7 +193,7 @@ abrir en modo popup</string>
<string name="app_license_title">Licencia de NewPipe</string>
<string name="contribution_encouragement">Si tienes ideas de; traducción, cambios de diseño, limpieza de código o cambios de código realmente fuertes—la ayuda siempre es bienvenida. Cuanto más se hace, mejor se pone!</string>
<string name="read_full_license">Leer licencia</string>
<string name="contribution_title">Contribución</string>
<string name="contribution_title">Contribuir</string>
<string name="subscribe_button_title">Suscribirse</string>
<string name="subscribed_button_title">Suscrito</string>
<string name="channel_unsubscribed">Canal no suscrito</string>
@@ -297,4 +297,15 @@ abrir en modo popup</string>
<string name="show_hold_to_append_title">Desplegar consejo \"Mantener para poner en la fila\"</string>
<string name="new_and_hot">Nuevo y popular</string>
<string name="hold_to_append">Mantener para poner en la fila</string>
<string name="donation_title">Donar</string>
<string name="donation_encouragement">NewPipe es desarrollado por voluntarios que emplean su tiempo libre en mejorar tu experiencia. ¡ Ahora puedes devolver el favor para asegurar que los desarrolladores puedan crear un NewPipe aún mejor mientras saborean una taza de Java !</string>
<string name="give_back">Donar</string>
<string name="website_title">Página web</string>
<string name="website_encouragement">Para obtener más información y las últimas noticias sobre NewPipe, visita nuestra web.</string>
<string name="default_content_country_title">País del contenido por defecto</string>
<string name="toggle_orientation">Alternar orientación</string>
<string name="switch_to_background">Cambiar a segundo plano</string>
<string name="switch_to_popup">Cambiar a popup</string>
<string name="switch_to_main">Cambiar a principal</string>
</resources>

View File

@@ -223,7 +223,7 @@
<string name="app_license_title">NewPipe:n Lisenssi</string>
<string name="contribution_encouragement">Olkoon sinulla ideoita; käännöksistä, design muutoksista, koodin siivoamisesta tai raskaista koodimuutoksista—apu on aina tervetullutta. Mitä enemmän saadaan tehtyä, sen paremmaksi sovellus tulee!</string>
<string name="read_full_license">Lue lisenssi</string>
<string name="contribution_title">Lahjoitus</string>
<string name="contribution_title">Osallistu</string>
<string name="title_activity_history">Historia</string>
<string name="title_history_search">Haettu</string>
@@ -275,4 +275,9 @@
<string name="start_here_on_main">Aloita toistaminen</string>
<string name="start_here_on_background">Aloita toisto taustalla</string>
<string name="start_here_on_popup">Aloita toisto ikkunassa</string>
</resources>
<string name="donation_title">Lahjoita</string>
<string name="donation_encouragement">NewPipe kehitetään vapaaehtoisten toimesta, jotka käyttävät vapaa-aikaansa tuottaakseen parhaimman kokemuksen sinulle. Nyt on aika antaa takaisin, jotta kehittäjät voivat tehdä NewPipe:sta vielä paremman nauttiessaan kupin kahvia!</string>
<string name="give_back">Anna takaisin</string>
<string name="website_title">Websivu</string>
<string name="website_encouragement">Käy verkkosivuillamme saadaksesi lisää tietoa ja uusimmat uutiset NewPipe:sta.</string>
</resources>

View File

@@ -2,7 +2,7 @@
<resources>
<string name="cancel">Annuler</string>
<string name="choose_browser">Choisir un navigateur</string>
<string name="default_resolution_title">Définition par défaut</string>
<string name="default_resolution_title">Résolution par défaut</string>
<string name="did_you_mean">Vouliez-vous dire : %1$s ?</string>
<string name="download">Télécharger</string>
<string name="download_path_title">Chemin de téléchargement</string>
@@ -53,7 +53,7 @@
<string name="settings_category_appearance_title">Apparence</string>
<string name="network_error">Erreur réseau</string>
<string name="download_path_audio_title">Chemin de téléchargement de l\'audio</string>
<string name="download_path_audio_title">Chemin de téléchargement</string>
<string name="download_path_audio_summary">Chemin de stockage des fichiers audio téléchargés</string>
<string name="download_path_audio_dialog_title">Entrez le chemin de téléchargement des fichiers audio</string>
@@ -66,12 +66,12 @@
<string name="error_snackbar_message">Désolé, des erreurs se sont produites.</string>
<string name="content">Contenu</string>
<string name="show_age_restricted_content_title">Afficher le contenu soumis à une restriction d\'âge</string>
<string name="duration_live">En direct</string>
<string name="show_age_restricted_content_title">Afficher le contenu avec restriction d\'âge</string>
<string name="duration_live">Direct</string>
<string name="could_not_load_thumbnails">Impossible de charger toutes les miniatures</string>
<string name="youtube_signature_decryption_error">Erreur lors du décryptage du lien</string>
<string name="light_parsing_error">Impossible d\'analyser le site complètement</string>
<string name="light_parsing_error">Impossible d\'analyser complètement le site web</string>
<string name="live_streams_not_supported">Il s\'agit d\'un direct, non supporté pour le moment.</string>
<string name="sorry_string">Désolé, une erreur inattendue s\'est produite.</string>
<string name="autoplay_by_calling_app_summary">Lire automatiquement la vidéo lorsque NewPipe est appelée par une autre application</string>
@@ -93,7 +93,7 @@
<string name="user_report">Rapport utilisateur</string>
<string name="error_snackbar_action">SIGNALER</string>
<string name="could_not_setup_download_menu">Impossible de mettre en place le menu de téléchargement</string>
<string name="could_not_setup_download_menu">Impossible de configurer le menu de téléchargement</string>
<string name="could_not_get_stream">Impossible d\'obtenir un flux</string>
<string name="downloads">Téléchargements</string>
<string name="downloads_title">Téléchargements</string>
@@ -109,19 +109,19 @@
<string name="finish">OK</string>
<string name="msg_name">Nom du fichier</string>
<string name="msg_threads">Threads</string>
<string name="msg_threads">Discussions</string>
<string name="msg_error">Erreur</string>
<string name="msg_server_unsupported">Serveur non supporté</string>
<string name="msg_exists">Fichier déjà existant</string>
<string name="msg_url_malform">URL malformée ou internet indisponible</string>
<string name="msg_running">Téléchargement NewPipe</string>
<string name="msg_running_detail">Toucher pour plus de détails</string>
<string name="msg_running_detail">Appuyer pour plus de détails</string>
<string name="msg_wait">Veuillez patienter…</string>
<string name="msg_copied">Copié dans le presse-papier</string>
<string name="no_available_dir">Sélectionner un dossier de téléchargement disponible</string>
<string name="could_not_load_image">Limage ne peut pas être chargée</string>
<string name="app_ui_crash">Lappli/linterface utilisateur a crashé</string>
<string name="could_not_load_image">Impossible de charger l\'image</string>
<string name="app_ui_crash">Lappli/linterface a crashé</string>
<string name="reCaptchaActivity">reCAPTCHA</string>
<string name="black_theme_title">Noir</string>
@@ -130,13 +130,13 @@
<string name="channel">Chaîne</string>
<string name="reCaptcha_title">Test reCAPTCHA</string>
<string name="recaptcha_request_toast">Test reCAPTCHA demandé</string>
<string name="reCaptcha_title">Défi reCAPTCHA</string>
<string name="recaptcha_request_toast">Défi reCAPTCHA demandé</string>
<string name="open_in_popup_mode">Ouvrir dans le lecteur pop-up</string>
<string name="popup_mode_share_menu_title">Lecteur pop-up de NewPipe</string>
<string name="open_in_popup_mode">Ouvrir en mode fenêtré</string>
<string name="popup_mode_share_menu_title">Mode fenêtré NewPipe</string>
<string name="popup_playing_toast">Lire dans le lecteur pop-up</string>
<string name="popup_playing_toast">Lire en mode fenêtré</string>
<string name="yes">Oui</string>
<string name="later">Plus tard</string>
<string name="disabled">Désactivé</string>
@@ -147,38 +147,38 @@
<string name="short_thousand">K</string>
<string name="short_million">M</string>
<string name="msg_popup_permission">Cette permission est nécessaire pour
\nutiliser le mode pop-up</string>
<string name="msg_popup_permission">Cette autorisation est nécessaire pour
\nutiliser le mode fenêtré</string>
<string name="controls_background_title">Arrière-plan</string>
<string name="controls_popup_title">Pop-up</string>
<string name="controls_popup_title">Fenêtre</string>
<string name="default_popup_resolution_title">Taille du lecteur pop-up</string>
<string name="default_popup_resolution_title">Résolution par défaut de la fenêtre</string>
<string name="show_higher_resolutions_title">Afficher des résolutions plus élevées</string>
<string name="show_higher_resolutions_summary">Seulement certains périphériques supportent la lecture 2K/4K</string>
<string name="show_higher_resolutions_summary">Certains appareils uniquement supportent la lecture 2K/4K</string>
<string name="default_video_format_title">Format vidéo par défaut</string>
<string name="popup_remember_size_pos_title">Mémoriser la taille et la position du lecteur pop-up</string>
<string name="popup_remember_size_pos_summary">Mémoriser le dernier emplacement et la taille du lecteur pop-up</string>
<string name="popup_remember_size_pos_title">Mémoriser la taille et la position de la fenêtre</string>
<string name="popup_remember_size_pos_summary">Mémoriser la dernière taille et position de la fenêtre</string>
<string name="settings_category_popup_title">Pop-up</string>
<string name="settings_category_popup_title">Fenêtre</string>
<string name="filter">Filtre</string>
<string name="refresh">Actualiser</string>
<string name="clear">Effacer</string>
<string name="popup_resizing_indicator_title">Redimensionner</string>
<string name="short_billion">Md</string>
<string name="short_billion">B</string>
<string name="use_external_video_player_summary">Certaines résolutions n\'auront PAS de son si cette option est activée</string>
<string name="player_gesture_controls_summary">Utilisez les gestes pour contrôler la luminosité et le volume du lecteur</string>
<string name="show_search_suggestions_title">Chercher des suggestions</string>
<string name="show_search_suggestions_summary">Montrer les suggestions pendant la recherche</string>
<string name="player_gesture_controls_summary">Utiliser les gestes pour contrôler la luminosité et le volume du lecteur</string>
<string name="show_search_suggestions_title">Suggestions de recherche</string>
<string name="show_search_suggestions_summary">Afficher les suggestions lors d\'une recherche</string>
<string name="player_gesture_controls_title">Gestes pour contrôler la lecture</string>
<string name="best_resolution">Meilleure résolution</string>
<string name="subscribe_button_title">S\'abonner</string>
<string name="subscribed_button_title">Abonné</string>
<string name="channel_unsubscribed">Désabonner de la chaîne</string>
<string name="channel_unsubscribed">Désabonné de la chaîne</string>
<string name="tab_main">Principal</string>
<string name="tab_subscriptions">Abonnements</string>
@@ -197,13 +197,13 @@
<string name="view_on_github">Voir sur GitHub</string>
<string name="app_license_title">Licence de NewPipe</string>
<string name="read_full_license">Lire la licence</string>
<string name="contribution_title">Contribution</string>
<string name="contribution_title">Contribuer</string>
<string name="charset_letters_and_digits">Lettres et chiffres</string>
<string name="title_activity_about">À propos de NewPipe</string>
<string name="copyright" formatted="true">© %1$s par %2$s sous %3$s</string>
<string name="contribution_encouragement">Que ce soit pour des idées, traductions, changements de design, nettoyage ou gros changements de code, l\'aide est toujours la bienvenue. Plus on contribue, meilleur il devient !</string>
<string name="subscription_change_failed">Incapable de changer l\'abonnement</string>
<string name="subscription_update_failed">Incapable de mettre à jour l\'abonnement</string>
<string name="subscription_change_failed">Impossible de modifier l\'abonnement</string>
<string name="subscription_update_failed">Impossible d\'actualiser l\'abonnement</string>
<string name="resume_on_audio_focus_gain_summary">Continuer la lecture après les interruptions (ex : appels)</string>
@@ -216,7 +216,7 @@
<string name="enable_watch_history_title">Historique</string>
<string name="title_activity_history">Historique</string>
<string name="title_history_search">Recherché</string>
<string name="title_history_view">Vue</string>
<string name="title_history_view">Regardé</string>
<string name="history_disabled">L\'historique est désactivé</string>
<string name="action_history">Historique</string>
<string name="history_empty">L\'historique est vide</string>
@@ -231,10 +231,10 @@
<string name="settings_category_player_behavior_title">Comportement</string>
<string name="settings_category_history_title">Historique</string>
<string name="playlist">Liste de lecture</string>
<string name="notification_channel_description">Notifications pour les lecteurs \"Arrière-plan\" et \"Pop-up\" de NewPipe</string>
<string name="notification_channel_description">Notifications pour les lecteurs \"Arrière-plan\" et \"Fenêtre\" de NewPipe</string>
<string name="search_no_results">Aucun résultat</string>
<string name="empty_subscription_feed_subtitle">Rien à voir ici</string>
<string name="empty_subscription_feed_subtitle">Aucun contenu</string>
<string name="no_subscribers">Aucun abonné</string>
<plurals name="subscribers">
@@ -242,10 +242,10 @@
<item quantity="other">%s abonnés</item>
</plurals>
<string name="no_views">Aucun visionnage</string>
<string name="no_views">Aucune vue</string>
<plurals name="views">
<item quantity="one">%s visionnage</item>
<item quantity="other">%s visionnages</item>
<item quantity="one">%s vue</item>
<item quantity="other">%s vues</item>
</plurals>
<string name="no_videos">Aucune vidéo</string>
@@ -256,31 +256,31 @@
<string name="charset_most_special_characters">Caractères spéciaux</string>
<string name="item_deleted">Objet effacé</string>
<string name="item_deleted">Élément effacé</string>
<string name="delete_item_search_history">Voulez-vous supprimer cet élément de l\'historique de recherche ?</string>
<string name="main_page_content">Contenu de la page principale</string>
<string name="blank_page_summary">Page vide</string>
<string name="subscription_page_summary">Abonnements</string>
<string name="feed_page_summary">Page de Flux</string>
<string name="channel_page_summary">Page de la chaîne</string>
<string name="select_a_channel">Sélectionnez une chaîne</string>
<string name="select_a_channel">Sélectionner une chaîne</string>
<string name="trending">Populaires</string>
<string name="top_50">Top 50</string>
<string name="new_and_hot">Nouveau &amp; populaire</string>
<string name="background_player_append">Mettre en file d\'attente du lecteur en arrière plan</string>
<string name="popup_playing_append">Mettre en file d\'attente du lecteur pop-up</string>
<string name="play_all">Lire tout</string>
<string name="background_player_append">Mis en file d\'attente du lecteur en arrière-plan</string>
<string name="popup_playing_append">Mis en file d\'attente du lecteur fenêtré</string>
<string name="play_all">Tout lire</string>
<string name="player_stream_failure">Échec de la lecture de cette vidéo</string>
<string name="player_stream_failure">Échec de la lecture de ce flux</string>
<string name="player_unrecoverable_failure">Une erreur irrécupérable du lecteur s\'est produite</string>
<string name="no_channel_subscribed_yet">Encore aucune chaîne souscrite</string>
<string name="title_activity_background_player">Lecteur en arrière plan</string>
<string name="title_activity_popup_player">Lecteur pop-up</string>
<string name="title_activity_background_player">Lecteur en arrière-plan</string>
<string name="title_activity_popup_player">Lecteur fenêtré</string>
<string name="play_queue_remove">Retirer</string>
<string name="play_queue_stream_detail">Détails</string>
<string name="play_queue_audio_settings">Réglages audio</string>
<string name="show_hold_to_append_title">Afficher l\'aide \"Appui long pour mettre en file d\'attente\"</string>
<string name="show_hold_to_append_summary">Afficher l\'aide en restant appuyé sur les boutons \"Arrière-plan\" et \"Pop-up\" sur la page de détails d\'une vidéo</string>
<string name="show_hold_to_append_summary">Afficher l\'aide en appuyant sur les boutons \"Arrière-plan\" et \"Fenêtre\" sur la page de détails d\'une vidéo</string>
<string name="unknown_content">[Inconnu]</string>
<string name="player_recoverable_failure">Récupération de l\'erreur du lecteur</string>
@@ -290,9 +290,20 @@
<string name="kiosk">Kiosque</string>
<string name="hold_to_append">Appui long pour mettre en file d\'attente</string>
<string name="enqueue_on_background">Mettre en file d\'attente en fond</string>
<string name="enqueue_on_popup">Mettre en file d\'attente du lecteur pop-up</string>
<string name="enqueue_on_background">Mettre en file d\'attente en arrière-plan</string>
<string name="enqueue_on_popup">Mettre en file d\'attente du lecteur fenêtré</string>
<string name="start_here_on_main">Démarrer ici</string>
<string name="start_here_on_background">Démarrer ici en fond</string>
<string name="start_here_on_popup">Démarrer dans le lecteur pop-up</string>
</resources>
<string name="start_here_on_background">Démarrer ici en arrière-plan</string>
<string name="start_here_on_popup">Démarrer ici en fenêtré</string>
<string name="donation_title">Donner</string>
<string name="donation_encouragement">NewPipe est développé par des volontaires sur leur temps libre afin de vous proposer la meilleur expérience. Maintenant il est temps de leurs offrir un café pour les soutenir dans leurs efforts et rendre NewPipe encore meilleur !</string>
<string name="website_title">Site</string>
<string name="website_encouragement">Pour obtenir plus d\'informations et les dernières nouvelles à propos de NewPipe, visitez notre site Internet.</string>
<string name="give_back">Donner en retour</string>
<string name="default_content_country_title">Pays du contenu par défaut</string>
<string name="toggle_orientation">Orientation</string>
<string name="switch_to_background">Basculer en arrière-plan</string>
<string name="switch_to_popup">Basculer en fenêtré</string>
<string name="switch_to_main">Basculer en normal</string>
</resources>

View File

@@ -2,12 +2,12 @@
<resources>
<string name="main_bg_subtitle">לחץ \"חפש\" כדי להתחיל</string>
<string name="view_count_text">%1$s צפיות</string>
<string name="upload_date_text">פורבם ב:-%1$s</string>
<string name="no_player_found">לא נמצאו נגני רשת, להתקין את נגן הרשת VLC?</string>
<string name="upload_date_text">פורסם ב:-%1$s</string>
<string name="no_player_found">לא נמצאו נגני רשת, האם תרצה להתקין את VLC?</string>
<string name="install">התקן</string>
<string name="cancel">סגור</string>
<string name="cancel">בטל</string>
<string name="open_in_browser">פתח בדפדפן</string>
<string name="open_in_popup_mode">פתח במצב חלון מוקטן</string>
<string name="open_in_popup_mode">פתח במצב חלון צץ</string>
<string name="share">שתף</string>
<string name="download">הורד</string>
<string name="search">חפש</string>
@@ -16,62 +16,62 @@
<string name="share_dialog_title">שתף עם</string>
<string name="choose_browser">בחר דפדפן</string>
<string name="screen_rotation">סיבוב</string>
<string name="use_external_video_player_title">השתמש בנגן וידאו חיצוני</string>
<string name="use_external_video_player_title">השתמש בנגן סרטים חיצוני</string>
<string name="use_external_video_player_summary">לחלק מהסרטונים עם רזולוציה גבוהה לא יהיה שמע כאשר אפשרות זו פועלת</string>
<string name="use_external_audio_player_title">השתמש בנגן וידאו חיצוני</string>
<string name="popup_mode_share_menu_title">מצב חלון מוקטן (NewPipe)</string>
<string name="use_external_audio_player_title">השתמש בנגן סרטים חיצוני</string>
<string name="popup_mode_share_menu_title">מצב חלון צץ (NewPipe)</string>
<string name="controls_background_title">רקע</string>
<string name="controls_popup_title">חלון מוקטן</string>
<string name="controls_popup_title">חלון צץ</string>
<string name="download_path_title">נתיב הורדה לסרטונים</string>
<string name="download_path_summary">מיקום לשמירת סרטונים.</string>
<string name="download_path_dialog_title">הכנס מיקום לשמירת סרטונים</string>
<string name="download_path_summary">נתיב לשמירת סרטונים</string>
<string name="download_path_dialog_title">הכנס נתיב לשמירת סרטונים</string>
<string name="download_path_audio_title">מיקום לשמירת שמע</string>
<string name="download_path_audio_title">נתיב לשמירת שמע</string>
<string name="download_path_audio_summary">נתיב לשמירת שמע</string>
<string name="download_path_audio_dialog_title">הכנס נתיב לשמירת שמע.</string>
<string name="download_path_audio_dialog_title">הכנס נתיב לשמירת קבצי שמע</string>
<string name="autoplay_by_calling_app_title">הפעל אוטומטית כאשר ממופעל דרך אפליקציה אחרת</string>
<string name="autoplay_by_calling_app_summary">הפעל סרטון אוטומטית כאשר NewPipe נפתח דרך אפליקציה אחרת.</string>
<string name="autoplay_by_calling_app_title">נגן אוטומטית</string>
<string name="autoplay_by_calling_app_summary">הפעל סרטון אוטומטית כאשר NewPipe נפתח דרך אפליקציה אחרת</string>
<string name="default_resolution_title">רזולוציית ברירת המחדל</string>
<string name="default_popup_resolution_title">רזולוציית ברירת המחדל לחלון המוקטן</string>
<string name="show_higher_resolutions_title">הראה ברזולוציות גבוהות</string>
<string name="show_higher_resolutions_summary">לא כל המכשירים תומכים בצפייה בסרטונים ב-2k/4k</string>
<string name="default_popup_resolution_title">רזולוציית ברירת המחדל לחלון צץ</string>
<string name="show_higher_resolutions_title">הצג רזולוציות גבוהות יותר</string>
<string name="show_higher_resolutions_summary">רק חלק מהמכשירים תומכים בצפייה בסרטונים ב-2k/4k</string>
<string name="play_with_kodi_title">נגן ב-Kodi</string>
<string name="kore_not_found">האפליקציה Kore לא נמצאה. להתקין את Kore?</string>
<string name="show_play_with_kodi_title">הראה את האפשרות לניגון עם Kodi</string>
<string name="show_play_with_kodi_summary">הראה אפשרות לנגן סרטון דרך \"Kodi media center\".</string>
<string name="kore_not_found">האפליקציה Kore לא נמצאה. להתקין אותה?</string>
<string name="show_play_with_kodi_title">הצג את האפשרות לניגון עם Kodi</string>
<string name="show_play_with_kodi_summary">הראה אפשרות לנגן סרטון דרך \"Kodi media center\"</string>
<string name="play_audio">שמע</string>
<string name="default_audio_format_title">פורמט ברירת המחדל לשמע</string>
<string name="default_video_format_title">פורמט הוידאו המועדף</string>
<string name="webm_description">WebM — פורמט חינמי</string>
<string name="m4a_description">m4a — איכות יותר גבוהה</string>
<string name="default_audio_format_title">תבנית ברירת המחדל לשמע</string>
<string name="default_video_format_title">תבנית סרט ברירת מחדל</string>
<string name="webm_description">WebM — תבנית חופשית</string>
<string name="m4a_description">M4A — איכות גבוהה יותר</string>
<string name="theme_title">ערכת נושא</string>
<string name="light_theme_title">מואר</string>
<string name="dark_theme_title">חשוך</string>
<string name="black_theme_title">שחור</string>
<string name="popup_remember_size_pos_title">זכור את מיקומו וגודלו של החלון המוקטן</string>
<string name="popup_remember_size_pos_summary">זכור את המיקום והגודל שנקבעו לחלון המוקטן</string>
<string name="player_gesture_controls_title">מחוות בנגן הוידאו</string>
<string name="popup_remember_size_pos_title">זכור את מיקומו וגודלו של החלון הצץ</string>
<string name="popup_remember_size_pos_summary">זכור את המיקום והגודל האחרונים של החלון הצץ</string>
<string name="player_gesture_controls_title">מחוות מגע לשליטה בנגן</string>
<string name="player_gesture_controls_summary">השתמש במחוות כדי לשלוט בבהירות ובעוצמת השמע של הנגן</string>
<string name="show_search_suggestions_title">הצעות חיפוש</string>
<string name="show_search_suggestions_summary">הראה השלמות מילים בחיפוש</string>
<string name="show_search_suggestions_summary">הצג הצעות כשמחפשים</string>
<string name="download_dialog_title">הורד</string>
<string name="next_video_title">הסרטון הבא</string>
<string name="show_next_and_similar_title">הראה את הסרטונים הבאים וסרטונים דומים</string>
<string name="url_not_supported_toast">כתובת URL לא נתמכת</string>
<string name="search_language_title">השפה המועדפת לסרטונים</string>
<string name="settings_category_video_audio_title">וידאו ושמע</string>
<string name="settings_category_popup_title">חלון מוקטן</string>
<string name="search_language_title">שפת התוכן המועדפת</string>
<string name="settings_category_video_audio_title">סרטים ושמע</string>
<string name="settings_category_popup_title">חלון צץ</string>
<string name="settings_category_appearance_title">תצוגה</string>
<string name="settings_category_other_title">אחרים</string>
<string name="background_player_playing_toast">מנגן ברקע</string>
<string name="popup_playing_toast">מנגן במצב חלון מוקטן</string>
<string name="popup_playing_toast">מנגן במצב חלון צץ</string>
<string name="play_btn_text">נגן</string>
<string name="content">תוכן</string>
<string name="show_age_restricted_content_title">הראה תוכן בעל הגבלת גיל</string>
<string name="video_is_age_restricted">לסרטון הגבלת גיל. הפעל צפייה בסרטונים בעלי הגבלות גיל בהגדרות כדי לצפות בסרטון זה.</string>
<string name="video_is_age_restricted">לסרטון קיימת הגבלת גיל. ניתן לאפשר צפייה בסרטונים אלו ע\"י שינוי ממסך ההגדרות.</string>
<string name="duration_live">חי</string>
<string name="downloads">הורדות</string>
<string name="downloads_title">הורדות</string>
@@ -84,26 +84,205 @@
<string name="filter">סינון</string>
<string name="refresh">רענן</string>
<string name="clear">נקה</string>
<string name="popup_resizing_indicator_title">משנה גודל</string>
<string name="popup_resizing_indicator_title">שינוי גודל</string>
<string name="general_error">שגיאה</string>
<string name="network_error">שגיאת אינטרנט</string>
<string name="could_not_load_thumbnails">אין אפשרות לטעון את כל התמונות הממוזערות</string>
<string name="youtube_signature_decryption_error">לא היתה אפשרות לפענח את חתימת הוידאו.</string>
<string name="parsing_error">לא הייתה אפשרות לפענח את האתר.</string>
<string name="light_parsing_error">לא הייתה אפשרות לפענח את האתר לחלוטין.</string>
<string name="content_not_available">תוכן אינו זמין.</string>
<string name="blocked_by_gema">חסום ע\"י GEMA.</string>
<string name="could_not_setup_download_menu">לא הייתה אפשרות להכין את תפריט ההורדות.</string>
<string name="live_streams_not_supported">זהו שידור ישיר. שידורים ישירים עוד לא נתמכים באפליקציה(יתמכו בעתיד בעזרת ה\').</string>
<string name="could_not_get_stream">לא הייתה אפשרות לקבל וידאו.</string>
<string name="youtube_signature_decryption_error">לא הייתה אפשרות לפענח את חתימת ה-URL של הסרט</string>
<string name="parsing_error">לא הייתה אפשרות לנתח את האתר</string>
<string name="light_parsing_error">לא הייתה אפשרות לנתח את האתר לחלוטין</string>
<string name="content_not_available">תוכן אינו זמין</string>
<string name="blocked_by_gema">חסום ע\"י GEMA</string>
<string name="could_not_setup_download_menu">לא הייתה אפשרות להכין את תפריט ההורדות</string>
<string name="live_streams_not_supported">זהו שידור ישיר. שידורים ישירים עדיין לא נתמכים.</string>
<string name="could_not_get_stream">לא הייתה אפשרות להזרים סרטון</string>
<string name="could_not_load_image">לא הייתה אפשרות לטעון את התמונה</string>
<string name="app_ui_crash">האפליקציה או ממשק המשתמש קרסו</string>
<string name="sorry_string">מצטער, זה לא אמור לקרות.</string>
<string name="error_report_button_text">דווח על הבעיה דרך האימייל</string>
<string name="error_snackbar_message">סליחה, קרו כמה שגיאות.</string>
<string name="sorry_string">מצטערים, זה לא היה אמור לקרות.</string>
<string name="error_report_button_text">דווח על השגיאה דרך הדוא\"ל</string>
<string name="error_snackbar_message">מצטערים, אירעו כמה שגיאות.</string>
<string name="error_snackbar_action">דווח</string>
<string name="what_device_headline">מידע:</string>
<string name="what_happened_headline">מה קרה:</string>
<string name="info_labels">מה:\\nבקשה:\\nשפת התוכן:\\nשירות:\\nזמן GMT:\\nחבילה:\\nגרסה:\\nגרסת מערכת ההפעלה:\\nGlob. טווח IP:</string>
<string name="subscribe_button_title">הירשם כמנוי</string>
<string name="subscribed_button_title">רשום כמנוי</string>
<string name="channel_unsubscribed">ביטול מנוי לערוץ</string>
<string name="subscription_change_failed">אין אפשרות לשנות מנוי</string>
<string name="subscription_update_failed">אין אפשרות לעדכן מנוי</string>
<string name="tab_main">ראשי</string>
<string name="tab_subscriptions">מנויים</string>
<string name="fragment_whats_new">מה חדש</string>
<string name="enable_search_history_title">היסטוריית חיפושים</string>
<string name="enable_search_history_summary">שמור חיפושים מקומית</string>
<string name="enable_watch_history_title">היסטוריה</string>
<string name="enable_watch_history_summary">המשך לעקוב אחר סרטונים שנצפו</string>
<string name="resume_on_audio_focus_gain_title">המשך לנגן בעת חזרת המיקוד ליישום</string>
<string name="resume_on_audio_focus_gain_summary">המשך לנגן לאחר הפרעות (לדוגמה: שיחות טלפון)</string>
<string name="show_hold_to_append_title">הצג עצה \"לחיצה ממושכת תוסיף לרשימה\"</string>
<string name="show_hold_to_append_summary">הצג עצה כאשר כפתור רקע או חלון צץ נלחץ במסך נגן הסרטים</string>
<string name="settings_category_player_title">נגן</string>
<string name="settings_category_player_behavior_title">התנהגות</string>
<string name="settings_category_history_title">היסטוריה</string>
<string name="background_player_append">נוסף לתור של הנגן ברקע</string>
<string name="popup_playing_append">נוסף לתור של הנגן הצץ</string>
<string name="playlist">רשימת ניגון</string>
<string name="best_resolution">רזולוציה מיטבית</string>
<string name="undo">בטל</string>
<string name="play_all">נגן הכל</string>
<string name="notification_channel_name">הודעה מ-NewPipe</string>
<string name="notification_channel_description">התראות עבור נגן הרקע והנגן הצץ של NewPipe</string>
<string name="unknown_content">[לא ידוע]</string>
<string name="player_stream_failure">נכשל בניגון הסרט הנוכחי</string>
<string name="player_unrecoverable_failure">תקלה בלתי ניתנת לשחזור אירעה בנגן</string>
<string name="player_recoverable_failure">מחלים מתקלה שאירעה לנגן</string>
<string name="your_comment">ההערה שלך (באנגלית):</string>
<string name="error_details_headline">פרטים:</string>
<string name="list_thumbnail_view_description">תמונות ממוזערות לתצוגה המקדמת של הסרטון</string>
<string name="detail_thumbnail_view_description">תמונות ממוזערות לתצוגה המקדמת של הסרטון</string>
<string name="detail_uploader_thumbnail_view_description">תמונה של המשתמש המפרסם</string>
<string name="detail_likes_img_view_description">אהבו</string>
<string name="detail_dislikes_img_view_description">לא אהבו</string>
<string name="use_tor_title">השתמש ב-Tor</string>
<string name="use_tor_summary">(ניסיוני) השתמש בתעבורת ההורדה דרך Tor להגברת הפרטיות (ניגון סרטים בהזרמה ישירה אינו נתמך עדיין).</string>
<string name="report_error">דווח על שגיאה</string>
<string name="user_report">דיווח משתמש</string>
<string name="search_no_results">אין תוצאות</string>
<string name="empty_subscription_feed_subtitle">אין כאן כלום מלבד צרצרים</string>
<string name="err_dir_create">לא ניתן ליצור את תיקיית ההורדות \'%1$s\'</string>
<string name="info_dir_created">תיקיית ההורדות נוצרה \'%1$s\'</string>
<string name="video">סרט</string>
<string name="audio">שמע</string>
<string name="retry">נסה שנית</string>
<string name="storage_permission_denied">הגישה לאחסון נדחתה</string>
<string name="use_old_player_title">השתמש בנגן הישן</string>
<string name="use_old_player_summary">השתמש בנגן המובנה Mediaframework</string>
<string name="short_thousand">K</string>
<string name="short_million">M</string>
<string name="short_billion">B</string>
<string name="no_subscribers">אין עוקבים</string>
<plurals name="subscribers">
<item quantity="one">%s עוקב</item>
<item quantity="two">%s עוקבים</item>
</plurals>
<string name="no_views">אין תצוגות</string>
<plurals name="views">
<item quantity="one">תצוגה %s</item>
<item quantity="two">%s תצוגות</item>
</plurals>
<string name="no_videos">אין סרטונים</string>
<plurals name="videos">
<item quantity="one">סרטון %s</item>
<item quantity="two">%s סרטונים</item>
</plurals>
<string name="start">התחל</string>
<string name="pause">השהה</string>
<string name="view">נגן</string>
<string name="delete">מחק</string>
<string name="checksum">בדיקה</string>
<string name="add">משימה חדשה</string>
<string name="finish">בסדר</string>
<string name="msg_name">שם קובץ</string>
<string name="msg_threads">אשכולות</string>
<string name="msg_error">שגיאה</string>
<string name="msg_server_unsupported">שרת לא נתמך</string>
<string name="msg_exists">קובץ כבר קיים</string>
<string name="msg_url_malform">URL לא תקין או שאין אינטרנט זמין</string>
<string name="msg_running">NewPipe מוריד</string>
<string name="msg_running_detail">לחץ לפרטים נוספים</string>
<string name="msg_wait">אנא המתן…</string>
<string name="msg_copied">הועתק ללוח</string>
<string name="no_available_dir">אנא בחר בתיקיית הורדות זמינה</string>
<string name="msg_popup_permission">הרשאה זו נדרשת עבור
\nפתח במצב חלון צץ</string>
<string name="reCaptchaActivity">reCAPTCHA</string>
<string name="reCaptcha_title">אתגר reCAPTCHA</string>
<string name="recaptcha_request_toast">נתבקש אתגר reCAPTCHA</string>
<string name="settings_category_downloads_title">הורדה</string>
<string name="settings_file_charset_title">רשימת תווים אפשרית בשמות קבצים</string>
<string name="settings_file_replacement_character_summary">תווים לא נתמכים מוחלפים עם הערך הזה</string>
<string name="settings_file_replacement_character_title">תו חלופי</string>
<string name="charset_letters_and_digits">אותיות וספרות</string>
<string name="charset_most_special_characters">רוב התווים הייחודיים</string>
<string name="title_activity_about">אודות NewPipe</string>
<string name="action_settings">הגדרות</string>
<string name="action_about">אודות</string>
<string name="title_licenses">רישיונות צד ג\'</string>
<string name="copyright" formatted="true">© %1$s ע\"י %2$s תחת %3$s</string>
<string name="error_unable_to_load_license">לא ניתן לטעון רישיון</string>
<string name="action_open_website">פתח אתר</string>
<string name="tab_about">אודות</string>
<string name="tab_contributors">תורמים</string>
<string name="tab_licenses">רישיונות</string>
<string name="app_description">נגן קל וחופשי לYouTube עבור אנדרואיד.</string>
<string name="contribution_title">תורם</string>
<string name="contribution_encouragement">בכל עת שיש לך רעיון ל: תרגום, עיצוב מחדש, ניקוי קוד, או תיקוני קוד משמעותיים—עזרה תמיד תתקבל בברכה. ככל שיותר מבוצע זה נעשה טוב יותר!</string>
<string name="view_on_github">הצג ב-GitHub</string>
<string name="donation_title">תרום</string>
<string name="donation_encouragement">NewPipe מפותח ע\"י מתנדבים אשר תורמים מזמנם להביא את החוויה המושלמת עבורך. עכשיו זה הזמן לתת להם חזרה כדי לדאוג לכך ש-NewPipe תמשיך לצמוח!</string>
<string name="give_back">לתרום בחזרה</string>
<string name="website_title">אתר הבית</string>
<string name="website_encouragement">לקבלת מידע נוסף ועדכונים אחרונים עבור NewPipe אנא בקר באתרנו.</string>
<string name="app_license_title">רישיון NewPipe</string>
<string name="read_full_license">קרא רישיון</string>
<string name="title_activity_history">היסטוריה</string>
<string name="title_history_search">חופש בעבר</string>
<string name="title_history_view">נצפה בעבר</string>
<string name="history_disabled">היסטוריה אינה פעילה</string>
<string name="action_history">היסטוריה</string>
<string name="history_empty">ההיסטוריה ריקה</string>
<string name="history_cleared">היסטוריה נוקתה</string>
<string name="item_deleted">פריט נמחק</string>
<string name="delete_item_search_history">האם ברצונך למחוק את הפריט הזה מהיסטורית החיפושים?</string>
<string name="main_page_content">תוכן הדף הראשי</string>
<string name="blank_page_summary">דף ריק</string>
<string name="kiosk_page_summary">דף קיוסק</string>
<string name="subscription_page_summary">דף עוקבים</string>
<string name="feed_page_summary">דף עדכונים</string>
<string name="channel_page_summary">דף ערוץ</string>
<string name="select_a_channel">בחר ערוץ</string>
<string name="no_channel_subscribed_yet">אף ערוץ אינו ברשימת המעקב עדיין</string>
<string name="select_a_kiosk">בחר קיוסק</string>
<string name="kiosk">קיוסק</string>
<string name="trending">החמים</string>
<string name="top_50">50 הנצפים ביותר</string>
<string name="new_and_hot">חדש &amp; חם</string>
<string name="title_activity_background_player">נגן רקע</string>
<string name="title_activity_popup_player">נגן צץ</string>
<string name="play_queue_remove">הסר</string>
<string name="play_queue_stream_detail">פרטים</string>
<string name="play_queue_audio_settings">אפשרויות שמע</string>
<string name="hold_to_append">החזק להוספה לרשימת ניגון</string>
<string name="enqueue_on_background">נוסף לרשימת הניגון ברקע</string>
<string name="enqueue_on_popup">נוסף לרשימת הניגון בנגן הצץ</string>
<string name="start_here_on_main">התחל לנגן כאן</string>
<string name="start_here_on_background">התחל כאן בנגן הרקע</string>
<string name="start_here_on_popup">התחל כאן בנגן הצץ</string>
</resources>

View File

@@ -280,4 +280,10 @@
<string name="play_queue_stream_detail">Detalji</string>
<string name="play_queue_audio_settings">Postavke zvuka</string>
<string name="hold_to_append">Zadržite za dodavanje u red čekanja</string>
</resources>
<string name="unknown_content">[Nepoznato]</string>
<string name="donation_title">Doniraj</string>
<string name="website_title">Web stranica</string>
<string name="start_here_on_main">Ovdje započni reprodukciju</string>
<string name="start_here_on_background">Ovdje započni repr. u pozadini</string>
</resources>

View File

@@ -196,7 +196,7 @@
<string name="app_license_title">Licenza di NewPipe</string>
<string name="contribution_encouragement">Un aiuto è sempre il benvenuto: nuove idee, design o traduzioni, piccoli cambi o modifiche radicali del codice rendono l\'applicazione sempre migliore!</string>
<string name="read_full_license">Leggi la licenza</string>
<string name="contribution_title">Contributi</string>
<string name="contribution_title">Partecipa</string>
<string name="title_activity_about">Informazioni su NewPipe</string>
<string name="subscribe_button_title">Iscriviti</string>
<string name="subscribed_button_title">Iscritto</string>
@@ -302,4 +302,15 @@
<string name="start_here_on_main">Inizia la riproduzione qui</string>
<string name="start_here_on_background">Inizia qui sullo sfondo</string>
<string name="start_here_on_popup">Inizia qui nel Popup</string>
</resources>
<string name="donation_title">Dona</string>
<string name="website_title">Sito web</string>
<string name="website_encouragement">Per ricevere maggiori informazioni e le ultime novità su NewPipe visita il nostro sito web.</string>
<string name="donation_encouragement">NewPipe è sviluppato da volontari che spendono il loro tempo libero per regalarti la migliore esperienza. È tempo di restituire il favore permettendo ai nostri sviluppatori di migliorare ulteriormente NewPipe mentre gustano una tazza di Giava!</string>
<string name="give_back">Restituisci</string>
<string name="default_content_country_title">Paese predefinito per i contenuti</string>
<string name="toggle_orientation">Cambia orientamento</string>
<string name="switch_to_background">Cambia in background</string>
<string name="switch_to_popup">Cambia in visualizzazione a comparsa</string>
<string name="switch_to_main">Cambia al menù principale</string>
</resources>

View File

@@ -14,12 +14,12 @@
<string name="choose_browser">ブラウザーを選択</string>
<string name="screen_rotation">回転</string>
<string name="download_path_title">動画を保存する場所</string>
<string name="download_path_summary">動画を保存する位置</string>
<string name="download_path_summary">動画を保存する場所</string>
<string name="download_path_dialog_title">動画を保存する場所を入力して下さい</string>
<string name="default_resolution_title">基本解像度</string>
<string name="default_resolution_title">デフォルトの解像度</string>
<string name="play_with_kodi_title">Kodi で再生</string>
<string name="kore_not_found">Koreが見つかりません。Kore を入手しますか</string>
<string name="show_play_with_kodi_title">\"Kodi で再生\" 設定を表示</string>
<string name="kore_not_found">Koreが見つかりません。Kore を入手しますか</string>
<string name="show_play_with_kodi_title">\"Kodi で再生\" オプションを表示</string>
<string name="show_play_with_kodi_summary">Kodi メディアセンター経由で動画を再生するための設定を表示します</string>
<string name="play_audio">音楽</string>
<string name="default_audio_format_title">基本の音楽形式</string>
@@ -31,7 +31,7 @@
<string name="url_not_supported_toast">URLは使用できません</string>
<string name="search_language_title">優先言語</string>
<string name="settings_category_video_audio_title">動画と音楽</string>
<string name="view_count_text">%1$s ビュー</string>
<string name="view_count_text">%1$s ビュー</string>
<string name="list_thumbnail_view_description">動画 プレビュー サムネイル</string>
<string name="detail_thumbnail_view_description">動画 プレビュー サムネイル</string>
<string name="detail_uploader_thumbnail_view_description">アップローダー サムネイル</string>
@@ -39,7 +39,7 @@
<string name="detail_likes_img_view_description">好ましい</string>
<string name="use_external_video_player_title">外部プレイヤーを使用する</string>
<string name="use_external_audio_player_title">外部プレイヤーを使用する</string>
<string name="background_player_playing_toast">背後で再生しています</string>
<string name="background_player_playing_toast">バックグラウンドで再生中</string>
<string name="play_btn_text">再生</string>
@@ -51,11 +51,11 @@
<string name="settings_category_appearance_title">外観</string>
<string name="settings_category_other_title">その他</string>
<string name="network_error">通信に異常</string>
<string name="network_error">ネットワークエラー</string>
<string name="download_path_audio_title">音楽を保存する場所</string>
<string name="download_path_audio_summary">音楽を保存する位置</string>
<string name="download_path_audio_dialog_title">音楽ファイルをダウンロードする位置を入力して下さい。</string>
<string name="download_path_audio_summary">音楽を保存する場所</string>
<string name="download_path_audio_dialog_title">音楽ファイルをダウンロードする場所を入力して下さい。</string>
<string name="err_dir_create">保存場所 \'%1$s\' を作成できません</string>
<string name="info_dir_created">保存場所 \'%1$s\' を作成しました</string>
@@ -73,7 +73,7 @@
<string name="content">内容</string>
<string name="show_age_restricted_content_title">年齢制限解除</string>
<string name="show_age_restricted_content_title">年齢制限のあるコンテンツを表示する</string>
<string name="video_is_age_restricted">この動画には、年齢制限があります。設定から制限を解除して下さい。</string>
<string name="light_parsing_error">Webサイトを完全には解析できませんでした</string>
@@ -91,34 +91,34 @@
<string name="video">動画</string>
<string name="audio">音楽</string>
<string name="retry">再試行</string>
<string name="storage_permission_denied">記録領域への接続要求が拒否されました</string>
<string name="autoplay_by_calling_app_title">呼び出し</string>
<string name="storage_permission_denied">ストレージへのアクセスが拒否されました</string>
<string name="autoplay_by_calling_app_title">自動再生</string>
<string name="autoplay_by_calling_app_summary">NewPipeが他のアプリケーションから呼び出された際に、自動的に動画を再生します。</string>
<string name="report_error">不具合を報告</string>
<string name="user_report">利用者報告</string>
<string name="duration_live">生放送</string>
<string name="main_bg_subtitle">検索を選択して開始</string>
<string name="main_bg_subtitle">開始するには検索をタップ</string>
<string name="start">開始</string>
<string name="pause">一時停止</string>
<string name="view">表示</string>
<string name="delete">削除</string>
<string name="checksum">整合性検査</string>
<string name="checksum">チェックサム</string>
<string name="add">新しいミッション</string>
<string name="finish">OK</string>
<string name="msg_name">ファイル名</string>
<string name="msg_threads">同時接続数</string>
<string name="msg_error">異常</string>
<string name="msg_error">エラー</string>
<string name="msg_server_unsupported">サーバーが対応していません</string>
<string name="msg_exists">ファイルが既に存在します</string>
<string name="msg_url_malform">URL の形式が正しくないか、通信が利用できません</string>
<string name="msg_running">NewPipeの保存中</string>
<string name="msg_running_detail">詳細はタップ</string>
<string name="msg_wait">暫くお待ちさい</string>
<string name="msg_copied">クリップボードに複製しました</string>
<string name="msg_wait">お待ちください</string>
<string name="msg_copied">クリップボードにコピーしました</string>
<string name="no_available_dir">利用可能な保存場所を選択して下さい</string>
<string name="downloads">保存</string>
@@ -136,13 +136,13 @@
<string name="black_theme_title"></string>
<string name="all"></string>
<string name="channel">チャンネル</string>
<string name="all">すべ</string>
<string name="channel">チャンネル</string>
<string name="short_thousand">K</string>
<string name="short_million">000000</string>
<string name="short_billion">000000000</string>
<string name="short_million">M</string>
<string name="short_billion">B</string>
<string name="yes">はい</string>
<string name="later">後で</string>
@@ -156,10 +156,10 @@
<string name="popup_playing_toast">ポップアップモードで再生中</string>
<string name="use_old_player_title">古いプレーヤーを使用する</string>
<string name="use_old_player_summary">Mediaframework プレーヤーの古いビルド。</string>
<string name="use_old_player_summary">古い内蔵のMediaframeworkプレーヤー</string>
<string name="disabled">無効</string>
<string name="default_video_format_title">お好みのビデオ フォーマット</string>
<string name="default_video_format_title">デフォルトの動画形式</string>
<string name="default_popup_resolution_title">デフォルトのポップアップ解像度</string>
<string name="show_higher_resolutions_title">高い解像度で表示</string>
@@ -172,14 +172,14 @@
<string name="clear">クリア</string>
<string name="popup_remember_size_pos_title">ポップアップのサイズと位置を記憶する</string>
<string name="popup_remember_size_pos_summary">最後のサイズと位置を記憶してポップアップを設定します</string>
<string name="popup_remember_size_pos_summary">前回のポップアップしたサイズと位置を記憶する</string>
<string name="settings_category_popup_title">ポップアップ</string>
<string name="popup_resizing_indicator_title">サイズを変更</string>
<string name="use_external_video_player_summary">このオプションが有効になっているとき、一部の解像度ではオーディオがありません</string>
<string name="player_gesture_controls_title">プレーヤーのジェスチャー コントロール</string>
<string name="player_gesture_controls_summary">プレーヤーの明るさと音量をコントロールするのにジェスチャーを使用します</string>
<string name="player_gesture_controls_summary">ジェスチャーを使用してプレーヤーの明るさと音量をコントロールする</string>
<string name="show_search_suggestions_title">検索候補</string>
<string name="show_search_suggestions_summary">検索時に候補を表示します</string>
@@ -187,18 +187,90 @@
<string name="title_activity_about">NewPipe について</string>
<string name="action_settings">設定</string>
<string name="action_about">アプリについて</string>
<string name="action_about">このアプリについて</string>
<string name="title_licenses">サードパーティー ライセンス</string>
<string name="copyright" formatted="true">© %1$s 作者 %2$s ライセンス %3$s</string>
<string name="error_unable_to_load_license">ライセンスをロードできません</string>
<string name="error_unable_to_load_license">ライセンスを読み込めません</string>
<string name="action_open_website">Web サイトを開く</string>
<string name="tab_about">アプリについて</string>
<string name="tab_about">このアプリについて</string>
<string name="tab_contributors">貢献者</string>
<string name="tab_licenses">ライセンス</string>
<string name="app_description">Androidの無料で軽量な Youtube フロントエンド。</string>
<string name="app_description">Android向けの無料で軽量なYouTubeフロントエンド。</string>
<string name="view_on_github">Github で表示</string>
<string name="app_license_title">NewPipe のライセンス</string>
<string name="contribution_encouragement">アイデア、翻訳、デザインの変更、コードのクリーニング、または本当に重いコードの変更がありますか。ヘルプは常に歓迎します。さらに良いものになりますように!</string>
<string name="contribution_encouragement">翻訳、デザインの変更、コードの整理、動作の重いコードの変更など、アイデアをお持ちではありませんか?ヘルプはいつでも歓迎します。より良いものを一緒に作り上げましょう!</string>
<string name="read_full_license">ライセンスを読む</string>
<string name="contribution_title">貢献</string>
</resources>
<string name="subscribe_button_title">チャンネル登録</string>
<string name="subscribed_button_title">チャンネル登録しました</string>
<string name="channel_unsubscribed">チャンネル登録を解除しました</string>
<string name="subscription_change_failed">チャンネル登録を変更できません</string>
<string name="subscription_update_failed">チャンネル登録を更新できません</string>
<string name="tab_main">メイン</string>
<string name="tab_subscriptions">登録リスト</string>
<string name="fragment_whats_new">新着</string>
<string name="enable_search_history_title">検索履歴</string>
<string name="enable_search_history_summary">検索履歴をローカルに保存します</string>
<string name="enable_watch_history_title">再生履歴</string>
<string name="enable_watch_history_summary">再生した動画を記録します</string>
<string name="resume_on_audio_focus_gain_title">フォーカスで再開</string>
<string name="resume_on_audio_focus_gain_summary">電話などによる中断の後、再生を再開します</string>
<string name="settings_category_player_title">プレーヤー</string>
<string name="show_hold_to_append_summary">動画の詳細ページで背景、またはポップアップボタンが押されたときにヒントを表示する</string>
<string name="settings_category_player_behavior_title">動作</string>
<string name="settings_category_history_title">履歴</string>
<string name="playlist">再生リスト</string>
<string name="undo">元に戻す</string>
<string name="play_all">すべて再生</string>
<string name="notification_channel_name">NewPipeの通知</string>
<string name="unknown_content">[不明]</string>
<string name="player_stream_failure">ストリームの再生に失敗しました</string>
<string name="player_unrecoverable_failure">回復不能な再生エラーが発生しました</string>
<string name="search_no_results">何も見つかりませんでした</string>
<string name="no_subscribers">チャンネル登録なし</string>
<string name="no_videos">動画がありません</string>
<string name="settings_category_downloads_title">保存</string>
<string name="settings_file_charset_title">ファイル名に使用可能な文字</string>
<string name="settings_file_replacement_character_summary">無効な文字は次の値で置き換えられます</string>
<string name="settings_file_replacement_character_title">置換文字</string>
<string name="charset_letters_and_digits">文字と数字</string>
<string name="charset_most_special_characters">ほとんどの特殊文字</string>
<string name="donation_title">寄付</string>
<string name="donation_encouragement">NewPipeはあなたに最高の経験をもたらすため、自由時間を費やしたボランティアによって開発されています。カップのコーヒー(Java)を楽しんでいる間に、開発者がNewPipeをより良いものにすることが出来るよう、今度はお返しをする時間です</string>
<string name="website_title">Webサイト</string>
<string name="website_encouragement">NewPipeに関する詳しい情報や最新のニュースについては、我々のWebサイトをご覧ください。</string>
<string name="title_activity_history">履歴</string>
<string name="title_history_search">検索履歴</string>
<string name="title_history_view">再生履歴</string>
<string name="history_disabled">履歴は無効です</string>
<string name="action_history">履歴</string>
<string name="history_empty">履歴に何もありません</string>
<string name="history_cleared">履歴を消去しました</string>
<string name="item_deleted">アイテムを削除しました</string>
<string name="delete_item_search_history">このアイテムを検索履歴から削除しますか?</string>
<string name="main_page_content">メインページのコンテンツ</string>
<string name="blank_page_summary">空白ページ</string>
<string name="kiosk_page_summary">キオスクページ</string>
<string name="subscription_page_summary">チャンネル登録ページ</string>
<string name="feed_page_summary">フィードページ</string>
<string name="channel_page_summary">チャンネルページ</string>
<string name="select_a_channel">選択したチャンネル</string>
<string name="no_channel_subscribed_yet">購読しているチャンネルはありません</string>
<string name="select_a_kiosk">選択したキオスク</string>
<string name="kiosk">キオスク</string>
<string name="trending">人気</string>
<string name="top_50">トップ50</string>
<string name="title_activity_popup_player">ポップアップ再生</string>
<string name="play_queue_remove">削除</string>
<string name="play_queue_stream_detail">詳細</string>
<string name="play_queue_audio_settings">音声の設定</string>
</resources>

View File

@@ -15,22 +15,22 @@
<string name="choose_browser">브라우저 선택</string>
<string name="screen_rotation">회전</string>
<string name="download_path_title">비디오 다운로드 위치</string>
<string name="download_path_summary">다운로드된 비디오가 저장될 경로를 선택하세요.</string>
<string name="download_path_summary">다운로드된 비디오가 저장될 경로를 선택하세요</string>
<string name="download_path_dialog_title">비디오 다운로드 경로 입력</string>
<string name="default_resolution_title">기본 해상도</string>
<string name="play_with_kodi_title">Kodi로 재생</string>
<string name="kore_not_found">Kore 앱이 발견되지 않았습니다. Kore를 설치할까요?</string>
<string name="show_play_with_kodi_title">\"Kodi로 재생\" 옵션 표시</string>
<string name="show_play_with_kodi_summary">비디오를 Kodi media center를 사용해 재생하는 옵션을 표시합니다.</string>
<string name="show_play_with_kodi_summary">비디오를 Kodi media center를 사용해 재생하는 옵션을 표시합니다</string>
<string name="play_audio">오디오</string>
<string name="default_audio_format_title">기본 오디오 포맷</string>
<string name="webm_description">WebM — 무료 자유 포맷입니다</string>
<string name="m4a_description">m4a — 보다 나은 품질</string>
<string name="default_audio_format_title">기본 오디오 형식</string>
<string name="webm_description">WebM — 공개형 무료 자유 포맷입니다</string>
<string name="m4a_description">m4a — 보다 나은 품질을 제공합니다</string>
<string name="download_dialog_title">다운로드</string>
<string name="next_video_title">다음 비디오</string>
<string name="show_next_and_similar_title">다음 및 유사한 비디오 표시</string>
<string name="url_not_supported_toast">지원하지 않는 URL 입니다</string>
<string name="search_language_title">선호하는 컨텐츠 언어</string>
<string name="search_language_title">기본 컨텐츠 언어</string>
<string name="settings_category_video_audio_title">비디오 &amp; 오디오</string>
<string name="list_thumbnail_view_description">비디오 미리보기 썸네일</string>
@@ -42,8 +42,8 @@
<string name="use_external_audio_player_title">외부 오디오 플레이어 사용</string>
<string name="download_path_audio_title">오디오 다운로드 경로</string>
<string name="download_path_audio_summary">다운로드된 오디오를 저장할 경로입니다.</string>
<string name="download_path_audio_dialog_title">오디오 파일 다운로드 경로를 입력하세요.</string>
<string name="download_path_audio_summary">다운로드된 오디오를 저장할 경로입니다</string>
<string name="download_path_audio_dialog_title">오디오 파일 다운로드 경로를 입력하세요</string>
<string name="theme_title">테마</string>
<string name="dark_theme_title">어두운 테마</string>
@@ -61,24 +61,24 @@
<string name="err_dir_create">다운로드 디렉토리를 만들 수 없습니다 \'%1$s\'</string>
<string name="info_dir_created">다운로드 디렉토리를 만들었습니다 \'%1$s\'</string>
<string name="main_bg_subtitle">검색 버튼을 눌러서 시작하세요</string>
<string name="autoplay_by_calling_app_title">다른 앱에서 호출되었을 경우 자동 재생합니다</string>
<string name="autoplay_by_calling_app_summary">NewPipe가 다른 앱으로부터 호출되었을 경우 비디오를 자동으로 재생합니다.</string>
<string name="autoplay_by_calling_app_title">자동으로 재생</string>
<string name="autoplay_by_calling_app_summary">NewPipe가 다른 앱으로부터 호출되었을 경우 비디오를 자동으로 재생합니다</string>
<string name="content">컨텐츠</string>
<string name="show_age_restricted_content_title">나이 제한이 있는 컨텐츠를 표시</string>
<string name="video_is_age_restricted">비디오에 나이 제한이 걸려있습니다. 설정에서 나이 제한 비디오를 먼저 허용하세요.</string>
<string name="video_is_age_restricted">연령 제한 비디오입니다. 설정 메뉴에서 시청 허용 여부를 변경하실 수 있습니다.</string>
<string name="duration_live">라이브</string>
<string name="general_error">오류</string>
<string name="could_not_load_thumbnails">모든 썸네일을 불러올 수 없습니다</string>
<string name="youtube_signature_decryption_error">비디오 URL 서명을 복호화할 수 없습니다.</string>
<string name="parsing_error">웹사이트를 가져올 수 없습니다.</string>
<string name="light_parsing_error">웹사이트를 완전히 가져올 수 없습니다.</string>
<string name="content_not_available">컨텐츠를 사용할 수 없습니다.</string>
<string name="blocked_by_gema">GEMA에 의해 차단되었습니다.</string>
<string name="could_not_setup_download_menu">다운로드 메뉴를 설할 수 없습니다.</string>
<string name="live_streams_not_supported">이것은 라이브 스트림입니다. 아직 지원되지 않습니다.</string>
<string name="could_not_get_stream">어떠한 스트림도 가져올 수 없습니다.</string>
<string name="sorry_string">죄송합니다.</string>
<string name="youtube_signature_decryption_error">비디오 URL 서명을 복호화할 수 없습니다</string>
<string name="parsing_error">웹사이트를 가져올 수 없습니다</string>
<string name="light_parsing_error">웹사이트를 완전히 가져올 수 없습니다</string>
<string name="content_not_available">컨텐츠를 사용할 수 없습니다</string>
<string name="blocked_by_gema">GEMA에 의해 차단되었습니다</string>
<string name="could_not_setup_download_menu">다운로드 메뉴를 설할 수 없습니다</string>
<string name="live_streams_not_supported">실시간 스트리밍 비디오는 아직 지원되지 않습니다.</string>
<string name="could_not_get_stream">어떠한 스트림도 가져올 수 없습니다</string>
<string name="sorry_string">죄송합니다</string>
<string name="error_report_button_text">이메일을 통해 오류 보고</string>
<string name="error_snackbar_message">죄송합니다. 오류가 발생했습니다.</string>
<string name="error_snackbar_action">보고</string>
@@ -102,4 +102,186 @@
<string name="delete">삭제</string>
<string name="checksum">체크섬</string>
<string name="open_in_popup_mode">팝업 모드에서 열기</string>
<string name="use_external_video_player_summary">이 옵션을 사용할 경우 일부 해상도에서 소리가 나지 않을 수 있습니다</string>
<string name="popup_mode_share_menu_title">뉴파이프 팝업 모드</string>
<string name="subscribe_button_title">구독</string>
<string name="subscribed_button_title">구독됨</string>
<string name="channel_unsubscribed">채널 구독 해제됨</string>
<string name="subscription_change_failed">구독 여부를 변경할 수 없음</string>
<string name="subscription_update_failed">구독을 업데이트할 수 없음</string>
<string name="tab_main">메인 화면</string>
<string name="tab_subscriptions">구독</string>
<string name="fragment_whats_new">새로운 영상</string>
<string name="controls_background_title">배경</string>
<string name="controls_popup_title">팝업</string>
<string name="default_popup_resolution_title">기본 팝업 해상도</string>
<string name="show_higher_resolutions_title">높은 해상도 표시</string>
<string name="show_higher_resolutions_summary">일부 기기에서만 2K/4K 해상도 재생이 지원됩니다</string>
<string name="default_video_format_title">기본 비디오 형식</string>
<string name="black_theme_title">검은 테마</string>
<string name="popup_remember_size_pos_title">팝업 크기 및 위치 기억</string>
<string name="popup_remember_size_pos_summary">마지막으로 사용한 팝업 위치 및 크기를 기억합니다</string>
<string name="player_gesture_controls_title">제스쳐로 재생 조작</string>
<string name="player_gesture_controls_summary">제스쳐를 사용해 화면 밝기와 음량을 조절합니다</string>
<string name="show_search_suggestions_title">검색 제안</string>
<string name="show_search_suggestions_summary">검색 중에 제안을 표시합니다</string>
<string name="enable_search_history_title">검색 기록</string>
<string name="enable_search_history_summary">검색 기록을 기기에 저장합니다</string>
<string name="enable_watch_history_title">기록</string>
<string name="enable_watch_history_summary">시청했던 비디오 기록을 저장</string>
<string name="resume_on_audio_focus_gain_title">초점 복원시 재생 재개</string>
<string name="resume_on_audio_focus_gain_summary">전화 통화 등으로 인해 재생이 중단된 이후에 다시 재생을 시작합니다</string>
<string name="show_hold_to_append_title">눌러서 팁 표시</string>
<string name="show_hold_to_append_summary">비디오 상세 정보 페이지에서 백그라운드 재생 또는 팝업 버튼을 누를 경우 팁 표시</string>
<string name="settings_category_player_title">플레이어</string>
<string name="settings_category_player_behavior_title">동작</string>
<string name="settings_category_history_title">기록</string>
<string name="settings_category_popup_title">팝업</string>
<string name="popup_playing_toast">팝업 모드에서 재생 중</string>
<string name="background_player_append">백그라운드 플레이어에 대기됨</string>
<string name="popup_playing_append">팝업 플레이어에 대기됨</string>
<string name="error_report_title">오류 보고</string>
<string name="all">전부</string>
<string name="channel">채널</string>
<string name="playlist">재생목록</string>
<string name="yes"></string>
<string name="later">나중에</string>
<string name="disabled">해제됨</string>
<string name="filter">필터</string>
<string name="refresh">새로고침</string>
<string name="clear">지우기</string>
<string name="popup_resizing_indicator_title">크기 조절</string>
<string name="best_resolution">최대 해상도</string>
<string name="undo">되돌리기</string>
<string name="play_all">전부 재생</string>
<string name="notification_channel_name">뉴파이프 알림</string>
<string name="notification_channel_description">뉴파이프 백그라운드 및 팝업 플레이어 알림</string>
<string name="unknown_content">[알 수 없음]</string>
<string name="could_not_load_image">이미지를 불러올 수 없습니다</string>
<string name="app_ui_crash">앱/UI 충돌</string>
<string name="player_stream_failure">이 스트림을 재생할 수 없습니다</string>
<string name="player_unrecoverable_failure">복구할 수 없는 플레이어 오류가 발생했습니다</string>
<string name="player_recoverable_failure">플레이어 오류로부터 복구 중</string>
<string name="info_labels">무엇을:\\n요청:\\n컨텐츠 언어:\\n서비스:\\nGMT 기준 시간:\\n패키지:\\n버전:\\n안드로이드 버전:\\nIP주소 범위:</string>
<string name="search_no_results">결과 없음</string>
<string name="empty_subscription_feed_subtitle">구독할 항목을 추가하세요</string>
<string name="use_old_player_title">구형 플레이어 사용</string>
<string name="use_old_player_summary">내장된 구형 Mediaframework 플레이어 사용</string>
<string name="short_thousand"></string>
<string name="short_million">백만</string>
<string name="short_billion">10억</string>
<string name="no_subscribers">구독자 없음</string>
<plurals name="subscribers">
<item quantity="other">%s 구독자</item>
</plurals>
<string name="no_views">시청 횟수 없음</string>
<plurals name="views">
<item quantity="other">%s 시청 횟수</item>
</plurals>
<string name="no_videos">비디오 없음</string>
<plurals name="videos">
<item quantity="other">%s 비디오</item>
</plurals>
<string name="view">재생</string>
<string name="add">새로운 미션</string>
<string name="finish">OK</string>
<string name="msg_name">파일명</string>
<string name="msg_threads">쓰레드</string>
<string name="msg_error">오류</string>
<string name="msg_server_unsupported">지원하지 않는 서버</string>
<string name="msg_exists">파일이 이미 존재합니다</string>
<string name="msg_url_malform">올바르지 않은 URL이거나 인터넷에 접속할 수 없음</string>
<string name="msg_running">뉴파이프 다운로드 중</string>
<string name="msg_running_detail">터치해서 상세 정보 확인</string>
<string name="msg_wait">잠시만 기다려주십시오…</string>
<string name="msg_copied">클립보드에 복사됨</string>
<string name="no_available_dir">다운로드 할 폴더를 선택하세요</string>
<string name="msg_popup_permission">이 권한은 팝업 모드에서
\n열기 위해 필요합니다</string>
<string name="reCaptchaActivity">reCAPTCHA</string>
<string name="recaptcha_request_toast">reCAPTCHA Challenge 요청됨</string>
<string name="settings_category_downloads_title">다운로드</string>
<string name="settings_file_charset_title">파일명에 허용되는 문자</string>
<string name="settings_file_replacement_character_summary">올바르지 않은 문자는 다음 문자로 대체됩니다</string>
<string name="settings_file_replacement_character_title">대체 문자</string>
<string name="charset_letters_and_digits">문자 및 숫자</string>
<string name="charset_most_special_characters">가장 특수한 문자</string>
<string name="title_activity_about">뉴파이프에 대해서</string>
<string name="action_settings">설정</string>
<string name="action_about">뉴파이프</string>
<string name="title_licenses">제3자 라이센스</string>
<string name="copyright" formatted="true">© %3$s 하에서 %2$s 에 의한 %1$s</string>
<string name="error_unable_to_load_license">라이센스 불러올 수 없음</string>
<string name="action_open_website">웹사이트 열기</string>
<string name="tab_about">뉴파이프</string>
<string name="tab_contributors">기여자</string>
<string name="tab_licenses">라이센스</string>
<string name="app_description">안드로이드를 위한 개방/자유/무료 유튜브 프론트엔드 입니다.</string>
<string name="contribution_title">기여</string>
<string name="contribution_encouragement">번역, 디자인, 코딩 등 다양한 기여를 언제나 환영합니다. 향상에 참여해주세요!</string>
<string name="view_on_github">GitHub에서 보기</string>
<string name="donation_title">기부</string>
<string name="donation_encouragement">뉴파이프는 자원봉사자들이 자발적으로 여가 시간을 활용해 개발하고 있습니다. 이제 이러한 노력에 보답할 시간입니다.</string>
<string name="give_back">보답하기</string>
<string name="website_title">웹사이트</string>
<string name="website_encouragement">뉴파이프에 관한 최신 및 상세 정보를 얻으려면 웹사이트를 방문하세요.</string>
<string name="app_license_title">뉴파이프가 채택한 라이센스</string>
<string name="read_full_license">라이센스 읽기</string>
<string name="title_activity_history">기록</string>
<string name="title_history_search">검색함</string>
<string name="title_history_view">시청함</string>
<string name="history_disabled">기록을 사용하지 않습니다</string>
<string name="action_history">기록</string>
<string name="history_empty">기록이 없습니다</string>
<string name="history_cleared">기록이 삭제되었습니다</string>
<string name="item_deleted">항목이 삭제되었습니다</string>
<string name="delete_item_search_history">이 항목을 검색 기록에서 삭제할까요?</string>
<string name="main_page_content">메인 화면의 내용</string>
<string name="blank_page_summary">빈 페이지</string>
<string name="kiosk_page_summary">키오스크 페이지</string>
<string name="subscription_page_summary">구독 페이지</string>
<string name="feed_page_summary">구독 피드 페이지</string>
<string name="channel_page_summary">채널 페이지</string>
<string name="select_a_channel">채널 선택</string>
<string name="no_channel_subscribed_yet">구독중인 채널이 없습니다</string>
<string name="select_a_kiosk">키오스크 선택</string>
<string name="kiosk">키오스크</string>
<string name="trending">인기 급상승</string>
<string name="top_50">탑 50</string>
<string name="new_and_hot">신작 &amp; 뜨는 동영상</string>
<string name="title_activity_background_player">백그라운드 플레이어</string>
<string name="title_activity_popup_player">팝업 플레이어</string>
<string name="play_queue_remove">제거</string>
<string name="play_queue_stream_detail">상세 정보</string>
<string name="play_queue_audio_settings">오디오 설정</string>
<string name="hold_to_append">눌러서 대기 목록에 추가</string>
<string name="enqueue_on_background">백그라운드에 대기</string>
<string name="enqueue_on_popup">팝업에 대기</string>
<string name="start_here_on_main">여기서부터 재생</string>
<string name="start_here_on_background">여기서부터 백그라운드에서 재생</string>
<string name="start_here_on_popup">여기서부터 팝업에 재생</string>
</resources>

View File

@@ -128,15 +128,10 @@
<plurals name="subscribers">
<item quantity="one">%s prenumeratorius</item>
<item quantity="few">%s prenumeratoriai</item>
<item quantity="many"></item>
<item quantity="other"></item>
</plurals>
<plurals name="videos">
<item quantity="one">Vaizdo įrašai</item>
<item quantity="few"></item>
<item quantity="many"></item>
<item quantity="other"></item>
</plurals>
<string name="start">Pradėti</string>
@@ -164,4 +159,124 @@
<string name="reCaptcha_title">reCAPTCHA iššūkis</string>
<string name="recaptcha_request_toast">reCAPTCHA prašomas iššūkis</string>
</resources>
<string name="subscribe_button_title">Prenumeruoti</string>
<string name="subscribed_button_title">Užprenumeruota</string>
<string name="channel_unsubscribed">Kanalas Nebeprenumeruojamas</string>
<string name="subscription_change_failed">Negalima keisti prenumeratos</string>
<string name="subscription_update_failed">Negalima atnaujinti prenumeratos</string>
<string name="tab_main">Pagrindinis</string>
<string name="tab_subscriptions">Prenumeratos</string>
<string name="fragment_whats_new">Kas Naujo</string>
<string name="enable_search_history_title">Ieškoti istorijoje</string>
<string name="enable_search_history_summary">Saugoti paieškos užklausas vietinėje atmintyje</string>
<string name="enable_watch_history_title">Istorija</string>
<string name="enable_watch_history_summary">Sekite peržiūrėtus vaizdo įrašus</string>
<string name="resume_on_audio_focus_gain_title">Atkurti kai dėmesio centre</string>
<string name="resume_on_audio_focus_gain_summary">Tęsti grojimą po pertraukčių (pvz. skambučių)</string>
<string name="show_hold_to_append_title">Rodyti laikyti, kad įtraukti patarimą</string>
<string name="show_hold_to_append_summary">Rodyti patarimą, kai foninis arba langelio rėžimo mygtukas paspaudžiamas vaizdo įrašų detalių puslapyje</string>
<string name="settings_category_player_title">Grotuvas</string>
<string name="settings_category_player_behavior_title">Elgsena</string>
<string name="settings_category_history_title">Istorija</string>
<string name="background_player_append">Foninio grotuvo eilėje</string>
<string name="popup_playing_append">Įtraukta į langelio rėžimo grojimo eilę</string>
<string name="video_is_age_restricted">Apriboto amžiaus vaizdo įrašas. Kad leisti tokius vaizdo įrašus eikite į nustatymus.</string>
<string name="playlist">Grojaraštis</string>
<string name="undo">Atgal</string>
<string name="play_all">Groti viską</string>
<string name="notification_channel_name">NewPipe pranešimai</string>
<string name="notification_channel_description">Foninio ir langelio rėžimo grotuvų pranešimai</string>
<string name="unknown_content">[Nežinoma]</string>
<string name="player_stream_failure">Nepavyko groti šio srauto</string>
<string name="player_unrecoverable_failure">Įvyko nepataisoma grotuvo klaida</string>
<string name="player_recoverable_failure">Atstatoma po grotuvo klaidos</string>
<string name="search_no_results">Nėra rezultatų</string>
<string name="empty_subscription_feed_subtitle">Čia nieko nėra išskyrus svirplius</string>
<string name="storage_permission_denied">Saugyklos prieiga uždrausta</string>
<string name="short_thousand">Tūkst.</string>
<string name="short_million">Mln.</string>
<string name="short_billion">Mlrd.</string>
<string name="no_subscribers">Nėra prenumeratorių</string>
<string name="no_views">Nėra peržiūrų</string>
<plurals name="views">
<item quantity="one">%a peržiūra</item>
</plurals>
<string name="no_videos">Nėra vaizdo įrašų</string>
<string name="view">Groti</string>
<string name="settings_category_downloads_title">Parsisiųsti</string>
<string name="settings_file_charset_title">Leidžiami simboliai bylų varduose</string>
<string name="settings_file_replacement_character_summary">Neleistini simboliai yra pakeičiami šia reikšme</string>
<string name="settings_file_replacement_character_title">Pakaitinis simbolis</string>
<string name="charset_letters_and_digits">Raidės ir skaičiai</string>
<string name="charset_most_special_characters">Ypatingieji simboliai</string>
<string name="title_activity_about">Apie NewPipe</string>
<string name="action_settings">Nustatymai</string>
<string name="action_about">Apie</string>
<string name="title_licenses">Trečiųjų šalių leidimai</string>
<string name="copyright" formatted="true">© %1$s %2$s pagal %3$s</string>
<string name="error_unable_to_load_license">Negalima įkelti leidimo</string>
<string name="action_open_website">Atidaryti interneto puslapį</string>
<string name="tab_about">Apie</string>
<string name="tab_contributors">Pagalbininkai</string>
<string name="tab_licenses">Leidimai</string>
<string name="app_description">Nemokama, atviro kodo Youtube peržiūros programėlė Android sistemai.</string>
<string name="contribution_title">Prisidėti</string>
<string name="contribution_encouragement">Jei turite įdėjų dėl- vertimų, išvaizdos pakeitimų, kodo supaprastinimo, arba rimtų kodo pakeitimų- pagalba visada laukiama.</string>
<string name="view_on_github">Peržiūrėti per GitHub</string>
<string name="donation_title">Paremti</string>
<string name="donation_encouragement">NewPipe yra vystoma savanorių, kurie praleidžia savo laisvą laiką, kad sukurtų geriausią patirtį Jums. Dabar yra laikas paremti juos, kad kūrėjai galėtų NewPipe paversti dar geresne programėle!</string>
<string name="give_back">Duokite grąžos</string>
<string name="website_title">Interneto puslapis</string>
<string name="website_encouragement">Kad sužinotumėte daugiau apie NewPipe apsilankykite mūsų interneto puslapyje.</string>
<string name="app_license_title">NewPipe Leidimas</string>
<string name="read_full_license">Skaityti leidimą</string>
<string name="title_activity_history">Istorija</string>
<string name="title_history_search">Ieškota</string>
<string name="title_history_view">Peržiūrėta</string>
<string name="history_disabled">Istorija išjungta</string>
<string name="action_history">Istorija</string>
<string name="history_empty">Istorija tuščia</string>
<string name="history_cleared">Istorija išvalyta</string>
<string name="item_deleted">Elementas ištrintas</string>
<string name="delete_item_search_history">Ar norite ištrinti šį elementą iš paieškos istorijos?</string>
<string name="main_page_content">Pagrindinio puslapio turinys</string>
<string name="blank_page_summary">Tuščias puslapis</string>
<string name="kiosk_page_summary">Kiosko puslapis</string>
<string name="subscription_page_summary">Prenumeratos puslapis</string>
<string name="feed_page_summary">Srauto puslapis</string>
<string name="channel_page_summary">Kanalo puslapis</string>
<string name="select_a_channel">Pasirinkite kanalą</string>
<string name="no_channel_subscribed_yet">Nė vienas kanalas dar neužprenumeruotas</string>
<string name="select_a_kiosk">Pasirinkite kioską</string>
<string name="kiosk">Kioskas</string>
<string name="trending">Tendencijos</string>
<string name="top_50">Top 50</string>
<string name="new_and_hot">Nauja ir karšta</string>
<string name="title_activity_background_player">Foninis grotuvas</string>
<string name="title_activity_popup_player">Langelio rėžimo grotuvas</string>
<string name="play_queue_remove">Pašalinti</string>
<string name="play_queue_stream_detail">Detalės</string>
<string name="play_queue_audio_settings">Garso nustatymai</string>
<string name="hold_to_append">Laikykite kad įtraukti į eilę</string>
<string name="enqueue_on_background">Įtrauktį į foninio grotuvo eilę</string>
<string name="enqueue_on_popup">Įtraukti į langelio rėžimo grotuvo eilę</string>
<string name="start_here_on_main">Pradėti groti čia</string>
<string name="start_here_on_background">Pradėti groti čia foniniame rėžime</string>
<string name="start_here_on_popup">Pradėti groti čia langelio grotuvo rėžime</string>
</resources>

View File

@@ -298,4 +298,9 @@ te openen in pop-upmodus</string>
<string name="start_here_on_main">Hier beginnen spelen</string>
<string name="start_here_on_background">Hier beginnen in achtergrond</string>
<string name="start_here_on_popup">Hier beginnen in pop-up</string>
</resources>
<string name="donation_title">Doneren</string>
<string name="donation_encouragement">NewPipe wordt door vrijwilligers in hun vrije tijd ontwikkeld om jou de beste ervaring te brengen. Nu is het tijd om terug te geven, zodat onze ontwikkelaars NewPipe nóg beter kunnen maken terwijl ze van hun kopje koffie genieten!</string>
<string name="give_back">Teruggeven</string>
<string name="website_title">Website</string>
<string name="website_encouragement">Bezoek onze website voor meer informatie en het laatste nieuws over NewPipe.</string>
</resources>

View File

@@ -1,6 +1,6 @@
<?xml version='1.0' encoding='UTF-8'?>
<resources>
<string name="main_bg_subtitle">Stuknij wyszukaj, aby rozpocząć</string>
<string name="main_bg_subtitle">Dotknij wyszukaj, aby rozpocząć</string>
<string name="install">Instaluj</string>
<string name="cancel">Anuluj</string>
<string name="open_in_browser">Otwórz w przeglądarce</string>
@@ -30,18 +30,18 @@
<string name="autoplay_by_calling_app_summary">Automatycznie odtwórz video, kiedy NewPipe zostanie wywołany z innej aplikacji</string>
<string name="default_resolution_title">Domyślna rozdzielczość</string>
<string name="play_with_kodi_title">Odtwórz w Kodi</string>
<string name="kore_not_found">Aplikacja Kore nie została znaleziona. Zainstalować Kore?</string>
<string name="kore_not_found">Aplikacja Kore nie została znaleziona. Zainstalować ?</string>
<string name="show_play_with_kodi_title">Pokaż opcję \"Odtwórz z Kodi\"</string>
<string name="show_play_with_kodi_summary">Wyświetl opcję, aby odtworzyć video przez Kodi</string>
<string name="play_audio">Audio</string>
<string name="default_audio_format_title">Domyślny format audio</string>
<string name="webm_description">WebM — otwarty i darmowy format</string>
<string name="m4a_description">m4a — lepsza jakość</string>
<string name="m4a_description">M4A — lepsza jakość</string>
<string name="theme_title">Motyw</string>
<string name="dark_theme_title">Ciemny</string>
<string name="light_theme_title">Jasny</string>
<string name="download_dialog_title">Pobieranie</string>
<string name="download_dialog_title">Pobrane</string>
<string name="next_video_title">Następne video</string>
<string name="show_next_and_similar_title">Pokaż następne i podobne filmy</string>
<string name="url_not_supported_toast">URL nie obsługiwany</string>
@@ -53,39 +53,39 @@
<string name="play_btn_text">Odtwórz</string>
<string name="content">Zawartość</string>
<string name="show_age_restricted_content_title">Pokaż zawartość z ograniczeniem wieku</string>
<string name="video_is_age_restricted">Film jest ograniczony wiekowo. Aktywuj najpierw filmy z ograniczeniem wiekowym w ustawieniach.</string>
<string name="video_is_age_restricted">Film z ograniczeniami wiekowymi. Najpierw zezwól na filmy z ograniczeniem wiekowym w ustawieniach.</string>
<string name="duration_live">Na żywo</string>
<string name="downloads">Pobrania</string>
<string name="downloads_title">Pobrania</string>
<string name="downloads">Pobrane</string>
<string name="downloads_title">Pobrane</string>
<string name="error_report_title">Raport błędu</string>
<string name="general_error">Błąd</string>
<string name="network_error">Błąd sieci</string>
<string name="could_not_load_thumbnails">Nie można załadować wszystkich miniatur</string>
<string name="youtube_signature_decryption_error">Nie można zdeszyfrować sygnatury URL filmu.</string>
<string name="parsing_error">Nie można przetworzyć strony.</string>
<string name="light_parsing_error">Nie można całkowicie przetworzyć strony.</string>
<string name="content_not_available">Zawartość niedostępna.</string>
<string name="blocked_by_gema">Zablokowane przez GEMA.</string>
<string name="could_not_setup_download_menu">Nie można ustawić menu pobierania.</string>
<string name="youtube_signature_decryption_error">Nie można odszyfrować sygnatury URL filmu</string>
<string name="parsing_error">Nie można przetworzyć strony</string>
<string name="light_parsing_error">Całkowicie nie można przetworzyć strony</string>
<string name="content_not_available">Zawartość niedostępna</string>
<string name="blocked_by_gema">Zablokowane przez GEMA</string>
<string name="could_not_setup_download_menu">Nie można ustawić menu pobierania</string>
<string name="live_streams_not_supported">To jest film NA ŻYWO. Te nie są jeszcze wspierane.</string>
<string name="could_not_get_stream">Nie można otrzymać żadnego strumienia.</string>
<string name="could_not_get_stream">Nie można otrzymać żadnego strumienia</string>
<string name="sorry_string">Przepraszamy, to nie powinno mieć miejsca.</string>
<string name="error_report_button_text">Zgłoś błąd przez email</string>
<string name="error_report_button_text">Zgłoś błąd przez email</string>
<string name="error_snackbar_message">Przepraszamy, wystąpiły pewne błędy.</string>
<string name="error_snackbar_action">ZGŁOŚ</string>
<string name="what_device_headline">Info:</string>
<string name="what_happened_headline">Co się stało:</string>
<string name="info_labels">Co:\\nRequest:\\nContent Lang:\\nService:\\nGMT Time:\\nPackage:\\nVersion:\\nOS version:\\nGlob. Zakres IP:</string>
<string name="info_labels">Co:\\nRequest:\\nContent Język:\\nService:\\nGMT Czas:\\nPackage:\\nVersion:\\nOS version:\\nGlob. Zakres IP:</string>
<string name="your_comment">Twój komentarz (po angielsku):</string>
<string name="error_details_headline">Szczegóły:</string>
<string name="list_thumbnail_view_description">Miniatura filmu</string>
<string name="detail_thumbnail_view_description">Miniatura filmu</string>
<string name="detail_uploader_thumbnail_view_description">Miniatura zdjęcia uploadera</string>
<string name="detail_uploader_thumbnail_view_description">Miniatura zdjęcia wysyłającego</string>
<string name="detail_likes_img_view_description">Polubienia</string>
<string name="detail_dislikes_img_view_description">Łapki w dół</string>
<string name="detail_dislikes_img_view_description">To mi się nie podoba</string>
<string name="use_tor_title">Użyj Tor</string>
<string name="report_error">Zgłoś błąd</string>
<string name="user_report">Raport użytkownika</string>
@@ -115,8 +115,8 @@
<string name="msg_running">Pobieranie NewPipe</string>
<string name="msg_running_detail">Dotknij dla szczegółów</string>
<string name="msg_wait">Proszę czekać…</string>
<string name="msg_copied">Skopiowano do schowka.</string>
<string name="no_available_dir">Proszę wybrać dostępny katalog pobierania.</string>
<string name="msg_copied">Skopiowano do schowka</string>
<string name="no_available_dir">Proszę wybrać dostępny katalog pobierania</string>
<string name="could_not_load_image">Nie można załadować obrazu</string>
<string name="app_ui_crash">Aplikacja/Interfejs uległ awarii</string>
@@ -134,10 +134,10 @@
<string name="default_video_format_title">Preferowany format video</string>
<string name="black_theme_title">Czarny</string>
<string name="popup_remember_size_pos_title">Zapamiętaj rozmiar i pozycję trybu okienkowego</string>
<string name="popup_remember_size_pos_summary">Zapamiętaj ostatni rozmiar i pozycję ustawioną dla trybu okienkowego</string>
<string name="popup_remember_size_pos_summary">Zapamiętaj ostatni rozmiar i pozycję trybu okienkowego</string>
<string name="player_gesture_controls_title">Sterowanie odtwarzaczem za pomocą gestów</string>
<string name="player_gesture_controls_summary">Użyj gestów, aby sterować jasnością i głośnością odtwarzacza</string>
<string name="show_search_suggestions_title">Szukaj sugestii</string>
<string name="show_search_suggestions_title">Wyszukaj sugestie</string>
<string name="show_search_suggestions_summary">Pokazuj sugestie podczas wyszukiwania</string>
<string name="settings_category_popup_title">Tryb okienkowy</string>
@@ -153,7 +153,7 @@
<string name="popup_resizing_indicator_title">Zmiana rozmiaru</string>
<string name="use_old_player_title">Użyj starego odtwarzacza</string>
<string name="use_old_player_summary">Stary odtwarzacz wbudowany w Mediaframework.</string>
<string name="use_old_player_summary">Stary odtwarzacz wbudowany w Mediaframework</string>
<string name="short_thousand">K</string>
@@ -164,7 +164,7 @@
\notworzyć w trybie okienkowym</string>
<string name="open_in_popup_mode">Odtwórz w trybie okienkowym</string>
<string name="popup_mode_share_menu_title">NewPipe w trybie okienkowym</string>
<string name="popup_mode_share_menu_title">NewPipe tryb okienkowy</string>
<string name="controls_popup_title">Tryb okienkowy</string>
<string name="best_resolution">Najlepsza rozdzielczość</string>
@@ -181,9 +181,9 @@
<string name="tab_about">O programie</string>
<string name="tab_licenses">Licencje</string>
<string name="app_description">Darmowa, lekka alternatywa Youtube dla Androida.</string>
<string name="view_on_github">Zobacz na Github</string>
<string name="view_on_github">Zobacz na GitHub</string>
<string name="app_license_title">Licencja NewPipe</string>
<string name="contribution_encouragement">Jeżeli masz pomysł na tłumaczenie, zmiany w wyglądzie aplikacji, czyszczenie kodu źródłowego, pomoc jest zawsze chętnie widziana. Im więcej jest zrobione, tym lepiej!</string>
<string name="contribution_encouragement">Jeżeli masz pomysł na tłumaczenie, zmiany w wyglądzie aplikacji, oczyszczenie kodu źródłowego, pomoc jest zawsze mile widziana. Im więcej jest zrobione, tym lepiej!</string>
<string name="read_full_license">Przeczytaj licencję</string>
<string name="contribution_title">Wkład</string>
<string name="settings_file_charset_title">Dozwolone znaki w nazwach plików</string>
@@ -203,14 +203,14 @@
<string name="enable_search_history_title">Historia wyszukiwania</string>
<string name="enable_search_history_summary">Zapisuj lokalnie historię wyszukiwania</string>
<string name="enable_watch_history_title">Historia oglądania</string>
<string name="enable_watch_history_title">Historia</string>
<string name="enable_watch_history_summary">Zapisuj historię oglądania</string>
<string name="resume_on_audio_focus_gain_title"/>
<string name="resume_on_audio_focus_gain_title">Wznów gdy na pierwszym planie</string>
<string name="resume_on_audio_focus_gain_summary">Kontynuuj odtwarzanie po przerwaniu (np. po rozmowie telefonicznej)</string>
<string name="notification_channel_name">Notyfikacja NewPipe</string>
<string name="notification_channel_description">Notyfikacje dla NewPipe w tle i odtwarzacza w okienku</string>
<string name="notification_channel_description">Powiadomienia dla odtwarzacza NewPipe w tle i w okienku</string>
<string name="tab_contributors">Współautorzy</string>
<string name="title_activity_history">Historia</string>
@@ -218,7 +218,7 @@
<string name="title_history_view">Obejrzane</string>
<string name="history_disabled">Historia jest wyłączona</string>
<string name="action_history">Historia</string>
<string name="history_empty">Historia jest pusta.</string>
<string name="history_empty">Historia jest pusta</string>
<string name="history_cleared">Historia została wyczyszczona</string>
<string name="settings_category_player_title">Odtwarzacz</string>
@@ -229,4 +229,71 @@
<string name="search_no_results">Brak wyników</string>
<string name="no_views">Brak wyświetleń</string>
</resources>
<string name="show_hold_to_append_title">Pokaż wskazówkę „Przytrzymaj, aby Dodać”</string>
<string name="show_hold_to_append_summary">Pokaż wskazówkę, podczas naciśnięcia odtwarzania na stronie szczegółów filmu</string>
<string name="background_player_append">W kolejce odtwarzania w tle</string>
<string name="popup_playing_append">W kolejce odtwarzania okienkowego</string>
<string name="play_all">Odtwórz Wszystkie</string>
<string name="unknown_content">[Nieznany]</string>
<string name="player_stream_failure">Nie udało się odtworzyć tego strumienia</string>
<string name="player_unrecoverable_failure">Wystąpił nieodwracalny błąd odtwarzacza</string>
<string name="player_recoverable_failure">Odzyskiwanie po błędzie odtwarzacza</string>
<string name="empty_subscription_feed_subtitle">Nic tu nie ma. Słychać świerszcze...</string>
<string name="no_subscribers">Brak subskrybentów</string>
<plurals name="subscribers">
<item quantity="one">%s subskrybent</item>
<item quantity="few">%s subskrybentów</item>
<item quantity="other">%s subskrybentów</item>
</plurals>
<plurals name="views">
<item quantity="one">%s odtworzenie</item>
<item quantity="other">%s odtworzeń</item>
</plurals>
<string name="no_videos">Brak filmów</string>
<plurals name="videos">
<item quantity="one">%s film</item>
<item quantity="few">%s filmów</item>
</plurals>
<string name="charset_most_special_characters">Większość znaków specjalnych</string>
<string name="donation_title">Dotacja</string>
<string name="donation_encouragement">NewPipe rozwijane jest przez wolontariuszy, którzy poświęcają swój wolny czas by zapewnić Ci jak najlepsze wrażenia podczas korzystania z aplikacji. To dobry moment aby wesprzeć programistów i sprawić, aby program był jeszcze lepszy, nie przerywając przy tym popijania kawy!</string>
<string name="give_back">Daj od siebie</string>
<string name="website_title">Witryna</string>
<string name="website_encouragement">By otrzymać więcej informacji oraz najnowsze wiadomości o NewPipe, odwiedź naszą stronę.</string>
<string name="item_deleted">Pozycja usunięta</string>
<string name="delete_item_search_history">Czy chcesz usunąć tę pozycję z historii wyszukiwania?</string>
<string name="main_page_content">Zawartość strony głównej</string>
<string name="blank_page_summary">Pusta Strona</string>
<string name="kiosk_page_summary">Strona Kiosk</string>
<string name="subscription_page_summary">Strona Subskrypcji</string>
<string name="feed_page_summary">Strona Kanału</string>
<string name="channel_page_summary">Strona kanału</string>
<string name="select_a_channel">Wybierz kanał</string>
<string name="no_channel_subscribed_yet">Brak subskrybowanych kanałów</string>
<string name="select_a_kiosk">Wybierz „kiosk”</string>
<string name="kiosk">„Kiosk”</string>
<string name="trending">Na czasie</string>
<string name="top_50">Najlepsze 50</string>
<string name="new_and_hot">Nowe i gorące</string>
<string name="title_activity_background_player">Odtwarzacz w Tle</string>
<string name="title_activity_popup_player">Odtwarzacz w Okienku</string>
<string name="play_queue_remove">Usuń</string>
<string name="play_queue_stream_detail">Szczegóły</string>
<string name="play_queue_audio_settings">Ustawienia Dźwięku</string>
<string name="hold_to_append">Przytrzymaj by dodać do listy</string>
<string name="enqueue_on_background">Dodaj do Kolejki w Tle</string>
<string name="enqueue_on_popup">Dodaj do Kolejki Okienka</string>
<string name="start_here_on_main">Zacznij Odtwarzanie Tutaj</string>
<string name="start_here_on_background">Zacznij Odwarzanie Tutaj — w Tle</string>
<string name="start_here_on_popup">Zacznij Odtwarzanie Tutaj — w Okienku</string>
</resources>

View File

@@ -280,7 +280,7 @@ abrir em modo popup</string>
<string name="start_here_on_background">Iniciar aqui em plano de fundo</string>
<string name="start_here_on_popup">Iniciar aqui em popup</string>
<string name="donation_title">Doar</string>
<string name="donation_encouragement">NewPipe é desenvolvido por voluntários que investem seu tempo livre para trazer a melhor experiência para você. Agora é a hora de retribuir o favor e ter certeza que os desenvolvedores podem fazer com que o NewPipe fique ainda melhor enquanto desfrutam uma xícara de café!</string>
<string name="donation_encouragement">NewPipe é desenvolvido por voluntários que gastam seu tempo livre para trazer a melhor experiência para você. Agora é a hora de retribuir o favor e ter certeza que os desenvolvedores podem fazer com que o NewPipe fique ainda melhor enquanto desfrutam uma xícara de café!</string>
<string name="give_back">Retribuir</string>
<string name="website_title">Site oficial</string>
<string name="website_encouragement">Para obter mais informações e as últimas notícias sobre o NewPipe visite nosso Site.</string>

View File

@@ -7,7 +7,7 @@
<string name="cancel">Cancelar</string>
<string name="open_in_browser">Abrir no navegador</string>
<string name="share">Partilhar</string>
<string name="download">Transferir</string>
<string name="download">Descarregar</string>
<string name="search">Pesquisar</string>
<string name="settings">Definições</string>
<string name="did_you_mean">Será que queria dizer: %1$s?</string>
@@ -16,12 +16,12 @@
<string name="screen_rotation">rotação</string>
<string name="use_external_video_player_title">Utilizar reprodutor de vídeo externo</string>
<string name="use_external_audio_player_title">Utilizar reprodutor de áudio externo</string>
<string name="download_path_title">Local de transferência de vídeo</string>
<string name="download_path_summary">Local para guardar os vídeos transferidos</string>
<string name="download_path_dialog_title">Introduza o caminho para os vídeos</string>
<string name="download_path_title">Local para a descarga de vídeos</string>
<string name="download_path_summary">Local para guardar os vídeos descarregados</string>
<string name="download_path_dialog_title">Digite o caminho para os vídeos</string>
<string name="default_resolution_title">Resolução padrão</string>
<string name="play_with_kodi_title">Reproduzir no Kodi</string>
<string name="kore_not_found">Aplicação Kore não encontrada. Quer instalá-la?</string>
<string name="kore_not_found">Aplicação Kore não encontrada. Instalar?</string>
<string name="show_play_with_kodi_title">Mostrar opção \"Reproduzir no Kodi\"</string>
<string name="show_play_with_kodi_summary">Mostra uma opção para reproduzir o vídeo no Kodi</string>
<string name="play_audio">Áudio</string>
@@ -52,9 +52,9 @@
<string name="use_tor_title">Usar Tor</string>
<string name="use_tor_summary">(Experimental) Usar a rede Tor para aumentar a privacidade (ainda não é suportada a emissão de vídeos).</string>
<string name="download_path_audio_title">Local de transferência de áudio</string>
<string name="download_path_audio_summary">Local para guardar o áudio transferido.</string>
<string name="download_path_audio_dialog_title">Introduza o caminho para os ficheiros de áudio</string>
<string name="download_path_audio_title">Local para a descarga de áudio</string>
<string name="download_path_audio_summary">Local para guardar o áudio descarregado</string>
<string name="download_path_audio_dialog_title">Digite o caminho para os ficheiros de áudio</string>
<string name="err_dir_create">Não foi possível criar o diretório \'%1$s\'</string>
<string name="info_dir_created">Diretório \'%1$s\' criado com sucesso</string>
@@ -165,7 +165,7 @@ o modo “popup“</string>
<string name="refresh">Atualizar</string>
<string name="clear">Limpar</string>
<string name="controls_background_title">Em segundo plano</string>
<string name="use_external_video_player_summary">Algumas resoluções NÃO terão áudio quando esta opção estiver ativada</string>
<string name="use_external_video_player_summary">Algumas resoluções não terão áudio se esta opção estiver ativa</string>
<string name="popup_remember_size_pos_summary">Lembrar último tamanho e posição do popup</string>
<string name="popup_resizing_indicator_title">Redimensionar</string>
@@ -201,7 +201,7 @@ o modo “popup“</string>
<string name="tab_main">Principal</string>
<string name="tab_subscriptions">Subscrições</string>
<string name="fragment_whats_new">O que há de novo</string>
<string name="fragment_whats_new">Novidades</string>
<string name="enable_search_history_title">Histórico de Pesquisa</string>
<string name="enable_search_history_summary">Armazenar termos de pesquisa localmente</string>

View File

@@ -236,24 +236,21 @@
<plurals name="subscribers">
<item quantity="one">%s подписчик</item>
<item quantity="few">%s подписчика</item>
<item quantity="many">%s подписчиков</item>
<item quantity="other"/>
<item quantity="other">%s подписчиков</item>
</plurals>
<string name="no_views">Нет просмотров</string>
<plurals name="views">
<item quantity="one">%s просмотр</item>
<item quantity="few">%s просмотра</item>
<item quantity="many">%s просмотров</item>
<item quantity="other"/>
<item quantity="other">%s просмотров</item>
</plurals>
<string name="no_videos">Нет видео</string>
<plurals name="videos">
<item quantity="one">%s видео</item>
<item quantity="few">%s видео</item>
<item quantity="many">%s видео</item>
<item quantity="other"/>
<item quantity="other">%s видео</item>
</plurals>
<string name="item_deleted">Элемент удалён</string>

View File

@@ -33,7 +33,7 @@
<string name="play_audio">Zvuk</string>
<string name="default_audio_format_title">Predvolený zvukový formát</string>
<string name="webm_description">WebM — voľný formát</string>
<string name="m4a_description">m4a — lepšia kvalita</string>
<string name="m4a_description">M4A — lepšia kvalita</string>
<string name="theme_title">Téma</string>
<string name="dark_theme_title">Tmavá</string>
<string name="light_theme_title">Svetlá</string>
@@ -128,7 +128,7 @@
<string name="reCaptchaActivity">reCAPTCHA</string>
<string name="reCaptcha_title">Výzva reCAPTCHA</string>
<string name="black_theme_title">Tmavá</string>
<string name="black_theme_title">Čierna</string>
<string name="all">Všetko</string>
<string name="channel">Kanály</string>
@@ -247,24 +247,21 @@ otvorenie okna na popredí</string>
<plurals name="subscribers">
<item quantity="one">%s odberateľ</item>
<item quantity="few">%s odberatelia</item>
<item quantity="many">%s odberateľov</item>
<item quantity="other"></item>
<item quantity="other">%s odberateľov</item>
</plurals>
<string name="no_views">Žiadne zobrazenia</string>
<plurals name="views">
<item quantity="one">%s zobrazenie</item>
<item quantity="few">%s zobrazenia</item>
<item quantity="many">%s zobrazení</item>
<item quantity="other"></item>
<item quantity="other">%s zobrazení</item>
</plurals>
<string name="no_videos">Žiadne videá</string>
<plurals name="videos">
<item quantity="one">%s video</item>
<item quantity="few">%s videá</item>
<item quantity="many">%s videí</item>
<item quantity="other"></item>
<item quantity="other">%s videí</item>
</plurals>
<string name="item_deleted">Položka bola odstránená</string>

View File

@@ -227,7 +227,7 @@ odpiranje v pojavnem načinu</string>
<string name="notification_channel_name">Obvestila NewPipe</string>
<string name="notification_channel_description">Obvestila predvajalnika NewPipe</string>
<string name="contribution_title">Sodelovanje pri projektu</string>
<string name="contribution_title">Doprinos k projektu</string>
<string name="title_activity_history">Zgodovina</string>
<string name="title_history_search">Preiskano</string>
@@ -291,4 +291,6 @@ odpiranje v pojavnem načinu</string>
<string name="play_queue_remove">Odstrani</string>
<string name="play_queue_stream_detail">Podrobnosti</string>
<string name="play_queue_audio_settings">Nastavitve zvoka</string>
<string name="donation_title">Donacija</string>
<string name="website_title">Spletišče</string>
</resources>

View File

@@ -242,7 +242,7 @@
<string name="app_license_title">NewPipes licens</string>
<string name="contribution_encouragement">Vad du än har för idéer gällande översättning, designändringar, kod rengöring eller riktigt tunga så är hjälp alltid välkommet. Ju mer som görs desto bättre blir det!</string>
<string name="read_full_license">Läs hela licensen</string>
<string name="contribution_title">Bidrag</string>
<string name="contribution_title">Bidra</string>
<string name="title_activity_history">Historik</string>
<string name="title_history_search">Sökt</string>
@@ -266,7 +266,7 @@
<string name="kiosk">Kiosk</string>
<string name="trending">Trend</string>
<string name="top_50">Top 50</string>
<string name="top_50">Topp 50</string>
<string name="new_and_hot">Aktuellt</string>
<string name="title_activity_background_player">Bakgrunds-spelare</string>
<string name="title_activity_popup_player">Popup-spelare</string>
@@ -279,4 +279,9 @@
<string name="start_here_on_main">Börja spela här</string>
<string name="start_here_on_background">Börja här i bakgrunden</string>
<string name="start_here_on_popup">Börja här i popup</string>
</resources>
<string name="donation_title">Donera</string>
<string name="donation_encouragement">NewPipe utvecklas av frivilliga som spenderar sin fritid på att ge dig den bästa användarupplevelsen. Nu är det tid att ge tillbaka för att säkerställa att utvecklarna kan göra NewPipe ännu bättre medan de njuter av en kopp kaffe!</string>
<string name="give_back">Ge tillbaka</string>
<string name="website_title">Webbplats</string>
<string name="website_encouragement">För att få mer information och de senaste nyheterna om NewPipe, besök vår webbplats.</string>
</resources>

View File

@@ -1,7 +1,7 @@
<?xml version='1.0' encoding='UTF-8'?>
<resources>
<string name="main_bg_subtitle">தொடங்குவதற்கு தேடல் பொத்தானை அழுத்தவும்</string>
<string name="view_count_text">"%1$ பார்வைகள்"</string>
<string name="view_count_text">"%1$s பார்வைகள்"</string>
<string name="upload_date_text">"%1$s அன்று வெளியிடப்பட்டது"</string>
<string name="no_player_found">ஸ்டீரீம் பிளேயர் கண்டறியப்படவில்லை. வில்சி நிருவ வேண்டுமா?</string>
<string name="install">நிறுவ</string>

View File

@@ -2,7 +2,7 @@
<resources>
<string name="main_bg_subtitle">ప్రారంభించడానికి శోధనను క్లిక్</string>
<string name="view_count_text">%1$s వీక్షణలు</string>
<string name="upload_date_text">%1$\ts ప్రచురించబడింది</string>
<string name="upload_date_text">%1$s ప్రచురించబడింది</string>
<string name="install">ఇన్స్టాల్</string>
<string name="cancel">రద్దు చేయి</string>
<string name="open_in_browser">బ్రౌజర్ తెరవండి</string>

View File

@@ -17,7 +17,7 @@
<string name="use_external_video_player_title">Sử dụng trình phát video bên ngoài</string>
<string name="use_external_video_player_summary">Một số độ phân giải sẽ KHÔNG có âm thanh khi chế độ này</string>
<string name="use_external_audio_player_title">Sử dụng trình phát âm thanh bên ngoài</string>
<string name="popup_mode_share_menu_title">Chế độ Popup của NewPipe</string>
<string name="popup_mode_share_menu_title">Chế độ popup của NewPipe</string>
<string name="controls_popup_title">Chế độ Popup</string>
<string name="download_path_title">Đường dẫn tải xuống video</string>
@@ -183,4 +183,10 @@
<string name="settings_category_history_title">Lịch sử</string>
<string name="playlist">Danh sách</string>
<string name="search_no_results">Không tìm thấy</string>
<string name="subscribe_button_title">Theo dõi</string>
<string name="subscribed_button_title">Đang theo dõi</string>
<string name="channel_unsubscribed">Đã dừng theo dõi kênh</string>
<string name="subscription_change_failed">Không thể thay đổi tình trạng theo dõi</string>
<string name="subscription_update_failed">Không thể cập nhật tình trạng theo dõi</string>
</resources>

View File

@@ -46,6 +46,13 @@
<item>144p</item>
</string-array>
<string-array name="service_list" translatable="false">
<item>@string/youtube</item>
<item>@string/soundcloud</item>
</string-array>
<string name="service_key" translatable="false">service</string>
<string name="default_service_value" translatable="false">@string/youtube</string>
<string name="video_mp4_key" translatable="false">video_mp4</string>
<string name="video_webm_key" translatable="false">video_webm</string>
<string name="video_3gp_key" translatable="false">video_3gp</string>
@@ -100,7 +107,9 @@
<string name="show_next_video_key" translatable="false">show_next_video</string>
<string name="show_hold_to_append_key" translatable="false">show_hold_to_append</string>
<string name="default_language_value">en</string>
<string name="default_country_value">GB</string>
<string name="search_language_key" translatable="false">search_language</string>
<string name="content_country_key" translatable="false">content_country</string>
<string name="show_age_restricted_content" translatable="false">show_age_restricted_content</string>
<string name="use_tor_key" translatable="false">use_tor</string>
<string name="enable_search_history_key" translatable="false">enable_search_history</string>
@@ -140,7 +149,6 @@
<string name="default_file_charset_value" translatable="false">@string/charset_most_special_characters_value</string>
<!-- TODO: scrape these programmatically, then store in a local cache -->
<!-- alternatively, load these from some local android data store -->
<string-array name="language_codes" translatable="false">
<item>af</item>
@@ -300,4 +308,505 @@
<item>日本語</item>
<item>한국어</item>
</string-array>
<string-array name="country_names" translatable="false">
<item>Afghanistan</item>
<item>Aland Islands</item>
<item>Albania</item>
<item>Algeria</item>
<item>American Samoa</item>
<item>Andorra</item>
<item>Angola</item>
<item>Anguilla</item>
<item>Antarctica</item>
<item>Antiguaand Barbuda</item>
<item>Argentina</item>
<item>Armenia</item>
<item>Aruba</item>
<item>Australia</item>
<item>Austria</item>
<item>Azerbaijan</item>
<item>Bahamas</item>
<item>Bahrain</item>
<item>Bangladesh</item>
<item>Barbados</item>
<item>Belarus</item>
<item>Belgium</item>
<item>Belize</item>
<item>Benin</item>
<item>Bermuda</item>
<item>Bhutan</item>
<item>Bolivia</item>
<item>Bosniaand Herzegovina</item>
<item>Botswana</item>
<item>BouvetIsland</item>
<item>Brazil</item>
<item>British Virgin Islands</item>
<item>British Indian Ocean Territory</item>
<item>Brunei Darussalam</item>
<item>Bulgaria</item>
<item>Burkina Faso</item>
<item>Burundi</item>
<item>Cambodia</item>
<item>Cameroon</item>
<item>Canada</item>
<item>CapeVerde</item>
<item>Cayman Islands</item>
<item>Central African Republic</item>
<item>Chad</item>
<item>Chile</item>
<item>China</item>
<item>HongKong, China</item>
<item>Macao,China</item>
<item>Christmas Island</item>
<item>Cocos(Keeling) Islands</item>
<item>Colombia</item>
<item>Comoros</item>
<item>Congo(Brazzaville)</item>
<item>Congo, (Kinshasa)</item>
<item>Cook Islands</item>
<item>CostaRica</item>
<item>Côted'Ivoire</item>
<item>Croatia</item>
<item>Cuba</item>
<item>Cyprus</item>
<item>Czech Republic</item>
<item>Denmark</item>
<item>Djibouti</item>
<item>Dominica</item>
<item>Dominican Republic</item>
<item>Ecuador</item>
<item>Egypt</item>
<item>ElSalvador</item>
<item>EquatorialGuinea</item>
<item>Eritrea</item>
<item>Estonia</item>
<item>Ethiopia</item>
<item>Falkland Islands (Malvinas)</item>
<item>Faroe Islands</item>
<item>Fiji</item>
<item>Finland</item>
<item>France</item>
<item>French Guiana</item>
<item>French Polynesia</item>
<item>French Southern Territories</item>
<item>Gabon</item>
<item>Gambia</item>
<item>Georgia</item>
<item>Germany</item>
<item>Ghana</item>
<item>Gibraltar</item>
<item>Greece</item>
<item>Greenland</item>
<item>Grenada</item>
<item>Guadeloupe</item>
<item>Guam</item>
<item>Guatemala</item>
<item>Guernsey</item>
<item>Guinea</item>
<item>Guinea-Bissau</item>
<item>Guyana</item>
<item>Haiti</item>
<item>Heardand Mcdonald Islands</item>
<item>HolySee (Vatican City State)</item>
<item>Honduras</item>
<item>Hungary</item>
<item>Iceland</item>
<item>India</item>
<item>Indonesia</item>
<item>Iran</item>
<item>Iraq</item>
<item>Ireland</item>
<item>Isleof Man</item>
<item>Israel</item>
<item>Italy</item>
<item>Jamaica</item>
<item>Japan</item>
<item>Jersey</item>
<item>Jordan</item>
<item>Kazakhstan</item>
<item>Kenya</item>
<item>Kiribati</item>
<item>Korea(North)</item>
<item>Korea(South)</item>
<item>Kuwait</item>
<item>Kyrgyzstan</item>
<item>Lao</item>
<item>Latvia</item>
<item>Lebanon</item>
<item>Lesotho</item>
<item>Liberia</item>
<item>Libya</item>
<item>Liechtenstein</item>
<item>Lithuania</item>
<item>Luxembourg</item>
<item>Macedonia</item>
<item>Madagascar</item>
<item>Malawi</item>
<item>Malaysia</item>
<item>Maldives</item>
<item>Mali</item>
<item>Malta</item>
<item>MarshallIslands</item>
<item>Martinique</item>
<item>Mauritania</item>
<item>Mauritius</item>
<item>Mayotte</item>
<item>Mexico</item>
<item>Micronesia</item>
<item>Moldova</item>
<item>Monaco</item>
<item>Mongolia</item>
<item>Montenegro</item>
<item>Montserrat</item>
<item>Morocco</item>
<item>Mozambique</item>
<item>Myanmar</item>
<item>Namibia</item>
<item>Nauru</item>
<item>Nepal</item>
<item>Netherlands</item>
<item>Netherlands Antilles</item>
<item>New Caledonia</item>
<item>New Zealand</item>
<item>Nicaragua</item>
<item>Niger</item>
<item>Nigeria</item>
<item>Niue</item>
<item>Norfolk Island</item>
<item>Northern Mariana Islands</item>
<item>Norway</item>
<item>Oman</item>
<item>Pakistan</item>
<item>Palau</item>
<item>Palestinian Territory</item>
<item>Panama</item>
<item>Papua New Guinea</item>
<item>Paraguay</item>
<item>Peru</item>
<item>Philippines</item>
<item>Pitcairn</item>
<item>Poland</item>
<item>Portugal</item>
<item>PuertoRico</item>
<item>Qatar</item>
<item>Réunion</item>
<item>Romania</item>
<item>Russian Federation</item>
<item>Rwanda</item>
<item>Saint-Barthélemy</item>
<item>Saint Helena</item>
<item>Saint KittsandNevis</item>
<item>SaintLucia</item>
<item>Saint-Martin(Frenchpart)</item>
<item>SaintPierreandMiquelon</item>
<item>Saint Vincentand Grenadines</item>
<item>Samoa</item>
<item>San Marino</item>
<item>Sao Tomeand Principe</item>
<item>SaudiArabia</item>
<item>Senegal</item>
<item>Serbia</item>
<item>Seychelles</item>
<item>SierraLeone</item>
<item>Singapore</item>
<item>Slovakia</item>
<item>Slovenia</item>
<item>SolomonIslands</item>
<item>Somalia</item>
<item>SouthAfrica</item>
<item>South Georgiaandthe South Sandwich Islands</item>
<item>South Sudan</item>
<item>Spain</item>
<item>Sri Lanka</item>
<item>Sudan</item>
<item>Suriname</item>
<item>Svalbardand Jan Mayen Islands</item>
<item>Swaziland</item>
<item>Sweden</item>
<item>Switzerland</item>
<item>Syrian ArabRepublic(Syria)</item>
<item>Taiwan, Republicof China</item>
<item>Tajikistan</item>
<item>Tanzania</item>
<item>Thailand</item>
<item>Timor-Leste</item>
<item>Togo</item>
<item>Tokelau</item>
<item>Tonga</item>
<item>Trinidadand Tobago</item>
<item>Tunisia</item>
<item>Turkey</item>
<item>Turkmenistan</item>
<item>Turksand Caicos Islands</item>
<item>Tuvalu</item>
<item>Uganda</item>
<item>Ukraine</item>
<item>United Arab Emirates</item>
<item>United Kingdom</item>
<item>USA</item>
<item>Minor Outlying Islands</item>
<item>Uruguay</item>
<item>Uzbekistan</item>
<item>Vanuatu</item>
<item>Venezuela (BolivarianRepublic)</item>
<item>VietNam</item>
<item>Virgin Islands,</item>
<item>Wallisand Futuna Islands</item>
<item>Western Sahara</item>
<item>Yemen</item>
<item>Zambia</item>
<item>Zimbabwe</item>
</string-array>
<string-array name="country_codes" translatable="false">
<item>AF</item>
<item>AX</item>
<item>AL</item>
<item>DZ</item>
<item>AS</item>
<item>AD</item>
<item>AO</item>
<item>AI</item>
<item>AQ</item>
<item>AG</item>
<item>AR</item>
<item>AM</item>
<item>AW</item>
<item>AU</item>
<item>AT</item>
<item>AZ</item>
<item>BS</item>
<item>BH</item>
<item>BD</item>
<item>BB</item>
<item>BY</item>
<item>BE</item>
<item>BZ</item>
<item>BJ</item>
<item>BM</item>
<item>BT</item>
<item>BO</item>
<item>BA</item>
<item>BW</item>
<item>BV</item>
<item>BR</item>
<item>VG</item>
<item>IO</item>
<item>BN</item>
<item>BG</item>
<item>BF</item>
<item>BI</item>
<item>KH</item>
<item>CM</item>
<item>CA</item>
<item>CV</item>
<item>KY</item>
<item>CF</item>
<item>TD</item>
<item>CL</item>
<item>CN</item>
<item>HK</item>
<item>MO</item>
<item>CX</item>
<item>CC</item>
<item>CO</item>
<item>KM</item>
<item>CG</item>
<item>CD</item>
<item>CK</item>
<item>CR</item>
<item>CI</item>
<item>HR</item>
<item>CU</item>
<item>CY</item>
<item>CZ</item>
<item>DK</item>
<item>DJ</item>
<item>DM</item>
<item>DO</item>
<item>EC</item>
<item>EG</item>
<item>SV</item>
<item>GQ</item>
<item>ER</item>
<item>EE</item>
<item>ET</item>
<item>FK</item>
<item>FO</item>
<item>FJ</item>
<item>FI</item>
<item>FR</item>
<item>GF</item>
<item>PF</item>
<item>TF</item>
<item>GA</item>
<item>GM</item>
<item>GE</item>
<item>DE</item>
<item>GH</item>
<item>GI</item>
<item>GR</item>
<item>GL</item>
<item>GD</item>
<item>GP</item>
<item>GU</item>
<item>GT</item>
<item>GG</item>
<item>GN</item>
<item>GW</item>
<item>GY</item>
<item>HT</item>
<item>HM</item>
<item>VA</item>
<item>HN</item>
<item>HU</item>
<item>IS</item>
<item>IN</item>
<item>ID</item>
<item>IR</item>
<item>IQ</item>
<item>IE</item>
<item>IM</item>
<item>IL</item>
<item>IT</item>
<item>JM</item>
<item>JP</item>
<item>JE</item>
<item>JO</item>
<item>KZ</item>
<item>KE</item>
<item>KI</item>
<item>KP</item>
<item>KR</item>
<item>KW</item>
<item>KG</item>
<item>LA</item>
<item>LV</item>
<item>LB</item>
<item>LS</item>
<item>LR</item>
<item>LY</item>
<item>LI</item>
<item>LT</item>
<item>LU</item>
<item>MK</item>
<item>MG</item>
<item>MW</item>
<item>MY</item>
<item>MV</item>
<item>ML</item>
<item>MT</item>
<item>MH</item>
<item>MQ</item>
<item>MR</item>
<item>MU</item>
<item>YT</item>
<item>MX</item>
<item>FM</item>
<item>MD</item>
<item>MC</item>
<item>MN</item>
<item>ME</item>
<item>MS</item>
<item>MA</item>
<item>MZ</item>
<item>MM</item>
<item>NA</item>
<item>NR</item>
<item>NP</item>
<item>NL</item>
<item>AN</item>
<item>NC</item>
<item>NZ</item>
<item>NI</item>
<item>NE</item>
<item>NG</item>
<item>NU</item>
<item>NF</item>
<item>MP</item>
<item>NO</item>
<item>OM</item>
<item>PK</item>
<item>PW</item>
<item>PS</item>
<item>PA</item>
<item>PG</item>
<item>PY</item>
<item>PE</item>
<item>PH</item>
<item>PN</item>
<item>PL</item>
<item>PT</item>
<item>PR</item>
<item>QA</item>
<item>RE</item>
<item>RO</item>
<item>RU</item>
<item>RW</item>
<item>BL</item>
<item>SH</item>
<item>KN</item>
<item>LC</item>
<item>MF</item>
<item>PM</item>
<item>VC</item>
<item>WS</item>
<item>SM</item>
<item>ST</item>
<item>SA</item>
<item>SN</item>
<item>RS</item>
<item>SC</item>
<item>SL</item>
<item>SG</item>
<item>SK</item>
<item>SI</item>
<item>SB</item>
<item>SO</item>
<item>ZA</item>
<item>GS</item>
<item>SS</item>
<item>ES</item>
<item>LK</item>
<item>SD</item>
<item>SR</item>
<item>SJ</item>
<item>SZ</item>
<item>SE</item>
<item>CH</item>
<item>SY</item>
<item>TW</item>
<item>TJ</item>
<item>TZ</item>
<item>TH</item>
<item>TL</item>
<item>TG</item>
<item>TK</item>
<item>TO</item>
<item>TT</item>
<item>TN</item>
<item>TR</item>
<item>TM</item>
<item>TC</item>
<item>TV</item>
<item>UG</item>
<item>UA</item>
<item>AE</item>
<item>GB</item>
<item>US</item>
<item>UM</item>
<item>UY</item>
<item>UZ</item>
<item>VU</item>
<item>VE</item>
<item>VN</item>
<item>VI</item>
<item>WF</item>
<item>EH</item>
<item>YE</item>
<item>ZM</item>
<item>ZW</item>
</string-array>
</resources>

View File

@@ -83,6 +83,8 @@
<string name="show_hold_to_append_title">Show Hold to Append Tip</string>
<string name="show_hold_to_append_summary">Show tip when background or popup button is pressed on video details page</string>
<string name="url_not_supported_toast">URL not supported</string>
<string name="default_content_country_title">Default content country</string>
<string name="service_title">Service</string>
<string name="search_language_title">Default content language</string>
<string name="settings_category_player_title">Player</string>
<string name="settings_category_player_behavior_title">Behavior</string>
@@ -124,6 +126,11 @@
<string name="unknown_content">[Unknown]</string>
<string name="toggle_orientation">Toggle Orientation</string>
<string name="switch_to_background">Switch to Background</string>
<string name="switch_to_popup">Switch to Popup</string>
<string name="switch_to_main">Switch to Main</string>
<!-- error strings -->
<string name="general_error">Error</string>
<string name="network_error">Network error</string>
@@ -323,4 +330,10 @@
<string name="start_here_on_main">Start Playing Here</string>
<string name="start_here_on_background">Start Here on Background</string>
<string name="start_here_on_popup">Start Here on Popup</string>
<!-- Drawer -->
<string name="drawer_open">Open Drawer</string>
<string name="drawer_close">Close Drawer</string>
<string name="youtube" translatable="false">YouTube</string>
<string name="soundcloud" translatable="false">SoundCloud</string>
</resources>

View File

@@ -2,7 +2,15 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
android:title="@string/content">
<ListPreference
android:defaultValue="@string/default_country_value"
android:entries="@array/country_names"
android:entryValues="@array/country_codes"
android:key="@string/content_country_key"
android:summary="%s"
android:title="@string/default_content_country_title"/>
<!-- TODO: add support for this within code
<ListPreference
android:defaultValue="@string/default_language_value"
android:entries="@array/language_names"
@@ -10,6 +18,7 @@
android:key="@string/search_language_key"
android:summary="%s"
android:title="@string/search_language_title"/>
-->
<SwitchPreference
android:defaultValue="false"
@@ -28,5 +37,4 @@
android:key="@string/main_page_content_key"
android:title="@string/main_page_content"
android:summary="%s"/>
</PreferenceScreen>

View File

@@ -14,35 +14,35 @@ import static org.junit.Assert.assertEquals;
public class ListHelperTest {
private static final String BEST_RESOLUTION_KEY = "best_resolution";
private static final List<AudioStream> audioStreamsTestList = Arrays.asList(
new AudioStream("", MediaFormat.M4A.id, /**/ 128),
new AudioStream("", MediaFormat.WEBMA.id, /**/ 192),
new AudioStream("", MediaFormat.MP3.id, /**/ 64),
new AudioStream("", MediaFormat.WEBMA.id, /**/ 192),
new AudioStream("", MediaFormat.M4A.id, /**/ 128),
new AudioStream("", MediaFormat.MP3.id, /**/ 128),
new AudioStream("", MediaFormat.WEBMA.id, /**/ 64),
new AudioStream("", MediaFormat.M4A.id, /**/ 320),
new AudioStream("", MediaFormat.MP3.id, /**/ 192),
new AudioStream("", MediaFormat.WEBMA.id, /**/ 320));
new AudioStream("", MediaFormat.M4A, /**/ 128),
new AudioStream("", MediaFormat.WEBMA, /**/ 192),
new AudioStream("", MediaFormat.MP3, /**/ 64),
new AudioStream("", MediaFormat.WEBMA, /**/ 192),
new AudioStream("", MediaFormat.M4A, /**/ 128),
new AudioStream("", MediaFormat.MP3, /**/ 128),
new AudioStream("", MediaFormat.WEBMA, /**/ 64),
new AudioStream("", MediaFormat.M4A, /**/ 320),
new AudioStream("", MediaFormat.MP3, /**/ 192),
new AudioStream("", MediaFormat.WEBMA, /**/ 320));
private static final List<VideoStream> videoStreamsTestList = Arrays.asList(
new VideoStream("", MediaFormat.MPEG_4.id, /**/ "720p"),
new VideoStream("", MediaFormat.v3GPP.id, /**/ "240p"),
new VideoStream("", MediaFormat.WEBM.id, /**/ "480p"),
new VideoStream("", MediaFormat.v3GPP.id, /**/ "144p"),
new VideoStream("", MediaFormat.MPEG_4.id, /**/ "360p"),
new VideoStream("", MediaFormat.WEBM.id, /**/ "360p"));
new VideoStream("", MediaFormat.MPEG_4, /**/ "720p"),
new VideoStream("", MediaFormat.v3GPP, /**/ "240p"),
new VideoStream("", MediaFormat.WEBM, /**/ "480p"),
new VideoStream("", MediaFormat.v3GPP, /**/ "144p"),
new VideoStream("", MediaFormat.MPEG_4, /**/ "360p"),
new VideoStream("", MediaFormat.WEBM, /**/ "360p"));
private static final List<VideoStream> videoOnlyStreamsTestList = Arrays.asList(
new VideoStream("", MediaFormat.MPEG_4.id, /**/ "720p", true),
new VideoStream("", MediaFormat.MPEG_4.id, /**/ "720p", true),
new VideoStream("", MediaFormat.MPEG_4.id, /**/ "2160p", true),
new VideoStream("", MediaFormat.MPEG_4.id, /**/ "1440p60", true),
new VideoStream("", MediaFormat.WEBM.id, /**/ "720p60", true),
new VideoStream("", MediaFormat.MPEG_4.id, /**/ "2160p60", true),
new VideoStream("", MediaFormat.MPEG_4.id, /**/ "720p60", true),
new VideoStream("", MediaFormat.MPEG_4.id, /**/ "1080p", true),
new VideoStream("", MediaFormat.MPEG_4.id, /**/ "1080p60", true));
new VideoStream("", MediaFormat.MPEG_4, /**/ "720p", true),
new VideoStream("", MediaFormat.MPEG_4, /**/ "720p", true),
new VideoStream("", MediaFormat.MPEG_4, /**/ "2160p", true),
new VideoStream("", MediaFormat.MPEG_4, /**/ "1440p60", true),
new VideoStream("", MediaFormat.WEBM, /**/ "720p60", true),
new VideoStream("", MediaFormat.MPEG_4, /**/ "2160p60", true),
new VideoStream("", MediaFormat.MPEG_4, /**/ "720p60", true),
new VideoStream("", MediaFormat.MPEG_4, /**/ "1080p", true),
new VideoStream("", MediaFormat.MPEG_4, /**/ "1080p60", true));
@Test
public void getSortedStreamVideosListTest() throws Exception {
@@ -81,52 +81,52 @@ public class ListHelperTest {
@Test
public void getDefaultResolutionTest() throws Exception {
List<VideoStream> testList = Arrays.asList(
new VideoStream("", MediaFormat.MPEG_4.id, /**/ "720p"),
new VideoStream("", MediaFormat.v3GPP.id, /**/ "240p"),
new VideoStream("", MediaFormat.WEBM.id, /**/ "480p"),
new VideoStream("", MediaFormat.WEBM.id, /**/ "240p"),
new VideoStream("", MediaFormat.MPEG_4.id, /**/ "240p"),
new VideoStream("", MediaFormat.WEBM.id, /**/ "144p"),
new VideoStream("", MediaFormat.MPEG_4.id, /**/ "360p"),
new VideoStream("", MediaFormat.WEBM.id, /**/ "360p"));
new VideoStream("", MediaFormat.MPEG_4, /**/ "720p"),
new VideoStream("", MediaFormat.v3GPP, /**/ "240p"),
new VideoStream("", MediaFormat.WEBM, /**/ "480p"),
new VideoStream("", MediaFormat.WEBM, /**/ "240p"),
new VideoStream("", MediaFormat.MPEG_4, /**/ "240p"),
new VideoStream("", MediaFormat.WEBM, /**/ "144p"),
new VideoStream("", MediaFormat.MPEG_4, /**/ "360p"),
new VideoStream("", MediaFormat.WEBM, /**/ "360p"));
VideoStream result = testList.get(ListHelper.getDefaultResolutionIndex("720p", BEST_RESOLUTION_KEY, MediaFormat.MPEG_4, testList));
assertEquals("720p", result.resolution);
assertEquals(MediaFormat.MPEG_4.id, result.format);
assertEquals(MediaFormat.MPEG_4, result.getFormat());
// Have resolution and the format
result = testList.get(ListHelper.getDefaultResolutionIndex("480p", BEST_RESOLUTION_KEY, MediaFormat.WEBM, testList));
assertEquals("480p", result.resolution);
assertEquals(MediaFormat.WEBM.id, result.format);
assertEquals(MediaFormat.WEBM, result.getFormat());
// Have resolution but not the format
result = testList.get(ListHelper.getDefaultResolutionIndex("480p", BEST_RESOLUTION_KEY, MediaFormat.MPEG_4, testList));
assertEquals("480p", result.resolution);
assertEquals(MediaFormat.WEBM.id, result.format);
assertEquals(MediaFormat.WEBM, result.getFormat());
// Have resolution and the format
result = testList.get(ListHelper.getDefaultResolutionIndex("240p", BEST_RESOLUTION_KEY, MediaFormat.WEBM, testList));
assertEquals("240p", result.resolution);
assertEquals(MediaFormat.WEBM.id, result.format);
assertEquals(MediaFormat.WEBM, result.getFormat());
// The best resolution
result = testList.get(ListHelper.getDefaultResolutionIndex(BEST_RESOLUTION_KEY, BEST_RESOLUTION_KEY, MediaFormat.WEBM, testList));
assertEquals("720p", result.resolution);
assertEquals(MediaFormat.MPEG_4.id, result.format);
assertEquals(MediaFormat.MPEG_4, result.getFormat());
// Doesn't have the 60fps variant and format
result = testList.get(ListHelper.getDefaultResolutionIndex("720p60", BEST_RESOLUTION_KEY, MediaFormat.WEBM, testList));
assertEquals("720p", result.resolution);
assertEquals(MediaFormat.MPEG_4.id, result.format);
assertEquals(MediaFormat.MPEG_4, result.getFormat());
// Doesn't have the 60fps variant
result = testList.get(ListHelper.getDefaultResolutionIndex("480p60", BEST_RESOLUTION_KEY, MediaFormat.WEBM, testList));
assertEquals("480p", result.resolution);
assertEquals(MediaFormat.WEBM.id, result.format);
assertEquals(MediaFormat.WEBM, result.getFormat());
// Doesn't have the resolution, will return the best one
result = testList.get(ListHelper.getDefaultResolutionIndex("2160p60", BEST_RESOLUTION_KEY, MediaFormat.WEBM, testList));
assertEquals("720p", result.resolution);
assertEquals(MediaFormat.MPEG_4.id, result.format);
assertEquals(MediaFormat.MPEG_4, result.getFormat());
}
@Test
@@ -138,15 +138,15 @@ public class ListHelperTest {
public void getHighestQualityAudioFormatTest() throws Exception {
AudioStream stream = audioStreamsTestList.get(ListHelper.getHighestQualityAudioIndex(MediaFormat.M4A, audioStreamsTestList));
assertEquals(320, stream.average_bitrate);
assertEquals(MediaFormat.M4A.id, stream.format);
assertEquals(MediaFormat.M4A, stream.getFormat());
stream = audioStreamsTestList.get(ListHelper.getHighestQualityAudioIndex(MediaFormat.WEBMA, audioStreamsTestList));
assertEquals(320, stream.average_bitrate);
assertEquals(MediaFormat.WEBMA.id, stream.format);
assertEquals(MediaFormat.WEBMA, stream.getFormat());
stream = audioStreamsTestList.get(ListHelper.getHighestQualityAudioIndex(MediaFormat.MP3, audioStreamsTestList));
assertEquals(192, stream.average_bitrate);
assertEquals(MediaFormat.MP3.id, stream.format);
assertEquals(MediaFormat.MP3, stream.getFormat());
}
@Test
@@ -157,36 +157,36 @@ public class ListHelperTest {
////////////////////////////////////////
List<AudioStream> testList = Arrays.asList(
new AudioStream("", MediaFormat.M4A.id, /**/ 128),
new AudioStream("", MediaFormat.WEBMA.id, /**/ 192));
new AudioStream("", MediaFormat.M4A, /**/ 128),
new AudioStream("", MediaFormat.WEBMA, /**/ 192));
// List doesn't contains this format, it should fallback to the highest bitrate audio no matter what format it is
AudioStream stream = testList.get(ListHelper.getHighestQualityAudioIndex(MediaFormat.MP3, testList));
assertEquals(192, stream.average_bitrate);
assertEquals(MediaFormat.WEBMA.id, stream.format);
assertEquals(MediaFormat.WEBMA, stream.getFormat());
////////////////////////////////////////////////////////
// Multiple not-preferred-formats and equal bitrates //
//////////////////////////////////////////////////////
testList = new ArrayList<>(Arrays.asList(
new AudioStream("", MediaFormat.WEBMA.id, /**/ 192),
new AudioStream("", MediaFormat.M4A.id, /**/ 192),
new AudioStream("", MediaFormat.WEBMA.id, /**/ 192),
new AudioStream("", MediaFormat.M4A.id, /**/ 192),
new AudioStream("", MediaFormat.WEBMA.id, /**/ 192),
new AudioStream("", MediaFormat.M4A.id, /**/ 192)));
new AudioStream("", MediaFormat.WEBMA, /**/ 192),
new AudioStream("", MediaFormat.M4A, /**/ 192),
new AudioStream("", MediaFormat.WEBMA, /**/ 192),
new AudioStream("", MediaFormat.M4A, /**/ 192),
new AudioStream("", MediaFormat.WEBMA, /**/ 192),
new AudioStream("", MediaFormat.M4A, /**/ 192)));
// List doesn't contains this format, it should fallback to the highest bitrate audio no matter what format it is
// and as it have multiple with the same high value, the last one wins
stream = testList.get(ListHelper.getHighestQualityAudioIndex(MediaFormat.MP3, testList));
assertEquals(192, stream.average_bitrate);
assertEquals(MediaFormat.M4A.id, stream.format);
assertEquals(MediaFormat.M4A, stream.getFormat());
// Again with a new element
testList.add(new AudioStream("", MediaFormat.WEBMA.id, /**/ 192));
testList.add(new AudioStream("", MediaFormat.WEBMA, /**/ 192));
stream = testList.get(ListHelper.getHighestQualityAudioIndex(MediaFormat.MP3, testList));
assertEquals(192, stream.average_bitrate);
assertEquals(MediaFormat.WEBMA.id, stream.format);
assertEquals(MediaFormat.WEBMA, stream.getFormat());
}
@Test

View File

@@ -0,0 +1,565 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="svg2"
viewBox="0 0 192 192"
height="204.8"
width="204.8"
inkscape:version="0.91 r13725"
sodipodi:docname="new_pipe_icon_5_beta2.svg"
inkscape:export-filename="/home/the-scrabi/Projects/NewPipe/assets/new_pipe_icon_5.png"
inkscape:export-xdpi="120"
inkscape:export-ydpi="120">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1021"
id="namedview4149"
showgrid="false"
inkscape:zoom="3.6307263"
inkscape:cx="129.93323"
inkscape:cy="102.41566"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" />
<defs
id="defs4">
<linearGradient
inkscape:collect="always"
id="linearGradient4447">
<stop
style="stop-color:#ffffff;stop-opacity:0.1"
offset="0"
id="stop4449" />
<stop
style="stop-color:#ffffff;stop-opacity:0"
offset="1"
id="stop4451" />
</linearGradient>
<filter
style="color-interpolation-filters:sRGB"
inkscape:label="Drop Shadow"
id="filter4454"
width="1.4"
height="1.4"
x="-0.2"
y="-0.2">
<feFlood
flood-opacity="0.427451"
flood-color="rgb(0,0,0)"
result="flood"
id="feFlood4456" />
<feComposite
in="flood"
in2="SourceGraphic"
operator="in"
result="composite1"
id="feComposite4458" />
<feGaussianBlur
in="composite1"
stdDeviation="10.9"
result="blur"
id="feGaussianBlur4460" />
<feOffset
dx="0"
dy="7"
result="offset"
id="feOffset4462" />
<feComposite
in="SourceGraphic"
in2="offset"
operator="over"
result="composite2"
id="feComposite4464" />
</filter>
<filter
style="color-interpolation-filters:sRGB"
inkscape:label="Drop Shadow"
id="filter4777">
<feFlood
flood-opacity="0.498039"
flood-color="rgb(0,0,0)"
result="flood"
id="feFlood4779" />
<feComposite
in="flood"
in2="SourceGraphic"
operator="in"
result="composite1"
id="feComposite4781" />
<feGaussianBlur
in="composite1"
stdDeviation="5.82011"
result="blur"
id="feGaussianBlur4783" />
<feOffset
dx="0"
dy="5.6"
result="offset"
id="feOffset4785" />
<feComposite
in="SourceGraphic"
in2="offset"
operator="over"
result="fbSourceGraphic"
id="feComposite4787" />
<feColorMatrix
result="fbSourceGraphicAlpha"
in="fbSourceGraphic"
values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"
id="feColorMatrix4789" />
<feFlood
id="feFlood4791"
flood-opacity="0.498039"
flood-color="rgb(0,0,0)"
result="flood"
in="fbSourceGraphic" />
<feComposite
id="feComposite4793"
in2="fbSourceGraphic"
in="flood"
operator="in"
result="composite1" />
<feGaussianBlur
id="feGaussianBlur4795"
in="composite1"
stdDeviation="5.8"
result="blur" />
<feOffset
id="feOffset4797"
dx="0"
dy="5.6"
result="offset" />
<feComposite
id="feComposite4799"
in2="offset"
in="fbSourceGraphic"
operator="over"
result="composite2" />
</filter>
<filter
style="color-interpolation-filters:sRGB"
inkscape:label="Drop Shadow"
id="filter4885">
<feFlood
flood-opacity="0.498039"
flood-color="rgb(0,0,0)"
result="flood"
id="feFlood4887" />
<feComposite
in="flood"
in2="SourceGraphic"
operator="in"
result="composite1"
id="feComposite4889" />
<feGaussianBlur
in="composite1"
stdDeviation="7.9"
result="blur"
id="feGaussianBlur4891" />
<feOffset
dx="0"
dy="2.54709"
result="offset"
id="feOffset4893" />
<feComposite
in="SourceGraphic"
in2="offset"
operator="over"
result="fbSourceGraphic"
id="feComposite4895" />
<feColorMatrix
result="fbSourceGraphicAlpha"
in="fbSourceGraphic"
values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"
id="feColorMatrix4897" />
<feFlood
id="feFlood4899"
flood-opacity="0.498039"
flood-color="rgb(0,0,0)"
result="flood"
in="fbSourceGraphic" />
<feComposite
id="feComposite4901"
in2="fbSourceGraphic"
in="flood"
operator="in"
result="composite1" />
<feGaussianBlur
id="feGaussianBlur4903"
in="composite1"
stdDeviation="7.9"
result="blur" />
<feOffset
id="feOffset4905"
dx="0"
dy="2.5"
result="offset" />
<feComposite
id="feComposite4907"
in2="offset"
in="fbSourceGraphic"
operator="over"
result="composite2" />
</filter>
<filter
style="color-interpolation-filters:sRGB"
inkscape:label="Drop Shadow"
id="filter4257">
<feFlood
flood-opacity="0.498039"
flood-color="rgb(0,0,0)"
result="flood"
id="feFlood4259" />
<feComposite
in="flood"
in2="SourceGraphic"
operator="in"
result="composite1"
id="feComposite4261" />
<feGaussianBlur
in="composite1"
stdDeviation="7.9"
result="blur"
id="feGaussianBlur4263" />
<feOffset
dx="0"
dy="5.02645"
result="offset"
id="feOffset4265" />
<feComposite
in="SourceGraphic"
in2="offset"
operator="over"
result="fbSourceGraphic"
id="feComposite4267" />
<feColorMatrix
result="fbSourceGraphicAlpha"
in="fbSourceGraphic"
values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"
id="feColorMatrix4269" />
<feFlood
id="feFlood4271"
flood-opacity="0.498039"
flood-color="rgb(0,0,0)"
result="flood"
in="fbSourceGraphic" />
<feComposite
id="feComposite4273"
in2="fbSourceGraphic"
in="flood"
operator="in"
result="composite1" />
<feGaussianBlur
id="feGaussianBlur4275"
in="composite1"
stdDeviation="7.9"
result="blur" />
<feOffset
id="feOffset4277"
dx="0"
dy="5"
result="offset" />
<feComposite
id="feComposite4279"
in2="offset"
in="fbSourceGraphic"
operator="over"
result="composite2" />
</filter>
<filter
style="color-interpolation-filters:sRGB"
inkscape:label="Drop Shadow"
id="filter4192">
<feFlood
flood-opacity="0.498039"
flood-color="rgb(0,0,0)"
result="flood"
id="feFlood4194" />
<feComposite
in="flood"
in2="SourceGraphic"
operator="in"
result="composite1"
id="feComposite4196" />
<feGaussianBlur
in="composite1"
stdDeviation="7.7"
result="blur"
id="feGaussianBlur4198" />
<feOffset
dx="0"
dy="5"
result="offset"
id="feOffset4200" />
<feComposite
in="SourceGraphic"
in2="offset"
operator="over"
result="composite2"
id="feComposite4202" />
</filter>
<filter
style="color-interpolation-filters:sRGB"
inkscape:label="Drop Shadow"
id="filter4349">
<feFlood
flood-opacity="0.498039"
flood-color="rgb(0,0,0)"
result="flood"
id="feFlood4351" />
<feComposite
in="flood"
in2="SourceGraphic"
operator="in"
result="composite1"
id="feComposite4353" />
<feGaussianBlur
in="composite1"
stdDeviation="7.2"
result="blur"
id="feGaussianBlur4355" />
<feOffset
dx="0"
dy="5"
result="offset"
id="feOffset4357" />
<feComposite
in="SourceGraphic"
in2="offset"
operator="over"
result="composite2"
id="feComposite4359" />
</filter>
<filter
style="color-interpolation-filters:sRGB"
inkscape:label="Drop Shadow"
id="filter4361">
<feFlood
flood-opacity="0.498039"
flood-color="rgb(0,0,0)"
result="flood"
id="feFlood4363" />
<feComposite
in="flood"
in2="SourceGraphic"
operator="in"
result="composite1"
id="feComposite4365" />
<feGaussianBlur
in="composite1"
stdDeviation="5.3"
result="blur"
id="feGaussianBlur4367" />
<feOffset
dx="0"
dy="5"
result="offset"
id="feOffset4369" />
<feComposite
in="SourceGraphic"
in2="offset"
operator="over"
result="composite2"
id="feComposite4371" />
</filter>
<filter
style="color-interpolation-filters:sRGB"
inkscape:label="Drop Shadow"
id="filter4481">
<feFlood
flood-opacity="0.498039"
flood-color="rgb(0,0,0)"
result="flood"
id="feFlood4483" />
<feComposite
in="flood"
in2="SourceGraphic"
operator="in"
result="composite1"
id="feComposite4485" />
<feGaussianBlur
in="composite1"
stdDeviation="5"
result="blur"
id="feGaussianBlur4487" />
<feOffset
dx="0"
dy="5"
result="offset"
id="feOffset4489" />
<feComposite
in="SourceGraphic"
in2="offset"
operator="over"
result="composite2"
id="feComposite4491" />
</filter>
<filter
style="color-interpolation-filters:sRGB"
inkscape:label="Drop Shadow"
id="filter4433">
<feFlood
flood-opacity="0.2"
flood-color="rgb(0,0,0)"
result="flood"
id="feFlood4435" />
<feComposite
in="flood"
in2="SourceGraphic"
operator="in"
result="composite1"
id="feComposite4437" />
<feGaussianBlur
in="composite1"
stdDeviation="4"
result="blur"
id="feGaussianBlur4439" />
<feOffset
dx="0"
dy="4"
result="offset"
id="feOffset4441" />
<feComposite
in="SourceGraphic"
in2="offset"
operator="over"
result="composite2"
id="feComposite4443" />
</filter>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4447"
id="radialGradient4453"
cx="0.56012386"
cy="0.35701406"
fx="0.56012386"
fy="0.35701406"
r="88"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.00132321,2.1587518,-2.1815784,0.00133718,1.1369825,-1.4250071)" />
<filter
style="color-interpolation-filters:sRGB;"
inkscape:label="Drop Shadow"
id="filter4447">
<feFlood
flood-opacity="0.498039"
flood-color="rgb(0,0,0)"
result="flood"
id="feFlood4449" />
<feComposite
in="flood"
in2="SourceGraphic"
operator="in"
result="composite1"
id="feComposite4451" />
<feGaussianBlur
in="composite1"
stdDeviation="1"
result="blur"
id="feGaussianBlur4453" />
<feOffset
dx="0"
dy="0"
result="offset"
id="feOffset4455" />
<feComposite
in="SourceGraphic"
in2="offset"
operator="over"
result="composite2"
id="feComposite4457" />
</filter>
</defs>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<path
style="opacity:1;fill:#ff7575;fill-opacity:1;stroke:none;stroke-width:17.10300064;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4144-9"
r="88"
cy="104"
cx="88"
d=""
inkscape:connector-curvature="0" />
<circle
style="fill:#ff5252;fill-opacity:1;stroke:none;stroke-width:17.10300064;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4144-6"
cx="88"
cy="104"
r="0" />
<circle
style="opacity:1;fill:#ff7575;fill-opacity:1;stroke:none;stroke-width:17.10300064;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter4433)"
id="path4144-67"
cx="96"
cy="96"
r="88" />
<path
style="opacity:1;fill:#cc4242;fill-opacity:1;stroke:none;stroke-width:17.10300064;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter4433)"
id="path4144-5"
sodipodi:type="arc"
sodipodi:cx="96"
sodipodi:cy="96"
sodipodi:rx="88"
sodipodi:ry="88"
sodipodi:start="0"
sodipodi:end="3.1387981"
sodipodi:open="true"
d="M 184,96 A 88,88 0 0 1 96.12296,183.99991 88,88 0 0 1 8.0003436,96.24592" />
<ellipse
style="fill:#cd201f;fill-opacity:1;stroke:none;stroke-width:17.10300064;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter4433)"
id="path4144"
cx="96"
cy="96"
rx="88"
ry="87" />
<circle
style="opacity:1;fill:url(#radialGradient4453);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4445"
cx="96.001984"
cy="94.989021"
r="88" />
<path
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter4433)"
d="m 68.234817,154.58953 17.847497,-11.37613 0.373296,-75.405673 45.92471,27.26706 -33.232668,19.162923 0,21.92836 L 168.18191,95.074787 68.141493,36.280281 Z"
id="path4234"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccccc" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:37.49999619px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter4447)"
x="-141.68971"
y="60.340179"
id="text4215"
sodipodi:linespacing="125%"
transform="matrix(0.003067,-0.9999953,0.9999953,0.003067,0,0)"><tspan
sodipodi:role="line"
id="tspan4217"
x="-141.68971"
y="60.340179">BETA</tspan></text>
</svg>

After

Width:  |  Height:  |  Size: 16 KiB

View File

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

4
fixplurals.sh Executable file
View File

@@ -0,0 +1,4 @@
#!/bin/bash
javac CheckTranslations.java
find app/src -name "*.xml" | grep values | xargs java CheckTranslations -d -r