diff --git a/app/build.gradle b/app/build.gradle index f8fc1565f..5da8c9ff0 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 { @@ -62,7 +63,7 @@ dependencies { exclude module: 'support-annotations' }) - implementation 'com.github.TeamNewPipe:NewPipeExtractor:ff61e284' + implementation 'com.github.TeamNewPipe:NewPipeExtractor:9112a10' testImplementation 'junit:junit:4.12' testImplementation 'org.mockito:mockito-core:2.23.0' @@ -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/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"/> on 06.12.16. * @@ -37,48 +42,46 @@ 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 WebView webView; + private String foundCookies = ""; @Override protected void onCreate(Bundle savedInstanceState) { + ThemeHelper.setTheme(this); super.onCreate(savedInstanceState); setContentView(R.layout.activity_recaptcha); + Toolbar toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); - url = getIntent().getStringExtra(RECAPTCHA_URL_EXTRA); + String url = getIntent().getStringExtra(RECAPTCHA_URL_EXTRA); if (url == null || url.isEmpty()) { url = YT_URL; } - - // Set return to Cancel by default + // set return to Cancel by default setResult(RESULT_CANCELED); - 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 = findViewById(R.id.reCaptchaWebView); - WebView myWebView = findViewById(R.id.reCaptchaWebView); - - // Enable Javascript - WebSettings webSettings = myWebView.getSettings(); + // enable Javascript + WebSettings webSettings = webView.getSettings(); webSettings.setJavaScriptEnabled(true); - ReCaptchaWebViewClient webClient = new ReCaptchaWebViewClient(this); - myWebView.setWebViewClient(webClient); + webView.setWebViewClient(new WebViewClient() { + @Override + public void onPageFinished(WebView view, String url) { + super.onPageFinished(view, url); + handleCookies(url); + } + }); - // Cleaning cache, history and cookies from webView - myWebView.clearCache(true); - myWebView.clearHistory(); + // cleaning cache, history and cookies from webView + webView.clearCache(true); + webView.clearHistory(); android.webkit.CookieManager cookieManager = CookieManager.getInstance(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { cookieManager.removeAllCookies(aBoolean -> {}); @@ -86,77 +89,82 @@ public class ReCaptchaActivity extends AppCompatActivity { cookieManager.removeAllCookie(); } - myWebView.loadUrl(url); + webView.loadUrl(url); } - private class ReCaptchaWebViewClient extends WebViewClient { - private final Activity context; - private String mCookies; + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.menu_recaptcha, menu); - ReCaptchaWebViewClient(Activity ctx) { - context = ctx; + ActionBar actionBar = getSupportActionBar(); + if (actionBar != null) { + actionBar.setDisplayHomeAsUpEnabled(false); + 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 true; + } - @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 R.id.menu_item_done: + saveCookiesAndFinish(); return true; - } default: return false; } } + + 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); + 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(String url) { + String cookies = CookieManager.getInstance().getCookie(url); + if (MainActivity.DEBUG) Log.d(TAG, "handleCookies: url=" + url + "; cookies=" + (cookies == null ? "null" : cookies)); + if (cookies == null) return; + + addYoutubeCookies(cookies); + // add other methods to extract cookies here + } + + 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: + addCookie(cookies); + } + } + + private void addCookie(String cookie) { + if (foundCookies.contains(cookie)) { + return; + } + + if (foundCookies.isEmpty() || foundCookies.endsWith("; ")) { + foundCookies += cookie; + } else if (foundCookies.endsWith(";")) { + foundCookies += " " + cookie; + } else { + foundCookies += "; " + cookie; + } + } } 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 f59cfaef0..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 @@ -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; @@ -58,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; @@ -96,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; @@ -483,7 +484,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 +919,41 @@ public class VideoDetailFragment return sortedVideoStreams != null ? sortedVideoStreams.get(selectedVideoStreamIndex) : null; } - private void prepareDescription(final String descriptionHtml) { - if (TextUtils.isEmpty(descriptionHtml)) { + private void prepareDescription(Description description) { + if (TextUtils.isEmpty(description.getContent()) || description == Description.emptyDescription) { 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 (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(descriptionText, 0); + } else { + //noinspection deprecation + parsedDescription = Html.fromHtml(descriptionText); + } + return parsedDescription; + }) + .subscribeOn(Schedulers.computation()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe((@io.reactivex.annotations.NonNull Spanned spanned) -> { + videoDescriptionView.setText(spanned); + videoDescriptionView.setVisibility(View.VISIBLE); + })); + } else if (description.getType() == Description.MARKDOWN) { + 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); + } } private void setHeightThumbnail() { 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..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 @@ -1,9 +1,15 @@ 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.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 +126,21 @@ public class CommentsMiniInfoItemHolder extends InfoItemHolder { itemBuilder.getOnCommentsSelectedListener().selected(item); } }); + + + 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,commentText)); + Toast.makeText(itemBuilder.getContext(), R.string.msg_copied, Toast.LENGTH_SHORT).show(); + return true; + + } + }); + } private void ellipsize() { diff --git a/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java b/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java index 8f67367aa..761fa4360 100644 --- a/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java @@ -1,8 +1,11 @@ package org.schabi.newpipe.local.bookmark; import android.app.AlertDialog; +import android.app.AlertDialog.Builder; import android.os.Bundle; import android.os.Parcelable; +import android.util.Log; +import android.widget.EditText; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.FragmentManager; @@ -10,6 +13,7 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import io.reactivex.disposables.Disposable; import org.reactivestreams.Subscriber; import org.reactivestreams.Subscription; import org.schabi.newpipe.NewPipeDatabase; @@ -118,8 +122,7 @@ public final class BookmarkFragment @Override public void held(LocalItem selectedItem) { if (selectedItem instanceof PlaylistMetadataEntry) { - showLocalDeleteDialog((PlaylistMetadataEntry) selectedItem); - + showLocalDialog((PlaylistMetadataEntry) selectedItem); } else if (selectedItem instanceof PlaylistRemoteEntity) { showRemoteDeleteDialog((PlaylistRemoteEntity) selectedItem); } @@ -247,14 +250,30 @@ public final class BookmarkFragment // Utils /////////////////////////////////////////////////////////////////////////// - private void showLocalDeleteDialog(final PlaylistMetadataEntry item) { - showDeleteDialog(item.name, localPlaylistManager.deletePlaylist(item.uid)); - } - private void showRemoteDeleteDialog(final PlaylistRemoteEntity item) { showDeleteDialog(item.getName(), remotePlaylistManager.deletePlaylist(item.getUid())); } + private void showLocalDialog(PlaylistMetadataEntry selectedItem) { + View dialogView = View.inflate(getContext(), R.layout.dialog_bookmark, null); + EditText editText = dialogView.findViewById(R.id.playlist_name_edit_text); + editText.setText(selectedItem.name); + + Builder builder = new AlertDialog.Builder(activity); + builder.setView(dialogView) + .setPositiveButton(R.string.rename_playlist, (dialog, which) -> { + changeLocalPlaylistName(selectedItem.uid, editText.getText().toString()); + }) + .setNegativeButton(R.string.cancel, null) + .setNeutralButton(R.string.delete, (dialog, which) -> { + showDeleteDialog(selectedItem.name, + localPlaylistManager.deletePlaylist(selectedItem.uid)); + dialog.dismiss(); + }) + .create() + .show(); + } + private void showDeleteDialog(final String name, final Single deleteReactor) { if (activity == null || disposables == null) return; @@ -271,6 +290,23 @@ public final class BookmarkFragment .show(); } + private void changeLocalPlaylistName(long id, String name) { + if (localPlaylistManager == null) { + return; + } + + if (DEBUG) { + Log.d(TAG, "Updating playlist id=[" + id + + "] with new name=[" + name + "] items"); + } + + localPlaylistManager.renamePlaylist(id, name); + final Disposable disposable = localPlaylistManager.renamePlaylist(id, name) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(longs -> {/*Do nothing on success*/}, this::onError); + disposables.add(disposable); + } + private static List merge(final List localPlaylists, final List remotePlaylists) { List items = new ArrayList<>( diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java index 9f21e05ff..17599a1ca 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java @@ -388,8 +388,10 @@ public class LocalPlaylistFragment extends BaseLocalListFragment 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; @@ -259,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) { @@ -272,11 +263,6 @@ public class Mp4FromDashWriter { final int ftyp_size = make_ftyp(); // reserve moov space in the output stream - /*if (outStream.canSetLength()) { - long length = writeOffset + auxSize; - outStream.setLength(length); - outSeek(length); - } else {*/ if (auxSize > 0) { int length = auxSize; byte[] buffer = new byte[64 * 1024];// 64 KiB @@ -292,10 +278,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 +291,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 +301,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 +316,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; } @@ -342,6 +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(); } sampleIndex[i] = -1; break; @@ -390,10 +378,6 @@ public class Mp4FromDashWriter { } else { tablesInfo[i].stco = writeEntryArray(tablesInfo[i].stco, 1, (int) chunkOffset); } - - if (singleChunk) { - tablesInfo[i].stco = -1; - } } outRestore(); @@ -470,7 +454,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 +604,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) { @@ -740,13 +769,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); @@ -766,7 +794,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 +817,11 @@ public class Mp4FromDashWriter { tablesInfo.stco = make(is64 ? 0x636F3634 : 0x7374636F, -1, is64 ? 2 : 1, tablesInfo.stco); } + if (isAudio) { + 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 +849,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 +902,6 @@ public class Mp4FromDashWriter { int stsz_default; int stss; int stco; + int sbgp; } } 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/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 @@ + + + diff --git a/app/src/main/res/layout/activity_recaptcha.xml b/app/src/main/res/layout/activity_recaptcha.xml index 411ada498..759e1f296 100644 --- a/app/src/main/res/layout/activity_recaptcha.xml +++ b/app/src/main/res/layout/activity_recaptcha.xml @@ -14,9 +14,7 @@ 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"/> + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/menu_recaptcha.xml b/app/src/main/res/menu/menu_recaptcha.xml new file mode 100644 index 000000000..07ad07b38 --- /dev/null +++ b/app/src/main/res/menu/menu_recaptcha.xml @@ -0,0 +1,10 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 02f79c8ab..4d91b40da 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -187,7 +187,7 @@ يرجى تحديد مجلد التنزيل لاحقا في الإعدادات هذا الإذن مطلوب \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 9fbc08493..d4119e83c 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 new file mode 100644 index 000000000..878efa9f2 --- /dev/null +++ b/app/src/main/res/values-cmn/strings.xml @@ -0,0 +1,504 @@ + + + 点击搜索按钮即可开始使用 + %1$s 次观看 + 发布于 %1$s + 找不到媒体播放器。您要安装 VLC 吗? + 找不到媒体播放器(您可以安装 VLC 来播放)。 + 安装 + 取消 + 在浏览器中打开 + 在悬浮窗模式下打开 + 分享 + 下载 + 下载媒体文件 + 搜索 + 设置 + 您是不是要找:%1$s? + 分享至 + 选择浏览器 + 旋转 + 使用外部视频播放器 + 删除某些分辨率下的音频 + 使用外部音频播放器 + NewPipe 悬浮窗模式 + 订阅 + 已订阅 + 退订成功 + 无法更改订阅 + 无法更新订阅 + 显示信息 + 主页 + 订阅 + 已添加书签到播放列表 + 新功能 + 转到后台 + 悬浮窗 + 添加到 + 视频下载文件夹 + 已下载的视频储存在此处 + 选择视频文件的下载文件夹 + 音频下载文件夹 + 已下载的音频存储在此处 + 选择音频文件的下载文件夹 + 自动播放 + NewPipes被其它程序调用时播放视频 + 默认分辨率 + 默认悬浮窗分辨率 + 显示更高的分辨率 + 只有部分设备支持播放 2K/4K 视频 + 用 Kodi 播放 + 没找到 Kore 应用,需要安装它吗? + 显示“用 Kodi 播放”选项 + 显示以 Kodi 媒体中心播放视频的选项 + 音频 + 默认音频格式 + 默认视频格式 + 主题 + 亮色 + 酷黑 + 黑色 + 记住悬浮窗的尺寸与位置 + 记住上一次悬浮窗的位置以及大小 + 已清除图像缓存 + 最小化悬浮窗播放器 + 清除观看历史 + 搜索记录已删除。 + 错误 + 网络错误 + 举报错误 + 没有结果 + 开始 + 暂停 + 播放 + 创建 + 删除 + 删除所有 + 新任务 + 好 +\n + 错误 +\n + 不支持的服务器 + 文件已存在 + NewPipe 下载中 + 请稍等… + 字母与数字 + 最特别的字符 + 这个文件里没有已下载应用程式 + 关于NewPipe + 设置 + 关于 + 第三方执照 + 打开网页 + 删除书签 + 确定删除该播放列表吗? + 已创建播放列表 + 播放列表 + 步骤 + 重置 + 为了遵守欧洲通用数据保护法规(GDPR,我们请你注意NewPipe的隐私政策.请仔细阅读. +\n你必须接受它才能将错误报告发送给我们. + 接受 + 拒绝 + 没有限制 + 使用移动数据时的解析度限制 + 最小化应用程序切换 + 从主视频播放器切换到其他应用时的操作 - %s + 没有 + 最小化后台播放 + 使用快速粗略定位 + 粗略定位功能允许播放器以略低的精确度为代价换取更快的定位速度 + 下载缩略图 + 清除缓存的元数据 + 移除所有缓存的网页数据 + 已清除缓存的元数据 + 不加载缩略图时,可以节省数据和存储空间。更改后将清除存储空间和扩展空间的缓存。 + 自动排列下一个媒体 + 在非重复排列中播放最后一个媒体时自动推荐相关媒体 + 玩家手势控制 + 使用手势控制播放器的亮度和音量 + 搜索建议 + 搜索时显示建议 + 搜索历史记录 + 在本地存储搜索 + 观看历史 + 记录观看过的视频 + 取得视窗焦点时继续播放 + 在被打断后继续播放(例如有来电) + 下载 + 下一部 + 显示「下一部」及「相关」的视频 + 显示「长按以新增」的提示 + 在视频详细信息页按下后台播放或悬浮窗按钮时提示 + 不支持该网址 + 默认内容的国家 + 服务 + 播放器 + 行为 + 视频与音频 + 历史记录和缓存数据 + 悬浮窗 + 外观 + 其他 + 调试 + 在后台播放 + 在悬浮窗下播放 + 已添加到后台播放队列 + 已添加到悬浮窗播放队列 + 播放 + 内容 + 年龄限制内容 + 显示有年龄限制的视频。可以从设置中允许该内容。 + 直播 + 下载 + 下载 + 错误报告 + 所有 + 频道 + 频道 + 播放列表 + 播放列表 + 曲目 + 用户 + 是的 + 稍等 + 不适用 + 过滤 + 刷新 + 清除 + 调整 + 最佳分辨率 + 复原 + 全部播放 + 总是 + 仅一次 + 文件 + NewPipe 通知 + NewPipe 后台播放和悬浮窗播放的通知 + [未知] + 切换方向 + 切换到后台 + 切换到悬浮窗 + 切换到首页 + 导入数据库 + 导出数据库 + 覆盖您当前的历史记录和订阅 + 导出历史记录、订阅和播放列表 + 删除播放过的媒体的历史记录及回放位置 + 确定要清除所有观看历史记录吗? + 观看历史记录已清除。 + 清除搜索历史记录 + 清除搜索关键词的历史记录 + 确定要清除所有搜索历史记录吗? + 无法加载所有缩略图 + 无法解析视频网址签名 + 无法解析网站 + 无法完全解析网站 + 内容不可用 + 无法设置下载菜单 + 目前还不支持观看直播 + 无法获得任何媒体 + 无法加载图片 + 应用程序或界面出现崩溃了 + 无法播放此媒体 + 发生了无法恢复的播放器错误 + 正在从播放器错误中恢复 + 外部播放器不支持此类型的链接 + 无效的网址 + 找不到视频串流 + 找不到音频串流 + 无效的文件夹 + 无效的文件/内容来源 + 该文件不存在或缺少读写权限 + 文件名不能为空 + 发生错误:%1$s + 没有可供下载的串流 + 抱歉,这不应该发生的。 + 通过电子邮件报告错误 + 抱歉,发生了一些错误。 + 报告 + 信息: + 发生了什么: + 事件:\\n请求:\\n内容语言:\\n服务:\\nGMT 时间:\\n组件:\\n版本:\\n系统版本: + 您的评论(请用英语): + 详细: + 视频预览缩略图 + 视频预览缩略图 + 上传者的头像缩略图 + 喜欢 + 不喜欢 + 使用 Tor + (实验性)通过 Tor 强制下载流量以增加隐私(暂不支持视频媒体)。 + 用户报告 + 这里什么都没有 + 拖动以重新排序 + 无法创建下载目录「%1$s」 + 已成功创建下载目录「%1$s」 + 视频 + 音频 + 重试 + 手机存储访问权限被拒绝 + + + 十亿 + 没有订阅者 + + %s 位订阅者 + + + 无观看次数 + + %s 次观看 + + + 没有视频 + 删除 + 校验 + 退出 + 重命名 + 文件名 + 线程 + 错误的网址或网络不可用 + 点按以查看详细信息 + 复制到剪贴板 + 请稍后在设置中定义一个下载文件夹 + 在悬浮窗模式打开 +\n需要此权限 + 已删除一个项目。 + reCAPTCHA 验证 + reCAPTCHA 验证 + 需完成 reCAPTCHA 验证 + 下载 + 文件名中允许的字符 + 无效字符将替换为该值 + 替换字符 + © %1$s 由 %2$s 使用 %3$s 版权所有 + 无法加载许可证 + 关于 + 贡献者 + 许可证 + 安卓上开源且轻便的媒体播放器。 + 贡献 + 您是否有想法帮助我们:翻译、界面设计、代码优化以及真正繁重的功能扩展 - 我们随时欢迎您提供帮助。让 NewPipe 越变越好! + 在 GitHub 上查看 + 捐赠 + NewPipe 由社区人员维护和开发额,他们耗费时间务求为您带来最佳体验。现在是时候回过头来,让我们的开发人员能够在使 NewPipe 更加完美的同时,享受一杯咖啡。 + 回馈 + 网站 + 访问 NewPipe 网站了解更多信息和新闻。 + NewPipe 的隐私政策 + NewPipe 项目是非常重视您的隐私。因此,未经您的同意,该应用程序不会收集任何数据。 +\nNewPipe 的隐私政策详细说明了当您发送崩溃报告时,什么资料会被传送及储存。 + 阅读隐私政策 + NewPipe 的许可证 + NewPipe 是一个 Copyleft 的自由软件:您可以随意使用、研究、分享或改进它。在遵守由自由软件基金会所发布的 GNU 通用公共授权条款的状况下,您可以自由地再发布或修改它;授权条款预设使用第三版,但您也可以选择更新的版本。 + 阅读许可证 + 历史记录 + 搜索 + 观看 + 历史记录被关闭了 + 历史记录 + 没有历史记录 + 清除历史记录 + 项目已删除 + 确定要从搜索历史记录中删除该项吗? + 确定要从观看历史记录中删除该项吗? + 您确定要删除历史记录中的所有项吗? + 上一次播放 + 最受欢迎 + 首页内容 + 空白页面 + 互动页面 + 订阅页面 + Feed 页面 + 频道页面 + 选择一个频道 + 尚未订阅任何频道 + 选择一个互动 + 输出 + 接入 + 无效的压缩文件 + 警告:无法导入所有文件。 + 这将覆盖您当前的设定。 + 您是否要导入设定? + 互动 + 趋势 + 前 50 + 最新和热门 + 转到后台播放 + 悬浮窗播放 + 移除 + 详细 + 音频设置 + 长按加入队列 + 加入后台播放列表 + 加入悬浮窗播放列表 + 从这里开始播放 + 开始在后台播放 + 开始在新悬浮窗播放 + 打开抽屉 + 关闭抽屉 + 很快就会出现在这里 ;D + 偏好的「开启」动作 + 开启内容时的默认动作 - %s + 视频播放器 + 后台播放器 + 悬浮窗播放器 + 总是询问 + 正在获取信息… + 正在载入请求的内容 + 新的播放列表 + 删除 + 重命名 + 名称 + 添加到播放列表 + 设为播放列表缩略图 + 将播放列表加入书签 + 播放列表缩略图已更改。 + 无法删除播放列表。 + 没有字幕 + 合适 + 填满 + 缩放 + 自动生成 + 字幕 + 修改播放器字幕文本比列和背景样式。需要重启才能生效。 + 启用 LeakCanary + 内存泄漏监视可能导致应用程序在存储时无响应 + 报告活动周期外错误 + 强制报告在处理完片段或活动周期外发生的无法传递的 Rx 异常 + 导入/导出 + 导入 + 导入至 + 导出到 + 正在导入… + 正在导出… + 导入文件 + 之前的导出 + 无法导入订阅 + 无法导出订阅 + 通过下载导出文件来导入 YouTube 订阅: +\n +\n1.移至该网址:%1$s +\n2.当被询问时登入帐号 +\n3.应该开始下载(这是导出文件) + 通过输入 URL 或 ID 来导入 SoundCloud的配置文件: +\n +\n1.在浏览器中启用「桌面模式」(该网站不适用于移动设备) +\n2.移至该网址:%1$s +\n3.当被询问时登入帐号 +\n4.复制您重定向的配置文件到网址。 + 您的 ID,soundcloud.com/yourid + 请记住,此操作可能造成昂贵的网络花费。 +\n +\n您是否要继续? + 播放速度控制 + 速度 + 音量 + 取消链接(可能会导致扭曲) + 静音时快进 + 退订 + 新标签 + 选择标签 + 音量手势控制 + 用手势控制播放器的音量 + 手势控制亮度 + 用手势控制播放器的亮度 + 默认的内容语言 + 升级 + 文件已删除 + 应用升级通知 + 新 NewPipe 版本通知 + 外储存不可行 + 无法下载到外部SD卡。重置下载文件夹位置? + 恢复默认 + 您真的要恢复至默认吗? + 选择 + 升级 + 列表 + 自动 + 轻按以下载 + 已完成 + 有待 + 已暂停 + 已加入队列 + 后处理 + 队列 + 系统拒绝该行动 + 下载失败 + 下载完成 + %s已下载完毕 + 生成独特的名字 + 覆写 + 同名的已下载文件已经存在 + 同名下载进行中 + 显示错误 + 代码 + 无法创建该文件 + 系统拒绝此批准 + 安全连接失败 + 找不到服务器 + 连不上服务器 + 伺服器没回送数据 + 找不到 + 后处理失败 + 清除已完毕的下载 + + 重试上限 + 取消下载前可以尝试的最多次数 + 换成手机数据时中断 + 事件 + 使用默认选项卡, 读取保存的选项卡时出错 + 订阅者计数不可用 + 主页上显示的选项卡 + 会议 + 显示通知, 以便在新版本可用时提示应用更新 + 列表视图模式 + 网格 + 切换视图 + NewPipe 更新可用! + 无法创建目标文件夹 + 服务器不接受多线程下载, 请使用 @string/msg_threads = 1重试 + 切换至移动数据时有用,尽管一些下载无法被暂停 + 显示评论 + 禁用停止显示评论 + 自动播放 + + 评论 + + + 没有评论 + 无法加载评论 + 关闭 + 继续播放 + 恢复上次播放位置 + 列表中的位置 + 在列表中显示播放位置指示符 + 清除数据 + 播放位置已删除。 + 文件被移动或删除 + 已存在具有此名称的文件 + 无法覆盖该文件 + 同名文件正在等待下载 + 处理此文件时 NewPipe 已关闭 + 设备上没有剩余空间 + 进度丢失,因为文件已被删除 + 连接超时 + 你确定吗? + 限制下载队列 + 同时只有一个下载进行 + 开始全部下载 + 暂停全部下载 + 询问下载位置 + 每次下载将询问保存的位置 + 每次下载将询问保存的位置. +\n如果要下载到外部SD卡,请选择外部存储访问框架 + 使用存储访问框架 + 存储访问框架(SAF)允许下载文件到外部SD卡。 +\n注:一些设备不兼容SAF + 删除回放位置 + 删除所有回放位置 + 删除所有的回放位置吗? + 更改要生效的下载文件夹 + \ No newline at end of file diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 548358473..0f18e0e1c 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 1fab90386..a8ae69c61 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 fe63caf1b..6370c5e0e 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 5b3265cd7..89723fbcf 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 7563e1be5..96745ee23 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 7695fe31c..da0cc5f83 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 3587ad136..1fda2a515 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -232,8 +232,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-in/strings.xml b/app/src/main/res/values-in/strings.xml index dd8413be8..36929856e 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/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 9d9241045..5acc513e7 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 fdab646b2..cf63e33e1 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 e2010c50f..54437a375 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 9a061bab7..cd73601fb 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 61e4b4574..fa39ae466 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 4d2b38b5f..f1abf0f87 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 7d3fb68e3..3c4977a06 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 63d0e7699..807351a52 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 e0149f2d8..627def4d3 100644 --- a/app/src/main/res/values-ur/strings.xml +++ b/app/src/main/res/values-ur/strings.xml @@ -228,9 +228,7 @@ براۓ مہربانی انتظار کريں… کلپ بورڈ میں نقل ہوا براہ کرم بعد میں ترتیبات میں ڈاؤن لوڈ فولڈر کی وضاحت رکھیں - پوپ اپ موڈ میں کھولنے کیلئے/nاس اجازت کی ضرورت ہے - reCAPTCHA - reCAPTCHA چیلنج + پوپ اپ موڈ میں کھولنے کیلئے اس اجازت کی ضرورت ہے reCAPTCHA چیلینج کی درخواست کی گئی ڈاؤن لوڈ فائل کے ناموں میں ان حروف کی اجازت ہے @@ -537,4 +535,4 @@ ڈاؤن لوڈ کی سرگزشت صاف کریں ڈاؤن لوڈ شدہ فائلیں حذف کریں %1$s ڈاؤن لوڈز کو حذف کیا گیا - \ No newline at end of file + 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 d0405b57d..0282e6c92 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -1,540 +1,457 @@ - + - 点击搜索按钮即可开始使用 - %1$s 次观看 - 发布于 %1$s - 在浏览器中打开 - 在悬浮窗模式下打开 - 您是不是要找:%1$s? - 找不到串流播放器 (您可以安装 VLC 进行播放)。 - 下载串流文件 + 点播%1$s次 + %1$s发布 + 找不到播放器。您是否要安装 VLC? 安装 取消 + 用浏览器打开 分享 下载 搜索 设置 - 分享给... + 您是不是要找: %1$s ? + 分享视频 选择浏览器 + 旋转 + 使用外置视频播放器 + 使用外置音频播放器 视频下载路径 - 已下载的视频存储在这里 - 请选择下载视频的保存位置 - 已下载的音频存储在这里 - 选择下载音频的储存位置 - 自动播放 - 使用Kodi播放 + 下载视频的存储路径 + 输入视频存储路径 + 默认分辨率 + 用Kodi播放 + 找不到Kore,您要安装Kore吗? + 显示“用Kodi播放”的选项 + 显示 Kodi 媒体中心播放视频的选项 + 音频 + 默认音频格式 主题 - 浅色 - 暗黑 - 黑色 + 灰暗 + 明亮 + 下载 - 下一个 - 不支持的 URL + 即将播放 + 显示下一部和相似的视频 + 不支援此网址 + 默认内容语言 + 视频和音频 外观 其他 - 全部 - 频道 - - 稍后 + 后台播放 + 播放 网络错误 - - %s 个视频 - %s 个视频 - - 禁用 - 后台播放 - 过滤器 - 刷新 - 搜索建议 - 订阅 - 已订阅 - 观看历史 - 播放器 - 历史记录与缓存 - 播放列表 - 撤销 - 全部播放 - 总是 - 仅一次 - 添加至 - 文件 - 加载缩略图 - 清除观看记录 - - 最小化后台播放器 - 最小化悬浮窗播放器 - 频道 - 播放列表 - 取消订阅 - 新标签 - 更新 - 文件已删除 - 无法得知订阅人数 - 每推出新版本时,弹出应用升级通知 - 网格 - 新版 NewPipe 已可升级! - 服务器不接受 接收 multi-threaded 下载, 以 @string/msg_threads = 1 重试 - 自动播放 - 清除数据 - 观看记录已删除 + + 视频预览缩略图 + 视频预览缩略图 + 上传者的头像缩图 喜欢 不喜欢 - 使用Tor - (实验性)通过 Tor 强制下载流量以增强隐私(暂不支持串流视频)。 + 使用 Tor + (实验性)强制下载流量使用 Tor 加强隐私(暂不支援流媒体视频)。 + 音频存储路径 + 下载音频的存储路径 + 输入音频文件存储路径 + + 未能建立下载路径 “%1$s” + 已创建下载目录 “%1$s” + 内容 + 显示年龄限制内容 + 视频有年龄限制。请先在设置中启用\"显示年龄限制内容\"。 + 错误 + 无法加载所有缩略图 + 无法解密视频网址签名 + 无法解析网站 + 无法完全解析网站 + 内容不可用 + 无法设置下载菜单 + 这是一个在线流媒体,尚不支持。 + 无法获取任何流媒体 + 抱歉,这本不应该发生。 + 使用邮件报告错误 + 抱歉,发生了一些错误。 + 报告 + 信息: + 发生什么: + 您的注释(英文): + 详细信息: + + 报告错误 用户报告 - 无法创建下载目录\"%1$s\" - 已成功创建下载目录「%1$s」 + 视频 音频 重试 - 存储访问权限已被拒绝 - - %s 次观看 - %s 次观看 - - - 百万 + 无权访问存储空间 + 自动播放 + 当NewPipe被其他应用调用时,自动播放视频 + 直播 + + 点击搜索开始NewPipe 开始 暂停 播放 删除 - 校验 - 新任务 - OK + 校验和 + + 确定 + 文件名 - 线程数 + 线程 错误 - 不支持的服务器 - 文件已存在 - 点击了解详情 + 服务器不支持 + 文件已经存在 + 网址不正确或网络不可用 + NewPipe 正在下载 + 点击了解细节 请稍候… - 复制至剪贴板 - reCAPTCHA验证码 - 悬浮窗播放 - 关于NewPipe - 设置 - 关于 - 第三方许可 - © %1$s :作者 %2$s (使用 %3$s ) - 无法加载许可证 - 打开网站 - 关于 - 贡献者 - 许可证 - 下载 - 文件名中允许的字符 - 无效字符将会被替换为此 - 字母和数字 - 最特殊字符 - 没有结果 - 没有订阅者 - - %s 位订阅者 - %s 位订阅者 - - 没有视频 - 视频 - 拖动以重新排序 - 创建 - 仅删除一个 - 全部删除 - 解除 - 重 命名 - 未安装用于播放此文件的应用程序 - 已删除1个项目。 - 哪些标签需要在主页上展示 - 列表视图模式 - 已完成 - 等待中… - 已暂停 - 排队中 - 加入队列 - 操作已被系统拒绝 - 下载失败 - 下载完成 - %s 次下载已完成 - 没有评论 - 切换服务,当前选择: - 找不到串流播放器。您想安装 VLC 吗? - 旋转 - 使用外部视频播放器 - 使用外部音频播放器 - 音频下载文件夹 - 从其他应用调用 NewPipe 时播放视频 - 默认分辨率 - 找不到Kore。是否安装? - 显示“用Kodi播放”选项 - 显示“通过Kodi media center播放视频的选项” - 音频 - 默认音频格式 - 显示“下一个”和“类似的”视频 - 视频和音频 - 在后台播放 - 播放 - 内容 - 受年龄限制的内容 - 显示受年龄限制的视频。可从设置允许此类内容。 - 直播 + 已复制到剪贴板 + 请选择一个可用的下载目录 + + 新任务 下载 下载 错误报告 - 错误 - 无法加载所有缩略图 - 无法解密视频的 URL 签名 - 无法解析网址 - 无法完全解析网址 - 内容不可用 - 无法设置下载菜单 - 暂时不支持观看直播 - 无法获得任何信息流 + 无法加载图像 - App UI 崩溃 - 抱歉,这不应该发生的。 - 通过电子邮件报告错误 - 抱歉,发生了一些错误。 - 报告 - 信息: - 发生了什么: - 详情:\\n请求:\\n内容语言:\\n服务:\\nGMT时间:\\n包:\\n版本:\\n操作系统版本: - 您的注释(请用英文): - 详细信息: - 视频预览缩略图 - 播放视频,时长: - 视频上传者的头像缩略图 - 字节 - 错误的 URL 或未联网 - NewPipe下载中 - 请稍后在设置中设定下载目录 - 用悬浮窗模式 -\n需要此权限 - reCAPTCHA验证 - 请求的新的CAPTCHA验证 - NewPipe 悬浮窗模式 - 在悬浮窗中播放 - 默认悬浮窗分辨率 - 使用更高的分辨率 - 仅某些设备支持播放2K / 4K视频 - 清除 - 记住悬浮窗的尺寸与位置 - 记住最后一次使用悬浮窗的大小和位置 - 悬浮窗 - 调整大小 - 隐藏部分没有音频的分辨率 - 播放器手势控制 - 使用手势控制播放器的亮度和音量 - 显示搜索建议 - 最佳分辨率 - 开源小巧的Android媒体播放器。 - 在GitHub上查看 - NewPipe开源许可证 - 你是否有想:翻译、设计、清理或重型代码更改 ——我们始终欢迎你来贡献! - 阅读许可证 - 贡献 - 替换字符 - 取消订阅频道 - 无法修改订阅 + 应用/界面已崩溃 + 原因:\\n请求:\\n内容语言:\\n服务:\\nGMT时间:\\n包:\\n版本:\\n操作系统版本: + reCAPTCHA + reCAPTCHA 验证 + + 需要 reCAPTCHA 验证 + +以悬浮窗打开 + 选项启用时,某分辨率的视频将没有声音 + NewPipe悬浮窗模式 + 订阅 + 已订阅 + 已取消订阅频道 + 无法更改订阅 无法更新订阅 - 主页 + + 首页 订阅 - 最新 - 恢复前台焦点 - 中断后继续播放(例如突然来电后) - 搜索历史记录 - 在本地存储搜索查询记录 - 记录已观看视频 - 历史 - 已搜索 - 已观看 - 历史记录功能已关闭 - 历史 - 历史记录为空 - 清除历史记录 + + 新鲜事 + + 后台播放 + 悬浮窗 + + 窗口模式默认分辨率 + 显示更高的分辨率 + 只有部分设备支持 2K/4K 视频 + 首选视频格式 + 纯黑 + 记住悬浮窗大小和位置 + 记住上次悬浮窗的大小和位置 + 播放手势控制 + 使用手势操作控制播放器的亮度和音量 + 搜索建议 + 在搜索时显示搜索建议 + 搜索记录 + 在本地存储搜索请求 + 历史和缓存 + 记住观看的视频 + 焦点恢复 + 在打扰(例如来电)过后恢复视频播放 + + + 窗口模式 + 以窗口模式播放 + 所有 + 频道 + 是的 + 稍后 + 已禁用 + 筛选器 + 刷新 + 清除 + 重新调整大小 + 最佳分辨率 + NewPipe 通知 - NewPipe 后台播放和悬浮窗播放的通知 - 默认视频格式 + NewPipe 后台播放和窗口播放器的通知 + + K + M + B + + 该项权限用于 +\n以窗口模式打开 + + 下载 + 在文件名中允许的字符 + 无效的字符将以该值取代 + 替换字符 + + 字母和数字 + 特殊字符 + + 关于 NewPipe + 设置 + 关于 + 第三方许可 + © %1$s by %2$s under %3$s + 无法加载许可 + 打开网站 + 关于 + 贡献者 + 许可 + 开源的轻量级流媒体Android客户端。 + 在 GitHub 上查看 + NewPipe 许可 + 无论你有什么想法:翻译程序,改进设计,优化代码或是想做出大量修改——我们都随时欢迎。做得越多它将变得越好! + 阅读许可 + 贡献 + + 历史记录 + 搜索记录 + 观看记录 + 历史记录已禁用 + 历史记录 + 没有历史记录 + 历史记录已清除 + +播放器 行为 - 空空如也... - 0次观看 + 历史记录 & 缓存 + 在后台播放器上排队 + 在弹出播放器上排队 + 播放列表 + 撤销 + 全部播放 + + [未知] + + 无法播放此流媒体 + 发生无法解决的播放器错误 + 没有结果 + 空空如也 + + 无订阅者 + + %s 位订阅者 + + + 无观看次数 + + %s 次观看 + + + 没有视频 + + %s 部视频 + + 项目已删除 - 是否要从搜索历史记录中删除此项目? - 显示在主页面内容 + 找不到播放器(你可以安装 VLC 来播放) + 下载串流文件。 + 显示详情 + + 书签 + + 添入 + + 使用粗略但快速的寻找 + 粗略寻找让播放器更快找到视频的进度位置 + 加载缩略图 + 停用后,NewPipe將不再加载缩略图,减少数据使用和腾空存储空间,亦会清除内存和内存卡上的缩略图缓存 + 已清除图像缓存 + 清除缓存元数据 + 移除所有网页的缓存数据 + 已清除元数据缓存 + 自动播放队列中下一个视频 + 当播放完非循环列表中的最后一个视频时,自动加入一个相关视频到播放列表 + 显示\"长按添加\"提示 + 当视频详情页中的背景或悬浮按钮被按下的时候显示提示 + 默认内容国家 + 服务 + 调试 + 总是 + 仅一次 + 文件 + + 切换方向 + 切换到后台 + 切换到悬浮窗 + 切换到主页 + + 导入数据库 + 导出数据库 + 将覆盖你现有历史记录和订阅 + 导出历史记录,订阅和播放列表 + 从播放器错误中恢复 + 外部播放器不支持这些链接类型 + 无效的链接 + 未找到视频 + 未找到音频 + 无效的目录 + 无效的文件/内容来源 + 文件不存在或无读写权限 + 文件名不能为空 + 发生了一个错误:%1$s + 无视频媒体可以下载 + + 拖拽以重新排列 + + 创建 + 删除一个 + 删除全部 + 解除 + 重命名 + + 捐赠 + NewPipe 是一群志愿者花费业余时间开发的,目的是为您带来最佳体验。你的一点心意,可以让开发者们在享受一杯 Java 的咖啡的同时让 NewPipe 变得更好用。 + 捐赠 + 网页 + 访问 NewPipe 网站以获取更多的信息和新闻。 + 你想从搜索历史中删除此项吗? + 你想从观看历史中删除此项吗? + 确实要删除历史记录的所有项目吗? + 上一次播放 + 最多播放 + + 主页内容 空白页 - 『时下流行』页-自定义 + Kiosk 页 订阅页 - Feed 页面 + Feed 页 频道页 - 选择一个频道 - 尚未订阅频道 - 选择一个时下流行页 - 『时下流行』 - 趋势 + 选择频道 + 还没有订阅的频道 + 选择 kiosk + 导出完成 + 导入完成 + 无有效的 ZIP 文件 + 警告:无法导入所有文件。 + 将覆盖你现有设置。 + + Kiosk + 流行的 前50 - 最新与热门 - 显示 \"长按添加\" 说明 - 在视频详情页中,按下背景播放或悬浮窗播放按钮时显示提示 - 已加入后台播放播放列表 - 已加入悬浮窗播放列表 - 无法播放此串流 - 发生无法恢复播放器错误 - 恢复播放器错误 - 后台播放 + 最新 & 最热 + 后台播放器 悬浮窗播放器 移除 详情 音频设置 - 长按队列 - [未知] - 添加到后台部分队列 - 添加至新悬浮窗列表 - 开始在此处开始播放 - 开始后台播放 - 开始在新悬浮窗中播放 - 捐赠 - NewPipe 是由志愿者花费时间为您带来最佳体验开发的。回馈帮助开发人员在享用一杯咖啡的同时,让 NewPipe 变得更好。 - 回馈 - 网站 - 请访问 NewPipe 网站了解更多信息和讯息。 - 默认国家/地区 - 切换方向 - 切换到背景播放 - 切换到悬浮窗播放 - 切换到主页面 - 服务 - 打开抽屉 - 关闭抽屉 - 第三方播放器不支持此类型链接 - 无效 URL - 未找到视频串流 - 找不到音频串流 + 按住以队列 + 在后台队列 + 在悬浮窗队列 + 从这里播放 + 从这里在后台播放 + 从这里在悬浮窗播放 + + 打开侧栏菜单 + 关闭侧栏菜单 + 精彩内容即将呈现 ;D + + + 偏好\"打开\"动作 + 打开内容的默认动作 — %s + 视频播放器 后台播放器 悬浮窗播放器 - 正在获取信息… - 正在加载请求的内容 - 导入数据库 - 导出数据库 - 覆盖当前历史记录和订阅 - 导出历史记录、订阅和播放列表 - 导出成功 - 导入成功 - 没有有效的ZIP文件 - 警告:无法导入所有文件。 - 这将覆盖当前设置。 - 显示信息 - 书签 - 确定要从观看历史记录中删除该项吗? - 是否确实要从历史记录中删除所有项目? - 最后播放 - 播放最多 - 总是寻问 - 新建播放列表 - 删除 - 重 命名 + 总是询问 + + 获取信息中… + 正在加载请求内容 + + 创建新播放列表 + 删除播放列表 + 重命名播放列表 名称 - 添加到播放列表 - 设为播放列表缩略图 - 收藏播放列表 - 删除收藏 - 删除此播放列表? - 新建播放列表成功 - 加入播放列表成功 - 播放列表缩略图更改成功。 + 加入播放列表 + 设置为播放列表缩略图 + + 书签播放列表 + 移除书签 + + 你想删除此播放列表吗? + 播放列表已创建 + 加入播放列表 + 播放列表缩略图已更改 无法删除播放列表 + 无字幕 + 适应屏幕 填充屏幕 - 缩放 - 敬请等待 - 调试 + 放大填充 + 自动生成 - 启用LeakCanary - 『内存泄漏监视』可能导致应用在『核心转储』时无响应 - 报告『提前结束Android生命周期』错误 - 强制报告处理后的未送达的Activity或Fragment生命周期之外的Rx异常 - 使用快速不精确搜索 - 粗略定位播放:允许播放器以略低的精确度为代价换取更快的定位速度 - 自动播放下一个 - 当播放完非循环列表中的最后一个视频时,自动加入一个相关视频到播放列表 - 没有此文件夹 - 无相似文件/内容源 - 该文件不存在 或 缺少读写该文件的权限 - 文件名不能为空 - 发生错误: %1$s + + 启用 LeakCanary + 内存泄露监测可能会在heap dumping时导致应用失去响应 + + 报告生命周期外的错误 + 处理完无法送达的、发生在Fragment或activity生命周期之外的Rx异常后强制报告 + 导入/导出 导入 - 从...导入 - 导出到... - 正在导入… - 正在导出… + 从导入 + 导出至 + + 导入中… + 导出中… + 导入文件 - 以前的导出 + 之前的导出 + 无法导入订阅 无法导出订阅 - 通过下载导出文件来导入 YouTube 订阅: -\n -\n1. 转到此网站: %1$s -\n2. 登录(如果需要) -\n3. 应该立即开始下载(即导出文件) - 通过键入网址或你的 ID 导入 SoundCloud 配置文件: -\n -\n1. 在浏览器中启用\"电脑模式\"(该网站不适用于移动设备) -\n2. 转到此 URL: %1$s -\n3. 登录(如果需要) -\n4. 复制重定向的配置文件下载地址。 - 你的 ID:soundcloud.com/[你的ID] - 该操作消耗大量流量, -\n你想继续吗? - 关闭可防止加载缩略图,节已省数据和内存使用。(若现在更改会清除内存和储存中缓存) - 清空图像缓存成功 - 清空已缓存元数据 - 清空已缓存的网页数据 - 清空元数据缓存成功 + + 通过下载导出文件导入 YouTube 订阅: +\n1. 在浏览器打开URL:%1$s +\n2. 登录账户 +\n3. 下载应该会马上开始(这个就是导出文件) + 通过输入URL或您的ID导入SoundCloud配置: +\n1. 在浏览器中开启\"桌面模式\"(该网站不适用于移动设备) +\n2. 打开URL:%1$s +\n3. 登录账号 +\n3. 复制重定向后的URL。 + 你的ID 或 soundcloud.com/你的ID + + 请注意该操作可能消耗大量网络流量。 +\n您希望继续吗? + 播放速度控制 - 节奏 + 速度 音调 - 解除关联(可能导致失真) - 首选“打开”操作 - 打开内容时默认操作: = %s - 无可下载的串流内容 + Unhook(可能导致失真) + 默认 +未安装能播放此文件的应用 + 字幕 - 修改播放器字幕比例和背景样式。需要重新启动应用程序才能生效。 - 删除串流的播放历史和播放位置 - 删除全部观看记录? - 清除搜索历史记录 - 清除搜索关键词的历史记录 - 是否删除全部搜索历史记录? - 搜索历史记录已删除。 - NewPipe 是版权自由软件:您可以随时使用、研究共享和改进它。您可以根据自由软件基金会发布的 GNU 通用公共许可证GPLv3或(由您选择的)任何更高版本的许可证重新分发或修改该许可证。 - 是否要同时导入设置? - NewPipe的隐私政策 - NewPipe 项目非常重视您的隐私。因此,未经您的同意,应用程序不会收集任何数据。 -\nNewPipe 的隐私政策详细解释了在发送崩溃报告时发送和存储的数据。 - 阅读隐私政策 - 为了遵守欧盟的《通用数据保护条例》(GDPR),我们特此提醒您注意 NewPipe 的隐私政策。请您仔细阅读。 -\n您必须在同意以后才能向我们发送错误报告。 + 修改播放器的字幕文本大小和背景样式。需要重启应用程序以生效 + + 清除观看记录 + 删除视频观看记录 + 删除全部观看记录。 + 观看记录已删除。 + 清除搜索记录 + 删除搜索关键词记录 + 删除全部搜索记录。 + 搜索记录已删除。 + 已删除1项。 + + NewPipe的隐私策略 + NewPipe 项目非常重视您的隐私。因此, 未经您的同意,应用程序不会收集任何您的数据。 NewPipe 的隐私策略详细解释了您在发送崩溃报告时会发送和存储的哪些数据。 + 阅读隐私策略 + NewPipe 是 copyleft 的自由软件: 你可以按照自己的意愿使用、学习、分享和改进它。具体地说, 您可以根据自由软件基金会发布的 GNU 通用公共许可证的条款(第3版或者任何更高版本), 重新发布和/或修改本软件。 + 您是否希望同时导入设置? + + 为了遵守欧洲通用数据保护条例(GDPR),我们提醒您注意NewPipe的隐私政策。 请仔细阅读。 +\n您必须接受它才能向我们发送错误报告。 接受 拒绝 - 无限制 + + 不限制 使用移动数据时限制分辨率 - 退出应用时最小化 - 从主播放器切换到其他应用时的操作 - %s - 静音时快进 - 滑块[比例尺] - 重 置 - 曲目 - 用户 - 选择标签 - 音量手势控制 - 使用手势控制播放器的音量 - 亮度手势控制 - 使用手势控制播放器的亮度 - 视频默认语言 - 应用更新通知 - NewPipe有新版本的通知 - 外置存储不可用 - 无法下载到外部 SD 卡。重置下载文件夹位置? - 读取已保存标签时发生错误,因此使用者默认标签 - 恢复默认 - 是否恢复默认值? - 选择 - 更新 - 列表 - 自动 - 切换视图 - 点击下载 - 后期处理 - 生成唯一名称 - 覆盖 - 正在使用此名称进行下载 - 显示错误 - 代码 - 无法创建目标文件夹 - 无法创建文件 - 权限被系统拒绝 - 安全连接失败 - 找不到服务器 - 无法连接到服务器 - 服务器未发送数据 - 找不到 NOT FOUND - 后期处理失败 - 清除已完成的下载 - 停止 - 最大重试次数 - 取消下载前的最多尝试次数 - 在切换到移动流量网络时中断播放 - 切换至移动数据时可能有用,尽管一些下载无法被暂停 - 事件 - 近期大会 - 显示评论 - 禁用,以停止显示评论 - - %s 条评论 - %s 条评论 - - 无法加载评论 - 关闭 - 恢复播放 - 恢复上次播放位置 - 列表中的位置 - 在列表中,显示视频最后一次播放时的播放位置 - 已删除播放位置记录。 - 文件被已移动或删除 - 该名称的文件已经存在 - 命名冲突,已存在具有此名称文件 - 无法覆盖文件 - 有此名称的已暂停下载 - NewPipe 在处理文件时被关闭 - 设备上没有剩余储存空间 - 进度丢失,文件已被删除 - 连接超时 - 是否要清除下载历史记录或删除所有下载的文件? - 最大下载队列 - 同时只允许一个下载进行 - 开始下载 - 暂停下载 - 询问下载位置 - 系统将询问您将每次下载的保存位置 - 系统将询问您将每次下载的保存位置。 -\n(如果要下载到外部 SD 卡,请选择 SAF) - 使用 SAF - 存储访问框架(SAF)允许下载文件到外部SD卡。 -\n注:一些设备不兼容SAF - 删除播放位置记录 - 删除所有播放位置记录 - 删除所有播放位置记录? - 更改下载目录让内容生效 - 『时下流行』页-默认 - 没有人在观看 - - %s 人在观看 - %s 人在观看 - - 没有人在听 - - %s 人在听 - %s 人在听 - - 重新启动应用后,语言将更改。 - PeerTube 服务器 - 设置自己喜欢的PeerTube服务器 - 查找最适合你的服务器%s - 添加服务器 - 输入服务器网址(URL) - 无法验证服务器 - 仅支持 HTTPS和URL - 该服务器已存在 - 本地 - 最近添加 - 最喜欢的 - 自动生成的(未找到上传者) - 正在恢复 - 无法恢复此下载 - 选择一个服务器 - 快进 / 快退的单位时间 - 在锁屏上显示视频缩略图 - 在后台播放时,锁屏上将会显示视频的缩略图 - 清除下载历史记录 - 删除下载了的文件 - 已删除 %1$s 下载 - \ No newline at end of file + 更多频道 + 更多频道 + 用户们 + 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 b82736f90..6457d4baf 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/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 763eb7426..dab9bde10 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -327,10 +327,12 @@ MD5 SHA-1 - reCAPTCHA - reCAPTCHA challenge + + reCAPTCHA + 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