From 49cc643dccefc66585b883d6ce8b1db858f88ef0 Mon Sep 17 00:00:00 2001 From: kapodamy Date: Mon, 13 Jan 2020 21:25:26 -0300 Subject: [PATCH 01/24] decrease the size of samples per chunk --- .../newpipe/streams/Mp4FromDashWriter.java | 179 +++++++++++++----- 1 file changed, 129 insertions(+), 50 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/streams/Mp4FromDashWriter.java b/app/src/main/java/org/schabi/newpipe/streams/Mp4FromDashWriter.java index 818f6148e..f94ebefb0 100644 --- a/app/src/main/java/org/schabi/newpipe/streams/Mp4FromDashWriter.java +++ b/app/src/main/java/org/schabi/newpipe/streams/Mp4FromDashWriter.java @@ -11,6 +11,7 @@ import org.schabi.newpipe.streams.io.SharpStream; import java.io.IOException; import java.nio.ByteBuffer; +import java.util.ArrayList; /** * @author kapodamy @@ -23,7 +24,6 @@ public class Mp4FromDashWriter { private final static byte SAMPLES_PER_CHUNK = 6;// ffmpeg uses 2, basic uses 1 (with 60fps uses 21 or 22). NewPipe will use 6 private final static long THRESHOLD_FOR_CO64 = 0xFFFEFFFFL;// near 3.999 GiB private final static int THRESHOLD_MOOV_LENGTH = (256 * 1024) + (2048 * 1024); // 2.2 MiB enough for: 1080p 60fps 00h35m00s - private final static short SINGLE_CHUNK_SAMPLE_BUFFER = 256; private final long time; @@ -46,6 +46,8 @@ public class Mp4FromDashWriter { private int overrideMainBrand = 0x00; + private ArrayList compatibleBrands = new ArrayList<>(5); + public Mp4FromDashWriter(SharpStream... sources) throws IOException { for (SharpStream src : sources) { if (!src.canRewind() && !src.canRead()) { @@ -57,6 +59,10 @@ public class Mp4FromDashWriter { readers = new Mp4DashReader[sourceTracks.length]; readersChunks = new Mp4DashChunk[readers.length]; time = (System.currentTimeMillis() / 1000L) + EPOCH_OFFSET; + + compatibleBrands.add(0x6D703431);// mp41 + compatibleBrands.add(0x69736F6D);// isom + compatibleBrands.add(0x69736F32);// iso2 } public Mp4Track[] getTracksFromSource(int sourceIndex) throws IllegalStateException { @@ -104,8 +110,8 @@ public class Mp4FromDashWriter { } } - public void setMainBrand(int brandId) { - overrideMainBrand = brandId; + public void setMainBrand(int brand) { + overrideMainBrand = brand; } public boolean isDone() { @@ -159,7 +165,13 @@ public class Mp4FromDashWriter { tablesInfo[i] = new TablesInfo(); } - boolean singleChunk = tracks.length == 1 && tracks[0].kind == TrackKind.Audio; + int single_sample_buffer; + if (tracks.length == 1 && tracks[0].kind == TrackKind.Audio) { + // near 1 second of audio data per chunk, avoid split the audio stream in large chunks + single_sample_buffer = tracks[0].trak.mdia.mdhd_timeScale / 1000; + } else { + single_sample_buffer = -1; + } for (int i = 0; i < readers.length; i++) { @@ -210,31 +222,10 @@ public class Mp4FromDashWriter { readers[i].rewind(); - int tmp = tablesInfo[i].stsz - SAMPLES_PER_CHUNK_INIT; - tablesInfo[i].stco = (tmp / SAMPLES_PER_CHUNK) + 1;// +1 for samples in first chunk - - tmp = tmp % SAMPLES_PER_CHUNK; - if (singleChunk) { - // avoid split audio streams in chunks - tablesInfo[i].stsc = 1; - tablesInfo[i].stsc_bEntries = new int[]{ - 1, tablesInfo[i].stsz, 1 - }; - tablesInfo[i].stco = 1; - } else if (tmp == 0) { - tablesInfo[i].stsc = 2;// first chunk (init) and succesive chunks - tablesInfo[i].stsc_bEntries = new int[]{ - 1, SAMPLES_PER_CHUNK_INIT, 1, - 2, SAMPLES_PER_CHUNK, 1 - }; + if (single_sample_buffer > 0) { + initChunkTables(tablesInfo[i], single_sample_buffer, single_sample_buffer); } else { - tablesInfo[i].stsc = 3;// first chunk (init) and successive chunks and remain chunk - tablesInfo[i].stsc_bEntries = new int[]{ - 1, SAMPLES_PER_CHUNK_INIT, 1, - 2, SAMPLES_PER_CHUNK, 1, - tablesInfo[i].stco + 1, tmp, 1 - }; - tablesInfo[i].stco++; + initChunkTables(tablesInfo[i], SAMPLES_PER_CHUNK_INIT, SAMPLES_PER_CHUNK); } sampleCount[i] = tablesInfo[i].stsz; @@ -274,6 +265,7 @@ public class Mp4FromDashWriter { // reserve moov space in the output stream /*if (outStream.canSetLength()) { long length = writeOffset + auxSize; + // warning: setLength() does not fill the unused space with zeros outStream.setLength(length); outSeek(length); } else {*/ @@ -292,10 +284,10 @@ public class Mp4FromDashWriter { } // tablesInfo contains row counts - // and after returning from make_moov() will contain table offsets + // and after returning from make_moov() will contain those table offsets make_moov(defaultMediaTime, tablesInfo, is64); - // write tables: stts stsc + // write tables: stts stsc sbgp // reset for ctts table: sampleCount sampleExtra for (int i = 0; i < readers.length; i++) { writeEntryArray(tablesInfo[i].stts, 2, sampleCount[i], defaultSampleDuration[i]); @@ -305,6 +297,7 @@ public class Mp4FromDashWriter { sampleCount[i] = 1;// the index is not base zero sampleExtra[i] = -1; } + writeEntryArray(tablesInfo[i].sbgp, 1, sampleCount[i]); } if (auxBuffer == null) { @@ -314,8 +307,8 @@ public class Mp4FromDashWriter { outWrite(make_mdat(totalSampleSize, is64)); int[] sampleIndex = new int[readers.length]; - int[] sizes = new int[singleChunk ? SINGLE_CHUNK_SAMPLE_BUFFER : SAMPLES_PER_CHUNK]; - int[] sync = new int[singleChunk ? SINGLE_CHUNK_SAMPLE_BUFFER : SAMPLES_PER_CHUNK]; + int[] sizes = new int[single_sample_buffer > 0 ? single_sample_buffer : SAMPLES_PER_CHUNK]; + int[] sync = new int[single_sample_buffer > 0 ? single_sample_buffer : SAMPLES_PER_CHUNK]; int written = readers.length; while (written > 0) { @@ -329,8 +322,8 @@ public class Mp4FromDashWriter { long chunkOffset = writeOffset; int syncCount = 0; int limit; - if (singleChunk) { - limit = SINGLE_CHUNK_SAMPLE_BUFFER; + if (single_sample_buffer > 0) { + limit = single_sample_buffer; } else { limit = sampleIndex[i] == 0 ? SAMPLES_PER_CHUNK_INIT : SAMPLES_PER_CHUNK; } @@ -390,10 +383,6 @@ public class Mp4FromDashWriter { } else { tablesInfo[i].stco = writeEntryArray(tablesInfo[i].stco, 1, (int) chunkOffset); } - - if (singleChunk) { - tablesInfo[i].stco = -1; - } } outRestore(); @@ -470,7 +459,42 @@ public class Mp4FromDashWriter { } } + private void initChunkTables(TablesInfo tables, int firstCount, int succesiveCount) { + // tables.stsz holds amount of samples of the track (total) + int totalSamples = (tables.stsz - firstCount); + float chunkAmount = totalSamples / (float) succesiveCount; + int remainChunkOffset = (int) Math.ceil(chunkAmount); + boolean remain = remainChunkOffset != (int) chunkAmount; + int index = 0; + tables.stsc = 1; + if (firstCount != succesiveCount) { + tables.stsc++; + } + if (remain) { + tables.stsc++; + } + + // stsc_table_entry = [first_chunk, samples_per_chunk, sample_description_index] + tables.stsc_bEntries = new int[tables.stsc * 3]; + tables.stco = remainChunkOffset + 1;// total entrys in chunk offset box + + tables.stsc_bEntries[index++] = 1; + tables.stsc_bEntries[index++] = firstCount; + tables.stsc_bEntries[index++] = 1; + + if (firstCount != succesiveCount) { + tables.stsc_bEntries[index++] = 2; + tables.stsc_bEntries[index++] = succesiveCount; + tables.stsc_bEntries[index++] = 1; + } + + if (remain) { + tables.stsc_bEntries[index++] = remainChunkOffset + 1; + tables.stsc_bEntries[index++] = totalSamples % succesiveCount; + tables.stsc_bEntries[index] = 1; + } + } private void outWrite(byte[] buffer) throws IOException { outWrite(buffer, buffer.length); @@ -585,19 +609,29 @@ public class Mp4FromDashWriter { private int make_ftyp() throws IOException { - byte[] buffer = new byte[]{ - 0x00, 0x00, 0x00, 0x1C, 0x66, 0x74, 0x79, 0x70,// ftyp - 0x6D, 0x70, 0x34, 0x32,// mayor brand (mp42) - 0x00, 0x00, 0x02, 0x00,// default minor version (512) - 0x6D, 0x70, 0x34, 0x31, 0x69, 0x73, 0x6F, 0x6D, 0x69, 0x73, 0x6F, 0x32// compatible brands: mp41 isom iso2 - }; + int size = 16 + (compatibleBrands.size() * 4); + if (overrideMainBrand != 0) size += 4; - if (overrideMainBrand != 0) - ByteBuffer.wrap(buffer).putInt(8, overrideMainBrand); + ByteBuffer buffer = ByteBuffer.allocate(size); + buffer.putInt(size); + buffer.putInt(0x66747970);// "ftyp" - outWrite(buffer); + if (overrideMainBrand == 0) { + buffer.putInt(0x6D703432);// mayor brand "mp42" + buffer.putInt(512);// default minor version + } else { + buffer.putInt(overrideMainBrand); + buffer.putInt(0); + buffer.putInt(0x6D703432);// "mp42" compatible brand + } - return buffer.length; + for (Integer brand : compatibleBrands) { + buffer.putInt(brand);// compatible brand + } + + outWrite(buffer.array()); + + return size; } private byte[] make_mdat(long refSize, boolean is64) { @@ -746,7 +780,6 @@ public class Mp4FromDashWriter { } private void make_mdia(Mdia mdia, TablesInfo tablesInfo, boolean is64) throws IOException { - int start_mdia = auxOffset(); auxWrite(new byte[]{0x00, 0x00, 0x00, 0x00, 0x6D, 0x64, 0x69, 0x61});// mdia auxWrite(mdia.mdhd); @@ -766,7 +799,7 @@ public class Mp4FromDashWriter { // And stsz can be empty if has a default sample size // if (moovSimulation) { - make(0x73747473, -1, 2, 1); + make(0x73747473, -1, 2, 1);// stts if (tablesInfo.stss > 0) { make(0x73747373, -1, 1, tablesInfo.stss); } @@ -789,6 +822,9 @@ public class Mp4FromDashWriter { tablesInfo.stco = make(is64 ? 0x636F3634 : 0x7374636F, -1, is64 ? 2 : 1, tablesInfo.stco); } + auxWrite(make_sgpd()); + tablesInfo.sbgp = make_sbgp();// during simulation the returned offset is ignored + lengthFor(start_stbl); lengthFor(start_minf); lengthFor(start_mdia); @@ -816,6 +852,48 @@ public class Mp4FromDashWriter { return buffer.array(); } + private int make_sbgp() throws IOException { + int offset = auxOffset(); + + auxWrite(new byte[] { + 0x00, 0x00, 0x00, 0x1C,// box size + 0x73, 0x62, 0x67, 0x70,// "sbpg" + 0x00, 0x00, 0x00, 0x00,// default box flags + 0x72, 0x6F, 0x6C, 0x6C,// group type "roll" + 0x00, 0x00, 0x00, 0x01,// group table size + 0x00, 0x00, 0x00, 0x00,// group[0] total samples (to be set later) + 0x00, 0x00, 0x00, 0x01// group[0] description index + }); + + return offset + 0x14; + } + + private byte[] make_sgpd() { + /* + * Sample Group Description Box + * + * ¿whats does? + * the table inside of this box gives information about the + * characteristics of sample groups. The descriptive information is any other + * information needed to define or characterize the sample group. + * + * ¿is replicabled this box? + * NO due lacks of documentation about this box but... + * most of m4a encoders and ffmpeg uses this box with dummy values (same values) + */ + + ByteBuffer buffer = ByteBuffer.wrap(new byte[] { + 0x00, 0x00, 0x00, 0x1A,// box size + 0x73, 0x67, 0x70, 0x64,// "sgpd" + 0x01, 0x00, 0x00, 0x00,// box flags (unknown flag sets) + 0x72, 0x6F, 0x6C, 0x6C, // ¿¿group type?? + 0x00, 0x00, 0x00, 0x02,// ¿¿?? + 0x00, 0x00, 0x00, 0x01,// ¿¿?? + (byte)0xFF, (byte)0xFF// ¿¿?? + }); + + return buffer.array(); + } class TablesInfo { @@ -827,5 +905,6 @@ public class Mp4FromDashWriter { int stsz_default; int stss; int stco; + int sbgp; } } From 9b71828b97a46227f214b76cf99e53bb1884a7ee Mon Sep 17 00:00:00 2001 From: kapodamy Date: Tue, 14 Jan 2020 01:08:46 -0300 Subject: [PATCH 02/24] implement sgpd and sbgp boxes in audio tracks --- .../org/schabi/newpipe/streams/Mp4FromDashWriter.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/streams/Mp4FromDashWriter.java b/app/src/main/java/org/schabi/newpipe/streams/Mp4FromDashWriter.java index f94ebefb0..963d84b40 100644 --- a/app/src/main/java/org/schabi/newpipe/streams/Mp4FromDashWriter.java +++ b/app/src/main/java/org/schabi/newpipe/streams/Mp4FromDashWriter.java @@ -774,12 +774,12 @@ public class Mp4FromDashWriter { .array() ); - make_mdia(tracks[index].trak.mdia, tables, is64); + make_mdia(tracks[index].trak.mdia, tables, is64, tracks[index].kind == TrackKind.Audio); lengthFor(start); } - private void make_mdia(Mdia mdia, TablesInfo tablesInfo, boolean is64) throws IOException { + private void make_mdia(Mdia mdia, TablesInfo tablesInfo, boolean is64, boolean isAudio) throws IOException { int start_mdia = auxOffset(); auxWrite(new byte[]{0x00, 0x00, 0x00, 0x00, 0x6D, 0x64, 0x69, 0x61});// mdia auxWrite(mdia.mdhd); @@ -822,8 +822,10 @@ public class Mp4FromDashWriter { tablesInfo.stco = make(is64 ? 0x636F3634 : 0x7374636F, -1, is64 ? 2 : 1, tablesInfo.stco); } - auxWrite(make_sgpd()); - tablesInfo.sbgp = make_sbgp();// during simulation the returned offset is ignored + if (isAudio) { + auxWrite(make_sgpd()); + tablesInfo.sbgp = make_sbgp();// during simulation the returned offset is ignored + } lengthFor(start_stbl); lengthFor(start_minf); From 342377e69ae3157c0b11a03d32721b80844a0b7b Mon Sep 17 00:00:00 2001 From: kapodamy Date: Wed, 29 Jan 2020 16:04:24 -0300 Subject: [PATCH 03/24] restore offset after writting lastest CTTS entries --- .../org/schabi/newpipe/streams/Mp4FromDashWriter.java | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/streams/Mp4FromDashWriter.java b/app/src/main/java/org/schabi/newpipe/streams/Mp4FromDashWriter.java index 963d84b40..3dfba8b2d 100644 --- a/app/src/main/java/org/schabi/newpipe/streams/Mp4FromDashWriter.java +++ b/app/src/main/java/org/schabi/newpipe/streams/Mp4FromDashWriter.java @@ -262,13 +262,6 @@ public class Mp4FromDashWriter { final int ftyp_size = make_ftyp(); - // reserve moov space in the output stream - /*if (outStream.canSetLength()) { - long length = writeOffset + auxSize; - // warning: setLength() does not fill the unused space with zeros - outStream.setLength(length); - outSeek(length); - } else {*/ if (auxSize > 0) { int length = auxSize; byte[] buffer = new byte[64 * 1024];// 64 KiB @@ -335,6 +328,7 @@ public class Mp4FromDashWriter { if (sample == null) { if (tablesInfo[i].ctts > 0 && sampleExtra[i] >= 0) { writeEntryArray(tablesInfo[i].ctts, 1, sampleCount[i], sampleExtra[i]);// flush last entries + outRestore(); } sampleIndex[i] = -1; break; From 0c5608506e9a2887b86cf6907e3c593efb442308 Mon Sep 17 00:00:00 2001 From: kapodamy Date: Wed, 29 Jan 2020 16:06:40 -0300 Subject: [PATCH 04/24] typo fixup --- .../java/org/schabi/newpipe/streams/Mp4FromDashWriter.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/streams/Mp4FromDashWriter.java b/app/src/main/java/org/schabi/newpipe/streams/Mp4FromDashWriter.java index 3dfba8b2d..57a7aaa9c 100644 --- a/app/src/main/java/org/schabi/newpipe/streams/Mp4FromDashWriter.java +++ b/app/src/main/java/org/schabi/newpipe/streams/Mp4FromDashWriter.java @@ -250,7 +250,7 @@ public class Mp4FromDashWriter { boolean is64 = read > THRESHOLD_FOR_CO64; - // calculate the moov size; + // calculate the moov size int auxSize = make_moov(defaultMediaTime, tablesInfo, is64); if (auxSize < THRESHOLD_MOOV_LENGTH) { @@ -262,6 +262,7 @@ public class Mp4FromDashWriter { final int ftyp_size = make_ftyp(); + // reserve moov space in the output stream if (auxSize > 0) { int length = auxSize; byte[] buffer = new byte[64 * 1024];// 64 KiB @@ -328,7 +329,7 @@ public class Mp4FromDashWriter { if (sample == null) { if (tablesInfo[i].ctts > 0 && sampleExtra[i] >= 0) { writeEntryArray(tablesInfo[i].ctts, 1, sampleCount[i], sampleExtra[i]);// flush last entries - outRestore(); + outRestore(); } sampleIndex[i] = -1; break; From c0519d8313505b5b074e17906edadacfb276484a Mon Sep 17 00:00:00 2001 From: Markus Richter <8398165+mqus@users.noreply.github.com> Date: Wed, 29 Jan 2020 13:48:02 +0100 Subject: [PATCH 05/24] fixes #3021, see also https://github.com/TeamNewPipe/NewPipe-legacy/pull/21 --- app/src/main/java/us/shandian/giga/get/DownloadMission.java | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/us/shandian/giga/get/DownloadMission.java b/app/src/main/java/us/shandian/giga/get/DownloadMission.java index c0f85b321..9ad73050b 100644 --- a/app/src/main/java/us/shandian/giga/get/DownloadMission.java +++ b/app/src/main/java/us/shandian/giga/get/DownloadMission.java @@ -223,6 +223,7 @@ public class DownloadMission extends Mission { conn.setInstanceFollowRedirects(true); conn.setRequestProperty("User-Agent", DownloaderImpl.USER_AGENT); conn.setRequestProperty("Accept", "*/*"); + conn.setRequestProperty("Accept-Encoding", "*"); if (headRequest) conn.setRequestMethod("HEAD"); From 61d102dc75a1a1470adab17edcf5d251c67e2549 Mon Sep 17 00:00:00 2001 From: Stypox Date: Wed, 29 Jan 2020 18:43:44 +0100 Subject: [PATCH 06/24] Change recaptcha string names to match style --- app/src/main/AndroidManifest.xml | 2 +- app/src/main/res/values-ar/strings.xml | 4 ++-- app/src/main/res/values-b+ast/strings.xml | 4 ++-- app/src/main/res/values-b+zh+HANS+CN/strings.xml | 4 ++-- app/src/main/res/values-be/strings.xml | 4 ++-- app/src/main/res/values-bg/strings.xml | 4 ++-- app/src/main/res/values-bn-rBD/strings.xml | 4 ++-- app/src/main/res/values-ca/strings.xml | 4 ++-- app/src/main/res/values-cmn/strings.xml | 4 ++-- app/src/main/res/values-cs/strings.xml | 4 ++-- app/src/main/res/values-da/strings.xml | 4 ++-- app/src/main/res/values-de/strings.xml | 4 ++-- app/src/main/res/values-el/strings.xml | 4 ++-- app/src/main/res/values-eo/strings.xml | 4 ++-- app/src/main/res/values-es/strings.xml | 4 ++-- app/src/main/res/values-et/strings.xml | 4 ++-- app/src/main/res/values-eu/strings.xml | 4 ++-- app/src/main/res/values-fa/strings.xml | 4 ++-- app/src/main/res/values-fi/strings.xml | 4 ++-- app/src/main/res/values-fr/strings.xml | 4 ++-- app/src/main/res/values-gl/strings.xml | 4 ++-- app/src/main/res/values-he/strings.xml | 4 ++-- app/src/main/res/values-hi/strings.xml | 4 ++-- app/src/main/res/values-hr/strings.xml | 4 ++-- app/src/main/res/values-hu/strings.xml | 4 ++-- app/src/main/res/values-id/strings.xml | 4 ++-- app/src/main/res/values-it/strings.xml | 4 ++-- app/src/main/res/values-ja/strings.xml | 4 ++-- app/src/main/res/values-ko/strings.xml | 4 ++-- app/src/main/res/values-ku/strings.xml | 4 ++-- app/src/main/res/values-lt/strings.xml | 4 ++-- app/src/main/res/values-mk/strings.xml | 4 ++-- app/src/main/res/values-ms/strings.xml | 4 ++-- app/src/main/res/values-nb-rNO/strings.xml | 4 ++-- app/src/main/res/values-nl-rBE/strings.xml | 4 ++-- app/src/main/res/values-nl/strings.xml | 4 ++-- app/src/main/res/values-pa/strings.xml | 4 ++-- app/src/main/res/values-pl/strings.xml | 4 ++-- app/src/main/res/values-pt-rBR/strings.xml | 4 ++-- app/src/main/res/values-pt/strings.xml | 4 ++-- app/src/main/res/values-ro/strings.xml | 4 ++-- app/src/main/res/values-ru/strings.xml | 4 ++-- app/src/main/res/values-sk/strings.xml | 4 ++-- app/src/main/res/values-sl/strings.xml | 4 ++-- app/src/main/res/values-sr/strings.xml | 4 ++-- app/src/main/res/values-sv/strings.xml | 4 ++-- app/src/main/res/values-tr/strings.xml | 4 ++-- app/src/main/res/values-uk/strings.xml | 4 ++-- app/src/main/res/values-ur/strings.xml | 4 ++-- app/src/main/res/values-vi/strings.xml | 4 ++-- app/src/main/res/values-zh-rCN/strings.xml | 4 ++-- app/src/main/res/values-zh-rHK/strings.xml | 4 ++-- app/src/main/res/values-zh-rTW/strings.xml | 4 ++-- app/src/main/res/values/strings.xml | 7 ++++--- 54 files changed, 109 insertions(+), 108 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 21a846494..f27f4bad0 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -112,7 +112,7 @@ + android:label="@string/recaptcha"/> يرجى تحديد مجلد التنزيل لاحقا في الإعدادات هذا الإذن مطلوب \nللفتح في وضع النافذة المنبثقة - اختبار reCAPTCHA + اختبار reCAPTCHA السماح بالرموز في أسماء الملفات يتم استبدال الرموز غير المسموح بها بهذه القيمة استبدال الحرف @@ -235,7 +235,7 @@ الإعدادات الصوتية تشغيل هنا بدأ التشغيل في نافذة منبثقة جديدة - تحدي الكابتشا + تحدي الكابتشا ضغط مطول للإدراج الى قائمة الانتظار %s بدون مشهد diff --git a/app/src/main/res/values-b+ast/strings.xml b/app/src/main/res/values-b+ast/strings.xml index 08b22c616..5ddfa7ead 100644 --- a/app/src/main/res/values-b+ast/strings.xml +++ b/app/src/main/res/values-b+ast/strings.xml @@ -58,8 +58,8 @@ Mil mill. Precísase esti permisu \np\'abrir nel mou ventanu - reCAPTCHA - Retu de reCAPTCHA + reCAPTCHA + Retu de reCAPTCHA Solicitóse\'l retu de reCAPTCHA En segundu planu Ventanu diff --git a/app/src/main/res/values-b+zh+HANS+CN/strings.xml b/app/src/main/res/values-b+zh+HANS+CN/strings.xml index 078379683..5fb13d968 100644 --- a/app/src/main/res/values-b+zh+HANS+CN/strings.xml +++ b/app/src/main/res/values-b+zh+HANS+CN/strings.xml @@ -110,7 +110,7 @@ 点击了解详情 请稍候… 复制至剪贴板 - reCAPTCHA验证码 + reCAPTCHA验证码 悬浮窗播放 关于NewPipe 设置 @@ -207,7 +207,7 @@ 请稍后在设置中设定下载目录 用悬浮窗模式 \n需要此权限 - reCAPTCHA验证 + reCAPTCHA验证 请求的新的CAPTCHA验证 NewPipe 悬浮窗模式 在悬浮窗中播放 diff --git a/app/src/main/res/values-be/strings.xml b/app/src/main/res/values-be/strings.xml index 1cf3abd7e..b3a09cb8f 100644 --- a/app/src/main/res/values-be/strings.xml +++ b/app/src/main/res/values-be/strings.xml @@ -247,8 +247,8 @@ Гэтае разрозненне трэба для \nпрайгравання ў акне 1 элемент выдалены. - reCAPTCHA - Запыт reCAPTCHA + reCAPTCHA + Запыт reCAPTCHA Запытаны ўвод reCAPTCHA Загрузкі Дапушчальныя сімвалы назвы файлаў diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml index 1eb9222ec..7c813d0a9 100644 --- a/app/src/main/res/values-bg/strings.xml +++ b/app/src/main/res/values-bg/strings.xml @@ -269,8 +269,8 @@ Това разрешение се изисква за \nвъзпроизвеждане в отделен прозорец 1 елемент е изтрит. - преКАПЧА - reCAPTCHA заявка + преКАПЧА + reCAPTCHA заявка Изисква се въвеждане на reCAPTCHA Изтегляне Повечето специални символи diff --git a/app/src/main/res/values-bn-rBD/strings.xml b/app/src/main/res/values-bn-rBD/strings.xml index 3a623f2c3..37938334c 100644 --- a/app/src/main/res/values-bn-rBD/strings.xml +++ b/app/src/main/res/values-bn-rBD/strings.xml @@ -145,8 +145,8 @@ - রিক্যাপচা - reCAPTCHA চ্যালেঞ্জ + রিক্যাপচা + reCAPTCHA চ্যালেঞ্জ reCAPTCHA চ্যালেঞ্জ অনুরোধ করা হয়েছে কি:\\nঅনুরোধ:\\nকন্টেন্ট ভাষা:\\nসার্ভিস:\\nসময়(GMT এ):\\nপ্যাকেজ:\\nসংস্করণ:\\nওএস সংস্করণ:\\nআইপি পরিসর: diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index bcc816577..20deb3160 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -67,7 +67,7 @@ D\'acord Nom de fitxer Error - reCAPTCHA + reCAPTCHA Baixades Paràmetres Quant a @@ -307,7 +307,7 @@ Feu un toc aquí per a més detalls Defineix una carpeta de baixades més endavant als paràmetres Es necessita aquest permís per a obrir el mode emergent - Camp reCAPTCHA + Camp reCAPTCHA S\'ha sol·licitat l\'emplenament d\'un camp reCAPTCHA Se substituiran els caràcters no vàlids amb aquest valor Caràcter de substitució diff --git a/app/src/main/res/values-cmn/strings.xml b/app/src/main/res/values-cmn/strings.xml index 3ff479bfd..878efa9f2 100644 --- a/app/src/main/res/values-cmn/strings.xml +++ b/app/src/main/res/values-cmn/strings.xml @@ -266,8 +266,8 @@ 在悬浮窗模式打开 \n需要此权限 已删除一个项目。 - reCAPTCHA 验证 - reCAPTCHA 验证 + reCAPTCHA 验证 + reCAPTCHA 验证 需完成 reCAPTCHA 验证 下载 文件名中允许的字符 diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 66c952a26..044d908c4 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -102,8 +102,8 @@ Přehrát Nová mise OK - reCAPTCHA - Výzva reCAPTCHA + reCAPTCHA + Výzva reCAPTCHA Požadována výzva reCAPTCHA Černé Kontrolní součet diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index 5e44aab61..ff2fea8c9 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -249,8 +249,8 @@ Vælg venligst en tilgængelig downloadmappe Denne tilladelse er nødvendig for at kunne åbne i pop op-tilstand 1 element slettet. - reCAPTCHA - reCAPTCHA-udfordring + reCAPTCHA + reCAPTCHA-udfordring Der blev anmodet om en reCAPTCHA-udfordring Download Tilladte tegn i filnavne diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 53b9a52eb..fa5e798a4 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -110,9 +110,9 @@ NewPipe lädt herunter Für Details antippen Ungültige URL oder Internet nicht verfügbar - reCAPTCHA + reCAPTCHA Schwarz - reCAPTCHA-Aufgabe + reCAPTCHA-Aufgabe reCAPTCHA-Aufgabe angefordert Später Ja diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index 3d2397a0c..915e1902d 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -251,8 +251,8 @@ Αυτή η άδεια είναι απαραίτητη για \nτο άνοιγμα αναδυόμενων παραθύρων 1 αντικείμενο διαγράφηκε. - Αυτόματο τεστ - Πρόκληση reCAPTCHA + Αυτόματο τεστ + Πρόκληση reCAPTCHA Ζητήθηκε πρόκληση reCAPTCHA Επιτρεπόμενοι χαρακτήρες σε ονόματα αρχείων Οι μη έγκυροι χαρακτήρες αντικαθίστανται με αυτήν την τιμή diff --git a/app/src/main/res/values-eo/strings.xml b/app/src/main/res/values-eo/strings.xml index 224e8837e..754df0784 100644 --- a/app/src/main/res/values-eo/strings.xml +++ b/app/src/main/res/values-eo/strings.xml @@ -109,8 +109,8 @@ Erarosignalo Ne povis ŝarĝi bildon Apo kraŝis - reCAPTCHA - reCAPTCHA defio + reCAPTCHA + reCAPTCHA defio reCAPTCHA defio petita Ĉiuj Kanalo diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 9f25208bb..d7a9bc2e8 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -115,11 +115,11 @@ k M MM - reCAPTCHA + reCAPTCHA Abrir en modo emergente Se necesita este permiso \npara abrir en modo emergente - Reto reCAPTCHA + Reto reCAPTCHA Reto reCAPTCHA requerido Modo emergente de NewPipe Reproduciendo en modo emergente diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml index 99dc6cc80..79442f421 100644 --- a/app/src/main/res/values-et/strings.xml +++ b/app/src/main/res/values-et/strings.xml @@ -238,7 +238,7 @@ Need õigused on vajalikud \nhüpikakna avamiseks Kustutati 1 element. - "reCAPTCHA " + "reCAPTCHA " Laadi alla Lubatud tähemärgid failinimedes Vigased tähemärgid asendatakse selle väärtusega @@ -370,7 +370,7 @@ Lood Kasutajad Lülitu peamisele - reCAPTCHA nõue + reCAPTCHA nõue reCAPTCHA nõude taotlus © %1$s %2$s %3$s alla Vaba kergekaaluline Androidi voogesitus. diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml index b376f1f6d..1ec970d5f 100644 --- a/app/src/main/res/values-eu/strings.xml +++ b/app/src/main/res/values-eu/strings.xml @@ -139,8 +139,8 @@ Ezarri deskargetarako karpeta bat ezarpenetan geroago Baimen hau beharrezkoa da \nlaster-leiho moduan irekitzeko - reCAPTCHA - reCAPTCHA erronka + reCAPTCHA + reCAPTCHA erronka reCAPTCHA erronka eskatu da NewPipe aplikazioari buruz Ezarpenak diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml index b2a04e14c..790c47669 100644 --- a/app/src/main/res/values-fa/strings.xml +++ b/app/src/main/res/values-fa/strings.xml @@ -296,7 +296,7 @@ زمان فعلی پخش کننده را به صورت تقریبی و سریع جلو ببر این گزینه باعث می شود هنگام جلو/عقب کردن زمان تصویر، به جای زمان دقیق انتخاب شده، به زمان غیر دقیق و نزدیک به مکان انتخاب شده برود که این کار سریع تر انجام می شود کاره یا رابط کاربری با خطا مواجه شد - ریکپچا + ریکپچا بارگیری تغییر جهت تغییر وضعیت به پس‌زمینه @@ -361,7 +361,7 @@ بازگردانی در صف پخش کننده پس‌زمینه قرار گرفت چه:\\nدرخواست:\\nزبان درخواست:\\nخدمت:\\nزمان GMT:\\nنگارش:\\nنگارش س.ع:\\nبازه آی‌پی: - چالش ری‌کپچا + چالش ری‌کپچا نیاز به چالش ری‌کپچا است این مجوز مورد نیاز است \nتا بتوان به حالت تصویر در تصویر رفت diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index 1e91fa55a..edf10c6f0 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -173,8 +173,8 @@ Kopioitu leikepöydälle Valitse saatavilla oleva latauskansio Tämä käyttöoikeus tarvitaan ponnahdusikkunan käytölle - reCAPTCHA - reCAPTCHA Haaste + reCAPTCHA + reCAPTCHA Haaste reCAPTCHA Haaste pyydetty Lataus Sallitut merkit tiedostonimissä diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 444310aef..6b86cd2b4 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -105,11 +105,11 @@ Veuillez définir ultérieurement un dossier de téléchargement dans les paramètres Impossible de charger l’image L’application a planté - reCAPTCHA + reCAPTCHA Noir Tout Chaîne - Défi reCAPTCHA + Défi reCAPTCHA Défi reCAPTCHA demandé Ouvrir en mode flottant Mode flottant NewPipe diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index 899a9be10..6427e1378 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -266,8 +266,8 @@ \npara abrir o vídeo no modo «popup» 1 elemento foi eliminado. - reCAPTCHA - Desafío reCAPTCHA + reCAPTCHA + Desafío reCAPTCHA Desafío reCAPTCHA solicitado Descarregar diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml index 7a1338f60..35b86ec2d 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -192,8 +192,8 @@ נא לציין תיקיית הורדה בהגדרות בהמשך הרשאה זו נדרשת לטובת \nפתיחה בחלון צף - reCAPTCHA - אתגר reCAPTCHA + reCAPTCHA + אתגר reCAPTCHA התקבלה בקשה לאתגר reCAPTCHA הורדה רשימת תווים אפשרית בשמות קבצים diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml index 82b2db1b5..a7746330a 100644 --- a/app/src/main/res/values-hi/strings.xml +++ b/app/src/main/res/values-hi/strings.xml @@ -206,8 +206,8 @@ क्लिपबोर्ड पर कॉपी हो गया है कृपया बाद में सेटिंग्स में डाउनलोड स्थान चुने पॉपअप के तरीके में खोलने के लिए अनुमति की जरुरत है - reCAPTCHA - reCAPTCHA चुनौती + reCAPTCHA + reCAPTCHA चुनौती reCAPTCHA चुनौती का अनुरोध किया डाउनलोड फाइल के नाम के लिए आवश्यक characters(जैसे - १२३, abc) की अनुमति है diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml index a981dcf5e..beb2bdd02 100644 --- a/app/src/main/res/values-hr/strings.xml +++ b/app/src/main/res/values-hr/strings.xml @@ -153,8 +153,8 @@ Molimo odaberite dostupnu mapu za preuzimanje Ova dozvola je potrebna za \notvaranje skočnog prozora - reCAPTCHA - reCAPTCHA zadatak + reCAPTCHA + reCAPTCHA zadatak Traži se reCAPTCHA zadatak Preuzimanja Dozvoljeni znakovi u nazivima datoteka diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index 4d7ff986e..dc1021adb 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -233,8 +233,8 @@ Átnevezés Ez az engedély szükséges a felugró ablakban történő megnyitáshoz 1 elem törölve. - reCAPTCHA - reCAPTCHA rejtvény + reCAPTCHA + reCAPTCHA rejtvény reCAPTCHA rejtvény igényelve Letöltés Fájlnevekben engedélyezett karakterek diff --git a/app/src/main/res/values-id/strings.xml b/app/src/main/res/values-id/strings.xml index 8677df678..ffcacdd6d 100644 --- a/app/src/main/res/values-id/strings.xml +++ b/app/src/main/res/values-id/strings.xml @@ -105,8 +105,8 @@ Apa:\\nPermintaan:\\nBahasa Konten:\\nLayanan:\\nWaktu GMT:\\nPaket:\\nVersi:\\nVersi OS: Laporan pengguna Thread - reCAPTCHA - Tantangan reCAPTCHA + reCAPTCHA + Tantangan reCAPTCHA Meminta kode reCAPTCHA Hitam Semua diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 4942f4720..7ab68268f 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -106,8 +106,8 @@ Impossibile caricare l\'immagine L\'app/UI si è interrotta Cosa:\\nRichiesta:\\nLingua contenuto:\\nServizio:\\nOrario GMT:\\nPacchetto:\\nVersione:\\nVersione SO: - reCAPTCHA - Risoluzione reCAPTCHA + reCAPTCHA + Risoluzione reCAPTCHA Nero Tutto Canale diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 553a54f1e..7980645e2 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -106,8 +106,8 @@ 画像を読み込みできません アプリ/UI がクラッシュしました 何:\\\\n提案:\\\\nコンテンツ言語:\\\\nサービス:\\\\nGMT 時間:\\\\nパッケージ:\\\\nバージョン:\\\\nOSバージョン: - reCAPTCHA - reCAPTCHA の要求 + reCAPTCHA + reCAPTCHA の要求 reCAPTCHA を要求しました ブラック すべて diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index e8a2a9c51..630abcdaa 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -180,7 +180,7 @@ 다운로드 할 폴더를 설정에서 지정하세요 이 권한은 팝업 모드에서 \n열기 위해 필요합니다 - reCAPTCHA + reCAPTCHA reCAPTCHA 확인 요청됨 다운로드 파일명에 허용되는 문자 @@ -274,7 +274,7 @@ 모두 삭제하기 취소 이름 바꾸기 - reCAPTCHA 확인 + reCAPTCHA 확인 이 항목을 시청 기록에서 삭제하시겠습니까? 모든 항목을 시청 기록에서 삭제하시겠습니까? 마지막으로 재생 diff --git a/app/src/main/res/values-ku/strings.xml b/app/src/main/res/values-ku/strings.xml index 50350e1b3..2f39136e2 100644 --- a/app/src/main/res/values-ku/strings.xml +++ b/app/src/main/res/values-ku/strings.xml @@ -215,8 +215,8 @@ تکایە فۆڵدەرێک بۆ شوێنی داگرتن دیاریبکە لە ڕێکخستنەکان ئەم دەسەڵاتە پێویستە بۆ \nکردنەوەی پەنجەرەی بچووک - reCAPTCHA - reCAPTCHA داواکاری + reCAPTCHA + reCAPTCHA داواکاری reCAPTCHA داواکراوە داگرتن پیت و ژمارەکان diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index 43fe9d862..f84a3c23c 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -153,8 +153,8 @@ Prašome pasirinkti galimą atsisiuntimų aplankalą Šis leidimas nereikalingas, kad atidarytiviššokančio lango rėžime - reCAPTCHA - reCAPTCHA iššūkis + reCAPTCHA + reCAPTCHA iššūkis reCAPTCHA prašomas iššūkis Prenumeruoti diff --git a/app/src/main/res/values-mk/strings.xml b/app/src/main/res/values-mk/strings.xml index c9388a78a..96b4c8819 100644 --- a/app/src/main/res/values-mk/strings.xml +++ b/app/src/main/res/values-mk/strings.xml @@ -230,8 +230,8 @@ Одберете достапна локација за превземања Оваа привилегија е потребна за \nотворање во подпрозорче - „reCAPTCHA“ - reCAPTCHA Предизвик + „reCAPTCHA“ + reCAPTCHA Предизвик Потребен е reCAPTCHA предизвик Превземања Дозволени знаци во имињата на датотеките diff --git a/app/src/main/res/values-ms/strings.xml b/app/src/main/res/values-ms/strings.xml index 354e7b7de..f53450e13 100644 --- a/app/src/main/res/values-ms/strings.xml +++ b/app/src/main/res/values-ms/strings.xml @@ -258,8 +258,8 @@ Kebenaran ini diperlukan untuk \nbuka dalam mod popup 1 item dipadamkan. - reCAPTCHA - Cabaran reCAPTCHA + reCAPTCHA + Cabaran reCAPTCHA Meminta kod reCAPTCHA Muat turun Karakter yang dibenarkan dalam nama fail diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml index d01647f5d..c20161f7d 100644 --- a/app/src/main/res/values-nb-rNO/strings.xml +++ b/app/src/main/res/values-nb-rNO/strings.xml @@ -106,8 +106,8 @@ Nytt mål Feilaktig nettadresse eller manglende internettilknytning Definer en nedlastingsmappe senere i innstillingene - reCAPTCHA - reCAPTCHA-oppgave + reCAPTCHA + reCAPTCHA-oppgave Åpne i oppsprettsmodus NewPipe oppsprettsmodus Forvalgt oppsprettsoppløsning diff --git a/app/src/main/res/values-nl-rBE/strings.xml b/app/src/main/res/values-nl-rBE/strings.xml index 198979def..de96152ec 100644 --- a/app/src/main/res/values-nl-rBE/strings.xml +++ b/app/src/main/res/values-nl-rBE/strings.xml @@ -230,8 +230,8 @@ Gekopieerd naar klembord Kies een beschikbare downloadmap Deze toestemming is vereist voor te openen in pop-upmodus - reCAPTCHA - reCAPTCHA-uitdaging + reCAPTCHA + reCAPTCHA-uitdaging reCAPTCHA-uitdaging gevraagd Download Toegelaten tekens in bestandsnamen diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 9ecc936eb..1cd1391a0 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -107,8 +107,8 @@ Gekopieerd naar klembord Kies een beschikbare downloadmap Zwart - reCAPTCHA - reCAPTCHA-uitdaging + reCAPTCHA + reCAPTCHA-uitdaging reCAPTCHA-uitdaging gevraagd Openen in pop-upmodus Alles diff --git a/app/src/main/res/values-pa/strings.xml b/app/src/main/res/values-pa/strings.xml index 0e579720a..7e39321e0 100644 --- a/app/src/main/res/values-pa/strings.xml +++ b/app/src/main/res/values-pa/strings.xml @@ -237,8 +237,8 @@ ਬਾਅਦ ਵਿੱਚ ਸੈਟਿੰਗਾਂ ਵਿਚੋਂ ਇੱਕ ਡਾਉਨਲੋਡ ਫੋਲਡਰ ਨੂੰ ਚੁਣੋ ਪੌਪ-ਅਪ ਮੋਡ ਵਿੱਚ ਖੋਲ੍ਹਣ ਵਾਸਤੇ ਇਸ ਇਜਾਜ਼ਤ ਦੀ ਲੋੜ ਹੈ 1 ਆਈਟਮ ਮਿਟਾਈ ਗਈ. - ReCaptcha - ReCaptcha ਚੁਣੌਤੀ + ReCaptcha + ReCaptcha ਚੁਣੌਤੀ ReCaptcha ਚੁਣੌਤੀ ਲਈ ਬੇਨਤੀ ਡਾਊਨਲੋਡ ਫਾਈਲ ਨਾਮ ਵਿੱਚ ਪ੍ਰਵਾਨਿਤ ਅੱਖਰ diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 0da89ad48..0009fa8d1 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -106,8 +106,8 @@ Awaria aplikacji/interfejsu (Eksperymentalne) Wymuś pobieranie przez Tora w celu zwiększenia prywatności (strumieniowe wideo nie jest jeszcze obsługiwane). Start - CAPTCHA - Wyzwanie reCAPTCHA + CAPTCHA + Wyzwanie reCAPTCHA Wymagane wyzwanie dotyczące reCAPTCHA Usuwa dźwięk w niektórych rozdzielczościach Tło diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 45fe51010..04c4e3960 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -50,8 +50,8 @@ Próximo Abrir no navegador Pausar - reCAPTCHA - Desafio reCAPTCHA + reCAPTCHA + Desafio reCAPTCHA Desafio reCAPTCHA solicitado Reportar um erro Tentar novamente diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 98b85bcab..64de827bf 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -117,8 +117,8 @@ B Esta permissão é necessária \npara o modo de janela - reCAPTCHA - Desafio reCAPTCHA + reCAPTCHA + Desafio reCAPTCHA Desafio reCAPTCHA solicitado Modo de janela autónoma do NewPipe Reproduzir no modo de janela autónoma diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 358de0ca8..e304e862d 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -106,8 +106,8 @@ Deschide in modul popup Aceasta permisiune este necesara pentru a deschide în mod pop-up - ReCAPTCHA - Provocare reCAPTCHA + ReCAPTCHA + Provocare reCAPTCHA reCAPTCHA nouă cerută NewPipe mod pop-up "Rezoluție pop-up inițială " diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 1da98cc74..c2e8b4d4e 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -124,7 +124,7 @@ Что:\\nЗапрос:\\nЯзык контента:\\nСервис:\\nВремя по Гринвичу:\\nПакет:\\nВерсия:\\nВерсия ОС: Это разрешение нужно для \nвоспроизведения в окне - reCAPTCHA + reCAPTCHA Открыть во всплывающем окне Предлагать варианты при поиске Позже @@ -138,7 +138,7 @@ Помнить последние размер и позицию всплывающего окна Поисковые предложения Лучшее разрешение - Запрос reCAPTCHA + Запрос reCAPTCHA Запрошен ввод reCAPTCHA Высокие разрешения NewPipe во всплывающем окне diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index 6624f7a3b..1652aefa1 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -106,8 +106,8 @@ Nemožno načítať obrázok Aplikácia/UP zlyhalo Čo:\\nPožiadavka:\\nJazyk obsahu:\\nSlužba:\\nČas v GMT:\\nBalík:\\nVerzia:\\nVerzia OS: - reCAPTCHA - Výzva reCAPTCHA + reCAPTCHA + Výzva reCAPTCHA Čierna Všetko Kanál diff --git a/app/src/main/res/values-sl/strings.xml b/app/src/main/res/values-sl/strings.xml index a67b48a62..f318ca77e 100644 --- a/app/src/main/res/values-sl/strings.xml +++ b/app/src/main/res/values-sl/strings.xml @@ -124,8 +124,8 @@ Slike ni mogoče naložiti Program se je sesul! - reCAPTCHA - Izziv reCAPTCHA + reCAPTCHA + Izziv reCAPTCHA Zahteva izziva reCAPTCHA Predmet:\\nZahteva:\\nJezik vsebine:\\nStoritev:\\nČas v GMT:\\nPaket:\\nRazličica:\\nRazličica OS: diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml index d5f031ad8..a8abb98e9 100644 --- a/app/src/main/res/values-sr/strings.xml +++ b/app/src/main/res/values-sr/strings.xml @@ -107,8 +107,8 @@ Не могох да учитам слику Апликација/УИ је краховала Шта:\\nЗахтев:\\nЈезик садржаја:\\nУслуга:\\nГМТ време:\\nПакет:\\nИздање:\\nИздање ОС-а:\\nГлоб. ИП распон: - Стопка - reCAPTCHA стопка + Стопка + reCAPTCHA стопка Решите reCAPTCHA стопку Црна Сви diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 89d51493e..e130ae1de 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -186,8 +186,8 @@ Ange en hämtningsmapp senare i inställningar Denna tillåtelse behövs för att \nöppna i popup-läge - reCAPTCHA - reCAPTCHA utmaning + reCAPTCHA + reCAPTCHA utmaning reCAPTCHA utmaning begärd Nedladdning Tillåtna tecken i filnamn diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index c6603382d..ee070eb81 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -124,8 +124,8 @@ B Bu izin, açılır pencere modunda \naçmak için gereklidir - reCAPTCHA - reCAPTCHA formu + reCAPTCHA + reCAPTCHA formu reCAPTCHA formu istendi Arka plan Açılır pencere diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 6aea1ad79..ef5dbee53 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -184,7 +184,7 @@ Помилковий URL або немає доступу в Інтернет Цей дозвіл потрібен для перегляду \nу віконному режимі - reCAPTCHA + reCAPTCHA Завантаження Допустимі символи у іменах файлів Недопустимі символи замінити на цей @@ -256,7 +256,7 @@ %s переглядів Нове завдання - Перевірка reCAPTCHA + Перевірка reCAPTCHA Запит на перевірку reCAPTCHA © %1$s, %2$s під %3$s Учасники diff --git a/app/src/main/res/values-ur/strings.xml b/app/src/main/res/values-ur/strings.xml index 724c9c3ed..ba8aa6b82 100644 --- a/app/src/main/res/values-ur/strings.xml +++ b/app/src/main/res/values-ur/strings.xml @@ -230,8 +230,8 @@ کلپ بورڈ میں کاپی کریں براہ کرم بعد میں ترتیبات میں ڈاؤن لوڈ فولڈر کی وضاحت رکھیں پوپ اپ موڈ میں کھولنے کیلئے اس اجازت کی ضرورت ہے - reCAPTCHA - reCAPTCHA چیلنج + reCAPTCHA + reCAPTCHA چیلنج reCAPTCHA چیلینج کی درخواست کی گئی ڈاؤن لوڈ فائل ناموں میں حروف کی اجازت ہے diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index ab0983e7a..bfde056b0 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -135,8 +135,8 @@ Chọn một thư mục tải về có sẵn trong cài đặt Cần quyền này để \nmở trong chế độ popup - ReCAPTCHA - reCAPTCHA + ReCAPTCHA + reCAPTCHA Yêu cầu reCAPTCHA Giới thiệu về NewPipe Cài đặt diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 9aa4b9245..0282e6c92 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -117,8 +117,8 @@ 无法加载图像 应用/界面已崩溃 原因:\\n请求:\\n内容语言:\\n服务:\\nGMT时间:\\n包:\\n版本:\\n操作系统版本: - reCAPTCHA - reCAPTCHA 验证 + reCAPTCHA + reCAPTCHA 验证 需要 reCAPTCHA 验证 diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index 3294094dc..20b14d7ea 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -120,8 +120,8 @@ 事件:\\n請求:\\n內容語言:\\n服務:\\nGMT 時間:\\nPackage:\\n版本:\\n作業系統版本: K M - reCAPTCHA - reCAPTCHA 挑戰 + reCAPTCHA + reCAPTCHA 挑戰 畫中畫模式需要此權限 需完成 reCAPTCHA 挑戰 啟用此選項將導致某些解像度的影片失去聲音 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 6cb16623f..388f4a8cd 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -136,8 +136,8 @@ 已複製至剪貼簿 稍後請在設定中選擇下載資料夾 使用懸浮視窗模式需要此權限 - reCAPTCHA 驗證 - reCAPTCHA 驗證 + reCAPTCHA 驗證 + reCAPTCHA 驗證 已請求 reCAPTCHA 驗證 懸浮視窗 直播 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e1b2cc0a4..56ecc3356 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -326,10 +326,11 @@ MD5 SHA-1 - reCAPTCHA - reCAPTCHA challenge + + reCAPTCHA + reCAPTCHA challenge + Press \"Done\" when solved reCAPTCHA challenge requested - Download Allowed characters in filenames From a3d8848825d52226479f7d14d5ddbb7c0d3bf605 Mon Sep 17 00:00:00 2001 From: Stypox Date: Wed, 29 Jan 2020 18:44:46 +0100 Subject: [PATCH 07/24] Add "Done" drawable (only white since it is used on toolbar) --- app/src/main/res/drawable/ic_done_white_24dp.xml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 app/src/main/res/drawable/ic_done_white_24dp.xml diff --git a/app/src/main/res/drawable/ic_done_white_24dp.xml b/app/src/main/res/drawable/ic_done_white_24dp.xml new file mode 100644 index 000000000..cab2aed1a --- /dev/null +++ b/app/src/main/res/drawable/ic_done_white_24dp.xml @@ -0,0 +1,5 @@ + + + From daa4fd510320f2ee8a898a38b3851d6408e50a93 Mon Sep 17 00:00:00 2001 From: Stypox Date: Wed, 29 Jan 2020 19:36:57 +0100 Subject: [PATCH 08/24] Fix ReCaptchaActivity crash and save cookies correctly --- .../org/schabi/newpipe/ReCaptchaActivity.java | 155 ++++++++++-------- 1 file changed, 86 insertions(+), 69 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/ReCaptchaActivity.java b/app/src/main/java/org/schabi/newpipe/ReCaptchaActivity.java index 0a2d51b53..533379dbb 100644 --- a/app/src/main/java/org/schabi/newpipe/ReCaptchaActivity.java +++ b/app/src/main/java/org/schabi/newpipe/ReCaptchaActivity.java @@ -1,6 +1,5 @@ package org.schabi.newpipe; -import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; import android.os.Build; @@ -9,12 +8,18 @@ import androidx.core.app.NavUtils; import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; + +import android.util.Log; +import android.view.Menu; import android.view.MenuItem; import android.webkit.CookieManager; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + /* * Created by beneth on 06.12.16. * @@ -37,18 +42,17 @@ import android.webkit.WebViewClient; public class ReCaptchaActivity extends AppCompatActivity { public static final int RECAPTCHA_REQUEST = 10; public static final String RECAPTCHA_URL_EXTRA = "recaptcha_url_extra"; - public static final String TAG = ReCaptchaActivity.class.toString(); public static final String YT_URL = "https://www.youtube.com"; - private String url; + private String foundCookies = ""; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_recaptcha); - url = getIntent().getStringExtra(RECAPTCHA_URL_EXTRA); + String url = getIntent().getStringExtra(RECAPTCHA_URL_EXTRA); if (url == null || url.isEmpty()) { url = YT_URL; } @@ -60,26 +64,24 @@ public class ReCaptchaActivity extends AppCompatActivity { Toolbar toolbar = findViewById(R.id.toolbar); setSupportActionBar(toolbar); - ActionBar actionBar = getSupportActionBar(); - if (actionBar != null) { - actionBar.setDisplayHomeAsUpEnabled(true); - actionBar.setTitle(R.string.reCaptcha_title); - actionBar.setDisplayShowTitleEnabled(true); - } - WebView myWebView = findViewById(R.id.reCaptchaWebView); // Enable Javascript WebSettings webSettings = myWebView.getSettings(); webSettings.setJavaScriptEnabled(true); - ReCaptchaWebViewClient webClient = new ReCaptchaWebViewClient(this); - myWebView.setWebViewClient(webClient); + myWebView.setWebViewClient(new WebViewClient() { + @Override + public void onPageFinished(WebView view, String url) { + super.onPageFinished(view, url); + handleCookies(CookieManager.getInstance().getCookie(url)); + } + }); // Cleaning cache, history and cookies from webView myWebView.clearCache(true); myWebView.clearHistory(); - android.webkit.CookieManager cookieManager = CookieManager.getInstance(); + android.webkit.CookieManager cookieManager = CookieManager .getInstance(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { cookieManager.removeAllCookies(aBoolean -> {}); } else { @@ -89,74 +91,89 @@ public class ReCaptchaActivity extends AppCompatActivity { myWebView.loadUrl(url); } - private class ReCaptchaWebViewClient extends WebViewClient { - private final Activity context; - private String mCookies; + @Override + public boolean onCreateOptionsMenu(Menu menu) { + boolean ret = super.onCreateOptionsMenu(menu); - ReCaptchaWebViewClient(Activity ctx) { - context = ctx; + ActionBar actionBar = getSupportActionBar(); + if (actionBar != null) { + actionBar.setDisplayHomeAsUpEnabled(true); + actionBar.setHomeAsUpIndicator(getResources().getDrawable(R.drawable.ic_done_white_24dp)); + actionBar.setTitle(R.string.title_activity_recaptcha); + actionBar.setSubtitle(R.string.subtitle_activity_recaptcha); } - @Override - public void onPageStarted(WebView view, String url, Bitmap favicon) { - // TODO: Start Loader - super.onPageStarted(view, url, favicon); - } + return ret; + } - @Override - public void onPageFinished(WebView view, String url) { - String cookies = CookieManager.getInstance().getCookie(url); - - // TODO: Stop Loader - - // find cookies : s_gl & goojf and Add cookies to Downloader - if (find_access_cookies(cookies)) { - // Give cookies to Downloader class - DownloaderImpl.getInstance().setCookies(mCookies); - - // Closing activity and return to parent - setResult(RESULT_OK); - finish(); - } - } - - private boolean find_access_cookies(String cookies) { - boolean ret = false; - String c_s_gl = ""; - String c_goojf = ""; - - String[] parts = cookies.split("; "); - for (String part : parts) { - if (part.trim().startsWith("s_gl")) { - c_s_gl = part.trim(); - } - if (part.trim().startsWith("goojf")) { - c_goojf = part.trim(); - } - } - if (c_s_gl.length() > 0 && c_goojf.length() > 0) { - ret = true; - //mCookies = c_s_gl + "; " + c_goojf; - // Youtube seems to also need the other cookies: - mCookies = cookies; - } - - return ret; - } + @Override + public void onBackPressed() { + saveCookiesAndFinish(); } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); switch (id) { - case android.R.id.home: { - Intent intent = new Intent(this, org.schabi.newpipe.MainActivity.class); - intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - NavUtils.navigateUpTo(this, intent); + case android.R.id.home: + saveCookiesAndFinish(); return true; - } default: return false; } } + + private void saveCookiesAndFinish() { + if (!foundCookies.isEmpty()) { + // Give cookies to Downloader class + DownloaderImpl.getInstance().setCookies(foundCookies); + setResult(RESULT_OK); + } + + Intent intent = new Intent(this, org.schabi.newpipe.MainActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + NavUtils.navigateUpTo(this, intent); + } + + + + private void handleCookies(@Nullable String cookies) { + if (MainActivity.DEBUG) Log.d(TAG, "handleCookies: cookies=" + (cookies == null ? "null" : cookies)); + if (cookies == null) return; + + addYoutubeCookies(cookies); + // add other methods to extract cookies here + } + + private void addYoutubeCookies(@Nonnull String cookies) { + String c_s_gl = ""; + String c_goojf = ""; + + String[] parts = cookies.split(";"); + for (String part : parts) { + String trimmedPart = part.trim(); + if (trimmedPart.startsWith("s_gl")) { + c_s_gl = trimmedPart; + } + if (trimmedPart.startsWith("goojf")) { + c_goojf = trimmedPart; + } + } + if (c_s_gl.length() > 0 && c_goojf.length() > 0) { + // addCookie(c_s_gl); + // addCookie(c_goojf); + // Youtube seems to also need the other cookies: + addCookie(cookies); + } + } + + private void addCookie(String cookie) { + if (foundCookies.isEmpty() || foundCookies.endsWith("; ")) { + foundCookies += cookie; + } else if (foundCookies.endsWith(";")) { + foundCookies += " " + cookie; + } else { + foundCookies += "; " + cookie; + } + } } From 4e1638f86e75d546154b28714fd1bd2f9a426e9a Mon Sep 17 00:00:00 2001 From: Stypox Date: Wed, 29 Jan 2020 19:37:43 +0100 Subject: [PATCH 09/24] Remove space between "Done" button and ReCaptchaActivity title --- app/src/main/res/layout/activity_recaptcha.xml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/layout/activity_recaptcha.xml b/app/src/main/res/layout/activity_recaptcha.xml index 411ada498..8e277d0c5 100644 --- a/app/src/main/res/layout/activity_recaptcha.xml +++ b/app/src/main/res/layout/activity_recaptcha.xml @@ -14,9 +14,8 @@ android:minHeight="?attr/actionBarSize" android:theme="@style/ThemeOverlay.AppCompat.ActionBar" app:popupTheme="@style/ThemeOverlay.AppCompat.ActionBar" - app:titleTextAppearance="@style/Toolbar.Title"> - - + app:titleTextAppearance="@style/Toolbar.Title" + app:contentInsetStartWithNavigation="0dp" /> Date: Thu, 30 Jan 2020 21:05:57 +0100 Subject: [PATCH 10/24] Improve formatting --- .../main/java/org/schabi/newpipe/ReCaptchaActivity.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/ReCaptchaActivity.java b/app/src/main/java/org/schabi/newpipe/ReCaptchaActivity.java index 533379dbb..7bd632f39 100644 --- a/app/src/main/java/org/schabi/newpipe/ReCaptchaActivity.java +++ b/app/src/main/java/org/schabi/newpipe/ReCaptchaActivity.java @@ -51,18 +51,17 @@ public class ReCaptchaActivity extends AppCompatActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_recaptcha); + Toolbar toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); String url = getIntent().getStringExtra(RECAPTCHA_URL_EXTRA); if (url == null || url.isEmpty()) { url = YT_URL; } - // Set return to Cancel by default setResult(RESULT_CANCELED); - Toolbar toolbar = findViewById(R.id.toolbar); - setSupportActionBar(toolbar); WebView myWebView = findViewById(R.id.reCaptchaWebView); @@ -81,7 +80,7 @@ public class ReCaptchaActivity extends AppCompatActivity { // Cleaning cache, history and cookies from webView myWebView.clearCache(true); myWebView.clearHistory(); - android.webkit.CookieManager cookieManager = CookieManager .getInstance(); + android.webkit.CookieManager cookieManager = CookieManager.getInstance(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { cookieManager.removeAllCookies(aBoolean -> {}); } else { From 0cc890a1d1384266916a9382309fcaa3cdbb0115 Mon Sep 17 00:00:00 2001 From: Stypox Date: Sat, 1 Feb 2020 17:53:43 +0100 Subject: [PATCH 11/24] Move "Done" button and make it theme conpliant in ReCaptcha --- .../java/org/schabi/newpipe/ReCaptchaActivity.java | 12 +++++++----- app/src/main/res/drawable/ic_done_black_24dp.xml | 9 +++++++++ app/src/main/res/layout/activity_recaptcha.xml | 3 +-- app/src/main/res/menu/menu_recaptcha.xml | 10 ++++++++++ app/src/main/res/values/attrs.xml | 1 + app/src/main/res/values/strings.xml | 1 + app/src/main/res/values/styles.xml | 2 ++ 7 files changed, 31 insertions(+), 7 deletions(-) create mode 100644 app/src/main/res/drawable/ic_done_black_24dp.xml create mode 100644 app/src/main/res/menu/menu_recaptcha.xml diff --git a/app/src/main/java/org/schabi/newpipe/ReCaptchaActivity.java b/app/src/main/java/org/schabi/newpipe/ReCaptchaActivity.java index 7bd632f39..f2970345f 100644 --- a/app/src/main/java/org/schabi/newpipe/ReCaptchaActivity.java +++ b/app/src/main/java/org/schabi/newpipe/ReCaptchaActivity.java @@ -17,6 +17,8 @@ import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; +import org.schabi.newpipe.util.ThemeHelper; + import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -49,6 +51,7 @@ public class ReCaptchaActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { + ThemeHelper.setTheme(this); super.onCreate(savedInstanceState); setContentView(R.layout.activity_recaptcha); Toolbar toolbar = findViewById(R.id.toolbar); @@ -92,17 +95,16 @@ public class ReCaptchaActivity extends AppCompatActivity { @Override public boolean onCreateOptionsMenu(Menu menu) { - boolean ret = super.onCreateOptionsMenu(menu); + getMenuInflater().inflate(R.menu.menu_recaptcha, menu); ActionBar actionBar = getSupportActionBar(); if (actionBar != null) { - actionBar.setDisplayHomeAsUpEnabled(true); - actionBar.setHomeAsUpIndicator(getResources().getDrawable(R.drawable.ic_done_white_24dp)); + actionBar.setDisplayHomeAsUpEnabled(false); actionBar.setTitle(R.string.title_activity_recaptcha); actionBar.setSubtitle(R.string.subtitle_activity_recaptcha); } - return ret; + return true; } @Override @@ -114,7 +116,7 @@ public class ReCaptchaActivity extends AppCompatActivity { public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); switch (id) { - case android.R.id.home: + case R.id.menu_item_done: saveCookiesAndFinish(); return true; default: diff --git a/app/src/main/res/drawable/ic_done_black_24dp.xml b/app/src/main/res/drawable/ic_done_black_24dp.xml new file mode 100644 index 000000000..7affe9ba9 --- /dev/null +++ b/app/src/main/res/drawable/ic_done_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_recaptcha.xml b/app/src/main/res/layout/activity_recaptcha.xml index 8e277d0c5..759e1f296 100644 --- a/app/src/main/res/layout/activity_recaptcha.xml +++ b/app/src/main/res/layout/activity_recaptcha.xml @@ -14,8 +14,7 @@ android:minHeight="?attr/actionBarSize" android:theme="@style/ThemeOverlay.AppCompat.ActionBar" app:popupTheme="@style/ThemeOverlay.AppCompat.ActionBar" - app:titleTextAppearance="@style/Toolbar.Title" - app:contentInsetStartWithNavigation="0dp" /> + app:titleTextAppearance="@style/Toolbar.Title"/> + + + + \ No newline at end of file diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml index c64ed1256..88925a598 100644 --- a/app/src/main/res/values/attrs.xml +++ b/app/src/main/res/values/attrs.xml @@ -45,6 +45,7 @@ + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 56ecc3356..b16713172 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -331,6 +331,7 @@ reCAPTCHA challenge Press \"Done\" when solved reCAPTCHA challenge requested + Done Download Allowed characters in filenames diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 679d4d1cd..8047ef7f4 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -60,6 +60,7 @@ @drawable/ic_grid_black_24dp @drawable/ic_delete_black_24dp @drawable/ic_settings_update_black + @drawable/ic_done_black_24dp @color/light_separator_color @color/light_contrast_background_color @@ -129,6 +130,7 @@ @drawable/ic_delete_white_24dp @drawable/ic_pause_white_24dp @drawable/ic_settings_update_white + @drawable/ic_done_white_24dp @color/dark_separator_color @color/dark_contrast_background_color From 9b09028440b2b12b9dfdac786d6489bdbbff131c Mon Sep 17 00:00:00 2001 From: Stypox Date: Sat, 1 Feb 2020 17:59:16 +0100 Subject: [PATCH 12/24] Try to extract cookies just before closing recaptcha activity Even if the page didn't auto-close --- .../org/schabi/newpipe/ReCaptchaActivity.java | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/ReCaptchaActivity.java b/app/src/main/java/org/schabi/newpipe/ReCaptchaActivity.java index f2970345f..06094cebd 100644 --- a/app/src/main/java/org/schabi/newpipe/ReCaptchaActivity.java +++ b/app/src/main/java/org/schabi/newpipe/ReCaptchaActivity.java @@ -47,6 +47,7 @@ public class ReCaptchaActivity extends AppCompatActivity { public static final String TAG = ReCaptchaActivity.class.toString(); public static final String YT_URL = "https://www.youtube.com"; + private WebView webView; private String foundCookies = ""; @Override @@ -66,23 +67,23 @@ public class ReCaptchaActivity extends AppCompatActivity { setResult(RESULT_CANCELED); - WebView myWebView = findViewById(R.id.reCaptchaWebView); + webView = findViewById(R.id.reCaptchaWebView); // Enable Javascript - WebSettings webSettings = myWebView.getSettings(); + WebSettings webSettings = webView.getSettings(); webSettings.setJavaScriptEnabled(true); - myWebView.setWebViewClient(new WebViewClient() { + webView.setWebViewClient(new WebViewClient() { @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); - handleCookies(CookieManager.getInstance().getCookie(url)); + handleCookies(url); } }); // Cleaning cache, history and cookies from webView - myWebView.clearCache(true); - myWebView.clearHistory(); + webView.clearCache(true); + webView.clearHistory(); android.webkit.CookieManager cookieManager = CookieManager.getInstance(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { cookieManager.removeAllCookies(aBoolean -> {}); @@ -90,7 +91,7 @@ public class ReCaptchaActivity extends AppCompatActivity { cookieManager.removeAllCookie(); } - myWebView.loadUrl(url); + webView.loadUrl(url); } @Override @@ -125,6 +126,7 @@ public class ReCaptchaActivity extends AppCompatActivity { } private void saveCookiesAndFinish() { + handleCookies(webView.getUrl()); // try to get cookies of unclosed page if (!foundCookies.isEmpty()) { // Give cookies to Downloader class DownloaderImpl.getInstance().setCookies(foundCookies); @@ -138,8 +140,10 @@ public class ReCaptchaActivity extends AppCompatActivity { - private void handleCookies(@Nullable String cookies) { - if (MainActivity.DEBUG) Log.d(TAG, "handleCookies: cookies=" + (cookies == null ? "null" : cookies)); + private void handleCookies(String url) { + String cookies = CookieManager.getInstance().getCookie(url); + if (MainActivity.DEBUG) Log.d(TAG, "handleCookies: url=" + url + "; cookies=" + (cookies == null ? "null" : cookies)); + Log.e(TAG, "handleCookies: url=" + url + "; cookies=" + (cookies == null ? "null" : cookies)); if (cookies == null) return; addYoutubeCookies(cookies); From 1bf55c21392090855f2c5e0363e221f92f2827ec Mon Sep 17 00:00:00 2001 From: Stypox Date: Sat, 1 Feb 2020 18:23:57 +0100 Subject: [PATCH 13/24] Remove left-behind Log --- app/src/main/java/org/schabi/newpipe/ReCaptchaActivity.java | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/ReCaptchaActivity.java b/app/src/main/java/org/schabi/newpipe/ReCaptchaActivity.java index 06094cebd..8abcd2435 100644 --- a/app/src/main/java/org/schabi/newpipe/ReCaptchaActivity.java +++ b/app/src/main/java/org/schabi/newpipe/ReCaptchaActivity.java @@ -143,7 +143,6 @@ public class ReCaptchaActivity extends AppCompatActivity { private void handleCookies(String url) { String cookies = CookieManager.getInstance().getCookie(url); if (MainActivity.DEBUG) Log.d(TAG, "handleCookies: url=" + url + "; cookies=" + (cookies == null ? "null" : cookies)); - Log.e(TAG, "handleCookies: url=" + url + "; cookies=" + (cookies == null ? "null" : cookies)); if (cookies == null) return; addYoutubeCookies(cookies); From 6da90961762b92a2d9cae90e4b5879fdf481ce5a Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 2 Feb 2020 21:33:07 +0100 Subject: [PATCH 14/24] Fix addYoutubeCookies functions (Yt changed things lately) --- .../org/schabi/newpipe/ReCaptchaActivity.java | 21 +++++-------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/ReCaptchaActivity.java b/app/src/main/java/org/schabi/newpipe/ReCaptchaActivity.java index 8abcd2435..566e1fc76 100644 --- a/app/src/main/java/org/schabi/newpipe/ReCaptchaActivity.java +++ b/app/src/main/java/org/schabi/newpipe/ReCaptchaActivity.java @@ -150,28 +150,17 @@ public class ReCaptchaActivity extends AppCompatActivity { } private void addYoutubeCookies(@Nonnull String cookies) { - String c_s_gl = ""; - String c_goojf = ""; - - String[] parts = cookies.split(";"); - for (String part : parts) { - String trimmedPart = part.trim(); - if (trimmedPart.startsWith("s_gl")) { - c_s_gl = trimmedPart; - } - if (trimmedPart.startsWith("goojf")) { - c_goojf = trimmedPart; - } - } - if (c_s_gl.length() > 0 && c_goojf.length() > 0) { - // addCookie(c_s_gl); - // addCookie(c_goojf); + if (cookies.contains("s_gl=") || cookies.contains("goojf=") || cookies.contains("VISITOR_INFO1_LIVE=")) { // Youtube seems to also need the other cookies: addCookie(cookies); } } private void addCookie(String cookie) { + if (foundCookies.contains(cookie)) { + return; + } + if (foundCookies.isEmpty() || foundCookies.endsWith("; ")) { foundCookies += cookie; } else if (foundCookies.endsWith(";")) { From b6841158df60b066a0b53fe80f4a780d822c227a Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 2 Feb 2020 21:48:45 +0100 Subject: [PATCH 15/24] Remove unused imports and clean up comment style --- .../java/org/schabi/newpipe/ReCaptchaActivity.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/ReCaptchaActivity.java b/app/src/main/java/org/schabi/newpipe/ReCaptchaActivity.java index 566e1fc76..d72f729b5 100644 --- a/app/src/main/java/org/schabi/newpipe/ReCaptchaActivity.java +++ b/app/src/main/java/org/schabi/newpipe/ReCaptchaActivity.java @@ -1,7 +1,6 @@ package org.schabi.newpipe; import android.content.Intent; -import android.graphics.Bitmap; import android.os.Build; import android.os.Bundle; import androidx.core.app.NavUtils; @@ -20,7 +19,6 @@ import android.webkit.WebViewClient; import org.schabi.newpipe.util.ThemeHelper; import javax.annotation.Nonnull; -import javax.annotation.Nullable; /* * Created by beneth on 06.12.16. @@ -63,13 +61,13 @@ public class ReCaptchaActivity extends AppCompatActivity { url = YT_URL; } - // Set return to Cancel by default + // set return to Cancel by default setResult(RESULT_CANCELED); webView = findViewById(R.id.reCaptchaWebView); - // Enable Javascript + // enable Javascript WebSettings webSettings = webView.getSettings(); webSettings.setJavaScriptEnabled(true); @@ -81,7 +79,7 @@ public class ReCaptchaActivity extends AppCompatActivity { } }); - // Cleaning cache, history and cookies from webView + // cleaning cache, history and cookies from webView webView.clearCache(true); webView.clearHistory(); android.webkit.CookieManager cookieManager = CookieManager.getInstance(); @@ -128,7 +126,7 @@ public class ReCaptchaActivity extends AppCompatActivity { private void saveCookiesAndFinish() { handleCookies(webView.getUrl()); // try to get cookies of unclosed page if (!foundCookies.isEmpty()) { - // Give cookies to Downloader class + // give cookies to Downloader class DownloaderImpl.getInstance().setCookies(foundCookies); setResult(RESULT_OK); } @@ -151,7 +149,7 @@ public class ReCaptchaActivity extends AppCompatActivity { private void addYoutubeCookies(@Nonnull String cookies) { if (cookies.contains("s_gl=") || cookies.contains("goojf=") || cookies.contains("VISITOR_INFO1_LIVE=")) { - // Youtube seems to also need the other cookies: + // youtube seems to also need the other cookies: addCookie(cookies); } } From af411a61ae62b37565117957fdecdfdbc855b07d Mon Sep 17 00:00:00 2001 From: Harshal Lele Date: Tue, 4 Feb 2020 16:40:57 +0530 Subject: [PATCH 16/24] added ability to copy comments on long press --- .../holder/CommentsMiniInfoItemHolder.java | 29 ++++++++++++++++++- app/src/main/res/values/settings_keys.xml | 1 + app/src/main/res/values/strings.xml | 1 + app/src/main/res/xml/content_settings.xml | 6 ++++ 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java index 4d94ec392..4b1d1bdae 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java @@ -1,9 +1,16 @@ package org.schabi.newpipe.info_list.holder; -import androidx.appcompat.app.AppCompatActivity; +import android.content.ClipData; +import android.content.ClipboardManager; +import android.content.Context; +import android.preference.PreferenceManager; import android.text.util.Linkify; +import android.view.View; import android.view.ViewGroup; import android.widget.TextView; +import android.widget.Toast; + +import androidx.appcompat.app.AppCompatActivity; import org.jsoup.helper.StringUtil; import org.schabi.newpipe.R; @@ -120,6 +127,26 @@ public class CommentsMiniInfoItemHolder extends InfoItemHolder { itemBuilder.getOnCommentsSelectedListener().selected(item); } }); + + boolean copyCommentOnLongPress = PreferenceManager.getDefaultSharedPreferences( + itemBuilder.getContext()).getBoolean(itemBuilder.getContext().getString(R.string.copy_comment_long_press), + false); + + if(copyCommentOnLongPress){ + + itemView.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View view) { + + ClipboardManager clipboardManager = (ClipboardManager) itemBuilder.getContext().getSystemService(Context.CLIPBOARD_SERVICE); + clipboardManager.setPrimaryClip(ClipData.newPlainText(null,itemContentView.getText())); + Toast.makeText(itemBuilder.getContext(), R.string.msg_copied, Toast.LENGTH_SHORT).show(); + return true; + + } + }); + + } } private void ellipsize() { diff --git a/app/src/main/res/values/settings_keys.xml b/app/src/main/res/values/settings_keys.xml index 1a7d61dae..90edd0ef8 100644 --- a/app/src/main/res/values/settings_keys.xml +++ b/app/src/main/res/values/settings_keys.xml @@ -159,6 +159,7 @@ show_play_with_kodi show_next_video show_comments + copy_comment_long_press stream_info_selected_tab show_hold_to_append en diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index dab9bde10..ca5a7527f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -76,6 +76,7 @@ Load thumbnails Show comments Disable to stop showing comments + Copy comment on long press Turn off to prevent loading thumbnails, saving data and memory usage. Changes clear both in-memory and on-disk image cache. Image cache wiped Wipe cached metadata diff --git a/app/src/main/res/xml/content_settings.xml b/app/src/main/res/xml/content_settings.xml index 197c14487..d1080bb4d 100644 --- a/app/src/main/res/xml/content_settings.xml +++ b/app/src/main/res/xml/content_settings.xml @@ -65,6 +65,12 @@ android:title="@string/show_comments_title" android:summary="@string/show_comments_summary"/> + + Date: Tue, 4 Feb 2020 18:01:39 +0530 Subject: [PATCH 17/24] removed settings entry --- .../holder/CommentsMiniInfoItemHolder.java | 26 +++++++------------ app/src/main/res/values/settings_keys.xml | 1 - app/src/main/res/values/strings.xml | 1 - app/src/main/res/xml/content_settings.xml | 5 ---- 4 files changed, 10 insertions(+), 23 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java index 4b1d1bdae..592378dc0 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java @@ -3,7 +3,6 @@ package org.schabi.newpipe.info_list.holder; import android.content.ClipData; import android.content.ClipboardManager; import android.content.Context; -import android.preference.PreferenceManager; import android.text.util.Linkify; import android.view.View; import android.view.ViewGroup; @@ -128,25 +127,20 @@ public class CommentsMiniInfoItemHolder extends InfoItemHolder { } }); - boolean copyCommentOnLongPress = PreferenceManager.getDefaultSharedPreferences( - itemBuilder.getContext()).getBoolean(itemBuilder.getContext().getString(R.string.copy_comment_long_press), - false); - if(copyCommentOnLongPress){ + itemView.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View view) { - itemView.setOnLongClickListener(new View.OnLongClickListener() { - @Override - public boolean onLongClick(View view) { + ClipboardManager clipboardManager = (ClipboardManager) itemBuilder.getContext() + .getSystemService(Context.CLIPBOARD_SERVICE); + clipboardManager.setPrimaryClip(ClipData.newPlainText(null,itemContentView.getText())); + Toast.makeText(itemBuilder.getContext(), R.string.msg_copied, Toast.LENGTH_SHORT).show(); + return true; - ClipboardManager clipboardManager = (ClipboardManager) itemBuilder.getContext().getSystemService(Context.CLIPBOARD_SERVICE); - clipboardManager.setPrimaryClip(ClipData.newPlainText(null,itemContentView.getText())); - Toast.makeText(itemBuilder.getContext(), R.string.msg_copied, Toast.LENGTH_SHORT).show(); - return true; + } + }); - } - }); - - } } private void ellipsize() { diff --git a/app/src/main/res/values/settings_keys.xml b/app/src/main/res/values/settings_keys.xml index 90edd0ef8..1a7d61dae 100644 --- a/app/src/main/res/values/settings_keys.xml +++ b/app/src/main/res/values/settings_keys.xml @@ -159,7 +159,6 @@ show_play_with_kodi show_next_video show_comments - copy_comment_long_press stream_info_selected_tab show_hold_to_append en diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ca5a7527f..dab9bde10 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -76,7 +76,6 @@ Load thumbnails Show comments Disable to stop showing comments - Copy comment on long press Turn off to prevent loading thumbnails, saving data and memory usage. Changes clear both in-memory and on-disk image cache. Image cache wiped Wipe cached metadata diff --git a/app/src/main/res/xml/content_settings.xml b/app/src/main/res/xml/content_settings.xml index d1080bb4d..2187b4a3c 100644 --- a/app/src/main/res/xml/content_settings.xml +++ b/app/src/main/res/xml/content_settings.xml @@ -65,11 +65,6 @@ android:title="@string/show_comments_title" android:summary="@string/show_comments_summary"/> - Date: Wed, 5 Feb 2020 14:48:39 +0530 Subject: [PATCH 18/24] Update CommentsMiniInfoItemHolder.java Co-Authored-By: yausername <5203007+yausername@users.noreply.github.com> --- .../newpipe/info_list/holder/CommentsMiniInfoItemHolder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java index 592378dc0..58f1ab90d 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java @@ -134,7 +134,7 @@ public class CommentsMiniInfoItemHolder extends InfoItemHolder { ClipboardManager clipboardManager = (ClipboardManager) itemBuilder.getContext() .getSystemService(Context.CLIPBOARD_SERVICE); - clipboardManager.setPrimaryClip(ClipData.newPlainText(null,itemContentView.getText())); + clipboardManager.setPrimaryClip(ClipData.newPlainText(null,commentText)); Toast.makeText(itemBuilder.getContext(), R.string.msg_copied, Toast.LENGTH_SHORT).show(); return true; From 34e31807fc864ae99511ded080323aa723dcad56 Mon Sep 17 00:00:00 2001 From: harshlele <45959248+harshlele@users.noreply.github.com> Date: Thu, 6 Feb 2020 18:33:06 +0530 Subject: [PATCH 19/24] removed empty line --- app/src/main/res/xml/content_settings.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/res/xml/content_settings.xml b/app/src/main/res/xml/content_settings.xml index 2187b4a3c..197c14487 100644 --- a/app/src/main/res/xml/content_settings.xml +++ b/app/src/main/res/xml/content_settings.xml @@ -65,7 +65,6 @@ android:title="@string/show_comments_title" android:summary="@string/show_comments_summary"/> - Date: Thu, 6 Feb 2020 17:00:32 -0300 Subject: [PATCH 20/24] Update DataReader.java make rewind() method fully rewind the stream --- app/src/main/java/org/schabi/newpipe/streams/DataReader.java | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/org/schabi/newpipe/streams/DataReader.java b/app/src/main/java/org/schabi/newpipe/streams/DataReader.java index 0e62810c5..75b55cd73 100644 --- a/app/src/main/java/org/schabi/newpipe/streams/DataReader.java +++ b/app/src/main/java/org/schabi/newpipe/streams/DataReader.java @@ -137,6 +137,7 @@ public class DataReader { position = 0; readOffset = readBuffer.length; + readCount = 0; } public boolean canRewind() { From 7045f9711c04a4a0610553f605c8c69a7fd4f21f Mon Sep 17 00:00:00 2001 From: bopol Date: Sun, 2 Feb 2020 16:54:09 +0100 Subject: [PATCH 21/24] fix thumbnail for PeerTube, and description changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit description: - PeerTube: it's now full description (it cut at 250 characters before), and it displays ok (newlines are ok, but markdown isn't) - MediaCCC: descriptions are now displayed well (newlines added) - YouTube: timestamps in descriptions are clickable and work more PeerTube fixes: thumbnail is now high quality age limit is now handled upload date in «recently added» feed is good now (it was one hour delayed) all fixes come from https://github.com/TeamNewPipe/NewPipeExtractor/pull/239, so it need to be merged before this PR --- app/build.gradle | 2 +- .../fragments/detail/VideoDetailFragment.java | 75 +++++++++++++------ 2 files changed, 53 insertions(+), 24 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index f8fc1565f..0f7ad5f92 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -62,7 +62,7 @@ dependencies { exclude module: 'support-annotations' }) - implementation 'com.github.TeamNewPipe:NewPipeExtractor:ff61e284' + implementation 'com.github.B0pol:NewPipeExtractor:5756df8dc7e89b7383d1d1e07a91c30bdab6f868' testImplementation 'junit:junit:4.12' testImplementation 'org.mockito:mockito-core:2.23.0' diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java index f59cfaef0..a297cddf3 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java @@ -2,7 +2,6 @@ package org.schabi.newpipe.fragments.detail; import android.app.Activity; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.net.Uri; @@ -18,7 +17,6 @@ import androidx.fragment.app.Fragment; import androidx.core.content.ContextCompat; import androidx.viewpager.widget.ViewPager; import androidx.appcompat.app.ActionBar; -import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import android.text.Html; import android.text.Spanned; @@ -193,6 +191,14 @@ public class VideoDetailFragment private TabLayout tabLayout; private FrameLayout relatedStreamsLayout; + private static final int DESCRIPTION_HTML = 1; + private static final int DESCRIPTION_MARKDOWN = 2; + private static final int DESCRIPTION_PLAIN_TEXT = 3; + + private static final int YOUTUBE_SERVICE_ID = ServiceList.YouTube.getServiceId(); + private static final int MEDIACCC_SERVICE_ID = ServiceList.MediaCCC.getServiceId(); + private static final int PEERTUBE_SERVICE_ID = ServiceList.PeerTube.getServiceId(); + /*////////////////////////////////////////////////////////////////////////*/ @@ -483,7 +489,6 @@ public class VideoDetailFragment videoUploadDateView = rootView.findViewById(R.id.detail_upload_date_view); videoDescriptionView = rootView.findViewById(R.id.detail_description_view); videoDescriptionView.setMovementMethod(LinkMovementMethod.getInstance()); - videoDescriptionView.setAutoLinkMask(Linkify.WEB_URLS); thumbsUpTextView = rootView.findViewById(R.id.detail_thumbs_up_count_view); thumbsUpImageView = rootView.findViewById(R.id.detail_thumbs_up_img_view); @@ -919,28 +924,39 @@ public class VideoDetailFragment return sortedVideoStreams != null ? sortedVideoStreams.get(selectedVideoStreamIndex) : null; } - private void prepareDescription(final String descriptionHtml) { - if (TextUtils.isEmpty(descriptionHtml)) { + private void prepareDescription(final String descriptionText, int descriptionTypeId) { + if (TextUtils.isEmpty(descriptionText)) { return; } - disposables.add(Single.just(descriptionHtml) - .map((@io.reactivex.annotations.NonNull String description) -> { - Spanned parsedDescription; - if (Build.VERSION.SDK_INT >= 24) { - parsedDescription = Html.fromHtml(description, 0); - } else { - //noinspection deprecation - parsedDescription = Html.fromHtml(description); - } - return parsedDescription; - }) - .subscribeOn(Schedulers.computation()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe((@io.reactivex.annotations.NonNull Spanned spanned) -> { - videoDescriptionView.setText(spanned); - videoDescriptionView.setVisibility(View.VISIBLE); - })); + if (descriptionTypeId == DESCRIPTION_PLAIN_TEXT) { + videoDescriptionView.setText(descriptionText, TextView.BufferType.SPANNABLE); + videoDescriptionView.setVisibility(View.VISIBLE); + } else if (descriptionTypeId == DESCRIPTION_MARKDOWN) { + //in the future we would use a library or a good method to show markdown. + //rn, we just remove **bold**, and let plain_text otherwise + videoDescriptionView.setText(descriptionText.replace("**", ""), TextView.BufferType.SPANNABLE); + videoDescriptionView.setVisibility(View.VISIBLE); + } else { + //== DESCRIPTION_HTML + disposables.add(Single.just(descriptionText) + .map((@io.reactivex.annotations.NonNull String description) -> { + Spanned parsedDescription; + if (Build.VERSION.SDK_INT >= 24) { + parsedDescription = Html.fromHtml(description, 0); + } else { + //noinspection deprecation + parsedDescription = Html.fromHtml(description); + } + return parsedDescription; + }) + .subscribeOn(Schedulers.computation()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe((@io.reactivex.annotations.NonNull Spanned spanned) -> { + videoDescriptionView.setText(spanned); + videoDescriptionView.setVisibility(View.VISIBLE); + })); + } } private void setHeightThumbnail() { @@ -1126,7 +1142,20 @@ public class VideoDetailFragment videoUploadDateView.setVisibility(View.GONE); } - prepareDescription(info.getDescription()); + int serviceId = info.getServiceId(); + + if (serviceId != YOUTUBE_SERVICE_ID) { + videoDescriptionView.setAutoLinkMask(Linkify.WEB_URLS); + } + + if (serviceId == PEERTUBE_SERVICE_ID) { + prepareDescription(info.getDescription(), DESCRIPTION_MARKDOWN); + } else if (serviceId == MEDIACCC_SERVICE_ID) { + prepareDescription(info.getDescription(), DESCRIPTION_PLAIN_TEXT); + } else { + prepareDescription(info.getDescription(), DESCRIPTION_HTML); + } + updateProgressInfo(info); animateView(spinnerToolbar, true, 500); From badaff8ebcd6f446a6a4b575adba43d627b4c7c2 Mon Sep 17 00:00:00 2001 From: bopol Date: Thu, 6 Feb 2020 23:54:36 +0100 Subject: [PATCH 22/24] refactor Description --- app/build.gradle | 2 +- .../fragments/detail/VideoDetailFragment.java | 60 +++++++------------ 2 files changed, 23 insertions(+), 39 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 0f7ad5f92..728d380c4 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -62,7 +62,7 @@ dependencies { exclude module: 'support-annotations' }) - implementation 'com.github.B0pol:NewPipeExtractor:5756df8dc7e89b7383d1d1e07a91c30bdab6f868' + implementation 'com.github.B0pol:NewPipeExtractor:11bcc78d9c8eb39e8d61a6f4bc4112025937f087' testImplementation 'junit:junit:4.12' testImplementation 'org.mockito:mockito-core:2.23.0' diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java index a297cddf3..c6c8ca04c 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java @@ -56,6 +56,7 @@ import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.services.youtube.extractors.YoutubeStreamExtractor; import org.schabi.newpipe.extractor.stream.AudioStream; +import org.schabi.newpipe.extractor.stream.Description; import org.schabi.newpipe.extractor.stream.Stream; import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.extractor.stream.StreamType; @@ -191,14 +192,6 @@ public class VideoDetailFragment private TabLayout tabLayout; private FrameLayout relatedStreamsLayout; - private static final int DESCRIPTION_HTML = 1; - private static final int DESCRIPTION_MARKDOWN = 2; - private static final int DESCRIPTION_PLAIN_TEXT = 3; - - private static final int YOUTUBE_SERVICE_ID = ServiceList.YouTube.getServiceId(); - private static final int MEDIACCC_SERVICE_ID = ServiceList.MediaCCC.getServiceId(); - private static final int PEERTUBE_SERVICE_ID = ServiceList.PeerTube.getServiceId(); - /*////////////////////////////////////////////////////////////////////////*/ @@ -924,29 +917,24 @@ public class VideoDetailFragment return sortedVideoStreams != null ? sortedVideoStreams.get(selectedVideoStreamIndex) : null; } - private void prepareDescription(final String descriptionText, int descriptionTypeId) { - if (TextUtils.isEmpty(descriptionText)) { + private void prepareDescription(Description description) { + if (TextUtils.isEmpty(description.getContent()) || description == Description.emptyDescription) { return; } - if (descriptionTypeId == DESCRIPTION_PLAIN_TEXT) { - videoDescriptionView.setText(descriptionText, TextView.BufferType.SPANNABLE); - videoDescriptionView.setVisibility(View.VISIBLE); - } else if (descriptionTypeId == DESCRIPTION_MARKDOWN) { - //in the future we would use a library or a good method to show markdown. - //rn, we just remove **bold**, and let plain_text otherwise - videoDescriptionView.setText(descriptionText.replace("**", ""), TextView.BufferType.SPANNABLE); - videoDescriptionView.setVisibility(View.VISIBLE); - } else { - //== DESCRIPTION_HTML - disposables.add(Single.just(descriptionText) - .map((@io.reactivex.annotations.NonNull String description) -> { + if (description.getType() != Description.HTML) { + videoDescriptionView.setAutoLinkMask(Linkify.WEB_URLS); + } + + if (description.getType() == Description.HTML) { + disposables.add(Single.just(description.getContent()) + .map((@io.reactivex.annotations.NonNull String descriptionText) -> { Spanned parsedDescription; if (Build.VERSION.SDK_INT >= 24) { - parsedDescription = Html.fromHtml(description, 0); + parsedDescription = Html.fromHtml(descriptionText, 0); } else { //noinspection deprecation - parsedDescription = Html.fromHtml(description); + parsedDescription = Html.fromHtml(descriptionText); } return parsedDescription; }) @@ -956,6 +944,15 @@ public class VideoDetailFragment videoDescriptionView.setText(spanned); videoDescriptionView.setVisibility(View.VISIBLE); })); + } else if (description.getType() == Description.MARKDOWN) { + //in the future we would use a library or a good method to show markdown. + //rn, we just remove **bold**, and let PLAIN_TEXT otherwise + videoDescriptionView.setText(description.getContent().replace("**", ""), TextView.BufferType.SPANNABLE); + videoDescriptionView.setVisibility(View.VISIBLE); + } else { + //== Description.PLAIN_TEXT + videoDescriptionView.setText(description.getContent(), TextView.BufferType.SPANNABLE); + videoDescriptionView.setVisibility(View.VISIBLE); } } @@ -1142,20 +1139,7 @@ public class VideoDetailFragment videoUploadDateView.setVisibility(View.GONE); } - int serviceId = info.getServiceId(); - - if (serviceId != YOUTUBE_SERVICE_ID) { - videoDescriptionView.setAutoLinkMask(Linkify.WEB_URLS); - } - - if (serviceId == PEERTUBE_SERVICE_ID) { - prepareDescription(info.getDescription(), DESCRIPTION_MARKDOWN); - } else if (serviceId == MEDIACCC_SERVICE_ID) { - prepareDescription(info.getDescription(), DESCRIPTION_PLAIN_TEXT); - } else { - prepareDescription(info.getDescription(), DESCRIPTION_HTML); - } - + prepareDescription(info.getDescription()); updateProgressInfo(info); animateView(spinnerToolbar, true, 500); From 2d62fa401d63551785859b0d909f8414e94ba191 Mon Sep 17 00:00:00 2001 From: bopol Date: Sat, 8 Feb 2020 09:56:37 +0100 Subject: [PATCH 23/24] real markdown support for descriptions and update third-party licences in about page --- app/build.gradle | 4 ++++ .../org/schabi/newpipe/about/AboutActivity.java | 16 +++++++++------- .../fragments/detail/VideoDetailFragment.java | 14 +++++++------- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 728d380c4..65ab78ffa 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -53,6 +53,7 @@ ext { okHttpLibVersion = '3.12.6' icepickLibVersion = '3.2.0' stethoLibVersion = '1.5.0' + markwonVersion = '4.2.1' } dependencies { @@ -108,4 +109,7 @@ dependencies { implementation "com.squareup.okhttp3:okhttp:${okHttpLibVersion}" debugImplementation "com.facebook.stetho:stetho-okhttp3:${stethoLibVersion}" + + implementation "io.noties.markwon:core:${markwonVersion}" + implementation "io.noties.markwon:linkify:${markwonVersion}" } diff --git a/app/src/main/java/org/schabi/newpipe/about/AboutActivity.java b/app/src/main/java/org/schabi/newpipe/about/AboutActivity.java index 9e23d9d3d..edfc54375 100644 --- a/app/src/main/java/org/schabi/newpipe/about/AboutActivity.java +++ b/app/src/main/java/org/schabi/newpipe/about/AboutActivity.java @@ -32,18 +32,20 @@ public class AboutActivity extends AppCompatActivity { * List of all software components */ private static final SoftwareComponent[] SOFTWARE_COMPONENTS = new SoftwareComponent[]{ - new SoftwareComponent("Giga Get", "2014", "Peter Cai", "https://github.com/PaperAirplane-Dev-Team/GigaGet", StandardLicenses.GPL2), - new SoftwareComponent("NewPipe Extractor", "2017", "Christian Schabesberger", "https://github.com/TeamNewPipe/NewPipeExtractor", StandardLicenses.GPL3), + new SoftwareComponent("Giga Get", "2014 - 2015", "Peter Cai", "https://github.com/PaperAirplane-Dev-Team/GigaGet", StandardLicenses.GPL2), + new SoftwareComponent("NewPipe Extractor", "2017 - 2020", "Christian Schabesberger", "https://github.com/TeamNewPipe/NewPipeExtractor", StandardLicenses.GPL3), new SoftwareComponent("Jsoup", "2017", "Jonathan Hedley", "https://github.com/jhy/jsoup", StandardLicenses.MIT), new SoftwareComponent("Rhino", "2015", "Mozilla", "https://www.mozilla.org/rhino/", StandardLicenses.MPL2), new SoftwareComponent("ACRA", "2013", "Kevin Gaudin", "http://www.acra.ch", StandardLicenses.APACHE2), new SoftwareComponent("Universal Image Loader", "2011 - 2015", "Sergey Tarasevich", "https://github.com/nostra13/Android-Universal-Image-Loader", StandardLicenses.APACHE2), - new SoftwareComponent("CircleImageView", "2014 - 2017", "Henning Dodenhof", "https://github.com/hdodenhof/CircleImageView", StandardLicenses.APACHE2), + new SoftwareComponent("CircleImageView", "2014 - 2020", "Henning Dodenhof", "https://github.com/hdodenhof/CircleImageView", StandardLicenses.APACHE2), new SoftwareComponent("NoNonsense-FilePicker", "2016", "Jonas Kalderstam", "https://github.com/spacecowboy/NoNonsense-FilePicker", StandardLicenses.MPL2), - new SoftwareComponent("ExoPlayer", "2014-2017", "Google Inc", "https://github.com/google/ExoPlayer", StandardLicenses.APACHE2), - new SoftwareComponent("RxAndroid", "2015", "The RxAndroid authors", "https://github.com/ReactiveX/RxAndroid", StandardLicenses.APACHE2), - new SoftwareComponent("RxJava", "2016-present", "RxJava Contributors", "https://github.com/ReactiveX/RxJava", StandardLicenses.APACHE2), - new SoftwareComponent("RxBinding", "2015", "Jake Wharton", "https://github.com/JakeWharton/RxBinding", StandardLicenses.APACHE2) + new SoftwareComponent("ExoPlayer", "2014 - 2020", "Google Inc", "https://github.com/google/ExoPlayer", StandardLicenses.APACHE2), + new SoftwareComponent("RxAndroid", "2015 - 2018", "The RxAndroid authors", "https://github.com/ReactiveX/RxAndroid", StandardLicenses.APACHE2), + new SoftwareComponent("RxJava", "2016 - 2020", "RxJava Contributors", "https://github.com/ReactiveX/RxJava", StandardLicenses.APACHE2), + new SoftwareComponent("RxBinding", "2015 - 2018", "Jake Wharton", "https://github.com/JakeWharton/RxBinding", StandardLicenses.APACHE2), + new SoftwareComponent("PrettyTime", "2012 - 2020", "Lincoln Baxter, III", "https://github.com/ocpsoft/prettytime", StandardLicenses.APACHE2), + new SoftwareComponent("Markwon", "2017 - 2020", "Noties", "https://github.com/noties/Markwon", StandardLicenses.APACHE2) }; /** diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java index c6c8ca04c..3c594bdfa 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java @@ -95,6 +95,8 @@ import java.util.List; import java.util.concurrent.TimeUnit; import icepick.State; +import io.noties.markwon.Markwon; +import io.noties.markwon.linkify.LinkifyPlugin; import io.reactivex.Single; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.disposables.CompositeDisposable; @@ -922,10 +924,6 @@ public class VideoDetailFragment return; } - if (description.getType() != Description.HTML) { - videoDescriptionView.setAutoLinkMask(Linkify.WEB_URLS); - } - if (description.getType() == Description.HTML) { disposables.add(Single.just(description.getContent()) .map((@io.reactivex.annotations.NonNull String descriptionText) -> { @@ -945,12 +943,14 @@ public class VideoDetailFragment videoDescriptionView.setVisibility(View.VISIBLE); })); } else if (description.getType() == Description.MARKDOWN) { - //in the future we would use a library or a good method to show markdown. - //rn, we just remove **bold**, and let PLAIN_TEXT otherwise - videoDescriptionView.setText(description.getContent().replace("**", ""), TextView.BufferType.SPANNABLE); + final Markwon markwon = Markwon.builder(getContext()) + .usePlugin(LinkifyPlugin.create()) + .build(); + markwon.setMarkdown(videoDescriptionView, description.getContent()); videoDescriptionView.setVisibility(View.VISIBLE); } else { //== Description.PLAIN_TEXT + videoDescriptionView.setAutoLinkMask(Linkify.WEB_URLS); videoDescriptionView.setText(description.getContent(), TextView.BufferType.SPANNABLE); videoDescriptionView.setVisibility(View.VISIBLE); } From 3f3d1bfccf9be4182bd2872358263d3c904e447a Mon Sep 17 00:00:00 2001 From: bopol Date: Sun, 9 Feb 2020 00:00:14 +0100 Subject: [PATCH 24/24] update extractor version --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 65ab78ffa..5da8c9ff0 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -63,7 +63,7 @@ dependencies { exclude module: 'support-annotations' }) - implementation 'com.github.B0pol:NewPipeExtractor:11bcc78d9c8eb39e8d61a6f4bc4112025937f087' + implementation 'com.github.TeamNewPipe:NewPipeExtractor:9112a10' testImplementation 'junit:junit:4.12' testImplementation 'org.mockito:mockito-core:2.23.0'