Merge branch 'dev' into playback_state_list

This commit is contained in:
Vasily 2019-06-23 20:13:20 +03:00
commit 2a41802f36
124 changed files with 7962 additions and 6669 deletions

View File

@ -66,15 +66,22 @@ NewPipe does not use any Google framework libraries, nor the YouTube API. Websit
* Enqueue videos
* Local playlists
* Subtitles
* Multi-service support (e.g. SoundCloud \[beta\])
* Livestream support
* Show comments
### Coming Features
* Cast to UPnP and Cast
* Show comments
* … and many more
### Supported Services
NewPipe supports multiple services. Our [docs](https://teamnewpipe.github.io/documentation/) provide more info on how a new service can be added to the app and the extractor. Please get in touch with us if you intend to add a new one. Currently supported services are:
* YouTube
* SoundCloud \[beta\]
* media.ccc.de \[beta\]
## Updates
When a change to the NewPipe code occurs (due to either adding features or bug fixing), eventually a release will occur. These are in the format x.xx.x . In order to get this new version, you can:
* Build a debug APK yourself. This is the fastest way to get new features on your device, but is much more complicated, so we recommend using one of the other methods.

View File

@ -8,8 +8,8 @@ android {
applicationId "org.schabi.newpipe"
minSdkVersion 19
targetSdkVersion 28
versionCode 720
versionName "0.16.0"
versionCode 740
versionName "0.16.2"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
@ -57,7 +57,7 @@ dependencies {
exclude module: 'support-annotations'
})
implementation 'com.github.TeamNewPipe:NewPipeExtractor:aa4f03a'
implementation 'com.github.TeamNewPipe:NewPipeExtractor:c64c90a'
testImplementation 'junit:junit:4.12'
testImplementation 'org.mockito:mockito-core:2.23.0'

View File

@ -55,7 +55,7 @@ public class DownloadActivity extends AppCompatActivity {
private void updateFragments() {
MissionsFragment fragment = new MissionsFragment();
getFragmentManager().beginTransaction()
getSupportFragmentManager().beginTransaction()
.replace(R.id.frame, fragment, MISSIONS_FRAGMENT_TAG)
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
.commit();

View File

@ -1210,7 +1210,7 @@ public class VideoDetailFragment
downloadDialog.setSelectedVideoStream(selectedVideoStreamIndex);
downloadDialog.setSubtitleStreams(currentInfo.getSubtitles());
downloadDialog.show(activity.getSupportFragmentManager(), "downloadDialog");
downloadDialog.show(getActivity().getSupportFragmentManager(), "downloadDialog");
} catch (Exception e) {
ErrorActivity.ErrorInfo info = ErrorActivity.ErrorInfo.make(UserAction.UI_ERROR,
ServiceList.all()

View File

@ -21,8 +21,8 @@ import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.channel.ChannelInfo;
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.fragments.list.BaseListFragment;
import org.schabi.newpipe.report.UserAction;
import org.schabi.newpipe.local.subscription.SubscriptionService;
import org.schabi.newpipe.report.UserAction;
import java.util.Collections;
import java.util.HashSet;
@ -262,7 +262,7 @@ public class FeedFragment extends BaseListFragment<List<SubscriptionEntity>, Voi
* If chosen feed already displayed, then we request another feed from another
* subscription, until the subscription table runs out of new items.
* <p>
* This Observer is self-contained and will dispose itself when complete. However, this
* This Observer is self-contained and will close itself when complete. However, this
* does not obey the fragment lifecycle and may continue running in the background
* until it is complete. This is done due to RxJava2 no longer propagate errors once
* an observer is unsubscribed while the thread process is still running.

View File

@ -46,7 +46,6 @@ import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.source.BehindLiveWindowException;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
@ -66,6 +65,7 @@ import org.schabi.newpipe.player.helper.PlayerDataSource;
import org.schabi.newpipe.player.helper.PlayerHelper;
import org.schabi.newpipe.player.mediasource.FailedMediaSource;
import org.schabi.newpipe.player.playback.BasePlayerMediaSession;
import org.schabi.newpipe.player.playback.CustomTrackSelector;
import org.schabi.newpipe.player.playback.MediaSourceManager;
import org.schabi.newpipe.player.playback.PlaybackListener;
import org.schabi.newpipe.player.playqueue.PlayQueue;
@ -115,7 +115,7 @@ public abstract class BasePlayer implements
final protected HistoryRecordManager recordManager;
@NonNull
final protected DefaultTrackSelector trackSelector;
final protected CustomTrackSelector trackSelector;
@NonNull
final protected PlayerDataSource dataSource;
@ -212,7 +212,7 @@ public abstract class BasePlayer implements
this.dataSource = new PlayerDataSource(context, userAgent, bandwidthMeter);
final TrackSelection.Factory trackSelectionFactory = PlayerHelper.getQualitySelector(context);
this.trackSelector = new DefaultTrackSelector(trackSelectionFactory);
this.trackSelector = new CustomTrackSelector(trackSelectionFactory);
this.loadControl = new LoadController(context);
this.renderFactory = new DefaultRenderersFactory(context);

View File

@ -305,9 +305,9 @@ public abstract class VideoPlayer extends BasePlayer
captionItem.setOnMenuItemClickListener(menuItem -> {
final int textRendererIndex = getRendererIndex(C.TRACK_TYPE_TEXT);
if (textRendererIndex != RENDERER_UNAVAILABLE) {
trackSelector.setPreferredTextLanguage(captionLanguage);
trackSelector.setParameters(trackSelector.buildUponParameters()
.setRendererDisabled(textRendererIndex, false)
.setPreferredTextLanguage(captionLanguage));
.setRendererDisabled(textRendererIndex, false));
}
return true;
});
@ -315,7 +315,6 @@ public abstract class VideoPlayer extends BasePlayer
captionPopupMenu.setOnDismissListener(this);
}
private void updateStreamRelatedViews() {
if (getCurrentMetadata() == null) return;
@ -508,7 +507,7 @@ public abstract class VideoPlayer extends BasePlayer
}
// Normalize mismatching language strings
final String preferredLanguage = trackSelector.getParameters().preferredTextLanguage;
final String preferredLanguage = trackSelector.getPreferredTextLanguage();
// Build UI
buildCaptionMenu(availableLanguages);
if (trackSelector.getParameters().getRendererDisabled(textRenderer) ||

View File

@ -0,0 +1,115 @@
package org.schabi.newpipe.player.playback;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.util.Pair;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.FixedTrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.util.Assertions;
/**
* This class allows irregular text language labels for use when selecting text captions and
* is mostly a copy-paste from {@link DefaultTrackSelector}.
*
* This is a hack and should be removed once ExoPlayer fixes language normalization to accept
* a broader set of languages.
* */
public class CustomTrackSelector extends DefaultTrackSelector {
private static final int WITHIN_RENDERER_CAPABILITIES_BONUS = 1000;
private String preferredTextLanguage;
public CustomTrackSelector(TrackSelection.Factory adaptiveTrackSelectionFactory) {
super(adaptiveTrackSelectionFactory);
}
public String getPreferredTextLanguage() {
return preferredTextLanguage;
}
public void setPreferredTextLanguage(@NonNull final String label) {
Assertions.checkNotNull(label);
if (!label.equals(preferredTextLanguage)) {
preferredTextLanguage = label;
invalidate();
}
}
/** @see DefaultTrackSelector#formatHasLanguage(Format, String)*/
protected static boolean formatHasLanguage(Format format, String language) {
return language != null && TextUtils.equals(language, format.language);
}
/** @see DefaultTrackSelector#formatHasNoLanguage(Format)*/
protected static boolean formatHasNoLanguage(Format format) {
return TextUtils.isEmpty(format.language) || formatHasLanguage(format, C.LANGUAGE_UNDETERMINED);
}
/** @see DefaultTrackSelector#selectTextTrack(TrackGroupArray, int[][], Parameters) */
@Override
protected Pair<TrackSelection, Integer> selectTextTrack(TrackGroupArray groups, int[][] formatSupport,
Parameters params) {
TrackGroup selectedGroup = null;
int selectedTrackIndex = 0;
int selectedTrackScore = 0;
for (int groupIndex = 0; groupIndex < groups.length; groupIndex++) {
TrackGroup trackGroup = groups.get(groupIndex);
int[] trackFormatSupport = formatSupport[groupIndex];
for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) {
if (isSupported(trackFormatSupport[trackIndex],
params.exceedRendererCapabilitiesIfNecessary)) {
Format format = trackGroup.getFormat(trackIndex);
int maskedSelectionFlags =
format.selectionFlags & ~params.disabledTextTrackSelectionFlags;
boolean isDefault = (maskedSelectionFlags & C.SELECTION_FLAG_DEFAULT) != 0;
boolean isForced = (maskedSelectionFlags & C.SELECTION_FLAG_FORCED) != 0;
int trackScore;
boolean preferredLanguageFound = formatHasLanguage(format, preferredTextLanguage);
if (preferredLanguageFound
|| (params.selectUndeterminedTextLanguage && formatHasNoLanguage(format))) {
if (isDefault) {
trackScore = 8;
} else if (!isForced) {
// Prefer non-forced to forced if a preferred text language has been specified. Where
// both are provided the non-forced track will usually contain the forced subtitles as
// a subset.
trackScore = 6;
} else {
trackScore = 4;
}
trackScore += preferredLanguageFound ? 1 : 0;
} else if (isDefault) {
trackScore = 3;
} else if (isForced) {
if (formatHasLanguage(format, params.preferredAudioLanguage)) {
trackScore = 2;
} else {
trackScore = 1;
}
} else {
// Track should not be selected.
continue;
}
if (isSupported(trackFormatSupport[trackIndex], false)) {
trackScore += WITHIN_RENDERER_CAPABILITIES_BONUS;
}
if (trackScore > selectedTrackScore) {
selectedGroup = trackGroup;
selectedTrackIndex = trackIndex;
selectedTrackScore = trackScore;
}
}
}
}
return selectedGroup == null
? null
: Pair.create(
new FixedTrackSelection(selectedGroup, selectedTrackIndex), selectedTrackScore);
}
}

View File

@ -158,7 +158,7 @@ public class MediaSourceManager {
* Dispose the manager and releases all message buses and loaders.
* */
public void dispose() {
if (DEBUG) Log.d(TAG, "dispose() called.");
if (DEBUG) Log.d(TAG, "close() called.");
debouncedSignal.onComplete();
debouncedLoader.dispose();

View File

@ -17,7 +17,9 @@ public enum UserAction {
REQUESTED_KIOSK("requested kiosk"),
REQUESTED_COMMENTS("requested comments"),
DELETE_FROM_HISTORY("delete from history"),
PLAY_STREAM("Play stream");
PLAY_STREAM("Play stream"),
DOWNLOAD_POSTPROCESSING("download post-processing"),
DOWNLOAD_FAILED("download failed");
private final String message;

View File

@ -1,30 +1,77 @@
package org.schabi.newpipe.settings;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.support.v7.preference.Preference;
import android.util.Log;
import android.widget.Toast;
import com.nononsenseapps.filepicker.Utils;
import org.schabi.newpipe.R;
import org.schabi.newpipe.util.FilePickerActivityHelper;
public class DownloadSettingsFragment extends BasePreferenceFragment {
private static final int REQUEST_DOWNLOAD_PATH = 0x1235;
private static final int REQUEST_DOWNLOAD_AUDIO_PATH = 0x1236;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
private String DOWNLOAD_PATH_PREFERENCE;
import us.shandian.giga.io.StoredDirectoryHelper;
public class DownloadSettingsFragment extends BasePreferenceFragment {
private static final int REQUEST_DOWNLOAD_VIDEO_PATH = 0x1235;
private static final int REQUEST_DOWNLOAD_AUDIO_PATH = 0x1236;
public static final boolean IGNORE_RELEASE_ON_OLD_PATH = true;
private String DOWNLOAD_PATH_VIDEO_PREFERENCE;
private String DOWNLOAD_PATH_AUDIO_PREFERENCE;
private String DOWNLOAD_STORAGE_ASK;
private Preference prefPathVideo;
private Preference prefPathAudio;
private Preference prefStorageAsk;
private Context ctx;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initKeys();
DOWNLOAD_PATH_VIDEO_PREFERENCE = getString(R.string.download_path_video_key);
DOWNLOAD_PATH_AUDIO_PREFERENCE = getString(R.string.download_path_audio_key);
DOWNLOAD_STORAGE_ASK = getString(R.string.downloads_storage_ask);
prefPathVideo = findPreference(DOWNLOAD_PATH_VIDEO_PREFERENCE);
prefPathAudio = findPreference(DOWNLOAD_PATH_AUDIO_PREFERENCE);
prefStorageAsk = findPreference(DOWNLOAD_STORAGE_ASK);
updatePreferencesSummary();
updatePathPickers(!defaultPreferences.getBoolean(DOWNLOAD_STORAGE_ASK, false));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
prefStorageAsk.setSummary(R.string.downloads_storage_ask_summary);
}
if (hasInvalidPath(DOWNLOAD_PATH_VIDEO_PREFERENCE) || hasInvalidPath(DOWNLOAD_PATH_AUDIO_PREFERENCE)) {
Toast.makeText(ctx, R.string.download_pick_path, Toast.LENGTH_SHORT).show();
updatePreferencesSummary();
}
prefStorageAsk.setOnPreferenceChangeListener((preference, value) -> {
updatePathPickers(!(boolean) value);
return true;
});
}
@Override
@ -32,52 +79,183 @@ public class DownloadSettingsFragment extends BasePreferenceFragment {
addPreferencesFromResource(R.xml.download_settings);
}
private void initKeys() {
DOWNLOAD_PATH_PREFERENCE = getString(R.string.download_path_key);
DOWNLOAD_PATH_AUDIO_PREFERENCE = getString(R.string.download_path_audio_key);
@Override
public void onAttach(Context context) {
super.onAttach(context);
ctx = context;
}
@Override
public void onDetach() {
super.onDetach();
ctx = null;
prefStorageAsk.setOnPreferenceChangeListener(null);
}
private void updatePreferencesSummary() {
findPreference(DOWNLOAD_PATH_PREFERENCE).setSummary(defaultPreferences.getString(DOWNLOAD_PATH_PREFERENCE, getString(R.string.download_path_summary)));
findPreference(DOWNLOAD_PATH_AUDIO_PREFERENCE).setSummary(defaultPreferences.getString(DOWNLOAD_PATH_AUDIO_PREFERENCE, getString(R.string.download_path_audio_summary)));
showPathInSummary(DOWNLOAD_PATH_VIDEO_PREFERENCE, R.string.download_path_summary, prefPathVideo);
showPathInSummary(DOWNLOAD_PATH_AUDIO_PREFERENCE, R.string.download_path_audio_summary, prefPathAudio);
}
private void showPathInSummary(String prefKey, @StringRes int defaultString, Preference target) {
String rawUri = defaultPreferences.getString(prefKey, null);
if (rawUri == null || rawUri.isEmpty()) {
target.setSummary(getString(defaultString));
return;
}
if (rawUri.charAt(0) == File.separatorChar) {
target.setSummary(rawUri);
return;
}
if (rawUri.startsWith(ContentResolver.SCHEME_FILE)) {
target.setSummary(new File(URI.create(rawUri)).getPath());
return;
}
try {
rawUri = URLDecoder.decode(rawUri, StandardCharsets.UTF_8.name());
} catch (UnsupportedEncodingException e) {
// nothing to do
}
target.setSummary(rawUri);
}
private boolean isFileUri(String path) {
return path.charAt(0) == File.separatorChar || path.startsWith(ContentResolver.SCHEME_FILE);
}
private boolean hasInvalidPath(String prefKey) {
String value = defaultPreferences.getString(prefKey, null);
return value == null || value.isEmpty();
}
private void updatePathPickers(boolean enabled) {
prefPathVideo.setEnabled(enabled);
prefPathAudio.setEnabled(enabled);
}
// FIXME: after releasing the old path, all downloads created on the folder becomes inaccessible
private void forgetSAFTree(Context ctx, String oldPath) {
if (IGNORE_RELEASE_ON_OLD_PATH) {
return;
}
if (oldPath == null || oldPath.isEmpty() || isFileUri(oldPath)) return;
try {
Uri uri = Uri.parse(oldPath);
ctx.getContentResolver().releasePersistableUriPermission(uri, StoredDirectoryHelper.PERMISSION_FLAGS);
ctx.revokeUriPermission(uri, StoredDirectoryHelper.PERMISSION_FLAGS);
Log.i(TAG, "Revoke old path permissions success on " + oldPath);
} catch (Exception err) {
Log.e(TAG, "Error revoking old path permissions on " + oldPath, err);
}
}
private void showMessageDialog(@StringRes int title, @StringRes int message) {
AlertDialog.Builder msg = new AlertDialog.Builder(ctx);
msg.setTitle(title);
msg.setMessage(message);
msg.setPositiveButton(android.R.string.ok, null);
msg.show();
}
@Override
public boolean onPreferenceTreeClick(Preference preference) {
if (DEBUG) {
Log.d(TAG, "onPreferenceTreeClick() called with: preference = [" + preference + "]");
Log.d(TAG, "onPreferenceTreeClick() called with: preference = [" + preference + "]");
}
if (preference.getKey().equals(DOWNLOAD_PATH_PREFERENCE)
|| preference.getKey().equals(DOWNLOAD_PATH_AUDIO_PREFERENCE)) {
Intent i = new Intent(getActivity(), FilePickerActivityHelper.class)
String key = preference.getKey();
int request;
if (key.equals(DOWNLOAD_PATH_VIDEO_PREFERENCE)) {
request = REQUEST_DOWNLOAD_VIDEO_PATH;
} else if (key.equals(DOWNLOAD_PATH_AUDIO_PREFERENCE)) {
request = REQUEST_DOWNLOAD_AUDIO_PATH;
} else {
return super.onPreferenceTreeClick(preference);
}
Intent i;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
i = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
.putExtra("android.content.extra.SHOW_ADVANCED", true)
.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION | StoredDirectoryHelper.PERMISSION_FLAGS);
} else {
i = new Intent(getActivity(), FilePickerActivityHelper.class)
.putExtra(FilePickerActivityHelper.EXTRA_ALLOW_MULTIPLE, false)
.putExtra(FilePickerActivityHelper.EXTRA_ALLOW_CREATE_DIR, true)
.putExtra(FilePickerActivityHelper.EXTRA_MODE, FilePickerActivityHelper.MODE_DIR);
if (preference.getKey().equals(DOWNLOAD_PATH_PREFERENCE)) {
startActivityForResult(i, REQUEST_DOWNLOAD_PATH);
} else if (preference.getKey().equals(DOWNLOAD_PATH_AUDIO_PREFERENCE)) {
startActivityForResult(i, REQUEST_DOWNLOAD_AUDIO_PATH);
}
}
return super.onPreferenceTreeClick(preference);
startActivityForResult(i, request);
return true;
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (DEBUG) {
Log.d(TAG, "onActivityResult() called with: requestCode = [" + requestCode + "], resultCode = [" + resultCode + "], data = [" + data + "]");
Log.d(TAG, "onActivityResult() called with: requestCode = [" + requestCode + "], " +
"resultCode = [" + resultCode + "], data = [" + data + "]"
);
}
if ((requestCode == REQUEST_DOWNLOAD_PATH || requestCode == REQUEST_DOWNLOAD_AUDIO_PATH)
&& resultCode == Activity.RESULT_OK && data.getData() != null) {
String key = getString(requestCode == REQUEST_DOWNLOAD_PATH ? R.string.download_path_key : R.string.download_path_audio_key);
String path = Utils.getFileForUri(data.getData()).getAbsolutePath();
if (resultCode != Activity.RESULT_OK) return;
defaultPreferences.edit().putString(key, path).apply();
updatePreferencesSummary();
String key;
if (requestCode == REQUEST_DOWNLOAD_VIDEO_PATH)
key = DOWNLOAD_PATH_VIDEO_PREFERENCE;
else if (requestCode == REQUEST_DOWNLOAD_AUDIO_PATH)
key = DOWNLOAD_PATH_AUDIO_PREFERENCE;
else
return;
Uri uri = data.getData();
if (uri == null) {
showMessageDialog(R.string.general_error, R.string.invalid_directory);
return;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// steps:
// 1. revoke permissions on the old save path
// 2. acquire permissions on the new save path
// 3. save the new path, if step(2) was successful
final Context ctx = getContext();
if (ctx == null) throw new NullPointerException("getContext()");
forgetSAFTree(ctx, defaultPreferences.getString(key, ""));
try {
ctx.grantUriPermission(ctx.getPackageName(), uri, StoredDirectoryHelper.PERMISSION_FLAGS);
StoredDirectoryHelper mainStorage = new StoredDirectoryHelper(ctx, uri, null);
Log.i(TAG, "Acquiring tree success from " + uri.toString());
if (!mainStorage.canWrite())
throw new IOException("No write permissions on " + uri.toString());
} catch (IOException err) {
Log.e(TAG, "Error acquiring tree from " + uri.toString(), err);
showMessageDialog(R.string.general_error, R.string.no_available_dir);
return;
}
} else {
File target = Utils.getFileForUri(data.getData());
if (!target.canWrite()) {
showMessageDialog(R.string.download_to_sdcard_error_title, R.string.download_to_sdcard_error_message);
return;
}
uri = Uri.fromFile(target);
}
defaultPreferences.edit().putString(key, uri.toString()).apply();
updatePreferencesSummary();
}
}

View File

@ -70,37 +70,23 @@ public class NewPipeSettings {
getAudioDownloadFolder(context);
}
public static File getVideoDownloadFolder(Context context) {
return getDir(context, R.string.download_path_key, Environment.DIRECTORY_MOVIES);
private static void getVideoDownloadFolder(Context context) {
getDir(context, R.string.download_path_video_key, Environment.DIRECTORY_MOVIES);
}
public static String getVideoDownloadPath(Context context) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
final String key = context.getString(R.string.download_path_key);
return prefs.getString(key, Environment.DIRECTORY_MOVIES);
private static void getAudioDownloadFolder(Context context) {
getDir(context, R.string.download_path_audio_key, Environment.DIRECTORY_MUSIC);
}
public static File getAudioDownloadFolder(Context context) {
return getDir(context, R.string.download_path_audio_key, Environment.DIRECTORY_MUSIC);
}
public static String getAudioDownloadPath(Context context) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
final String key = context.getString(R.string.download_path_audio_key);
return prefs.getString(key, Environment.DIRECTORY_MUSIC);
}
private static File getDir(Context context, int keyID, String defaultDirectoryName) {
private static void getDir(Context context, int keyID, String defaultDirectoryName) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
final String key = context.getString(keyID);
String downloadPath = prefs.getString(key, null);
if ((downloadPath != null) && (!downloadPath.isEmpty())) return new File(downloadPath.trim());
if ((downloadPath != null) && (!downloadPath.isEmpty())) return;
final File dir = getDir(defaultDirectoryName);
SharedPreferences.Editor spEditor = prefs.edit();
spEditor.putString(key, getNewPipeChildFolderPathForDir(dir));
spEditor.putString(key, getNewPipeChildFolderPathForDir(getDir(defaultDirectoryName)));
spEditor.apply();
return dir;
}
@NonNull
@ -108,19 +94,7 @@ public class NewPipeSettings {
return new File(Environment.getExternalStorageDirectory(), defaultDirectoryName);
}
public static void resetDownloadFolders(Context context) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
resetDownloadFolder(prefs, context.getString(R.string.download_path_audio_key), Environment.DIRECTORY_MUSIC);
resetDownloadFolder(prefs, context.getString(R.string.download_path_key), Environment.DIRECTORY_MOVIES);
}
private static void resetDownloadFolder(SharedPreferences prefs, String key, String defaultDirectoryName) {
SharedPreferences.Editor spEditor = prefs.edit();
spEditor.putString(key, getNewPipeChildFolderPathForDir(getDir(defaultDirectoryName)));
spEditor.apply();
}
private static String getNewPipeChildFolderPathForDir(File dir) {
return new File(dir, "NewPipe").getAbsolutePath();
return new File(dir, "NewPipe").toURI().toString();
}
}

View File

@ -1,9 +1,10 @@
package org.schabi.newpipe.streams;
import org.schabi.newpipe.streams.io.SharpStream;
import java.io.EOFException;
import java.io.IOException;
import org.schabi.newpipe.streams.io.SharpStream;
import java.io.InputStream;
/**
* @author kapodamy
@ -15,89 +16,239 @@ public class DataReader {
public final static int INTEGER_SIZE = 4;
public final static int FLOAT_SIZE = 4;
private long pos;
public final SharpStream stream;
private final boolean rewind;
private final static int BUFFER_SIZE = 128 * 1024;// 128 KiB
private long position = 0;
private final SharpStream stream;
private InputStream view;
private int viewSize;
public DataReader(SharpStream stream) {
this.rewind = stream.canRewind();
this.stream = stream;
this.pos = 0L;
this.readOffset = this.readBuffer.length;
}
public long position() {
return pos;
return position;
}
public final int readInt() throws IOException {
public int read() throws IOException {
if (fillBuffer()) {
return -1;
}
position++;
readCount--;
return readBuffer[readOffset++] & 0xFF;
}
public long skipBytes(long amount) throws IOException {
if (readCount < 0) {
return 0;
} else if (readCount == 0) {
amount = stream.skip(amount);
} else {
if (readCount > amount) {
readCount -= (int) amount;
readOffset += (int) amount;
} else {
amount = readCount + stream.skip(amount - readCount);
readCount = 0;
readOffset = readBuffer.length;
}
}
position += amount;
return amount;
}
public int readInt() throws IOException {
primitiveRead(INTEGER_SIZE);
return primitive[0] << 24 | primitive[1] << 16 | primitive[2] << 8 | primitive[3];
}
public final int read() throws IOException {
int value = stream.read();
if (value == -1) {
throw new EOFException();
}
pos++;
return value;
public short readShort() throws IOException {
primitiveRead(SHORT_SIZE);
return (short) (primitive[0] << 8 | primitive[1]);
}
public final long skipBytes(long amount) throws IOException {
amount = stream.skip(amount);
pos += amount;
return amount;
}
public final long readLong() throws IOException {
public long readLong() throws IOException {
primitiveRead(LONG_SIZE);
long high = primitive[0] << 24 | primitive[1] << 16 | primitive[2] << 8 | primitive[3];
long low = primitive[4] << 24 | primitive[5] << 16 | primitive[6] << 8 | primitive[7];
return high << 32 | low;
}
public final short readShort() throws IOException {
primitiveRead(SHORT_SIZE);
return (short) (primitive[0] << 8 | primitive[1]);
}
public final int read(byte[] buffer) throws IOException {
public int read(byte[] buffer) throws IOException {
return read(buffer, 0, buffer.length);
}
public final int read(byte[] buffer, int offset, int count) throws IOException {
int res = stream.read(buffer, offset, count);
pos += res;
public int read(byte[] buffer, int offset, int count) throws IOException {
if (readCount < 0) {
return -1;
}
int total = 0;
return res;
if (count >= readBuffer.length) {
if (readCount > 0) {
System.arraycopy(readBuffer, readOffset, buffer, offset, readCount);
readOffset += readCount;
offset += readCount;
count -= readCount;
total = readCount;
readCount = 0;
}
total += Math.max(stream.read(buffer, offset, count), 0);
} else {
while (count > 0 && !fillBuffer()) {
int read = Math.min(readCount, count);
System.arraycopy(readBuffer, readOffset, buffer, offset, read);
readOffset += read;
readCount -= read;
offset += read;
count -= read;
total += read;
}
}
position += total;
return total;
}
public final boolean available() {
return stream.available() > 0;
public boolean available() {
return readCount > 0 || stream.available() > 0;
}
public void rewind() throws IOException {
stream.rewind();
pos = 0;
if ((position - viewSize) > 0) {
viewSize = 0;// drop view
} else {
viewSize += position;
}
position = 0;
readOffset = readBuffer.length;
}
public boolean canRewind() {
return rewind;
return stream.canRewind();
}
private short[] primitive = new short[LONG_SIZE];
/**
* Wraps this instance of {@code DataReader} into {@code InputStream}
* object. Note: Any read in the {@code DataReader} will not modify
* (decrease) the view size
*
* @param size the size of the view
* @return the view
*/
public InputStream getView(int size) {
if (view == null) {
view = new InputStream() {
@Override
public int read() throws IOException {
if (viewSize < 1) {
return -1;
}
int res = DataReader.this.read();
if (res > 0) {
viewSize--;
}
return res;
}
@Override
public int read(byte[] buffer) throws IOException {
return read(buffer, 0, buffer.length);
}
@Override
public int read(byte[] buffer, int offset, int count) throws IOException {
if (viewSize < 1) {
return -1;
}
int res = DataReader.this.read(buffer, offset, Math.min(viewSize, count));
viewSize -= res;
return res;
}
@Override
public long skip(long amount) throws IOException {
if (viewSize < 1) {
return 0;
}
int res = (int) DataReader.this.skipBytes(Math.min(amount, viewSize));
viewSize -= res;
return res;
}
@Override
public int available() {
return viewSize;
}
@Override
public void close() {
viewSize = 0;
}
@Override
public boolean markSupported() {
return false;
}
};
}
viewSize = size;
return view;
}
private final short[] primitive = new short[LONG_SIZE];
private void primitiveRead(int amount) throws IOException {
byte[] buffer = new byte[amount];
int read = stream.read(buffer, 0, amount);
pos += read;
int read = read(buffer, 0, amount);
if (read != amount) {
throw new EOFException("Truncated data, missing " + String.valueOf(amount - read) + " bytes");
throw new EOFException("Truncated stream, missing " + String.valueOf(amount - read) + " bytes");
}
for (int i = 0; i < buffer.length; i++) {
primitive[i] = (short) (buffer[i] & 0xFF);// the "byte" datatype is signed and is very annoying
for (int i = 0; i < amount; i++) {
primitive[i] = (short) (buffer[i] & 0xFF);// the "byte" data type in java is signed and is very annoying
}
}
private final byte[] readBuffer = new byte[BUFFER_SIZE];
private int readOffset;
private int readCount;
private boolean fillBuffer() throws IOException {
if (readCount < 0) {
return true;
}
if (readOffset >= readBuffer.length) {
readCount = stream.read(readBuffer);
if (readCount < 1) {
readCount = -1;
return true;
}
readOffset = 0;
}
return readCount < 1;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,6 @@
package org.schabi.newpipe.streams;
import org.schabi.newpipe.streams.io.SharpStream;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
@ -12,8 +13,6 @@ import java.nio.charset.Charset;
import java.text.ParseException;
import java.util.Locale;
import org.schabi.newpipe.streams.io.SharpStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
@ -27,11 +26,11 @@ public class SubtitleConverter {
public void dumpTTML(SharpStream in, final SharpStream out, final boolean ignoreEmptyFrames, final boolean detectYoutubeDuplicateLines
) throws IOException, ParseException, SAXException, ParserConfigurationException, XPathExpressionException {
final FrameWriter callback = new FrameWriter() {
int frameIndex = 0;
final Charset charset = Charset.forName("utf-8");
@Override
public void yield(SubtitleFrame frame) throws IOException {
if (ignoreEmptyFrames && frame.isEmptyText()) {
@ -48,13 +47,13 @@ public class SubtitleConverter {
out.write(NEW_LINE.getBytes(charset));
}
};
read_xml_based(in, callback, detectYoutubeDuplicateLines,
"tt", "xmlns", "http://www.w3.org/ns/ttml",
new String[]{"timedtext", "head", "wp"},
new String[]{"body", "div", "p"},
"begin", "end", true
);
);
}
private void read_xml_based(SharpStream source, FrameWriter callback, boolean detectYoutubeDuplicateLines,
@ -70,7 +69,7 @@ public class SubtitleConverter {
* Language parsing is not supported
*/
byte[] buffer = new byte[source.available()];
byte[] buffer = new byte[(int) source.available()];
source.read(buffer);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
@ -206,7 +205,7 @@ public class SubtitleConverter {
}
}
private static NodeList selectNodes(Document xml, String[] path, String namespaceUri) throws XPathExpressionException {
private static NodeList selectNodes(Document xml, String[] path, String namespaceUri) {
Element ref = xml.getDocumentElement();
for (int i = 0; i < path.length - 1; i++) {

View File

@ -1,65 +0,0 @@
package org.schabi.newpipe.streams;
import java.io.InputStream;
import java.io.IOException;
public class TrackDataChunk extends InputStream {
private final DataReader base;
private int size;
public TrackDataChunk(DataReader base, int size) {
this.base = base;
this.size = size;
}
@Override
public int read() throws IOException {
if (size < 1) {
return -1;
}
int res = base.read();
if (res >= 0) {
size--;
}
return res;
}
@Override
public int read(byte[] buffer) throws IOException {
return read(buffer, 0, buffer.length);
}
@Override
public int read(byte[] buffer, int offset, int count) throws IOException {
count = Math.min(size, count);
int read = base.read(buffer, offset, count);
size -= count;
return read;
}
@Override
public long skip(long amount) throws IOException {
long res = base.skipBytes(Math.min(amount, size));
size -= res;
return res;
}
@Override
public int available() {
return size;
}
@Override
public void close() {
size = 0;
}
@Override
public boolean markSupported() {
return false;
}
}

View File

@ -1,12 +1,13 @@
package org.schabi.newpipe.streams;
import org.schabi.newpipe.streams.io.SharpStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.NoSuchElementException;
import java.util.Objects;
import org.schabi.newpipe.streams.io.SharpStream;
/**
*
@ -121,7 +122,7 @@ public class WebMReader {
}
private String readString(Element parent) throws IOException {
return new String(readBlob(parent), "utf-8");
return new String(readBlob(parent), StandardCharsets.UTF_8);// or use "utf-8"
}
private byte[] readBlob(Element parent) throws IOException {
@ -193,6 +194,7 @@ public class WebMReader {
return elem;
}
}
ensure(elem);
}
@ -306,7 +308,7 @@ public class WebMReader {
entry.trackNumber = readNumber(elem);
break;
case ID_TrackType:
entry.trackType = (int)readNumber(elem);
entry.trackType = (int) readNumber(elem);
break;
case ID_CodecID:
entry.codecId = readString(elem);
@ -445,7 +447,7 @@ public class WebMReader {
public class SimpleBlock {
public TrackDataChunk data;
public InputStream data;
SimpleBlock(Element ref) {
this.ref = ref;
@ -492,7 +494,7 @@ public class WebMReader {
currentSimpleBlock = readSimpleBlock(elem);
if (currentSimpleBlock.trackNumber == tracks[selectedTrack].trackNumber) {
currentSimpleBlock.data = new TrackDataChunk(stream, (int) currentSimpleBlock.dataSize);
currentSimpleBlock.data = stream.getView((int) currentSimpleBlock.dataSize);
return currentSimpleBlock;
}

View File

@ -1,20 +1,20 @@
package org.schabi.newpipe.streams;
import android.support.annotation.NonNull;
import org.schabi.newpipe.streams.WebMReader.Cluster;
import org.schabi.newpipe.streams.WebMReader.Segment;
import org.schabi.newpipe.streams.WebMReader.SimpleBlock;
import org.schabi.newpipe.streams.WebMReader.WebMTrack;
import org.schabi.newpipe.streams.io.SharpStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import org.schabi.newpipe.streams.io.SharpStream;
/**
*
* @author kapodamy
*/
public class WebMWriter {
@ -94,10 +94,6 @@ public class WebMWriter {
}
}
public long getBytesWritten() {
return written;
}
public boolean isDone() {
return done;
}
@ -111,7 +107,7 @@ public class WebMWriter {
parsed = true;
for (SharpStream src : sourceTracks) {
src.dispose();
src.close();
}
sourceTracks = null;
@ -138,42 +134,42 @@ public class WebMWriter {
/* segment */
listBuffer.add(new byte[]{
0x18, 0x53, (byte) 0x80, 0x67, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00// segment content size
0x18, 0x53, (byte) 0x80, 0x67, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00// segment content size
});
long baseSegmentOffset = written + listBuffer.get(0).length;
/* seek head */
listBuffer.add(new byte[]{
0x11, 0x4d, (byte) 0x9b, 0x74, (byte) 0xbe,
0x4d, (byte) 0xbb, (byte) 0x8b,
0x53, (byte) 0xab, (byte) 0x84, 0x15, 0x49, (byte) 0xa9, 0x66, 0x53,
(byte) 0xac, (byte) 0x81, /*info offset*/ 0x43,
0x4d, (byte) 0xbb, (byte) 0x8b, 0x53, (byte) 0xab,
(byte) 0x84, 0x16, 0x54, (byte) 0xae, 0x6b, 0x53, (byte) 0xac, (byte) 0x81,
/*tracks offset*/ 0x6a,
0x4d, (byte) 0xbb, (byte) 0x8e, 0x53, (byte) 0xab, (byte) 0x84, 0x1f,
0x43, (byte) 0xb6, 0x75, 0x53, (byte) 0xac, (byte) 0x84, /*cluster offset [2]*/ 0x00, 0x00, 0x00, 0x00,
0x4d, (byte) 0xbb, (byte) 0x8e, 0x53, (byte) 0xab, (byte) 0x84, 0x1c, 0x53,
(byte) 0xbb, 0x6b, 0x53, (byte) 0xac, (byte) 0x84, /*cues offset [7]*/ 0x00, 0x00, 0x00, 0x00
0x11, 0x4d, (byte) 0x9b, 0x74, (byte) 0xbe,
0x4d, (byte) 0xbb, (byte) 0x8b,
0x53, (byte) 0xab, (byte) 0x84, 0x15, 0x49, (byte) 0xa9, 0x66, 0x53,
(byte) 0xac, (byte) 0x81, /*info offset*/ 0x43,
0x4d, (byte) 0xbb, (byte) 0x8b, 0x53, (byte) 0xab,
(byte) 0x84, 0x16, 0x54, (byte) 0xae, 0x6b, 0x53, (byte) 0xac, (byte) 0x81,
/*tracks offset*/ 0x6a,
0x4d, (byte) 0xbb, (byte) 0x8e, 0x53, (byte) 0xab, (byte) 0x84, 0x1f,
0x43, (byte) 0xb6, 0x75, 0x53, (byte) 0xac, (byte) 0x84, /*cluster offset [2]*/ 0x00, 0x00, 0x00, 0x00,
0x4d, (byte) 0xbb, (byte) 0x8e, 0x53, (byte) 0xab, (byte) 0x84, 0x1c, 0x53,
(byte) 0xbb, 0x6b, 0x53, (byte) 0xac, (byte) 0x84, /*cues offset [7]*/ 0x00, 0x00, 0x00, 0x00
});
/* info */
listBuffer.add(new byte[]{
0x15, 0x49, (byte) 0xa9, 0x66, (byte) 0xa2, 0x2a, (byte) 0xd7, (byte) 0xb1
0x15, 0x49, (byte) 0xa9, 0x66, (byte) 0xa2, 0x2a, (byte) 0xd7, (byte) 0xb1
});
listBuffer.add(encode(DEFAULT_TIMECODE_SCALE, true));// this value MUST NOT exceed 4 bytes
listBuffer.add(new byte[]{0x44, (byte) 0x89, (byte) 0x84,
0x00, 0x00, 0x00, 0x00,// info.duration
/* MuxingApp */
0x4d, (byte) 0x80, (byte) 0x87, 0x4E,
0x65, 0x77, 0x50, 0x69, 0x70, 0x65, // "NewPipe" binary string
/* WritingApp */
0x57, 0x41, (byte) 0x87, 0x4E,
0x65, 0x77, 0x50, 0x69, 0x70, 0x65// "NewPipe" binary string
0x00, 0x00, 0x00, 0x00,// info.duration
/* MuxingApp */
0x4d, (byte) 0x80, (byte) 0x87, 0x4E,
0x65, 0x77, 0x50, 0x69, 0x70, 0x65, // "NewPipe" binary string
/* WritingApp */
0x57, 0x41, (byte) 0x87, 0x4E,
0x65, 0x77, 0x50, 0x69, 0x70, 0x65// "NewPipe" binary string
});
/* tracks */
@ -200,7 +196,6 @@ public class WebMWriter {
long nextCueTime = infoTracks[cuesForTrackId].trackType == 1 ? -1 : 0;
ArrayList<KeyFrame> keyFrames = new ArrayList<>(32);
//ArrayList<Block> chunks = new ArrayList<>(readers.length);
ArrayList<Long> clusterOffsets = new ArrayList<>(32);
ArrayList<Integer> clusterSizes = new ArrayList<>(32);
@ -283,24 +278,21 @@ public class WebMWriter {
long segmentSize = written - offsetSegmentSizeSet - 7;
// final step write offsets and sizes
out.rewind();
written = 0;
skipTo(out, offsetSegmentSizeSet);
/* ---- final step write offsets and sizes ---- */
seekTo(out, offsetSegmentSizeSet);
writeLong(out, segmentSize);
if (predefinedDurations[durationFromTrackId] > -1) {
duration += predefinedDurations[durationFromTrackId];// this value is full-filled in makeTrackEntry() method
}
skipTo(out, offsetInfoDurationSet);
seekTo(out, offsetInfoDurationSet);
writeFloat(out, duration);
firstClusterOffset -= baseSegmentOffset;
skipTo(out, offsetClusterSet);
seekTo(out, offsetClusterSet);
writeInt(out, firstClusterOffset);
skipTo(out, cueReservedOffset);
seekTo(out, cueReservedOffset);
/* Cue */
dump(new byte[]{0x1c, 0x53, (byte) 0xbb, 0x6b, 0x20, 0x00, 0x00}, out);
@ -321,20 +313,16 @@ public class WebMWriter {
voidBuffer.putShort((short) (firstClusterOffset - written - 4));
dump(voidBuffer.array(), out);
out.rewind();
written = 0;
skipTo(out, offsetCuesSet);
seekTo(out, offsetCuesSet);
writeInt(out, (int) (cueReservedOffset - baseSegmentOffset));
skipTo(out, cueReservedOffset + 5);
seekTo(out, cueReservedOffset + 5);
writeShort(out, cueSize);
for (int i = 0; i < clusterSizes.size(); i++) {
skipTo(out, clusterOffsets.get(i));
byte[] size = ByteBuffer.allocate(4).putInt(clusterSizes.get(i) | 0x200000).array();
out.write(size, 1, 3);
written += 3;
seekTo(out, clusterOffsets.get(i));
byte[] buffer = ByteBuffer.allocate(4).putInt(clusterSizes.get(i) | 0x10000000).array();
dump(buffer, out);
}
}
@ -365,20 +353,29 @@ public class WebMWriter {
bloq.dataSize = (int) res.dataSize;
bloq.trackNumber = internalTrackId;
bloq.flags = res.flags;
bloq.absoluteTimecode = convertTimecode(res.relativeTimeCode, readersSegment[internalTrackId].info.timecodeScale, DEFAULT_TIMECODE_SCALE);
bloq.absoluteTimecode = convertTimecode(res.relativeTimeCode, readersSegment[internalTrackId].info.timecodeScale);
bloq.absoluteTimecode += readersCluter[internalTrackId].timecode;
return bloq;
}
private short convertTimecode(int time, long oldTimeScale, int newTimeScale) {
return (short) (time * (newTimeScale / oldTimeScale));
private short convertTimecode(int time, long oldTimeScale) {
return (short) (time * (DEFAULT_TIMECODE_SCALE / oldTimeScale));
}
private void skipTo(SharpStream stream, long absoluteOffset) throws IOException {
absoluteOffset -= written;
written += absoluteOffset;
stream.skip(absoluteOffset);
private void seekTo(SharpStream stream, long offset) throws IOException {
if (stream.canSeek()) {
stream.seek(offset);
} else {
if (offset > written) {
stream.skip(offset - written);
} else {
stream.rewind();
stream.skip(offset);
}
}
written = offset;
}
private void writeLong(SharpStream stream, long number) throws IOException {
@ -453,7 +450,7 @@ public class WebMWriter {
/* cluster */
dump(new byte[]{0x1f, 0x43, (byte) 0xb6, 0x75}, stream);
clusterOffsets.add(written);// warning: max cluster size is 256 MiB
dump(new byte[]{0x20, 0x00, 0x00}, stream);
dump(new byte[]{0x10, 0x00, 0x00, 0x00}, stream);
startOffset = written;// size for the this cluster
@ -468,12 +465,12 @@ public class WebMWriter {
private void makeEBML(SharpStream stream) throws IOException {
// deafult values
dump(new byte[]{
0x1A, 0x45, (byte) 0xDF, (byte) 0xA3, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x1F, 0x42, (byte) 0x86, (byte) 0x81, 0x01,
0x42, (byte) 0xF7, (byte) 0x81, 0x01, 0x42, (byte) 0xF2, (byte) 0x81, 0x04,
0x42, (byte) 0xF3, (byte) 0x81, 0x08, 0x42, (byte) 0x82, (byte) 0x84, 0x77,
0x65, 0x62, 0x6D, 0x42, (byte) 0x87, (byte) 0x81, 0x02,
0x42, (byte) 0x85, (byte) 0x81, 0x02
0x1A, 0x45, (byte) 0xDF, (byte) 0xA3, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x1F, 0x42, (byte) 0x86, (byte) 0x81, 0x01,
0x42, (byte) 0xF7, (byte) 0x81, 0x01, 0x42, (byte) 0xF2, (byte) 0x81, 0x04,
0x42, (byte) 0xF3, (byte) 0x81, 0x08, 0x42, (byte) 0x82, (byte) 0x84, 0x77,
0x65, 0x62, 0x6D, 0x42, (byte) 0x87, (byte) 0x81, 0x02,
0x42, (byte) 0x85, (byte) 0x81, 0x02
}, stream);
}
@ -618,9 +615,10 @@ public class WebMWriter {
int offset = withLength ? 1 : 0;
byte[] buffer = new byte[offset + length];
long marker = (long) Math.floor((length - 1) / 8);
long marker = (long) Math.floor((length - 1f) / 8f);
for (int i = length - 1, mul = 1; i >= 0; i--, mul *= 0x100) {
float mul = 1;
for (int i = length - 1; i >= 0; i--, mul *= 0x100) {
long b = (long) Math.floor(number / mul);
if (!withLength && i == marker) {
b = b | (0x80 >> (length - 1));
@ -637,11 +635,7 @@ public class WebMWriter {
private ArrayList<byte[]> encode(String value) {
byte[] str;
try {
str = value.getBytes("utf-8");
} catch (UnsupportedEncodingException err) {
str = value.getBytes();
}
str = value.getBytes(StandardCharsets.UTF_8);// or use "utf-8"
ArrayList<byte[]> buffer = new ArrayList<>(2);
buffer.add(encode(str.length, false));
@ -720,9 +714,10 @@ public class WebMWriter {
return (flags & 0x80) == 0x80;
}
@NonNull
@Override
public String toString() {
return String.format("trackNumber=%s isKeyFrame=%S absoluteTimecode=%s", trackNumber, (flags & 0x80) == 0x80, absoluteTimecode);
return String.format("trackNumber=%s isKeyFrame=%S absoluteTimecode=%s", trackNumber, isKeyframe(), absoluteTimecode);
}
}
}

View File

@ -1,11 +1,12 @@
package org.schabi.newpipe.streams.io;
import java.io.Closeable;
import java.io.IOException;
/**
* based c#
* based on c#
*/
public abstract class SharpStream {
public abstract class SharpStream implements Closeable {
public abstract int read() throws IOException;
@ -15,16 +16,14 @@ public abstract class SharpStream {
public abstract long skip(long amount) throws IOException;
public abstract int available();
public abstract long available();
public abstract void rewind() throws IOException;
public abstract boolean isClosed();
public abstract void dispose();
public abstract boolean isDisposed();
@Override
public abstract void close();
public abstract boolean canRewind();
@ -32,6 +31,13 @@ public abstract class SharpStream {
public abstract boolean canWrite();
public boolean canSetLength() {
return false;
}
public boolean canSeek() {
return false;
}
public abstract void write(byte value) throws IOException;
@ -39,9 +45,19 @@ public abstract class SharpStream {
public abstract void write(byte[] buffer, int offset, int count) throws IOException;
public abstract void flush() throws IOException;
public void flush() throws IOException {
// STUB
}
public void setLength(long length) throws IOException {
throw new IOException("Not implemented");
}
public void seek(long offset) throws IOException {
throw new IOException("Not implemented");
}
public long length() throws IOException {
throw new UnsupportedOperationException("Unsupported operation");
}
}

View File

@ -10,6 +10,9 @@ import java.util.regex.Pattern;
public class FilenameUtils {
private static final String CHARSET_MOST_SPECIAL = "[\\n\\r|?*<\":\\\\>/']+";
private static final String CHARSET_ONLY_LETTERS_AND_DIGITS = "[^\\w\\d]+";
/**
* #143 #44 #42 #22: make sure that the filename does not contain illegal chars.
* @param context the context to retrieve strings and preferences from
@ -18,11 +21,28 @@ public class FilenameUtils {
*/
public static String createFilename(Context context, String title) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
final String key = context.getString(R.string.settings_file_charset_key);
final String value = sharedPreferences.getString(key, context.getString(R.string.default_file_charset_value));
Pattern pattern = Pattern.compile(value);
final String charset_ld = context.getString(R.string.charset_letters_and_digits_value);
final String charset_ms = context.getString(R.string.charset_most_special_value);
final String defaultCharset = context.getString(R.string.default_file_charset_value);
final String replacementChar = sharedPreferences.getString(context.getString(R.string.settings_file_replacement_character_key), "_");
String selectedCharset = sharedPreferences.getString(context.getString(R.string.settings_file_charset_key), null);
final String charset;
if (selectedCharset == null || selectedCharset.isEmpty()) selectedCharset = defaultCharset;
if (selectedCharset.equals(charset_ld)) {
charset = CHARSET_ONLY_LETTERS_AND_DIGITS;
} else if (selectedCharset.equals(charset_ms)) {
charset = CHARSET_MOST_SPECIAL;
} else {
charset = selectedCharset;// ¿is the user using a custom charset?
}
Pattern pattern = Pattern.compile(charset);
return createFilename(title, pattern, replacementChar);
}

View File

@ -430,24 +430,26 @@ public final class ListHelper {
*/
private static String getResolutionLimit(Context context) {
String resolutionLimit = null;
if (!isWifiActive(context)) {
if (isMeteredNetwork(context)) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
String defValue = context.getString(R.string.limit_data_usage_none_key);
String value = preferences.getString(
context.getString(R.string.limit_mobile_data_usage_key), defValue);
resolutionLimit = value.equals(defValue) ? null : value;
resolutionLimit = defValue.equals(value) ? null : value;
}
return resolutionLimit;
}
/**
* Are we connected to wifi?
* The current network is metered (like mobile data)?
* @param context App context
* @return {@code true} if connected to wifi
* @return {@code true} if connected to a metered network
*/
private static boolean isWifiActive(Context context)
private static boolean isMeteredNetwork(Context context)
{
ConnectivityManager manager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
return manager != null && manager.getActiveNetworkInfo() != null && manager.getActiveNetworkInfo().getType() == ConnectivityManager.TYPE_WIFI;
if (manager == null || manager.getActiveNetworkInfo() == null) return false;
return manager.isActiveNetworkMetered();
}
}

View File

@ -38,7 +38,7 @@ public class SecondaryStreamHelper<T extends Stream> {
public static AudioStream getAudioStreamFor(@NonNull List<AudioStream> audioStreams, @NonNull VideoStream videoStream) {
switch (videoStream.getFormat()) {
case WEBM:
case MPEG_4:
case MPEG_4:// ¿is mpeg-4 DASH?
break;
default:
return null;

View File

@ -1,185 +1,191 @@
package us.shandian.giga.get;
import android.support.annotation.NonNull;
import android.util.Log;
import java.io.File;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.nio.channels.ClosedByInterruptException;
import us.shandian.giga.util.Utility;
import static org.schabi.newpipe.BuildConfig.DEBUG;
public class DownloadInitializer extends Thread {
private final static String TAG = "DownloadInitializer";
final static int mId = 0;
private DownloadMission mMission;
private HttpURLConnection mConn;
DownloadInitializer(@NonNull DownloadMission mission) {
mMission = mission;
mConn = null;
}
@Override
public void run() {
if (mMission.current > 0) mMission.resetState();
int retryCount = 0;
while (true) {
try {
mMission.currentThreadCount = mMission.threadCount;
mConn = mMission.openConnection(mId, -1, -1);
mMission.establishConnection(mId, mConn);
if (!mMission.running || Thread.interrupted()) return;
mMission.length = Utility.getContentLength(mConn);
if (mMission.length == 0) {
mMission.notifyError(DownloadMission.ERROR_HTTP_NO_CONTENT, null);
return;
}
// check for dynamic generated content
if (mMission.length == -1 && mConn.getResponseCode() == 200) {
mMission.blocks = 0;
mMission.length = 0;
mMission.fallback = true;
mMission.unknownLength = true;
mMission.currentThreadCount = 1;
if (DEBUG) {
Log.d(TAG, "falling back (unknown length)");
}
} else {
// Open again
mConn = mMission.openConnection(mId, mMission.length - 10, mMission.length);
mMission.establishConnection(mId, mConn);
if (!mMission.running || Thread.interrupted()) return;
synchronized (mMission.blockState) {
if (mConn.getResponseCode() == 206) {
if (mMission.currentThreadCount > 1) {
mMission.blocks = mMission.length / DownloadMission.BLOCK_SIZE;
if (mMission.currentThreadCount > mMission.blocks) {
mMission.currentThreadCount = (int) mMission.blocks;
}
if (mMission.currentThreadCount <= 0) {
mMission.currentThreadCount = 1;
}
if (mMission.blocks * DownloadMission.BLOCK_SIZE < mMission.length) {
mMission.blocks++;
}
} else {
// if one thread is solicited don't calculate blocks, is useless
mMission.blocks = 1;
mMission.fallback = true;
mMission.unknownLength = false;
}
if (DEBUG) {
Log.d(TAG, "http response code = " + mConn.getResponseCode());
}
} else {
// Fallback to single thread
mMission.blocks = 0;
mMission.fallback = true;
mMission.unknownLength = false;
mMission.currentThreadCount = 1;
if (DEBUG) {
Log.d(TAG, "falling back due http response code = " + mConn.getResponseCode());
}
}
for (long i = 0; i < mMission.currentThreadCount; i++) {
mMission.threadBlockPositions.add(i);
mMission.threadBytePositions.add(0L);
}
}
if (!mMission.running || Thread.interrupted()) return;
}
File file;
if (mMission.current == 0) {
file = new File(mMission.location);
if (!Utility.mkdir(file, true)) {
mMission.notifyError(DownloadMission.ERROR_PATH_CREATION, null);
return;
}
file = new File(file, mMission.name);
// if the name is used by another process, delete it
if (file.exists() && !file.isFile() && !file.delete()) {
mMission.notifyError(DownloadMission.ERROR_FILE_CREATION, null);
return;
}
if (!file.exists() && !file.createNewFile()) {
mMission.notifyError(DownloadMission.ERROR_FILE_CREATION, null);
return;
}
} else {
file = new File(mMission.location, mMission.name);
}
RandomAccessFile af = new RandomAccessFile(file, "rw");
af.setLength(mMission.offsets[mMission.current] + mMission.length);
af.seek(mMission.offsets[mMission.current]);
af.close();
if (!mMission.running || Thread.interrupted()) return;
mMission.running = false;
break;
} catch (InterruptedIOException | ClosedByInterruptException e) {
return;
} catch (Exception e) {
if (!mMission.running) return;
if (e instanceof IOException && e.getMessage().contains("Permission denied")) {
mMission.notifyError(DownloadMission.ERROR_PERMISSION_DENIED, e);
return;
}
if (retryCount++ > mMission.maxRetry) {
Log.e(TAG, "initializer failed", e);
mMission.notifyError(e);
return;
}
Log.e(TAG, "initializer failed, retrying", e);
}
}
// hide marquee in the progress bar
mMission.done++;
mMission.start();
}
@Override
public void interrupt() {
super.interrupt();
if (mConn != null) {
try {
mConn.disconnect();
} catch (Exception e) {
// nothing to do
}
}
}
}
package us.shandian.giga.get;
import android.support.annotation.NonNull;
import android.util.Log;
import org.schabi.newpipe.streams.io.SharpStream;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.HttpURLConnection;
import java.nio.channels.ClosedByInterruptException;
import us.shandian.giga.util.Utility;
import static org.schabi.newpipe.BuildConfig.DEBUG;
public class DownloadInitializer extends Thread {
private final static String TAG = "DownloadInitializer";
final static int mId = 0;
private final static int RESERVE_SPACE_DEFAULT = 5 * 1024 * 1024;// 5 MiB
private final static int RESERVE_SPACE_MAXIMUM = 150 * 1024 * 1024;// 150 MiB
private DownloadMission mMission;
private HttpURLConnection mConn;
DownloadInitializer(@NonNull DownloadMission mission) {
mMission = mission;
mConn = null;
}
@Override
public void run() {
if (mMission.current > 0) mMission.resetState(false, true, DownloadMission.ERROR_NOTHING);
int retryCount = 0;
while (true) {
try {
mMission.currentThreadCount = mMission.threadCount;
if (mMission.blocks < 0 && mMission.current == 0) {
// calculate the whole size of the mission
long finalLength = 0;
long lowestSize = Long.MAX_VALUE;
for (int i = 0; i < mMission.urls.length && mMission.running; i++) {
mConn = mMission.openConnection(mMission.urls[i], mId, -1, -1);
mMission.establishConnection(mId, mConn);
if (Thread.interrupted()) return;
long length = Utility.getContentLength(mConn);
if (i == 0) mMission.length = length;
if (length > 0) finalLength += length;
if (length < lowestSize) lowestSize = length;
}
mMission.nearLength = finalLength;
// reserve space at the start of the file
if (mMission.psAlgorithm != null && mMission.psAlgorithm.reserveSpace) {
if (lowestSize < 1) {
// the length is unknown use the default size
mMission.offsets[0] = RESERVE_SPACE_DEFAULT;
} else {
// use the smallest resource size to download, otherwise, use the maximum
mMission.offsets[0] = lowestSize < RESERVE_SPACE_MAXIMUM ? lowestSize : RESERVE_SPACE_MAXIMUM;
}
}
} else {
// ask for the current resource length
mConn = mMission.openConnection(mId, -1, -1);
mMission.establishConnection(mId, mConn);
if (!mMission.running || Thread.interrupted()) return;
mMission.length = Utility.getContentLength(mConn);
}
if (mMission.length == 0 || mConn.getResponseCode() == 204) {
mMission.notifyError(DownloadMission.ERROR_HTTP_NO_CONTENT, null);
return;
}
// check for dynamic generated content
if (mMission.length == -1 && mConn.getResponseCode() == 200) {
mMission.blocks = 0;
mMission.length = 0;
mMission.fallback = true;
mMission.unknownLength = true;
mMission.currentThreadCount = 1;
if (DEBUG) {
Log.d(TAG, "falling back (unknown length)");
}
} else {
// Open again
mConn = mMission.openConnection(mId, mMission.length - 10, mMission.length);
mMission.establishConnection(mId, mConn);
if (!mMission.running || Thread.interrupted()) return;
synchronized (mMission.blockState) {
if (mConn.getResponseCode() == 206) {
if (mMission.currentThreadCount > 1) {
mMission.blocks = mMission.length / DownloadMission.BLOCK_SIZE;
if (mMission.currentThreadCount > mMission.blocks) {
mMission.currentThreadCount = (int) mMission.blocks;
}
if (mMission.currentThreadCount <= 0) {
mMission.currentThreadCount = 1;
}
if (mMission.blocks * DownloadMission.BLOCK_SIZE < mMission.length) {
mMission.blocks++;
}
} else {
// if one thread is solicited don't calculate blocks, is useless
mMission.blocks = 1;
mMission.fallback = true;
mMission.unknownLength = false;
}
if (DEBUG) {
Log.d(TAG, "http response code = " + mConn.getResponseCode());
}
} else {
// Fallback to single thread
mMission.blocks = 0;
mMission.fallback = true;
mMission.unknownLength = false;
mMission.currentThreadCount = 1;
if (DEBUG) {
Log.d(TAG, "falling back due http response code = " + mConn.getResponseCode());
}
}
for (long i = 0; i < mMission.currentThreadCount; i++) {
mMission.threadBlockPositions.add(i);
mMission.threadBytePositions.add(0L);
}
}
if (!mMission.running || Thread.interrupted()) return;
}
SharpStream fs = mMission.storage.getStream();
fs.setLength(mMission.offsets[mMission.current] + mMission.length);
fs.seek(mMission.offsets[mMission.current]);
fs.close();
if (!mMission.running || Thread.interrupted()) return;
mMission.running = false;
break;
} catch (InterruptedIOException | ClosedByInterruptException e) {
return;
} catch (Exception e) {
if (!mMission.running) return;
if (e instanceof IOException && e.getMessage().contains("Permission denied")) {
mMission.notifyError(DownloadMission.ERROR_PERMISSION_DENIED, e);
return;
}
if (retryCount++ > mMission.maxRetry) {
Log.e(TAG, "initializer failed", e);
mMission.notifyError(e);
return;
}
Log.e(TAG, "initializer failed, retrying", e);
}
}
mMission.start();
}
@Override
public void interrupt() {
super.interrupt();
if (mConn != null) {
try {
mConn.disconnect();
} catch (Exception e) {
// nothing to do
}
}
}
}

View File

@ -4,11 +4,14 @@ import android.os.Handler;
import android.os.Message;
import android.util.Log;
import org.schabi.newpipe.Downloader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.ArrayList;
@ -17,6 +20,7 @@ import java.util.List;
import javax.net.ssl.SSLException;
import us.shandian.giga.io.StoredFileHelper;
import us.shandian.giga.postprocessing.Postprocessing;
import us.shandian.giga.service.DownloadManagerService;
import us.shandian.giga.util.Utility;
@ -24,7 +28,7 @@ import us.shandian.giga.util.Utility;
import static org.schabi.newpipe.BuildConfig.DEBUG;
public class DownloadMission extends Mission {
private static final long serialVersionUID = 3L;// last bump: 8 november 2018
private static final long serialVersionUID = 4L;// last bump: 27 march 2019
static final int BUFFER_SIZE = 64 * 1024;
final static int BLOCK_SIZE = 512 * 1024;
@ -40,6 +44,11 @@ public class DownloadMission extends Mission {
public static final int ERROR_UNKNOWN_HOST = 1005;
public static final int ERROR_CONNECT_HOST = 1006;
public static final int ERROR_POSTPROCESSING = 1007;
public static final int ERROR_POSTPROCESSING_STOPPED = 1008;
public static final int ERROR_POSTPROCESSING_HOLD = 1009;
public static final int ERROR_INSUFFICIENT_STORAGE = 1010;
public static final int ERROR_PROGRESS_LOST = 1011;
public static final int ERROR_TIMEOUT = 1012;
public static final int ERROR_HTTP_NO_CONTENT = 204;
public static final int ERROR_HTTP_UNSUPPORTED_RANGE = 206;
@ -68,43 +77,34 @@ public class DownloadMission extends Mission {
*/
public long[] offsets;
/**
* The post-processing algorithm arguments
*/
public String[] postprocessingArgs;
/**
* The post-processing algorithm name
*/
public String postprocessingName;
/**
* Indicates if the post-processing state:
* 0: ready
* 1: running
* 2: completed
* 3: hold
*/
public int postprocessingState;
public volatile int psState;
/**
* Indicate if the post-processing algorithm works on the same file
* the post-processing algorithm instance
*/
public boolean postprocessingThis;
public Postprocessing psAlgorithm;
/**
* The current resource to download {@code urls[current]}
* The current resource to download, see {@code urls[current]} and {@code offsets[current]}
*/
public int current;
/**
* Metadata where the mission state is saved
*/
public File metadata;
public transient File metadata;
/**
* maximum attempts
*/
public int maxRetry;
public transient int maxRetry;
/**
* Approximated final length, this represent the sum of all resources sizes
@ -115,11 +115,11 @@ public class DownloadMission extends Mission {
boolean fallback;
private int finishCount;
public transient boolean running;
public transient boolean enqueued = true;
public boolean enqueued;
public int errCode = ERROR_NOTHING;
public transient Exception errObject = null;
public Exception errObject = null;
public transient boolean recovered;
public transient Handler mHandler;
private transient boolean mWritingToFile;
@ -131,41 +131,26 @@ public class DownloadMission extends Mission {
private transient boolean deleted;
int currentThreadCount;
private transient Thread[] threads = new Thread[0];
public transient volatile Thread[] threads = new Thread[0];
private transient Thread init = null;
protected DownloadMission() {
}
public DownloadMission(String url, String name, String location, char kind) {
this(new String[]{url}, name, location, kind, null, null);
}
public DownloadMission(String[] urls, String name, String location, char kind, String postprocessingName, String[] postprocessingArgs) {
if (name == null) throw new NullPointerException("name is null");
if (name.isEmpty()) throw new IllegalArgumentException("name is empty");
public DownloadMission(String[] urls, StoredFileHelper storage, char kind, Postprocessing psInstance) {
if (urls == null) throw new NullPointerException("urls is null");
if (urls.length < 1) throw new IllegalArgumentException("urls is empty");
if (location == null) throw new NullPointerException("location is null");
if (location.isEmpty()) throw new IllegalArgumentException("location is empty");
this.urls = urls;
this.name = name;
this.location = location;
this.kind = kind;
this.offsets = new long[urls.length];
this.enqueued = true;
this.maxRetry = 3;
this.storage = storage;
this.psAlgorithm = psInstance;
if (postprocessingName != null) {
Postprocessing algorithm = Postprocessing.getAlgorithm(postprocessingName, null);
this.postprocessingThis = algorithm.worksOnSameFile;
this.offsets[0] = algorithm.recommendedReserve;
this.postprocessingName = postprocessingName;
this.postprocessingArgs = postprocessingArgs;
} else {
if (DEBUG && urls.length > 1) {
Log.w(TAG, "mission created with multiple urls ¿missing post-processing algorithm?");
}
if (DEBUG && psInstance == null && urls.length > 1) {
Log.w(TAG, "mission created with multiple urls ¿missing post-processing algorithm?");
}
}
@ -183,6 +168,7 @@ public class DownloadMission extends Mission {
*/
boolean isBlockPreserved(long block) {
checkBlock(block);
//noinspection ConstantConditions
return blockState.containsKey(block) ? blockState.get(block) : false;
}
@ -243,9 +229,18 @@ public class DownloadMission extends Mission {
* @throws IOException if an I/O exception occurs.
*/
HttpURLConnection openConnection(int threadId, long rangeStart, long rangeEnd) throws IOException {
URL url = new URL(urls[current]);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
return openConnection(urls[current], threadId, rangeStart, rangeEnd);
}
HttpURLConnection openConnection(String url, int threadId, long rangeStart, long rangeEnd) throws IOException {
HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
conn.setInstanceFollowRedirects(true);
conn.setRequestProperty("User-Agent", Downloader.USER_AGENT);
conn.setRequestProperty("Accept", "*/*");
// BUG workaround: switching between networks can freeze the download forever
conn.setConnectTimeout(30000);
conn.setReadTimeout(10000);
if (rangeStart >= 0) {
String req = "bytes=" + rangeStart + "-";
@ -337,17 +332,42 @@ public class DownloadMission extends Mission {
notifyError(ERROR_CONNECT_HOST, null);
} else if (err instanceof UnknownHostException) {
notifyError(ERROR_UNKNOWN_HOST, null);
} else if (err instanceof SocketTimeoutException) {
notifyError(ERROR_TIMEOUT, null);
} else {
notifyError(ERROR_UNKNOWN_EXCEPTION, err);
}
}
synchronized void notifyError(int code, Exception err) {
public synchronized void notifyError(int code, Exception err) {
Log.e(TAG, "notifyError() code = " + code, err);
if (err instanceof IOException) {
if (!storage.canWrite() || err.getMessage().contains("Permission denied")) {
code = ERROR_PERMISSION_DENIED;
err = null;
} else if (err.getMessage().contains("ENOSPC")) {
code = ERROR_INSUFFICIENT_STORAGE;
err = null;
}
}
errCode = code;
errObject = err;
switch (code) {
case ERROR_SSL_EXCEPTION:
case ERROR_UNKNOWN_HOST:
case ERROR_CONNECT_HOST:
case ERROR_TIMEOUT:
// do not change the queue flag for network errors, can be
// recovered silently without the user interaction
break;
default:
// also checks for server errors
if (code < 500 || code > 599) enqueued = false;
}
pause();
notify(DownloadManagerService.MESSAGE_ERROR);
@ -378,6 +398,7 @@ public class DownloadMission extends Mission {
if (!doPostprocessing()) return;
enqueued = false;
running = false;
deleteThisFromFile();
@ -386,25 +407,23 @@ public class DownloadMission extends Mission {
}
private void notifyPostProcessing(int state) {
if (DEBUG) {
String action;
switch (state) {
case 1:
action = "Running";
break;
case 2:
action = "Completed";
break;
default:
action = "Failed";
}
Log.d(TAG, action + " postprocessing on " + location + File.separator + name);
String action;
switch (state) {
case 1:
action = "Running";
break;
case 2:
action = "Completed";
break;
default:
action = "Failed";
}
Log.d(TAG, action + " postprocessing on " + storage.getName());
synchronized (blockState) {
// don't return without fully write the current state
postprocessingState = state;
psState = state;
Utility.writeToFile(metadata, DownloadMission.this);
}
}
@ -420,11 +439,10 @@ public class DownloadMission extends Mission {
if (threads != null)
for (Thread thread : threads) joinForThread(thread);
enqueued = false;
running = true;
errCode = ERROR_NOTHING;
if (current >= urls.length && postprocessingName != null) {
if (current >= urls.length && psAlgorithm != null) {
runAsync(1, () -> {
if (doPostprocessing()) {
running = false;
@ -463,7 +481,7 @@ public class DownloadMission extends Mission {
}
/**
* Pause the mission, does not affect the blocks that are being downloaded.
* Pause the mission
*/
public synchronized void pause() {
if (!running) return;
@ -477,12 +495,11 @@ public class DownloadMission extends Mission {
running = false;
recovered = true;
enqueued = false;
if (init != null && Thread.currentThread() != init && init.isAlive()) {
init.interrupt();
synchronized (blockState) {
resetState();
resetState(false, true, ERROR_NOTHING);
}
return;
}
@ -514,20 +531,31 @@ public class DownloadMission extends Mission {
}
/**
* Removes the file and the meta file
* Removes the downloaded file and the meta file
*/
@Override
public boolean delete() {
deleted = true;
if (psAlgorithm != null) psAlgorithm.cleanupTemporalDir();
boolean res = deleteThisFromFile();
if (!super.delete()) res = false;
if (!super.delete()) return false;
return res;
}
void resetState() {
/**
* Resets the mission state
*
* @param rollback {@code true} true to forget all progress, otherwise, {@code false}
* @param persistChanges {@code true} to commit changes to the metadata file, otherwise, {@code false}
*/
public void resetState(boolean rollback, boolean persistChanges, int errorCode) {
done = 0;
blocks = -1;
errCode = ERROR_NOTHING;
errCode = errorCode;
errObject = null;
fallback = false;
unknownLength = false;
finishCount = 0;
@ -536,7 +564,10 @@ public class DownloadMission extends Mission {
blockState.clear();
threads = new Thread[0];
Utility.writeToFile(metadata, DownloadMission.this);
if (rollback) current = 0;
if (persistChanges)
Utility.writeToFile(metadata, DownloadMission.this);
}
private void initializer() {
@ -562,7 +593,7 @@ public class DownloadMission extends Mission {
* @return true, otherwise, false
*/
public boolean isFinished() {
return current >= urls.length && (postprocessingName == null || postprocessingState == 2);
return current >= urls.length && (psAlgorithm == null || psState == 2);
}
/**
@ -571,7 +602,13 @@ public class DownloadMission extends Mission {
* @return {@code true} if this mission is unrecoverable
*/
public boolean isPsFailed() {
return postprocessingName != null && errCode == DownloadMission.ERROR_POSTPROCESSING && postprocessingThis;
switch (errCode) {
case ERROR_POSTPROCESSING:
case ERROR_POSTPROCESSING_STOPPED:
return psAlgorithm.worksOnSameFile;
}
return false;
}
/**
@ -580,12 +617,26 @@ public class DownloadMission extends Mission {
* @return true, otherwise, false
*/
public boolean isPsRunning() {
return postprocessingName != null && postprocessingState == 1;
return psAlgorithm != null && (psState == 1 || psState == 3);
}
/**
* Indicated if the mission is ready
*
* @return true, otherwise, false
*/
public boolean isInitialized() {
return blocks >= 0; // DownloadMissionInitializer was executed
}
/**
* Gets the approximated final length of the file
*
* @return the length in bytes
*/
public long getLength() {
long calculated;
if (postprocessingState == 1) {
if (psState == 1 || psState == 3) {
calculated = length;
} else {
calculated = offsets[current < offsets.length ? current : (offsets.length - 1)] + length;
@ -596,30 +647,67 @@ public class DownloadMission extends Mission {
return calculated > nearLength ? calculated : nearLength;
}
/**
* set this mission state on the queue
*
* @param queue true to add to the queue, otherwise, false
*/
public void setEnqueued(boolean queue) {
enqueued = queue;
runAsync(-2, this::writeThisToFile);
}
/**
* Attempts to continue a blocked post-processing
*
* @param recover {@code true} to retry, otherwise, {@code false} to cancel
*/
public void psContinue(boolean recover) {
psState = 1;
errCode = recover ? ERROR_NOTHING : ERROR_POSTPROCESSING;
threads[0].interrupt();
}
/**
* Indicates whatever the backed storage is invalid
*
* @return {@code true}, if storage is invalid and cannot be used
*/
public boolean hasInvalidStorage() {
return errCode == ERROR_PROGRESS_LOST || storage == null || storage.isInvalid() || !storage.existsAsFile();
}
/**
* Indicates whatever is possible to start the mission
*
* @return {@code true} is this mission its "healthy", otherwise, {@code false}
*/
public boolean isCorrupt() {
return (isPsFailed() || errCode == ERROR_POSTPROCESSING_HOLD) || isFinished() || hasInvalidStorage();
}
private boolean doPostprocessing() {
if (postprocessingName == null || postprocessingState == 2) return true;
if (psAlgorithm == null || psState == 2) return true;
errObject = null;
notifyPostProcessing(1);
notifyProgress(0);
Thread.currentThread().setName("[" + TAG + "] post-processing = " + postprocessingName + " filename = " + name);
if (DEBUG)
Thread.currentThread().setName("[" + TAG + "] ps = " +
psAlgorithm.getClass().getSimpleName() +
" filename = " + storage.getName()
);
threads = new Thread[]{Thread.currentThread()};
Exception exception = null;
try {
Postprocessing
.getAlgorithm(postprocessingName, this)
.run();
psAlgorithm.run(this);
} catch (Exception err) {
StringBuilder args = new StringBuilder(" ");
if (postprocessingArgs != null) {
for (String arg : postprocessingArgs) {
args.append(", ");
args.append(arg);
}
args.delete(0, 1);
}
Log.e(TAG, String.format("Post-processing failed. algorithm = %s args = [%s]", postprocessingName, args), err);
Log.e(TAG, "Post-processing failed. " + psAlgorithm.toString(), err);
if (errCode == ERROR_NOTHING) errCode = ERROR_POSTPROCESSING;
@ -669,7 +757,7 @@ public class DownloadMission extends Mission {
// >=1: any download thread
if (DEBUG) {
who.setName(String.format("%s[%s] %s", TAG, id, name));
who.setName(String.format("%s[%s] %s", TAG, id, storage.getName()));
}
who.start();

View File

@ -2,9 +2,10 @@ package us.shandian.giga.get;
import android.util.Log;
import java.io.FileNotFoundException;
import org.schabi.newpipe.streams.io.SharpStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.nio.channels.ClosedByInterruptException;
@ -26,7 +27,6 @@ public class DownloadRunnable extends Thread {
if (mission == null) throw new NullPointerException("mission is null");
mMission = mission;
mId = id;
mConn = null;
}
@Override
@ -40,12 +40,12 @@ public class DownloadRunnable extends Thread {
Log.d(TAG, mId + ":recovered: " + mMission.recovered);
}
RandomAccessFile f;
SharpStream f;
InputStream is = null;
try {
f = new RandomAccessFile(mMission.getDownloadedFile(), "rw");
} catch (FileNotFoundException e) {
f = mMission.storage.getStream();
} catch (IOException e) {
mMission.notifyError(e);// this never should happen
return;
}
@ -136,6 +136,10 @@ public class DownloadRunnable extends Thread {
mMission.setThreadBytePosition(mId, total);// download paused, save progress for this block
} catch (Exception e) {
if (DEBUG) {
Log.d(TAG, mId + ": position=" + blockPosition + " total=" + total + " stopped due exception", e);
}
mMission.setThreadBytePosition(mId, total);
if (!mMission.running || e instanceof ClosedByInterruptException) break;
@ -145,10 +149,6 @@ public class DownloadRunnable extends Thread {
break;
}
if (DEBUG) {
Log.d(TAG, mId + ":position " + blockPosition + " retrying due exception", e);
}
retry = true;
}
}

View File

@ -1,16 +1,15 @@
package us.shandian.giga.get;
import android.annotation.SuppressLint;
import android.support.annotation.NonNull;
import android.util.Log;
import org.schabi.newpipe.streams.io.SharpStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.nio.channels.ClosedByInterruptException;
import us.shandian.giga.util.Utility;
import static org.schabi.newpipe.BuildConfig.DEBUG;
@ -19,21 +18,17 @@ import static org.schabi.newpipe.BuildConfig.DEBUG;
* Single-threaded fallback mode
*/
public class DownloadRunnableFallback extends Thread {
private static final String TAG = "DownloadRunnableFallback";
private static final String TAG = "DownloadRunnableFallbac";
private final DownloadMission mMission;
private final int mId = 1;
private int mRetryCount = 0;
private InputStream mIs;
private RandomAccessFile mF;
private SharpStream mF;
private HttpURLConnection mConn;
DownloadRunnableFallback(@NonNull DownloadMission mission) {
mMission = mission;
mIs = null;
mF = null;
mConn = null;
}
private void dispose() {
@ -43,15 +38,10 @@ public class DownloadRunnableFallback extends Thread {
// nothing to do
}
try {
if (mF != null) mF.close();
} catch (IOException e) {
// ¿ejected media storage? ¿file deleted? ¿storage ran out of space?
}
if (mF != null) mF.close();
}
@Override
@SuppressLint("LongLogTag")
public void run() {
boolean done;
@ -67,6 +57,7 @@ public class DownloadRunnableFallback extends Thread {
try {
long rangeStart = (mMission.unknownLength || start < 1) ? -1 : start;
int mId = 1;
mConn = mMission.openConnection(mId, rangeStart, -1);
mMission.establishConnection(mId, mConn);
@ -81,7 +72,7 @@ public class DownloadRunnableFallback extends Thread {
if (!mMission.unknownLength)
mMission.unknownLength = Utility.getContentLength(mConn) == -1;
mF = new RandomAccessFile(mMission.getDownloadedFile(), "rw");
mF = mMission.storage.getStream();
mF.seek(mMission.offsets[mMission.current] + start);
mIs = mConn.getInputStream();
@ -110,6 +101,10 @@ public class DownloadRunnableFallback extends Thread {
return;
}
if (DEBUG) {
Log.e(TAG, "got exception, retrying...", e);
}
run();// try again
return;
}

View File

@ -1,16 +1,18 @@
package us.shandian.giga.get;
import android.support.annotation.NonNull;
public class FinishedMission extends Mission {
public FinishedMission() {
}
public FinishedMission(DownloadMission mission) {
public FinishedMission(@NonNull DownloadMission mission) {
source = mission.source;
length = mission.length;// ¿or mission.done?
timestamp = mission.timestamp;
name = mission.name;
location = mission.location;
kind = mission.kind;
storage = mission.storage;
}
}

View File

@ -1,12 +1,14 @@
package us.shandian.giga.get;
import java.io.File;
import android.support.annotation.NonNull;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import us.shandian.giga.io.StoredFileHelper;
public abstract class Mission implements Serializable {
private static final long serialVersionUID = 0L;// last bump: 5 october 2018
private static final long serialVersionUID = 1L;// last bump: 27 march 2019
/**
* Source url of the resource
@ -23,33 +25,24 @@ public abstract class Mission implements Serializable {
*/
public long timestamp;
/**
* The filename
*/
public String name;
/**
* The directory to store the download
*/
public String location;
/**
* pre-defined content type
*/
public char kind;
/**
* get the target file on the storage
*
* @return File object
* The downloaded file
*/
public File getDownloadedFile() {
return new File(location, name);
}
public StoredFileHelper storage;
/**
* Delete the downloaded file
*
* @return {@code true] if and only if the file is successfully deleted, otherwise, {@code false}
*/
public boolean delete() {
deleted = true;
return getDownloadedFile().delete();
if (storage != null) return storage.delete();
return true;
}
/**
@ -57,10 +50,11 @@ public abstract class Mission implements Serializable {
*/
public transient boolean deleted = false;
@NonNull
@Override
public String toString() {
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(timestamp);
return "[" + calendar.getTime().toString() + "] " + location + File.separator + name;
return "[" + calendar.getTime().toString() + "] " + (storage.isInvalid() ? storage.getName() : storage.getUri());
}
}

View File

@ -1,73 +0,0 @@
package us.shandian.giga.get.sqlite;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import java.util.ArrayList;
import java.util.List;
import us.shandian.giga.get.DownloadMission;
import us.shandian.giga.get.FinishedMission;
import us.shandian.giga.get.Mission;
import static us.shandian.giga.get.sqlite.DownloadMissionHelper.KEY_LOCATION;
import static us.shandian.giga.get.sqlite.DownloadMissionHelper.KEY_NAME;
import static us.shandian.giga.get.sqlite.DownloadMissionHelper.MISSIONS_TABLE_NAME;
public class DownloadDataSource {
private static final String TAG = "DownloadDataSource";
private final DownloadMissionHelper downloadMissionHelper;
public DownloadDataSource(Context context) {
downloadMissionHelper = new DownloadMissionHelper(context);
}
public ArrayList<FinishedMission> loadFinishedMissions() {
SQLiteDatabase database = downloadMissionHelper.getReadableDatabase();
Cursor cursor = database.query(MISSIONS_TABLE_NAME, null, null,
null, null, null, DownloadMissionHelper.KEY_TIMESTAMP);
int count = cursor.getCount();
if (count == 0) return new ArrayList<>(1);
ArrayList<FinishedMission> result = new ArrayList<>(count);
while (cursor.moveToNext()) {
result.add(DownloadMissionHelper.getMissionFromCursor(cursor));
}
return result;
}
public void addMission(DownloadMission downloadMission) {
if (downloadMission == null) throw new NullPointerException("downloadMission is null");
SQLiteDatabase database = downloadMissionHelper.getWritableDatabase();
ContentValues values = DownloadMissionHelper.getValuesOfMission(downloadMission);
database.insert(MISSIONS_TABLE_NAME, null, values);
}
public void deleteMission(Mission downloadMission) {
if (downloadMission == null) throw new NullPointerException("downloadMission is null");
SQLiteDatabase database = downloadMissionHelper.getWritableDatabase();
database.delete(MISSIONS_TABLE_NAME,
KEY_LOCATION + " = ? AND " +
KEY_NAME + " = ?",
new String[]{downloadMission.location, downloadMission.name});
}
public void updateMission(DownloadMission downloadMission) {
if (downloadMission == null) throw new NullPointerException("downloadMission is null");
SQLiteDatabase database = downloadMissionHelper.getWritableDatabase();
ContentValues values = DownloadMissionHelper.getValuesOfMission(downloadMission);
String whereClause = KEY_LOCATION + " = ? AND " +
KEY_NAME + " = ?";
int rowsAffected = database.update(MISSIONS_TABLE_NAME, values,
whereClause, new String[]{downloadMission.location, downloadMission.name});
if (rowsAffected != 1) {
Log.e(TAG, "Expected 1 row to be affected by update but got " + rowsAffected);
}
}
}

View File

@ -1,112 +0,0 @@
package us.shandian.giga.get.sqlite;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import us.shandian.giga.get.DownloadMission;
import us.shandian.giga.get.FinishedMission;
/**
* SQLiteHelper to store finished {@link us.shandian.giga.get.DownloadMission}'s
*/
public class DownloadMissionHelper extends SQLiteOpenHelper {
private final String TAG = "DownloadMissionHelper";
// TODO: use NewPipeSQLiteHelper ('s constants) when playlist branch is merged (?)
private static final String DATABASE_NAME = "downloads.db";
private static final int DATABASE_VERSION = 3;
/**
* The table name of download missions
*/
static final String MISSIONS_TABLE_NAME = "download_missions";
/**
* The key to the directory location of the mission
*/
static final String KEY_LOCATION = "location";
/**
* The key to the urls of a mission
*/
static final String KEY_SOURCE_URL = "url";
/**
* The key to the name of a mission
*/
static final String KEY_NAME = "name";
/**
* The key to the done.
*/
static final String KEY_DONE = "bytes_downloaded";
static final String KEY_TIMESTAMP = "timestamp";
static final String KEY_KIND = "kind";
/**
* The statement to create the table
*/
private static final String MISSIONS_CREATE_TABLE =
"CREATE TABLE " + MISSIONS_TABLE_NAME + " (" +
KEY_LOCATION + " TEXT NOT NULL, " +
KEY_NAME + " TEXT NOT NULL, " +
KEY_SOURCE_URL + " TEXT NOT NULL, " +
KEY_DONE + " INTEGER NOT NULL, " +
KEY_TIMESTAMP + " INTEGER NOT NULL, " +
KEY_KIND + " TEXT NOT NULL, " +
" UNIQUE(" + KEY_LOCATION + ", " + KEY_NAME + "));";
public DownloadMissionHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(MISSIONS_CREATE_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (oldVersion == 2) {
db.execSQL("ALTER TABLE " + MISSIONS_TABLE_NAME + " ADD COLUMN " + KEY_KIND + " TEXT;");
}
}
/**
* Returns all values of the download mission as ContentValues.
*
* @param downloadMission the download mission
* @return the content values
*/
public static ContentValues getValuesOfMission(DownloadMission downloadMission) {
ContentValues values = new ContentValues();
values.put(KEY_SOURCE_URL, downloadMission.source);
values.put(KEY_LOCATION, downloadMission.location);
values.put(KEY_NAME, downloadMission.name);
values.put(KEY_DONE, downloadMission.done);
values.put(KEY_TIMESTAMP, downloadMission.timestamp);
values.put(KEY_KIND, String.valueOf(downloadMission.kind));
return values;
}
public static FinishedMission getMissionFromCursor(Cursor cursor) {
if (cursor == null) throw new NullPointerException("cursor is null");
String kind = cursor.getString(cursor.getColumnIndex(KEY_KIND));
if (kind == null || kind.isEmpty()) kind = "?";
FinishedMission mission = new FinishedMission();
mission.name = cursor.getString(cursor.getColumnIndexOrThrow(KEY_NAME));
mission.location = cursor.getString(cursor.getColumnIndexOrThrow(KEY_LOCATION));
mission.source = cursor.getString(cursor.getColumnIndexOrThrow(KEY_SOURCE_URL));;
mission.length = cursor.getLong(cursor.getColumnIndexOrThrow(KEY_DONE));
mission.timestamp = cursor.getLong(cursor.getColumnIndexOrThrow(KEY_TIMESTAMP));
mission.kind = kind.charAt(0);
return mission;
}
}

View File

@ -0,0 +1,237 @@
package us.shandian.giga.get.sqlite;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.util.Log;
import java.io.File;
import java.util.ArrayList;
import us.shandian.giga.get.DownloadMission;
import us.shandian.giga.get.FinishedMission;
import us.shandian.giga.get.Mission;
import us.shandian.giga.io.StoredFileHelper;
/**
* SQLite helper to store finished {@link us.shandian.giga.get.FinishedMission}'s
*/
public class FinishedMissionStore extends SQLiteOpenHelper {
// TODO: use NewPipeSQLiteHelper ('s constants) when playlist branch is merged (?)
private static final String DATABASE_NAME = "downloads.db";
private static final int DATABASE_VERSION = 4;
/**
* The table name of download missions (old)
*/
private static final String MISSIONS_TABLE_NAME_v2 = "download_missions";
/**
* The table name of download missions
*/
private static final String FINISHED_TABLE_NAME = "finished_missions";
/**
* The key to the urls of a mission
*/
private static final String KEY_SOURCE = "url";
/**
* The key to the done.
*/
private static final String KEY_DONE = "bytes_downloaded";
private static final String KEY_TIMESTAMP = "timestamp";
private static final String KEY_KIND = "kind";
private static final String KEY_PATH = "path";
/**
* The statement to create the table
*/
private static final String MISSIONS_CREATE_TABLE =
"CREATE TABLE " + FINISHED_TABLE_NAME + " (" +
KEY_PATH + " TEXT NOT NULL, " +
KEY_SOURCE + " TEXT NOT NULL, " +
KEY_DONE + " INTEGER NOT NULL, " +
KEY_TIMESTAMP + " INTEGER NOT NULL, " +
KEY_KIND + " TEXT NOT NULL, " +
" UNIQUE(" + KEY_TIMESTAMP + ", " + KEY_PATH + "));";
private Context context;
public FinishedMissionStore(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
this.context = context;
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(MISSIONS_CREATE_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (oldVersion == 2) {
db.execSQL("ALTER TABLE " + MISSIONS_TABLE_NAME_v2 + " ADD COLUMN " + KEY_KIND + " TEXT;");
oldVersion++;
}
if (oldVersion == 3) {
final String KEY_LOCATION = "location";
final String KEY_NAME = "name";
db.execSQL(MISSIONS_CREATE_TABLE);
Cursor cursor = db.query(MISSIONS_TABLE_NAME_v2, null, null,
null, null, null, KEY_TIMESTAMP);
int count = cursor.getCount();
if (count > 0) {
db.beginTransaction();
while (cursor.moveToNext()) {
ContentValues values = new ContentValues();
values.put(KEY_SOURCE, cursor.getString(cursor.getColumnIndex(KEY_SOURCE)));
values.put(KEY_DONE, cursor.getString(cursor.getColumnIndex(KEY_DONE)));
values.put(KEY_TIMESTAMP, cursor.getLong(cursor.getColumnIndex(KEY_TIMESTAMP)));
values.put(KEY_KIND, cursor.getString(cursor.getColumnIndex(KEY_KIND)));
values.put(KEY_PATH, Uri.fromFile(
new File(
cursor.getString(cursor.getColumnIndex(KEY_LOCATION)),
cursor.getString(cursor.getColumnIndex(KEY_NAME))
)
).toString());
db.insert(FINISHED_TABLE_NAME, null, values);
}
db.setTransactionSuccessful();
db.endTransaction();
}
cursor.close();
db.execSQL("DROP TABLE " + MISSIONS_TABLE_NAME_v2);
}
}
/**
* Returns all values of the download mission as ContentValues.
*
* @param downloadMission the download mission
* @return the content values
*/
private ContentValues getValuesOfMission(@NonNull Mission downloadMission) {
ContentValues values = new ContentValues();
values.put(KEY_SOURCE, downloadMission.source);
values.put(KEY_PATH, downloadMission.storage.getUri().toString());
values.put(KEY_DONE, downloadMission.length);
values.put(KEY_TIMESTAMP, downloadMission.timestamp);
values.put(KEY_KIND, String.valueOf(downloadMission.kind));
return values;
}
private FinishedMission getMissionFromCursor(Cursor cursor) {
if (cursor == null) throw new NullPointerException("cursor is null");
String kind = cursor.getString(cursor.getColumnIndex(KEY_KIND));
if (kind == null || kind.isEmpty()) kind = "?";
String path = cursor.getString(cursor.getColumnIndexOrThrow(KEY_PATH));
FinishedMission mission = new FinishedMission();
mission.source = cursor.getString(cursor.getColumnIndexOrThrow(KEY_SOURCE));
mission.length = cursor.getLong(cursor.getColumnIndexOrThrow(KEY_DONE));
mission.timestamp = cursor.getLong(cursor.getColumnIndexOrThrow(KEY_TIMESTAMP));
mission.kind = kind.charAt(0);
try {
mission.storage = new StoredFileHelper(context,null, Uri.parse(path), "");
} catch (Exception e) {
Log.e("FinishedMissionStore", "failed to load the storage path of: " + path, e);
mission.storage = new StoredFileHelper(null, path, "", "");
}
return mission;
}
//////////////////////////////////
// Data source methods
///////////////////////////////////
public ArrayList<FinishedMission> loadFinishedMissions() {
SQLiteDatabase database = getReadableDatabase();
Cursor cursor = database.query(FINISHED_TABLE_NAME, null, null,
null, null, null, KEY_TIMESTAMP + " DESC");
int count = cursor.getCount();
if (count == 0) return new ArrayList<>(1);
ArrayList<FinishedMission> result = new ArrayList<>(count);
while (cursor.moveToNext()) {
result.add(getMissionFromCursor(cursor));
}
return result;
}
public void addFinishedMission(DownloadMission downloadMission) {
if (downloadMission == null) throw new NullPointerException("downloadMission is null");
SQLiteDatabase database = getWritableDatabase();
ContentValues values = getValuesOfMission(downloadMission);
database.insert(FINISHED_TABLE_NAME, null, values);
}
public void deleteMission(Mission mission) {
if (mission == null) throw new NullPointerException("mission is null");
String ts = String.valueOf(mission.timestamp);
SQLiteDatabase database = getWritableDatabase();
if (mission instanceof FinishedMission) {
if (mission.storage.isInvalid()) {
database.delete(FINISHED_TABLE_NAME, KEY_TIMESTAMP + " = ?", new String[]{ts});
} else {
database.delete(FINISHED_TABLE_NAME, KEY_TIMESTAMP + " = ? AND " + KEY_PATH + " = ?", new String[]{
ts, mission.storage.getUri().toString()
});
}
} else {
throw new UnsupportedOperationException("DownloadMission");
}
}
public void updateMission(Mission mission) {
if (mission == null) throw new NullPointerException("mission is null");
SQLiteDatabase database = getWritableDatabase();
ContentValues values = getValuesOfMission(mission);
String ts = String.valueOf(mission.timestamp);
int rowsAffected;
if (mission instanceof FinishedMission) {
if (mission.storage.isInvalid()) {
rowsAffected = database.update(FINISHED_TABLE_NAME, values, KEY_TIMESTAMP + " = ?", new String[]{ts});
} else {
rowsAffected = database.update(FINISHED_TABLE_NAME, values, KEY_PATH + " = ?", new String[]{
mission.storage.getUri().toString()
});
}
} else {
throw new UnsupportedOperationException("DownloadMission");
}
if (rowsAffected != 1) {
Log.e("FinishedMissionStore", "Expected 1 row to be affected by update but got " + rowsAffected);
}
}
}

View File

@ -1,153 +1,148 @@
package us.shandian.giga.postprocessing.io;
import org.schabi.newpipe.streams.io.SharpStream;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
public class ChunkFileInputStream extends SharpStream {
private RandomAccessFile source;
private final long offset;
private final long length;
private long position;
public ChunkFileInputStream(File file, long start, long end, String mode) throws IOException {
source = new RandomAccessFile(file, mode);
offset = start;
length = end - start;
position = 0;
if (length < 1) {
source.close();
throw new IOException("The chunk is empty or invalid");
}
if (source.length() < end) {
try {
throw new IOException(String.format("invalid file length. expected = %s found = %s", end, source.length()));
} finally {
source.close();
}
}
source.seek(offset);
}
/**
* Get absolute position on file
*
* @return the position
*/
public long getFilePointer() {
return offset + position;
}
@Override
public int read() throws IOException {
if ((position + 1) > length) {
return 0;
}
int res = source.read();
if (res >= 0) {
position++;
}
return res;
}
@Override
public int read(byte b[]) throws IOException {
return read(b, 0, b.length);
}
@Override
public int read(byte b[], int off, int len) throws IOException {
if ((position + len) > length) {
len = (int) (length - position);
}
if (len == 0) {
return 0;
}
int res = source.read(b, off, len);
position += res;
return res;
}
@Override
public long skip(long pos) throws IOException {
pos = Math.min(pos + position, length);
if (pos == 0) {
return 0;
}
source.seek(offset + pos);
long oldPos = position;
position = pos;
return pos - oldPos;
}
@Override
public int available() {
return (int) (length - position);
}
@SuppressWarnings("EmptyCatchBlock")
@Override
public void dispose() {
try {
source.close();
} catch (IOException err) {
} finally {
source = null;
}
}
@Override
public boolean isDisposed() {
return source == null;
}
@Override
public void rewind() throws IOException {
position = 0;
source.seek(offset);
}
@Override
public boolean canRewind() {
return true;
}
@Override
public boolean canRead() {
return true;
}
@Override
public boolean canWrite() {
return false;
}
@Override
public void write(byte value) {
}
@Override
public void write(byte[] buffer) {
}
@Override
public void write(byte[] buffer, int offset, int count) {
}
@Override
public void flush() {
}
}
package us.shandian.giga.io;
import org.schabi.newpipe.streams.io.SharpStream;
import java.io.IOException;
public class ChunkFileInputStream extends SharpStream {
private SharpStream source;
private final long offset;
private final long length;
private long position;
public ChunkFileInputStream(SharpStream target, long start) throws IOException {
this(target, start, target.length());
}
public ChunkFileInputStream(SharpStream target, long start, long end) throws IOException {
source = target;
offset = start;
length = end - start;
position = 0;
if (length < 1) {
source.close();
throw new IOException("The chunk is empty or invalid");
}
if (source.length() < end) {
try {
throw new IOException(String.format("invalid file length. expected = %s found = %s", end, source.length()));
} finally {
source.close();
}
}
source.seek(offset);
}
/**
* Get absolute position on file
*
* @return the position
*/
public long getFilePointer() {
return offset + position;
}
@Override
public int read() throws IOException {
if ((position + 1) > length) {
return 0;
}
int res = source.read();
if (res >= 0) {
position++;
}
return res;
}
@Override
public int read(byte b[]) throws IOException {
return read(b, 0, b.length);
}
@Override
public int read(byte b[], int off, int len) throws IOException {
if ((position + len) > length) {
len = (int) (length - position);
}
if (len == 0) {
return 0;
}
int res = source.read(b, off, len);
position += res;
return res;
}
@Override
public long skip(long pos) throws IOException {
pos = Math.min(pos + position, length);
if (pos == 0) {
return 0;
}
source.seek(offset + pos);
long oldPos = position;
position = pos;
return pos - oldPos;
}
@Override
public long available() {
return (int) (length - position);
}
@SuppressWarnings("EmptyCatchBlock")
@Override
public void close() {
source.close();
source = null;
}
@Override
public boolean isClosed() {
return source == null;
}
@Override
public void rewind() throws IOException {
position = 0;
source.seek(offset);
}
@Override
public boolean canRewind() {
return true;
}
@Override
public boolean canRead() {
return true;
}
@Override
public boolean canWrite() {
return false;
}
@Override
public void write(byte value) {
}
@Override
public void write(byte[] buffer) {
}
@Override
public void write(byte[] buffer, int offset, int count) {
}
}

View File

@ -0,0 +1,497 @@
package us.shandian.giga.io;
import android.support.annotation.NonNull;
import org.schabi.newpipe.streams.io.SharpStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
public class CircularFileWriter extends SharpStream {
private final static int QUEUE_BUFFER_SIZE = 8 * 1024;// 8 KiB
private final static int COPY_BUFFER_SIZE = 128 * 1024; // 128 KiB
private final static int NOTIFY_BYTES_INTERVAL = 64 * 1024;// 64 KiB
private final static int THRESHOLD_AUX_LENGTH = 15 * 1024 * 1024;// 15 MiB
private OffsetChecker callback;
public ProgressReport onProgress;
public WriteErrorHandle onWriteError;
private long reportPosition;
private long maxLengthKnown = -1;
private BufferedFile out;
private BufferedFile aux;
public CircularFileWriter(SharpStream target, File temp, OffsetChecker checker) throws IOException {
if (checker == null) {
throw new NullPointerException("checker is null");
}
if (!temp.exists()) {
if (!temp.createNewFile()) {
throw new IOException("Cannot create a temporal file");
}
}
aux = new BufferedFile(temp);
out = new BufferedFile(target);
callback = checker;
reportPosition = NOTIFY_BYTES_INTERVAL;
}
private void flushAuxiliar(long amount) throws IOException {
if (aux.length < 1) {
return;
}
out.flush();
aux.flush();
boolean underflow = aux.offset < aux.length || out.offset < out.length;
byte[] buffer = new byte[COPY_BUFFER_SIZE];
aux.target.seek(0);
out.target.seek(out.length);
long length = amount;
while (length > 0) {
int read = (int) Math.min(length, Integer.MAX_VALUE);
read = aux.target.read(buffer, 0, Math.min(read, buffer.length));
if (read < 1) {
amount -= length;
break;
}
out.writeProof(buffer, read);
length -= read;
}
if (underflow) {
if (out.offset >= out.length) {
// calculate the aux underflow pointer
if (aux.offset < amount) {
out.offset += aux.offset;
aux.offset = 0;
out.target.seek(out.offset);
} else {
aux.offset -= amount;
out.offset = out.length + amount;
}
} else {
aux.offset = 0;
}
} else {
out.offset += amount;
aux.offset -= amount;
}
out.length += amount;
if (out.length > maxLengthKnown) {
maxLengthKnown = out.length;
}
if (amount < aux.length) {
// move the excess data to the beginning of the file
long readOffset = amount;
long writeOffset = 0;
aux.length -= amount;
length = aux.length;
while (length > 0) {
int read = (int) Math.min(length, Integer.MAX_VALUE);
read = aux.target.read(buffer, 0, Math.min(read, buffer.length));
aux.target.seek(writeOffset);
aux.writeProof(buffer, read);
writeOffset += read;
readOffset += read;
length -= read;
aux.target.seek(readOffset);
}
aux.target.setLength(aux.length);
return;
}
if (aux.length > THRESHOLD_AUX_LENGTH) {
aux.target.setLength(THRESHOLD_AUX_LENGTH);// or setLength(0);
}
aux.reset();
}
/**
* Flush any buffer and close the output file. Use this method if the
* operation is successful
*
* @return the final length of the file
* @throws IOException if an I/O error occurs
*/
public long finalizeFile() throws IOException {
flushAuxiliar(aux.length);
out.flush();
// change file length (if required)
long length = Math.max(maxLengthKnown, out.length);
if (length != out.target.length()) {
out.target.setLength(length);
}
close();
return length;
}
/**
* Close the file without flushing any buffer
*/
@Override
public void close() {
if (out != null) {
out.close();
out = null;
}
if (aux != null) {
aux.close();
aux = null;
}
}
@Override
public void write(byte b) throws IOException {
write(new byte[]{b}, 0, 1);
}
@Override
public void write(byte b[]) throws IOException {
write(b, 0, b.length);
}
@Override
public void write(byte b[], int off, int len) throws IOException {
if (len == 0) {
return;
}
long available;
long offsetOut = out.getOffset();
long offsetAux = aux.getOffset();
long end = callback.check();
if (end == -1) {
available = Integer.MAX_VALUE;
} else if (end < offsetOut) {
throw new IOException("The reported offset is invalid: " + end + "<" + offsetOut);
} else {
available = end - offsetOut;
}
boolean usingAux = aux.length > 0 && offsetOut >= out.length;
boolean underflow = offsetAux < aux.length || offsetOut < out.length;
if (usingAux) {
// before continue calculate the final length of aux
long length = offsetAux + len;
if (underflow) {
if (aux.length > length) {
length = aux.length;// the length is not changed
}
} else {
length = aux.length + len;
}
aux.write(b, off, len);
if (length >= THRESHOLD_AUX_LENGTH && length <= available) {
flushAuxiliar(available);
}
} else {
if (underflow) {
available = out.length - offsetOut;
}
int length = Math.min(len, (int) available);
out.write(b, off, length);
len -= length;
off += length;
if (len > 0) {
aux.write(b, off, len);
}
}
if (onProgress != null) {
long absoluteOffset = out.getOffset() + aux.getOffset();
if (absoluteOffset > reportPosition) {
reportPosition = absoluteOffset + NOTIFY_BYTES_INTERVAL;
onProgress.report(absoluteOffset);
}
}
}
@Override
public void flush() throws IOException {
aux.flush();
out.flush();
long total = out.length + aux.length;
if (total > maxLengthKnown) {
maxLengthKnown = total;// save the current file length in case the method {@code rewind()} is called
}
}
@Override
public long skip(long amount) throws IOException {
seek(out.getOffset() + aux.getOffset() + amount);
return amount;
}
@Override
public void rewind() throws IOException {
if (onProgress != null) {
onProgress.report(-out.length - aux.length);// rollback the whole progress
}
seek(0);
reportPosition = NOTIFY_BYTES_INTERVAL;
}
@Override
public void seek(long offset) throws IOException {
long total = out.length + aux.length;
if (offset == total) {
// do not ignore the seek offset if a underflow exists
long relativeOffset = out.getOffset() + aux.getOffset();
if (relativeOffset == total) {
return;
}
}
// flush everything, avoid any underflow
flush();
if (offset < 0 || offset > total) {
throw new IOException("desired offset is outside of range=0-" + total + " offset=" + offset);
}
if (offset > out.length) {
out.seek(out.length);
aux.seek(offset - out.length);
} else {
out.seek(offset);
aux.seek(0);
}
}
@Override
public boolean isClosed() {
return out == null;
}
@Override
public boolean canRewind() {
return true;
}
@Override
public boolean canWrite() {
return true;
}
@Override
public boolean canSeek() {
return true;
}
// <editor-fold defaultstate="collapsed" desc="stub read methods">
@Override
public boolean canRead() {
return false;
}
@Override
public int read() {
throw new UnsupportedOperationException("write-only");
}
@Override
public int read(byte[] buffer
) {
throw new UnsupportedOperationException("write-only");
}
@Override
public int read(byte[] buffer, int offset, int count
) {
throw new UnsupportedOperationException("write-only");
}
@Override
public long available() {
throw new UnsupportedOperationException("write-only");
}
//</editor-fold>
public interface OffsetChecker {
/**
* Checks the amount of available space ahead
*
* @return absolute offset in the file where no more data SHOULD NOT be
* written. If the value is -1 the whole file will be used
*/
long check();
}
public interface ProgressReport {
/**
* Report the size of the new file
*
* @param progress the new size
*/
void report(long progress);
}
public interface WriteErrorHandle {
/**
* Attempts to handle a I/O exception
*
* @param err the cause
* @return {@code true} to retry and continue, otherwise, {@code false}
* and throw the exception
*/
boolean handle(Exception err);
}
class BufferedFile {
protected final SharpStream target;
private long offset;
protected long length;
private byte[] queue = new byte[QUEUE_BUFFER_SIZE];
private int queueSize;
BufferedFile(File file) throws FileNotFoundException {
this.target = new FileStream(file);
}
BufferedFile(SharpStream target) {
this.target = target;
}
protected long getOffset() {
return offset + queueSize;// absolute offset in the file
}
protected void close() {
queue = null;
target.close();
}
protected void write(byte b[], int off, int len) throws IOException {
while (len > 0) {
// if the queue is full, the method available() will flush the queue
int read = Math.min(available(), len);
// enqueue incoming buffer
System.arraycopy(b, off, queue, queueSize, read);
queueSize += read;
len -= read;
off += read;
}
long total = offset + queueSize;
if (total > length) {
length = total;// save length
}
}
void flush() throws IOException {
writeProof(queue, queueSize);
offset += queueSize;
queueSize = 0;
}
protected void rewind() throws IOException {
offset = 0;
target.seek(0);
}
protected int available() throws IOException {
if (queueSize >= queue.length) {
flush();
return queue.length;
}
return queue.length - queueSize;
}
void reset() throws IOException {
offset = 0;
length = 0;
target.seek(0);
}
protected void seek(long absoluteOffset) throws IOException {
if (absoluteOffset == offset) {
return;// nothing to do
}
offset = absoluteOffset;
target.seek(absoluteOffset);
}
void writeProof(byte[] buffer, int length) throws IOException {
if (onWriteError == null) {
target.write(buffer, 0, length);
return;
}
while (true) {
try {
target.write(buffer, 0, length);
return;
} catch (Exception e) {
if (!onWriteError.handle(e)) {
throw e;// give up
}
}
}
}
@NonNull
@Override
public String toString() {
String absLength;
try {
absLength = Long.toString(target.length());
} catch (IOException e) {
absLength = "[" + e.getLocalizedMessage() + "]";
}
return String.format(
"offset=%s length=%s queue=%s absLength=%s",
offset, length, queueSize, absLength
);
}
}
}

View File

@ -1,126 +1,131 @@
package us.shandian.giga.postprocessing.io;
import org.schabi.newpipe.streams.io.SharpStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
/**
* @author kapodamy
*/
public class FileStream extends SharpStream {
public enum Mode {
Read,
ReadWrite
}
public RandomAccessFile source;
private final Mode mode;
public FileStream(String path, Mode mode) throws IOException {
String flags;
if (mode == Mode.Read) {
flags = "r";
} else {
flags = "rw";
}
this.mode = mode;
source = new RandomAccessFile(path, flags);
}
@Override
public int read() throws IOException {
return source.read();
}
@Override
public int read(byte b[]) throws IOException {
return read(b, 0, b.length);
}
@Override
public int read(byte b[], int off, int len) throws IOException {
return source.read(b, off, len);
}
@Override
public long skip(long pos) throws IOException {
FileChannel fc = source.getChannel();
fc.position(fc.position() + pos);
return pos;
}
@Override
public int available() {
try {
return (int) (source.length() - source.getFilePointer());
} catch (IOException ex) {
return 0;
}
}
@SuppressWarnings("EmptyCatchBlock")
@Override
public void dispose() {
try {
source.close();
} catch (IOException err) {
} finally {
source = null;
}
}
@Override
public boolean isDisposed() {
return source == null;
}
@Override
public void rewind() throws IOException {
source.getChannel().position(0);
}
@Override
public boolean canRewind() {
return true;
}
@Override
public boolean canRead() {
return mode == Mode.Read || mode == Mode.ReadWrite;
}
@Override
public boolean canWrite() {
return mode == Mode.ReadWrite;
}
@Override
public void write(byte value) throws IOException {
source.write(value);
}
@Override
public void write(byte[] buffer) throws IOException {
source.write(buffer);
}
@Override
public void write(byte[] buffer, int offset, int count) throws IOException {
source.write(buffer, offset, count);
}
@Override
public void flush() {
}
@Override
public void setLength(long length) throws IOException {
source.setLength(length);
}
}
package us.shandian.giga.io;
import android.support.annotation.NonNull;
import org.schabi.newpipe.streams.io.SharpStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* @author kapodamy
*/
public class FileStream extends SharpStream {
public RandomAccessFile source;
public FileStream(@NonNull File target) throws FileNotFoundException {
this.source = new RandomAccessFile(target, "rw");
}
public FileStream(@NonNull String path) throws FileNotFoundException {
this.source = new RandomAccessFile(path, "rw");
}
@Override
public int read() throws IOException {
return source.read();
}
@Override
public int read(byte b[]) throws IOException {
return source.read(b);
}
@Override
public int read(byte b[], int off, int len) throws IOException {
return source.read(b, off, len);
}
@Override
public long skip(long pos) throws IOException {
return source.skipBytes((int) pos);
}
@Override
public long available() {
try {
return source.length() - source.getFilePointer();
} catch (IOException e) {
return 0;
}
}
@Override
public void close() {
if (source == null) return;
try {
source.close();
} catch (IOException err) {
// nothing to do
}
source = null;
}
@Override
public boolean isClosed() {
return source == null;
}
@Override
public void rewind() throws IOException {
source.seek(0);
}
@Override
public boolean canRewind() {
return true;
}
@Override
public boolean canRead() {
return true;
}
@Override
public boolean canWrite() {
return true;
}
@Override
public boolean canSeek() {
return true;
}
@Override
public boolean canSetLength() {
return true;
}
@Override
public void write(byte value) throws IOException {
source.write(value);
}
@Override
public void write(byte[] buffer) throws IOException {
source.write(buffer);
}
@Override
public void write(byte[] buffer, int offset, int count) throws IOException {
source.write(buffer, offset, count);
}
@Override
public void setLength(long length) throws IOException {
source.setLength(length);
}
@Override
public void seek(long offset) throws IOException {
source.seek(offset);
}
@Override
public long length() throws IOException {
return source.length();
}
}

View File

@ -0,0 +1,145 @@
package us.shandian.giga.io;
import android.content.ContentResolver;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.support.annotation.NonNull;
import android.util.Log;
import org.schabi.newpipe.streams.io.SharpStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
public class FileStreamSAF extends SharpStream {
private final FileInputStream in;
private final FileOutputStream out;
private final FileChannel channel;
private final ParcelFileDescriptor file;
private boolean disposed;
public FileStreamSAF(@NonNull ContentResolver contentResolver, Uri fileUri) throws IOException {
// Notes:
// the file must exists first
// ¡read-write mode must allow seek!
// It is not guaranteed to work with files in the cloud (virtual files), tested in local storage devices
file = contentResolver.openFileDescriptor(fileUri, "rw");
if (file == null) {
throw new IOException("Cannot get the ParcelFileDescriptor for " + fileUri.toString());
}
in = new FileInputStream(file.getFileDescriptor());
out = new FileOutputStream(file.getFileDescriptor());
channel = out.getChannel();// or use in.getChannel()
}
@Override
public int read() throws IOException {
return in.read();
}
@Override
public int read(byte[] buffer) throws IOException {
return in.read(buffer);
}
@Override
public int read(byte[] buffer, int offset, int count) throws IOException {
return in.read(buffer, offset, count);
}
@Override
public long skip(long amount) throws IOException {
return in.skip(amount);// ¿or use channel.position(channel.position() + amount)?
}
@Override
public long available() {
try {
return in.available();
} catch (IOException e) {
return 0;// ¡but not -1!
}
}
@Override
public void rewind() throws IOException {
seek(0);
}
@Override
public void close() {
try {
disposed = true;
file.close();
in.close();
out.close();
channel.close();
} catch (IOException e) {
Log.e("FileStreamSAF", "close() error", e);
}
}
@Override
public boolean isClosed() {
return disposed;
}
@Override
public boolean canRewind() {
return true;
}
@Override
public boolean canRead() {
return true;
}
@Override
public boolean canWrite() {
return true;
}
public boolean canSetLength() {
return true;
}
public boolean canSeek() {
return true;
}
@Override
public void write(byte value) throws IOException {
out.write(value);
}
@Override
public void write(byte[] buffer) throws IOException {
out.write(buffer);
}
@Override
public void write(byte[] buffer, int offset, int count) throws IOException {
out.write(buffer, offset, count);
}
public void setLength(long length) throws IOException {
channel.truncate(length);
}
public void seek(long offset) throws IOException {
channel.position(offset);
}
@Override
public long length() throws IOException {
return channel.size();
}
}

View File

@ -1,59 +1,61 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package us.shandian.giga.postprocessing.io;
import android.support.annotation.NonNull;
import org.schabi.newpipe.streams.io.SharpStream;
import java.io.IOException;
import java.io.InputStream;
/**
* Wrapper for the classic {@link java.io.InputStream}
* @author kapodamy
*/
public class SharpInputStream extends InputStream {
private final SharpStream base;
public SharpInputStream(SharpStream base) throws IOException {
if (!base.canRead()) {
throw new IOException("The provided stream is not readable");
}
this.base = base;
}
@Override
public int read() throws IOException {
return base.read();
}
@Override
public int read(@NonNull byte[] bytes) throws IOException {
return base.read(bytes);
}
@Override
public int read(@NonNull byte[] bytes, int i, int i1) throws IOException {
return base.read(bytes, i, i1);
}
@Override
public long skip(long l) throws IOException {
return base.skip(l);
}
@Override
public int available() {
return base.available();
}
@Override
public void close() {
base.dispose();
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package us.shandian.giga.io;
import android.support.annotation.NonNull;
import org.schabi.newpipe.streams.io.SharpStream;
import java.io.IOException;
import java.io.InputStream;
/**
* Wrapper for the classic {@link java.io.InputStream}
*
* @author kapodamy
*/
public class SharpInputStream extends InputStream {
private final SharpStream base;
public SharpInputStream(SharpStream base) throws IOException {
if (!base.canRead()) {
throw new IOException("The provided stream is not readable");
}
this.base = base;
}
@Override
public int read() throws IOException {
return base.read();
}
@Override
public int read(@NonNull byte[] bytes) throws IOException {
return base.read(bytes);
}
@Override
public int read(@NonNull byte[] bytes, int i, int i1) throws IOException {
return base.read(bytes, i, i1);
}
@Override
public long skip(long l) throws IOException {
return base.skip(l);
}
@Override
public int available() {
long res = base.available();
return res > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) res;
}
@Override
public void close() {
base.close();
}
}

View File

@ -0,0 +1,289 @@
package us.shandian.giga.io;
import android.annotation.TargetApi;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.provider.DocumentsContract;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.provider.DocumentFile;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import static android.provider.DocumentsContract.Document.COLUMN_DISPLAY_NAME;
import static android.provider.DocumentsContract.Root.COLUMN_DOCUMENT_ID;
public class StoredDirectoryHelper {
public final static int PERMISSION_FLAGS = Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
private File ioTree;
private DocumentFile docTree;
private Context context;
private String tag;
public StoredDirectoryHelper(@NonNull Context context, @NonNull Uri path, String tag) throws IOException {
this.tag = tag;
if (ContentResolver.SCHEME_FILE.equalsIgnoreCase(path.getScheme())) {
this.ioTree = new File(URI.create(path.toString()));
return;
}
this.context = context;
try {
this.context.getContentResolver().takePersistableUriPermission(path, PERMISSION_FLAGS);
} catch (Exception e) {
throw new IOException(e);
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
throw new IOException("Storage Access Framework with Directory API is not available");
this.docTree = DocumentFile.fromTreeUri(context, path);
if (this.docTree == null)
throw new IOException("Failed to create the tree from Uri");
}
@TargetApi(Build.VERSION_CODES.KITKAT)
public StoredDirectoryHelper(@NonNull URI location, String tag) {
ioTree = new File(location);
this.tag = tag;
}
public StoredFileHelper createFile(String filename, String mime) {
return createFile(filename, mime, false);
}
public StoredFileHelper createUniqueFile(String name, String mime) {
ArrayList<String> matches = new ArrayList<>();
String[] filename = splitFilename(name);
String lcFilename = filename[0].toLowerCase();
if (docTree == null || Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
for (File file : ioTree.listFiles())
addIfStartWith(matches, lcFilename, file.getName());
} else {
// warning: SAF file listing is very slow
Uri docTreeChildren = DocumentsContract.buildChildDocumentsUriUsingTree(
docTree.getUri(), DocumentsContract.getDocumentId(docTree.getUri())
);
String[] projection = new String[]{COLUMN_DISPLAY_NAME};
String selection = "(LOWER(" + COLUMN_DISPLAY_NAME + ") LIKE ?%";
ContentResolver cr = context.getContentResolver();
try (Cursor cursor = cr.query(docTreeChildren, projection, selection, new String[]{lcFilename}, null)) {
if (cursor != null) {
while (cursor.moveToNext())
addIfStartWith(matches, lcFilename, cursor.getString(0));
}
}
}
if (matches.size() < 1) {
return createFile(name, mime, true);
} else {
// check if the filename is in use
String lcName = name.toLowerCase();
for (String testName : matches) {
if (testName.equals(lcName)) {
lcName = null;
break;
}
}
// check if not in use
if (lcName != null) return createFile(name, mime, true);
}
Collections.sort(matches, String::compareTo);
for (int i = 1; i < 1000; i++) {
if (Collections.binarySearch(matches, makeFileName(lcFilename, i, filename[1])) < 0)
return createFile(makeFileName(filename[0], i, filename[1]), mime, true);
}
return createFile(String.valueOf(System.currentTimeMillis()).concat(filename[1]), mime, false);
}
private StoredFileHelper createFile(String filename, String mime, boolean safe) {
StoredFileHelper storage;
try {
if (docTree == null)
storage = new StoredFileHelper(ioTree, filename, mime);
else
storage = new StoredFileHelper(context, docTree, filename, mime, safe);
} catch (IOException e) {
return null;
}
storage.tag = tag;
return storage;
}
public Uri getUri() {
return docTree == null ? Uri.fromFile(ioTree) : docTree.getUri();
}
public boolean exists() {
return docTree == null ? ioTree.exists() : docTree.exists();
}
/**
* Indicates whatever if is possible access using the {@code java.io} API
*
* @return {@code true} for Java I/O API, otherwise, {@code false} for Storage Access Framework
*/
public boolean isDirect() {
return docTree == null;
}
/**
* Only using Java I/O. Creates the directory named by this abstract pathname, including any
* necessary but nonexistent parent directories. Note that if this
* operation fails it may have succeeded in creating some of the necessary
* parent directories.
*
* @return <code>true</code> if and only if the directory was created,
* along with all necessary parent directories or already exists; <code>false</code>
* otherwise
*/
public boolean mkdirs() {
if (docTree == null) {
return ioTree.exists() || ioTree.mkdirs();
}
if (docTree.exists()) return true;
try {
DocumentFile parent;
String child = docTree.getName();
while (true) {
parent = docTree.getParentFile();
if (parent == null || child == null) break;
if (parent.exists()) return true;
parent.createDirectory(child);
child = parent.getName();// for the next iteration
}
} catch (Exception e) {
// no more parent directories or unsupported by the storage provider
}
return false;
}
public String getTag() {
return tag;
}
public Uri findFile(String filename) {
if (docTree == null) {
File res = new File(ioTree, filename);
return res.exists() ? Uri.fromFile(res) : null;
}
DocumentFile res = findFileSAFHelper(context, docTree, filename);
return res == null ? null : res.getUri();
}
public boolean canWrite() {
return docTree == null ? ioTree.canWrite() : docTree.canWrite();
}
@NonNull
@Override
public String toString() {
return docTree == null ? Uri.fromFile(ioTree).toString() : docTree.getUri().toString();
}
////////////////////
// Utils
///////////////////
private static void addIfStartWith(ArrayList<String> list, @NonNull String base, String str) {
if (str == null || str.isEmpty()) return;
str = str.toLowerCase();
if (str.startsWith(base)) list.add(str);
}
private static String[] splitFilename(@NonNull String filename) {
int dotIndex = filename.lastIndexOf('.');
if (dotIndex < 0 || (dotIndex == filename.length() - 1))
return new String[]{filename, ""};
return new String[]{filename.substring(0, dotIndex), filename.substring(dotIndex)};
}
private static String makeFileName(String name, int idx, String ext) {
return name.concat(" (").concat(String.valueOf(idx)).concat(")").concat(ext);
}
/**
* Fast (but not enough) file/directory finder under the storage access framework
*
* @param context The context
* @param tree Directory where search
* @param filename Target filename
* @return A {@link android.support.v4.provider.DocumentFile} contain the reference, otherwise, null
*/
static DocumentFile findFileSAFHelper(@Nullable Context context, DocumentFile tree, String filename) {
if (context == null || Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
return tree.findFile(filename);// warning: this is very slow
}
if (!tree.canRead()) return null;// missing read permission
final int name = 0;
final int documentId = 1;
// LOWER() SQL function is not supported
String selection = COLUMN_DISPLAY_NAME + " = ?";
//String selection = COLUMN_DISPLAY_NAME + " LIKE ?%";
Uri childrenUri = DocumentsContract.buildChildDocumentsUriUsingTree(
tree.getUri(), DocumentsContract.getDocumentId(tree.getUri())
);
String[] projection = {COLUMN_DISPLAY_NAME, COLUMN_DOCUMENT_ID};
ContentResolver contentResolver = context.getContentResolver();
filename = filename.toLowerCase();
try (Cursor cursor = contentResolver.query(childrenUri, projection, selection, new String[]{filename}, null)) {
if (cursor == null) return null;
while (cursor.moveToNext()) {
if (cursor.isNull(name) || !cursor.getString(name).toLowerCase().startsWith(filename))
continue;
return DocumentFile.fromSingleUri(
context, DocumentsContract.buildDocumentUriUsingTree(
tree.getUri(), cursor.getString(documentId)
)
);
}
}
return null;
}
}

View File

@ -0,0 +1,381 @@
package us.shandian.giga.io;
import android.annotation.TargetApi;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.provider.DocumentsContract;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.provider.DocumentFile;
import org.schabi.newpipe.streams.io.SharpStream;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.net.URI;
public class StoredFileHelper implements Serializable {
private static final long serialVersionUID = 0L;
public static final String DEFAULT_MIME = "application/octet-stream";
private transient DocumentFile docFile;
private transient DocumentFile docTree;
private transient File ioFile;
private transient Context context;
protected String source;
private String sourceTree;
protected String tag;
private String srcName;
private String srcType;
public StoredFileHelper(@Nullable Uri parent, String filename, String mime, String tag) {
this.source = null;// this instance will be "invalid" see invalidate()/isInvalid() methods
this.srcName = filename;
this.srcType = mime == null ? DEFAULT_MIME : mime;
if (parent != null) this.sourceTree = parent.toString();
this.tag = tag;
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
StoredFileHelper(@Nullable Context context, DocumentFile tree, String filename, String mime, boolean safe) throws IOException {
this.docTree = tree;
this.context = context;
DocumentFile res;
if (safe) {
// no conflicts (the filename is not in use)
res = this.docTree.createFile(mime, filename);
if (res == null) throw new IOException("Cannot create the file");
} else {
res = createSAF(context, mime, filename);
}
this.docFile = res;
this.source = docFile.getUri().toString();
this.sourceTree = docTree.getUri().toString();
this.srcName = this.docFile.getName();
this.srcType = this.docFile.getType();
}
StoredFileHelper(File location, String filename, String mime) throws IOException {
this.ioFile = new File(location, filename);
if (this.ioFile.exists()) {
if (!this.ioFile.isFile() && !this.ioFile.delete())
throw new IOException("The filename is already in use by non-file entity and cannot overwrite it");
} else {
if (!this.ioFile.createNewFile())
throw new IOException("Cannot create the file");
}
this.source = Uri.fromFile(this.ioFile).toString();
this.sourceTree = Uri.fromFile(location).toString();
this.srcName = ioFile.getName();
this.srcType = mime;
}
@TargetApi(Build.VERSION_CODES.KITKAT)
public StoredFileHelper(Context context, @Nullable Uri parent, @NonNull Uri path, String tag) throws IOException {
this.tag = tag;
this.source = path.toString();
if (path.getScheme() == null || path.getScheme().equalsIgnoreCase(ContentResolver.SCHEME_FILE)) {
this.ioFile = new File(URI.create(this.source));
} else {
DocumentFile file = DocumentFile.fromSingleUri(context, path);
if (file == null) throw new RuntimeException("SAF not available");
this.context = context;
if (file.getName() == null) {
this.source = null;
return;
} else {
this.docFile = file;
takePermissionSAF();
}
}
if (parent != null) {
if (!ContentResolver.SCHEME_FILE.equals(parent.getScheme()))
this.docTree = DocumentFile.fromTreeUri(context, parent);
this.sourceTree = parent.toString();
}
this.srcName = getName();
this.srcType = getType();
}
public static StoredFileHelper deserialize(@NonNull StoredFileHelper storage, Context context) throws IOException {
Uri treeUri = storage.sourceTree == null ? null : Uri.parse(storage.sourceTree);
if (storage.isInvalid())
return new StoredFileHelper(treeUri, storage.srcName, storage.srcType, storage.tag);
StoredFileHelper instance = new StoredFileHelper(context, treeUri, Uri.parse(storage.source), storage.tag);
// under SAF, if the target document is deleted, conserve the filename and mime
if (instance.srcName == null) instance.srcName = storage.srcName;
if (instance.srcType == null) instance.srcType = storage.srcType;
return instance;
}
public static void requestSafWithFileCreation(@NonNull Fragment who, int requestCode, String filename, String mime) {
// SAF notes:
// ACTION_OPEN_DOCUMENT Do not let you create the file, useful for overwrite files
// ACTION_CREATE_DOCUMENT No overwrite support, useless the file provider resolve the conflict
Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT)
.addCategory(Intent.CATEGORY_OPENABLE)
.setType(mime)
.putExtra(Intent.EXTRA_TITLE, filename)
.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION | StoredDirectoryHelper.PERMISSION_FLAGS)
.putExtra("android.content.extra.SHOW_ADVANCED", true);// hack, show all storage disks
who.startActivityForResult(intent, requestCode);
}
public SharpStream getStream() throws IOException {
invalid();
if (docFile == null)
return new FileStream(ioFile);
else
return new FileStreamSAF(context.getContentResolver(), docFile.getUri());
}
/**
* Indicates whatever if is possible access using the {@code java.io} API
*
* @return {@code true} for Java I/O API, otherwise, {@code false} for Storage Access Framework
*/
public boolean isDirect() {
invalid();
return docFile == null;
}
public boolean isInvalid() {
return source == null;
}
public Uri getUri() {
invalid();
return docFile == null ? Uri.fromFile(ioFile) : docFile.getUri();
}
public Uri getParentUri() {
invalid();
return sourceTree == null ? null : Uri.parse(sourceTree);
}
public void truncate() throws IOException {
invalid();
try (SharpStream fs = getStream()) {
fs.setLength(0);
}
}
public boolean delete() {
if (source == null) return true;
if (docFile == null) return ioFile.delete();
boolean res = docFile.delete();
try {
int flags = Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
context.getContentResolver().releasePersistableUriPermission(docFile.getUri(), flags);
} catch (Exception ex) {
// nothing to do
}
return res;
}
public long length() {
invalid();
return docFile == null ? ioFile.length() : docFile.length();
}
public boolean canWrite() {
if (source == null) return false;
return docFile == null ? ioFile.canWrite() : docFile.canWrite();
}
public String getName() {
if (source == null)
return srcName;
else if (docFile == null)
return ioFile.getName();
String name = docFile.getName();
return name == null ? srcName : name;
}
public String getType() {
if (source == null || docFile == null)
return srcType;
String type = docFile.getType();
return type == null ? srcType : type;
}
public String getTag() {
return tag;
}
public boolean existsAsFile() {
if (source == null) return false;
boolean exists = docFile == null ? ioFile.exists() : docFile.exists();
boolean isFile = docFile == null ? ioFile.isFile() : docFile.isFile();// ¿docFile.isVirtual() means is no-physical?
return exists && isFile;
}
public boolean create() {
invalid();
boolean result;
if (docFile == null) {
try {
result = ioFile.createNewFile();
} catch (IOException e) {
return false;
}
} else if (docTree == null) {
result = false;
} else {
if (!docTree.canRead() || !docTree.canWrite()) return false;
try {
docFile = createSAF(context, srcType, srcName);
if (docFile == null || docFile.getName() == null) return false;
result = true;
} catch (IOException e) {
return false;
}
}
if (result) {
source = (docFile == null ? Uri.fromFile(ioFile) : docFile.getUri()).toString();
srcName = getName();
srcType = getType();
}
return result;
}
public void invalidate() {
if (source == null) return;
srcName = getName();
srcType = getType();
source = null;
docTree = null;
docFile = null;
ioFile = null;
context = null;
}
public boolean equals(StoredFileHelper storage) {
if (this == storage) return true;
// note: do not compare tags, files can have the same parent folder
//if (stringMismatch(this.tag, storage.tag)) return false;
if (stringMismatch(getLowerCase(this.sourceTree), getLowerCase(this.sourceTree)))
return false;
if (this.isInvalid() || storage.isInvalid()) {
return this.srcName.equalsIgnoreCase(storage.srcName) && this.srcType.equalsIgnoreCase(storage.srcType);
}
if (this.isDirect() != storage.isDirect()) return false;
if (this.isDirect())
return this.ioFile.getPath().equalsIgnoreCase(storage.ioFile.getPath());
return DocumentsContract.getDocumentId(
this.docFile.getUri()
).equalsIgnoreCase(DocumentsContract.getDocumentId(
storage.docFile.getUri()
));
}
@NonNull
@Override
public String toString() {
if (source == null)
return "[Invalid state] name=" + srcName + " type=" + srcType + " tag=" + tag;
else
return "sourceFile=" + source + " treeSource=" + (sourceTree == null ? "" : sourceTree) + " tag=" + tag;
}
private void invalid() {
if (source == null)
throw new IllegalStateException("In invalid state");
}
private void takePermissionSAF() throws IOException {
try {
context.getContentResolver().takePersistableUriPermission(docFile.getUri(), StoredDirectoryHelper.PERMISSION_FLAGS);
} catch (Exception e) {
if (docFile.getName() == null) throw new IOException(e);
}
}
private DocumentFile createSAF(@Nullable Context context, String mime, String filename) throws IOException {
DocumentFile res = StoredDirectoryHelper.findFileSAFHelper(context, docTree, filename);
if (res != null && res.exists() && res.isDirectory()) {
if (!res.delete())
throw new IOException("Directory with the same name found but cannot delete");
res = null;
}
if (res == null) {
res = this.docTree.createFile(srcType == null ? DEFAULT_MIME : mime, filename);
if (res == null) throw new IOException("Cannot create the file");
}
return res;
}
private String getLowerCase(String str) {
return str == null ? null : str.toLowerCase();
}
private boolean stringMismatch(String str1, String str2) {
if (str1 == null && str2 == null) return false;
if ((str1 == null) != (str2 == null)) return true;
return !str1.equals(str2);
}
}

View File

@ -0,0 +1,41 @@
package us.shandian.giga.postprocessing;
import org.schabi.newpipe.streams.Mp4DashReader;
import org.schabi.newpipe.streams.Mp4FromDashWriter;
import org.schabi.newpipe.streams.io.SharpStream;
import java.io.IOException;
class M4aNoDash extends Postprocessing {
M4aNoDash() {
super(false, true, ALGORITHM_M4A_NO_DASH);
}
@Override
boolean test(SharpStream... sources) throws IOException {
// check if the mp4 file is DASH (youtube)
Mp4DashReader reader = new Mp4DashReader(sources[0]);
reader.parse();
switch (reader.getBrands()[0]) {
case 0x64617368:// DASH
case 0x69736F35:// ISO5
return true;
default:
return false;
}
}
@Override
int process(SharpStream out, SharpStream... sources) throws IOException {
Mp4FromDashWriter muxer = new Mp4FromDashWriter(sources[0]);
muxer.setMainBrand(0x4D344120);// binary string "M4A "
muxer.parseSources();
muxer.selectTracks(0);
muxer.build(out);
return OK_RESULT;
}
}

View File

@ -1,29 +1,27 @@
package us.shandian.giga.postprocessing;
import org.schabi.newpipe.streams.Mp4DashWriter;
import org.schabi.newpipe.streams.io.SharpStream;
import java.io.IOException;
import us.shandian.giga.get.DownloadMission;
/**
* @author kapodamy
*/
class Mp4DashMuxer extends Postprocessing {
Mp4DashMuxer(DownloadMission mission) {
super(mission, 15360 * 1024/* 15 MiB */, true);
}
@Override
int process(SharpStream out, SharpStream... sources) throws IOException {
Mp4DashWriter muxer = new Mp4DashWriter(sources);
muxer.parseSources();
muxer.selectTracks(0, 0);
muxer.build(out);
return OK_RESULT;
}
}
package us.shandian.giga.postprocessing;
import org.schabi.newpipe.streams.Mp4FromDashWriter;
import org.schabi.newpipe.streams.io.SharpStream;
import java.io.IOException;
/**
* @author kapodamy
*/
class Mp4FromDashMuxer extends Postprocessing {
Mp4FromDashMuxer() {
super(true, true, ALGORITHM_MP4_FROM_DASH_MUXER);
}
@Override
int process(SharpStream out, SharpStream... sources) throws IOException {
Mp4FromDashWriter muxer = new Mp4FromDashWriter(sources);
muxer.parseSources();
muxer.selectTracks(0, 0);
muxer.build(out);
return OK_RESULT;
}
}

View File

@ -1,136 +0,0 @@
package us.shandian.giga.postprocessing;
import android.media.MediaCodec.BufferInfo;
import android.media.MediaExtractor;
import android.media.MediaMuxer;
import android.media.MediaMuxer.OutputFormat;
import android.util.Log;
import static org.schabi.newpipe.BuildConfig.DEBUG;
import org.schabi.newpipe.streams.io.SharpStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import us.shandian.giga.get.DownloadMission;
class Mp4Muxer extends Postprocessing {
private static final String TAG = "Mp4Muxer";
private static final int NOTIFY_BYTES_INTERVAL = 128 * 1024;// 128 KiB
Mp4Muxer(DownloadMission mission) {
super(mission, 0, false);
}
@Override
int process(SharpStream out, SharpStream... sources) throws IOException {
File dlFile = mission.getDownloadedFile();
File tmpFile = new File(mission.location, mission.name.concat(".tmp"));
if (tmpFile.exists())
if (!tmpFile.delete()) return DownloadMission.ERROR_FILE_CREATION;
if (!tmpFile.createNewFile()) return DownloadMission.ERROR_FILE_CREATION;
FileInputStream source = null;
MediaMuxer muxer = null;
//noinspection TryFinallyCanBeTryWithResources
try {
source = new FileInputStream(dlFile);
MediaExtractor tracks[] = {
getMediaExtractor(source, mission.offsets[0], mission.offsets[1] - mission.offsets[0]),
getMediaExtractor(source, mission.offsets[1], mission.length - mission.offsets[1])
};
muxer = new MediaMuxer(tmpFile.getAbsolutePath(), OutputFormat.MUXER_OUTPUT_MPEG_4);
int tracksIndex[] = {
muxer.addTrack(tracks[0].getTrackFormat(0)),
muxer.addTrack(tracks[1].getTrackFormat(0))
};
ByteBuffer buffer = ByteBuffer.allocate(512 * 1024);// 512 KiB
BufferInfo info = new BufferInfo();
long written = 0;
long nextReport = NOTIFY_BYTES_INTERVAL;
muxer.start();
while (true) {
int done = 0;
for (int i = 0; i < tracks.length; i++) {
if (tracksIndex[i] < 0) continue;
info.set(0,
tracks[i].readSampleData(buffer, 0),
tracks[i].getSampleTime(),
tracks[i].getSampleFlags()
);
if (info.size >= 0) {
muxer.writeSampleData(tracksIndex[i], buffer, info);
written += info.size;
done++;
}
if (!tracks[i].advance()) {
// EOF reached
tracks[i].release();
tracksIndex[i] = -1;
}
if (written > nextReport) {
nextReport = written + NOTIFY_BYTES_INTERVAL;
super.progressReport(written);
}
}
if (done < 1) break;
}
// this part should not fail
if (!dlFile.delete()) return DownloadMission.ERROR_FILE_CREATION;
if (!tmpFile.renameTo(dlFile)) return DownloadMission.ERROR_FILE_CREATION;
return OK_RESULT;
} finally {
try {
if (muxer != null) {
muxer.stop();
muxer.release();
}
} catch (Exception err) {
if (DEBUG)
Log.e(TAG, "muxer stop/release failed", err);
}
if (source != null) {
try {
source.close();
} catch (IOException e) {
// nothing to do
}
}
// if the operation fails, delete the temporal file
if (tmpFile.exists()) {
//noinspection ResultOfMethodCallIgnored
tmpFile.delete();
}
}
}
private MediaExtractor getMediaExtractor(FileInputStream source, long offset, long length) throws IOException {
MediaExtractor extractor = new MediaExtractor();
extractor.setDataSource(source.getFD(), offset, length);
extractor.selectTrack(0);
return extractor;
}
}

View File

@ -1,164 +1,256 @@
package us.shandian.giga.postprocessing;
import android.os.Message;
import org.schabi.newpipe.streams.io.SharpStream;
import java.io.File;
import java.io.IOException;
import us.shandian.giga.get.DownloadMission;
import us.shandian.giga.postprocessing.io.ChunkFileInputStream;
import us.shandian.giga.postprocessing.io.CircularFile;
import us.shandian.giga.service.DownloadManagerService;
public abstract class Postprocessing {
static final byte OK_RESULT = DownloadMission.ERROR_NOTHING;
public static final String ALGORITHM_TTML_CONVERTER = "ttml";
public static final String ALGORITHM_MP4_DASH_MUXER = "mp4D";
public static final String ALGORITHM_MP4_MUXER = "mp4";
public static final String ALGORITHM_WEBM_MUXER = "webm";
public static Postprocessing getAlgorithm(String algorithmName, DownloadMission mission) {
if (null == algorithmName) {
throw new NullPointerException("algorithmName");
} else switch (algorithmName) {
case ALGORITHM_TTML_CONVERTER:
return new TtmlConverter(mission);
case ALGORITHM_MP4_DASH_MUXER:
return new Mp4DashMuxer(mission);
case ALGORITHM_MP4_MUXER:
return new Mp4Muxer(mission);
case ALGORITHM_WEBM_MUXER:
return new WebMMuxer(mission);
/*case "example-algorithm":
return new ExampleAlgorithm(mission);*/
default:
throw new RuntimeException("Unimplemented post-processing algorithm: " + algorithmName);
}
}
/**
* Get a boolean value that indicate if the given algorithm work on the same
* file
*/
public boolean worksOnSameFile;
/**
* Get the recommended space to reserve for the given algorithm. The amount
* is in bytes
*/
public int recommendedReserve;
/**
* the download to post-process
*/
protected DownloadMission mission;
Postprocessing(DownloadMission mission, int recommendedReserve, boolean worksOnSameFile) {
this.mission = mission;
this.recommendedReserve = recommendedReserve;
this.worksOnSameFile = worksOnSameFile;
}
public void run() throws IOException {
File file = mission.getDownloadedFile();
CircularFile out = null;
int result;
long finalLength = -1;
mission.done = 0;
mission.length = file.length();
if (worksOnSameFile) {
ChunkFileInputStream[] sources = new ChunkFileInputStream[mission.urls.length];
try {
int i = 0;
for (; i < sources.length - 1; i++) {
sources[i] = new ChunkFileInputStream(file, mission.offsets[i], mission.offsets[i + 1], "rw");
}
sources[i] = new ChunkFileInputStream(file, mission.offsets[i], mission.getDownloadedFile().length(), "rw");
int[] idx = {0};
CircularFile.OffsetChecker checker = () -> {
while (idx[0] < sources.length) {
/*
* WARNING: never use rewind() in any chunk after any writing (especially on first chunks)
* or the CircularFile can lead to unexpected results
*/
if (sources[idx[0]].isDisposed() || sources[idx[0]].available() < 1) {
idx[0]++;
continue;// the selected source is not used anymore
}
return sources[idx[0]].getFilePointer() - 1;
}
return -1;
};
out = new CircularFile(file, 0, this::progressReport, checker);
result = process(out, sources);
if (result == OK_RESULT)
finalLength = out.finalizeFile();
} finally {
for (SharpStream source : sources) {
if (source != null && !source.isDisposed()) {
source.dispose();
}
}
if (out != null) {
out.dispose();
}
}
} else {
result = process(null);
}
if (result == OK_RESULT) {
if (finalLength < 0) finalLength = file.length();
mission.done = finalLength;
mission.length = finalLength;
} else {
mission.errCode = DownloadMission.ERROR_UNKNOWN_EXCEPTION;
mission.errObject = new RuntimeException("post-processing algorithm returned " + result);
}
if (result != OK_RESULT && worksOnSameFile) {
//noinspection ResultOfMethodCallIgnored
file.delete();
}
}
/**
* Abstract method to execute the pos-processing algorithm
*
* @param out output stream
* @param sources files to be processed
* @return a error code, 0 means the operation was successful
* @throws IOException if an I/O error occurs.
*/
abstract int process(SharpStream out, SharpStream... sources) throws IOException;
String getArgumentAt(int index, String defaultValue) {
if (mission.postprocessingArgs == null || index >= mission.postprocessingArgs.length) {
return defaultValue;
}
return mission.postprocessingArgs[index];
}
void progressReport(long done) {
mission.done = done;
if (mission.length < mission.done) mission.length = mission.done;
Message m = new Message();
m.what = DownloadManagerService.MESSAGE_PROGRESS;
m.obj = mission;
mission.mHandler.sendMessage(m);
}
}
package us.shandian.giga.postprocessing;
import android.os.Message;
import android.support.annotation.NonNull;
import android.util.Log;
import org.schabi.newpipe.streams.io.SharpStream;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import us.shandian.giga.get.DownloadMission;
import us.shandian.giga.io.ChunkFileInputStream;
import us.shandian.giga.io.CircularFileWriter;
import us.shandian.giga.io.CircularFileWriter.OffsetChecker;
import us.shandian.giga.service.DownloadManagerService;
import static us.shandian.giga.get.DownloadMission.ERROR_NOTHING;
import static us.shandian.giga.get.DownloadMission.ERROR_POSTPROCESSING_HOLD;
import static us.shandian.giga.get.DownloadMission.ERROR_UNKNOWN_EXCEPTION;
public abstract class Postprocessing implements Serializable {
static transient final byte OK_RESULT = ERROR_NOTHING;
public transient static final String ALGORITHM_TTML_CONVERTER = "ttml";
public transient static final String ALGORITHM_WEBM_MUXER = "webm";
public transient static final String ALGORITHM_MP4_FROM_DASH_MUXER = "mp4D-mp4";
public transient static final String ALGORITHM_M4A_NO_DASH = "mp4D-m4a";
public static Postprocessing getAlgorithm(@NonNull String algorithmName, String[] args) {
Postprocessing instance;
switch (algorithmName) {
case ALGORITHM_TTML_CONVERTER:
instance = new TtmlConverter();
break;
case ALGORITHM_WEBM_MUXER:
instance = new WebMMuxer();
break;
case ALGORITHM_MP4_FROM_DASH_MUXER:
instance = new Mp4FromDashMuxer();
break;
case ALGORITHM_M4A_NO_DASH:
instance = new M4aNoDash();
break;
/*case "example-algorithm":
instance = new ExampleAlgorithm();*/
default:
throw new UnsupportedOperationException("Unimplemented post-processing algorithm: " + algorithmName);
}
instance.args = args;
return instance;
}
/**
* Get a boolean value that indicate if the given algorithm work on the same
* file
*/
public final boolean worksOnSameFile;
/**
* Indicates whether the selected algorithm needs space reserved at the beginning of the file
*/
public final boolean reserveSpace;
/**
* Gets the given algorithm short name
*/
private final String name;
private String[] args;
protected transient DownloadMission mission;
private File tempFile;
Postprocessing(boolean reserveSpace, boolean worksOnSameFile, String algorithmName) {
this.reserveSpace = reserveSpace;
this.worksOnSameFile = worksOnSameFile;
this.name = algorithmName;// for debugging only
}
public void setTemporalDir(@NonNull File directory) {
long rnd = (int) (Math.random() * 100000f);
tempFile = new File(directory, rnd + "_" + System.nanoTime() + ".tmp");
}
public void cleanupTemporalDir() {
if (tempFile != null && tempFile.exists()) {
//noinspection ResultOfMethodCallIgnored
tempFile.delete();
}
}
public void run(DownloadMission target) throws IOException {
this.mission = target;
CircularFileWriter out = null;
int result;
long finalLength = -1;
mission.done = 0;
mission.length = mission.storage.length();
if (worksOnSameFile) {
ChunkFileInputStream[] sources = new ChunkFileInputStream[mission.urls.length];
try {
int i = 0;
for (; i < sources.length - 1; i++) {
sources[i] = new ChunkFileInputStream(mission.storage.getStream(), mission.offsets[i], mission.offsets[i + 1]);
}
sources[i] = new ChunkFileInputStream(mission.storage.getStream(), mission.offsets[i]);
if (test(sources)) {
for (SharpStream source : sources) source.rewind();
OffsetChecker checker = () -> {
for (ChunkFileInputStream source : sources) {
/*
* WARNING: never use rewind() in any chunk after any writing (especially on first chunks)
* or the CircularFileWriter can lead to unexpected results
*/
if (source.isClosed() || source.available() < 1) {
continue;// the selected source is not used anymore
}
return source.getFilePointer() - 1;
}
return -1;
};
out = new CircularFileWriter(mission.storage.getStream(), tempFile, checker);
out.onProgress = this::progressReport;
out.onWriteError = (err) -> {
mission.psState = 3;
mission.notifyError(ERROR_POSTPROCESSING_HOLD, err);
try {
synchronized (this) {
while (mission.psState == 3)
wait();
}
} catch (InterruptedException e) {
// nothing to do
Log.e(this.getClass().getSimpleName(), "got InterruptedException");
}
return mission.errCode == ERROR_NOTHING;
};
result = process(out, sources);
if (result == OK_RESULT)
finalLength = out.finalizeFile();
} else {
result = OK_RESULT;
}
} finally {
for (SharpStream source : sources) {
if (source != null && !source.isClosed()) {
source.close();
}
}
if (out != null) {
out.close();
}
if (tempFile != null) {
//noinspection ResultOfMethodCallIgnored
tempFile.delete();
tempFile = null;
}
}
} else {
result = test() ? process(null) : OK_RESULT;
}
if (result == OK_RESULT) {
if (finalLength != -1) {
mission.done = finalLength;
mission.length = finalLength;
}
} else {
mission.errCode = ERROR_UNKNOWN_EXCEPTION;
mission.errObject = new RuntimeException("post-processing algorithm returned " + result);
}
if (result != OK_RESULT && worksOnSameFile) mission.storage.delete();
this.mission = null;
}
/**
* Test if the post-processing algorithm can be skipped
*
* @param sources files to be processed
* @return {@code true} if the post-processing is required, otherwise, {@code false}
* @throws IOException if an I/O error occurs.
*/
boolean test(SharpStream... sources) throws IOException {
return true;
}
/**
* Abstract method to execute the post-processing algorithm
*
* @param out output stream
* @param sources files to be processed
* @return a error code, 0 means the operation was successful
* @throws IOException if an I/O error occurs.
*/
abstract int process(SharpStream out, SharpStream... sources) throws IOException;
String getArgumentAt(int index, String defaultValue) {
if (args == null || index >= args.length) {
return defaultValue;
}
return args[index];
}
private void progressReport(long done) {
mission.done = done;
if (mission.length < mission.done) mission.length = mission.done;
Message m = new Message();
m.what = DownloadManagerService.MESSAGE_PROGRESS;
m.obj = mission;
mission.mHandler.sendMessage(m);
}
@NonNull
@Override
public String toString() {
StringBuilder str = new StringBuilder();
str.append("name=").append(name).append('[');
if (args != null) {
for (String arg : args) {
str.append(", ");
str.append(arg);
}
str.delete(0, 1);
}
return str.append(']').toString();
}
}

View File

@ -1,75 +1,72 @@
package us.shandian.giga.postprocessing;
import android.util.Log;
import org.schabi.newpipe.streams.io.SharpStream;
import org.schabi.newpipe.streams.SubtitleConverter;
import org.xml.sax.SAXException;
import java.io.IOException;
import java.text.ParseException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPathExpressionException;
import us.shandian.giga.get.DownloadMission;
import us.shandian.giga.postprocessing.io.SharpInputStream;
/**
* @author kapodamy
*/
class TtmlConverter extends Postprocessing {
private static final String TAG = "TtmlConverter";
TtmlConverter(DownloadMission mission) {
// due how XmlPullParser works, the xml is fully loaded on the ram
super(mission, 0, true);
}
@Override
int process(SharpStream out, SharpStream... sources) throws IOException {
// check if the subtitle is already in srt and copy, this should never happen
String format = getArgumentAt(0, null);
if (format == null || format.equals("ttml")) {
SubtitleConverter ttmlDumper = new SubtitleConverter();
try {
ttmlDumper.dumpTTML(
sources[0],
out,
getArgumentAt(1, "true").equals("true"),
getArgumentAt(2, "true").equals("true")
);
} catch (Exception err) {
Log.e(TAG, "subtitle parse failed", err);
if (err instanceof IOException) {
return 1;
} else if (err instanceof ParseException) {
return 2;
} else if (err instanceof SAXException) {
return 3;
} else if (err instanceof ParserConfigurationException) {
return 4;
} else if (err instanceof XPathExpressionException) {
return 7;
}
return 8;
}
return OK_RESULT;
} else if (format.equals("srt")) {
byte[] buffer = new byte[8 * 1024];
int read;
while ((read = sources[0].read(buffer)) > 0) {
out.write(buffer, 0, read);
}
return OK_RESULT;
}
throw new UnsupportedOperationException("Can't convert this subtitle, unimplemented format: " + format);
}
}
package us.shandian.giga.postprocessing;
import android.util.Log;
import org.schabi.newpipe.streams.SubtitleConverter;
import org.schabi.newpipe.streams.io.SharpStream;
import org.xml.sax.SAXException;
import java.io.IOException;
import java.text.ParseException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPathExpressionException;
/**
* @author kapodamy
*/
class TtmlConverter extends Postprocessing {
private static final String TAG = "TtmlConverter";
TtmlConverter() {
// due how XmlPullParser works, the xml is fully loaded on the ram
super(false, true, ALGORITHM_TTML_CONVERTER);
}
@Override
int process(SharpStream out, SharpStream... sources) throws IOException {
// check if the subtitle is already in srt and copy, this should never happen
String format = getArgumentAt(0, null);
if (format == null || format.equals("ttml")) {
SubtitleConverter ttmlDumper = new SubtitleConverter();
try {
ttmlDumper.dumpTTML(
sources[0],
out,
getArgumentAt(1, "true").equals("true"),
getArgumentAt(2, "true").equals("true")
);
} catch (Exception err) {
Log.e(TAG, "subtitle parse failed", err);
if (err instanceof IOException) {
return 1;
} else if (err instanceof ParseException) {
return 2;
} else if (err instanceof SAXException) {
return 3;
} else if (err instanceof ParserConfigurationException) {
return 4;
} else if (err instanceof XPathExpressionException) {
return 7;
}
return 8;
}
return OK_RESULT;
} else if (format.equals("srt")) {
byte[] buffer = new byte[8 * 1024];
int read;
while ((read = sources[0].read(buffer)) > 0) {
out.write(buffer, 0, read);
}
return OK_RESULT;
}
throw new UnsupportedOperationException("Can't convert this subtitle, unimplemented format: " + format);
}
}

View File

@ -1,42 +1,44 @@
package us.shandian.giga.postprocessing;
import org.schabi.newpipe.streams.WebMReader.TrackKind;
import org.schabi.newpipe.streams.WebMReader.WebMTrack;
import org.schabi.newpipe.streams.WebMWriter;
import org.schabi.newpipe.streams.io.SharpStream;
import java.io.IOException;
import us.shandian.giga.get.DownloadMission;
/**
* @author kapodamy
*/
class WebMMuxer extends Postprocessing {
WebMMuxer(DownloadMission mission) {
super(mission, 2048 * 1024/* 2 MiB */, true);
}
@Override
int process(SharpStream out, SharpStream... sources) throws IOException {
WebMWriter muxer = new WebMWriter(sources);
muxer.parseSources();
// youtube uses a webm with a fake video track that acts as a "cover image"
WebMTrack[] tracks = muxer.getTracksFromSource(1);
int audioTrackIndex = 0;
for (int i = 0; i < tracks.length; i++) {
if (tracks[i].kind == TrackKind.Audio) {
audioTrackIndex = i;
break;
}
}
muxer.selectTracks(0, audioTrackIndex);
muxer.build(out);
return OK_RESULT;
}
}
package us.shandian.giga.postprocessing;
import org.schabi.newpipe.streams.WebMReader.TrackKind;
import org.schabi.newpipe.streams.WebMReader.WebMTrack;
import org.schabi.newpipe.streams.WebMWriter;
import org.schabi.newpipe.streams.io.SharpStream;
import java.io.IOException;
/**
* @author kapodamy
*/
class WebMMuxer extends Postprocessing {
WebMMuxer() {
super(true, true, ALGORITHM_WEBM_MUXER);
}
@Override
int process(SharpStream out, SharpStream... sources) throws IOException {
WebMWriter muxer = new WebMWriter(sources);
muxer.parseSources();
// youtube uses a webm with a fake video track that acts as a "cover image"
int[] indexes = new int[sources.length];
for (int i = 0; i < sources.length; i++) {
WebMTrack[] tracks = muxer.getTracksFromSource(i);
for (int j = 0; j < tracks.length; j++) {
if (tracks[j].kind == TrackKind.Audio) {
indexes[i] = j;
i = sources.length;
break;
}
}
}
muxer.selectTracks(indexes);
muxer.build(out);
return OK_RESULT;
}
}

View File

@ -1,375 +0,0 @@
package us.shandian.giga.postprocessing.io;
import org.schabi.newpipe.streams.io.SharpStream;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
public class CircularFile extends SharpStream {
private final static int AUX_BUFFER_SIZE = 1024 * 1024;// 1 MiB
private final static int AUX_BUFFER_SIZE2 = 512 * 1024;// 512 KiB
private final static int NOTIFY_BYTES_INTERVAL = 64 * 1024;// 64 KiB
private final static int QUEUE_BUFFER_SIZE = 8 * 1024;// 8 KiB
private final static boolean IMMEDIATE_AUX_BUFFER_FLUSH = false;
private RandomAccessFile out;
private long position;
private long maxLengthKnown = -1;
private ArrayList<ManagedBuffer> auxiliaryBuffers;
private OffsetChecker callback;
private ManagedBuffer queue;
private long startOffset;
private ProgressReport onProgress;
private long reportPosition;
public CircularFile(File file, long offset, ProgressReport progressReport, OffsetChecker checker) throws IOException {
if (checker == null) {
throw new NullPointerException("checker is null");
}
try {
queue = new ManagedBuffer(QUEUE_BUFFER_SIZE);
out = new RandomAccessFile(file, "rw");
out.seek(offset);
position = offset;
} catch (IOException err) {
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
// nothing to do
}
throw err;
}
auxiliaryBuffers = new ArrayList<>(15);
callback = checker;
startOffset = offset;
reportPosition = offset;
onProgress = progressReport;
}
/**
* Close the file without flushing any buffer
*/
@Override
public void dispose() {
try {
auxiliaryBuffers = null;
if (out != null) {
out.close();
out = null;
}
} catch (IOException err) {
// nothing to do
}
}
/**
* Flush any buffer and close the output file. Use this method if the
* operation is successful
*
* @return the final length of the file
* @throws IOException if an I/O error occurs
*/
public long finalizeFile() throws IOException {
flushEverything();
if (maxLengthKnown > -1) {
position = maxLengthKnown;
}
if (position < out.length()) {
out.setLength(position);
}
dispose();
return position;
}
@Override
public void write(byte b) throws IOException {
write(new byte[]{b}, 0, 1);
}
@Override
public void write(byte b[]) throws IOException {
write(b, 0, b.length);
}
@Override
public void write(byte b[], int off, int len) throws IOException {
if (len == 0) {
return;
}
long end = callback.check();
long available;
if (end == -1) {
available = Long.MAX_VALUE;
} else {
if (end < startOffset) {
throw new IOException("The reported offset is invalid. reported offset is " + String.valueOf(end));
}
available = end - position;
}
// Check if possible flush one or more auxiliary buffer
if (auxiliaryBuffers.size() > 0) {
ManagedBuffer aux = auxiliaryBuffers.get(0);
// check if there is enough space to flush it completely
while (available >= (aux.size + queue.size)) {
available -= aux.size;
writeQueue(aux.buffer, 0, aux.size);
aux.dereference();
auxiliaryBuffers.remove(0);
if (auxiliaryBuffers.size() < 1) {
aux = null;
break;
}
aux = auxiliaryBuffers.get(0);
}
if (IMMEDIATE_AUX_BUFFER_FLUSH) {
// try partial flush to avoid allocate another auxiliary buffer
if (aux != null && aux.available() < len && available > queue.size) {
int size = Math.min(aux.size, (int) available - queue.size);
writeQueue(aux.buffer, 0, size);
aux.dereference(size);
available -= size;
}
}
}
if (auxiliaryBuffers.size() < 1 && available > (len + queue.size)) {
writeQueue(b, off, len);
} else {
int i = auxiliaryBuffers.size() - 1;
while (len > 0) {
if (i < 0) {
// allocate a new auxiliary buffer
auxiliaryBuffers.add(new ManagedBuffer(AUX_BUFFER_SIZE));
i++;
}
ManagedBuffer aux = auxiliaryBuffers.get(i);
available = aux.available();
if (available < 1) {
// secondary auxiliary buffer
available = len;
aux = new ManagedBuffer(Math.max(len, AUX_BUFFER_SIZE2));
auxiliaryBuffers.add(aux);
i++;
} else {
available = Math.min(len, available);
}
aux.write(b, off, (int) available);
len -= available;
if (len > 0) off += available;
}
}
}
private void writeOutside(byte buffer[], int offset, int length) throws IOException {
out.write(buffer, offset, length);
position += length;
if (onProgress != null && position > reportPosition) {
reportPosition = position + NOTIFY_BYTES_INTERVAL;
onProgress.report(position);
}
}
private void writeQueue(byte[] buffer, int offset, int length) throws IOException {
while (length > 0) {
if (queue.available() < length) {
flushQueue();
if (length >= queue.buffer.length) {
writeOutside(buffer, offset, length);
return;
}
}
int size = Math.min(queue.available(), length);
queue.write(buffer, offset, size);
offset += size;
length -= size;
}
if (queue.size >= queue.buffer.length) {
flushQueue();
}
}
private void flushQueue() throws IOException {
writeOutside(queue.buffer, 0, queue.size);
queue.size = 0;
}
private void flushEverything() throws IOException {
flushQueue();
if (auxiliaryBuffers.size() > 0) {
for (ManagedBuffer aux : auxiliaryBuffers) {
writeOutside(aux.buffer, 0, aux.size);
aux.dereference();
}
auxiliaryBuffers.clear();
}
}
/**
* Flush any buffer directly to the file. Warning: use this method ONLY if
* all read dependencies are disposed
*
* @throws IOException if the dependencies are not disposed
*/
@Override
public void flush() throws IOException {
if (callback.check() != -1) {
throw new IOException("All read dependencies of this file must be disposed first");
}
flushEverything();
// Save the current file length in case the method {@code rewind()} is called
if (position > maxLengthKnown) {
maxLengthKnown = position;
}
}
@Override
public void rewind() throws IOException {
flush();
out.seek(startOffset);
if (onProgress != null) {
onProgress.report(-position);
}
position = startOffset;
reportPosition = startOffset;
}
@Override
public long skip(long amount) throws IOException {
flush();
position += amount;
out.seek(position);
return amount;
}
@Override
public boolean isDisposed() {
return out == null;
}
@Override
public boolean canRewind() {
return true;
}
@Override
public boolean canWrite() {
return true;
}
//<editor-fold defaultState="collapsed" desc="stub read methods">
@Override
public boolean canRead() {
return false;
}
@Override
public int read() {
throw new UnsupportedOperationException("write-only");
}
@Override
public int read(byte[] buffer) {
throw new UnsupportedOperationException("write-only");
}
@Override
public int read(byte[] buffer, int offset, int count) {
throw new UnsupportedOperationException("write-only");
}
@Override
public int available() {
throw new UnsupportedOperationException("write-only");
}
//</editor-fold>
public interface OffsetChecker {
/**
* Checks the amount of available space ahead
*
* @return absolute offset in the file where no more data SHOULD NOT be
* written. If the value is -1 the whole file will be used
*/
long check();
}
public interface ProgressReport {
void report(long progress);
}
class ManagedBuffer {
byte[] buffer;
int size;
ManagedBuffer(int length) {
buffer = new byte[length];
}
void dereference() {
buffer = null;
size = 0;
}
void dereference(int amount) {
if (amount > size) {
throw new IndexOutOfBoundsException("Invalid dereference amount (" + amount + ">=" + size + ")");
}
size -= amount;
System.arraycopy(buffer, amount, buffer, 0, size);
}
protected int available() {
return buffer.length - size;
}
private void write(byte[] b, int off, int len) {
System.arraycopy(b, off, buffer, size, len);
size += len;
}
@Override
public String toString() {
return "holding: " + String.valueOf(size) + " length: " + String.valueOf(buffer.length) + " available: " + String.valueOf(available());
}
}
}

View File

@ -0,0 +1,5 @@
package us.shandian.giga.service;
public enum MissionState {
None, Pending, PendingRunning, Finished
}

View File

@ -3,8 +3,6 @@ package us.shandian.giga.ui.common;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.support.design.widget.Snackbar;
import android.view.View;
@ -23,8 +21,6 @@ public class Deleter {
private static final int TIMEOUT = 5000;// ms
private static final int DELAY = 350;// ms
private static final int DELAY_RESUME = 400;// ms
private static final String BUNDLE_NAMES = "us.shandian.giga.ui.common.deleter.names";
private static final String BUNDLE_LOCATIONS = "us.shandian.giga.ui.common.deleter.locations";
private Snackbar snackbar;
private ArrayList<Mission> items;
@ -41,7 +37,7 @@ public class Deleter {
private final Runnable rNext;
private final Runnable rCommit;
public Deleter(Bundle b, View v, Context c, MissionAdapter a, DownloadManager d, MissionIterator i, Handler h) {
public Deleter(View v, Context c, MissionAdapter a, DownloadManager d, MissionIterator i, Handler h) {
mView = v;
mContext = c;
mAdapter = a;
@ -55,27 +51,6 @@ public class Deleter {
rCommit = this::commit;
items = new ArrayList<>(2);
if (b != null) {
String[] names = b.getStringArray(BUNDLE_NAMES);
String[] locations = b.getStringArray(BUNDLE_LOCATIONS);
if (names == null || locations == null) return;
if (names.length < 1 || locations.length < 1) return;
if (names.length != locations.length) return;
items.ensureCapacity(names.length);
for (int j = 0; j < locations.length; j++) {
Mission mission = mDownloadManager.getAnyMission(locations[j], names[j]);
if (mission == null) continue;
items.add(mission);
mIterator.hide(mission);
}
if (items.size() > 0) resume();
}
}
public void append(Mission item) {
@ -104,7 +79,7 @@ public class Deleter {
private void next() {
if (items.size() < 1) return;
String msg = mContext.getString(R.string.file_deleted).concat(":\n").concat(items.get(0).name);
String msg = mContext.getString(R.string.file_deleted).concat(":\n").concat(items.get(0).storage.getName());
snackbar = Snackbar.make(mView, msg, Snackbar.LENGTH_INDEFINITE);
snackbar.setAction(R.string.undo, s -> forget());
@ -125,7 +100,7 @@ public class Deleter {
mDownloadManager.deleteMission(mission);
if (mission instanceof FinishedMission) {
mContext.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(mission.getDownloadedFile())));
mContext.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, mission.storage.getUri()));
}
break;
}
@ -151,27 +126,14 @@ public class Deleter {
mHandler.postDelayed(rShow, DELAY_RESUME);
}
public void dispose(Bundle bundle) {
public void dispose(boolean commitChanges) {
if (items.size() < 1) return;
pause();
if (bundle == null) {
for (Mission mission : items) mDownloadManager.deleteMission(mission);
items = null;
return;
}
if (!commitChanges) return;
String[] names = new String[items.size()];
String[] locations = new String[items.size()];
for (int i = 0; i < items.size(); i++) {
Mission mission = items.get(i);
names[i] = mission.name;
locations[i] = mission.location;
}
bundle.putStringArray(BUNDLE_NAMES, names);
bundle.putStringArray(BUNDLE_LOCATIONS, locations);
for (Mission mission : items) mDownloadManager.deleteMission(mission);
items = null;
}
}

View File

@ -1,7 +1,7 @@
package us.shandian.giga.ui.fragment;
import android.app.Activity;
import android.app.Fragment;
import android.app.AlertDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@ -10,6 +10,8 @@ import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
@ -18,23 +20,31 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import org.schabi.newpipe.R;
import org.schabi.newpipe.util.ThemeHelper;
import java.io.IOException;
import us.shandian.giga.get.DownloadMission;
import us.shandian.giga.io.StoredFileHelper;
import us.shandian.giga.service.DownloadManager;
import us.shandian.giga.service.DownloadManagerService;
import us.shandian.giga.service.DownloadManagerService.DMBinder;
import us.shandian.giga.service.DownloadManagerService.DownloadManagerBinder;
import us.shandian.giga.ui.adapter.MissionAdapter;
public class MissionsFragment extends Fragment {
private static final int SPAN_SIZE = 2;
private static final int REQUEST_DOWNLOAD_PATH_SAF = 0x1230;
private SharedPreferences mPrefs;
private boolean mLinear;
private MenuItem mSwitch;
private MenuItem mClear = null;
private MenuItem mStart = null;
private MenuItem mPause = null;
private RecyclerView mList;
private View mEmpty;
@ -43,21 +53,24 @@ public class MissionsFragment extends Fragment {
private LinearLayoutManager mLinearManager;
private Context mContext;
private DMBinder mBinder;
private Bundle mBundle;
private DownloadManagerBinder mBinder;
private boolean mForceUpdate;
private DownloadMission unsafeMissionTarget = null;
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder binder) {
mBinder = (DownloadManagerService.DMBinder) binder;
mBinder = (DownloadManagerBinder) binder;
mBinder.clearDownloadNotifications();
mAdapter = new MissionAdapter(mContext, mBinder.getDownloadManager(), mClear, mEmpty);
mAdapter.deleterLoad(mBundle, getView());
mAdapter = new MissionAdapter(mContext, mBinder.getDownloadManager(), mEmpty);
mAdapter.deleterLoad(getView());
mBundle = null;
mAdapter.setRecover(MissionsFragment.this::recoverMission);
setAdapterButtons();
mBinder.addMissionEventListener(mAdapter.getMessenger());
mBinder.enableNotifications(false);
@ -74,15 +87,12 @@ public class MissionsFragment extends Fragment {
};
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.missions, container, false);
mPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
mLinear = mPrefs.getBoolean("linear", false);
//mContext = getActivity().getApplicationContext();
mBundle = savedInstanceState;
// Bind the service
mContext.bindService(new Intent(mContext, DownloadManagerService.class), mConnection, Context.BIND_AUTO_CREATE);
@ -132,7 +142,7 @@ public class MissionsFragment extends Fragment {
public void onAttach(Activity activity) {
super.onAttach(activity);
mContext = activity.getApplicationContext();
mContext = activity;
}
@ -144,7 +154,7 @@ public class MissionsFragment extends Fragment {
mBinder.removeMissionEventListener(mAdapter.getMessenger());
mBinder.enableNotifications(true);
mContext.unbindService(mConnection);
mAdapter.deleterDispose(null);
mAdapter.deleterDispose(true);
mBinder = null;
mAdapter = null;
@ -154,7 +164,11 @@ public class MissionsFragment extends Fragment {
public void onPrepareOptionsMenu(Menu menu) {
mSwitch = menu.findItem(R.id.switch_mode);
mClear = menu.findItem(R.id.clear_list);
if (mAdapter != null) mAdapter.setClearButton(mClear);
mStart = menu.findItem(R.id.start_downloads);
mPause = menu.findItem(R.id.pause_downloads);
if (mAdapter != null) setAdapterButtons();
super.onPrepareOptionsMenu(menu);
}
@ -166,8 +180,23 @@ public class MissionsFragment extends Fragment {
updateList();
return true;
case R.id.clear_list:
mAdapter.clearFinishedDownloads();
AlertDialog.Builder prompt = new AlertDialog.Builder(mContext);
prompt.setTitle(R.string.clear_finished_download);
prompt.setMessage(R.string.confirm_prompt);
prompt.setPositiveButton(android.R.string.ok, (dialog, which) -> mAdapter.clearFinishedDownloads());
prompt.setNegativeButton(R.string.cancel, null);
prompt.create().show();
return true;
case R.id.start_downloads:
item.setVisible(false);
mPause.setVisible(true);
mBinder.getDownloadManager().startAllMissions();
return true;
case R.id.pause_downloads:
item.setVisible(false);
mStart.setVisible(true);
mBinder.getDownloadManager().pauseAllMissions(false);
mAdapter.ensurePausedMissions();// update items view
default:
return super.onOptionsItemSelected(item);
}
@ -193,9 +222,9 @@ public class MissionsFragment extends Fragment {
int icon;
if (mLinear)
icon = isLight ? R.drawable.ic_list_black_24dp : R.drawable.ic_list_white_24dp;
else
icon = isLight ? R.drawable.ic_grid_black_24dp : R.drawable.ic_grid_white_24dp;
else
icon = isLight ? R.drawable.ic_list_black_24dp : R.drawable.ic_list_white_24dp;
mSwitch.setIcon(icon);
mSwitch.setTitle(mLinear ? R.string.grid : R.string.list);
@ -203,12 +232,29 @@ public class MissionsFragment extends Fragment {
}
}
private void setAdapterButtons() {
if (mClear == null || mStart == null || mPause == null) return;
mAdapter.setClearButton(mClear);
mAdapter.setMasterButtons(mStart, mPause);
}
private void recoverMission(@NonNull DownloadMission mission) {
unsafeMissionTarget = mission;
StoredFileHelper.requestSafWithFileCreation(
MissionsFragment.this,
REQUEST_DOWNLOAD_PATH_SAF,
mission.storage.getName(),
mission.storage.getType()
);
}
@Override
public void onSaveInstanceState(Bundle outState) {
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
if (mAdapter != null) {
mAdapter.deleterDispose(outState);
mAdapter.deleterDispose(false);
mForceUpdate = true;
mBinder.removeMissionEventListener(mAdapter.getMessenger());
}
@ -237,4 +283,23 @@ public class MissionsFragment extends Fragment {
if (mAdapter != null) mAdapter.onPaused();
if (mBinder != null) mBinder.enableNotifications(true);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode != REQUEST_DOWNLOAD_PATH_SAF || resultCode != Activity.RESULT_OK) return;
if (unsafeMissionTarget == null || data.getData() == null) {
return;// unsafeMissionTarget cannot be null
}
try {
String tag = unsafeMissionTarget.storage.getTag();
unsafeMissionTarget.storage = new StoredFileHelper(mContext, null, data.getData(), tag);
mAdapter.recoverMission(unsafeMissionTarget);
} catch (IOException e) {
Toast.makeText(mContext, R.string.general_error, Toast.LENGTH_LONG).show();
}
}
}

View File

@ -9,14 +9,15 @@ import android.support.annotation.DrawableRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.widget.Toast;
import org.schabi.newpipe.R;
import org.schabi.newpipe.streams.io.SharpStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
@ -25,7 +26,8 @@ import java.io.Serializable;
import java.net.HttpURLConnection;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Locale;
import us.shandian.giga.io.StoredFileHelper;
public class Utility {
@ -80,6 +82,7 @@ public class Utility {
objectInputStream = new ObjectInputStream(new FileInputStream(file));
object = (T) objectInputStream.readObject();
} catch (Exception e) {
Log.e("Utility", "Failed to deserialize the object", e);
object = null;
}
@ -206,7 +209,7 @@ public class Utility {
Toast.makeText(context, R.string.msg_copied, Toast.LENGTH_SHORT).show();
}
public static String checksum(String path, String algorithm) {
public static String checksum(StoredFileHelper source, String algorithm) {
MessageDigest md;
try {
@ -215,11 +218,11 @@ public class Utility {
throw new RuntimeException(e);
}
FileInputStream i;
SharpStream i;
try {
i = new FileInputStream(path);
} catch (FileNotFoundException e) {
i = source.getStream();
} catch (Exception e) {
throw new RuntimeException(e);
}
@ -247,15 +250,15 @@ public class Utility {
}
@SuppressWarnings("ResultOfMethodCallIgnored")
public static boolean mkdir(File path, boolean allDirs) {
if (path.exists()) return true;
public static boolean mkdir(File p, boolean allDirs) {
if (p.exists()) return true;
if (allDirs)
path.mkdirs();
p.mkdirs();
else
path.mkdir();
p.mkdir();
return path.exists();
return p.exists();
}
public static long getContentLength(HttpURLConnection connection) {
@ -264,8 +267,7 @@ public class Utility {
}
try {
long length = Long.parseLong(connection.getHeaderField("Content-Length"));
if (length >= 0) return length;
return Long.parseLong(connection.getHeaderField("Content-Length"));
} catch (Exception err) {
// nothing to do
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 248 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 254 B

View File

@ -7,6 +7,18 @@
android:title="@string/grid"
app:showAsAction="ifRoom" />
<item android:id="@+id/start_downloads"
android:visible="false"
android:icon="?attr/play"
android:title="@string/start_downloads"
app:showAsAction="ifRoom" />
<item android:id="@+id/pause_downloads"
android:visible="false"
android:icon="?attr/pause"
android:title="@string/pause_downloads"
app:showAsAction="ifRoom" />
<item android:id="@+id/clear_list"
android:visible="false"
android:icon="?attr/ic_delete"

View File

@ -1,4 +1,13 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/retry"
android:title="@string/retry" />
<item
android:id="@+id/cancel"
android:title="@string/cancel" />
<item
android:id="@+id/start"
android:title="@string/start" />
@ -13,8 +22,8 @@
android:checkable="true"/>
<item
android:id="@+id/open"
android:title="@string/view" />
android:id="@+id/menu_item_share"
android:title="@string/share" />
<item
android:id="@+id/delete"

View File

@ -26,7 +26,7 @@
<string name="light_theme_title">مضيء</string>
<string name="list_thumbnail_view_description">صور معاينة الفيديو</string>
<string name="network_error">خطأ في الشبكة</string>
<string name="next_video_title">التالى</string>
<string name="next_video_title">التالي</string>
<string name="no_player_found">لا يوجد مشغل فيديو. هل تريد تثبيت VLC ؟</string>
<string name="open_in_browser">افتح في المتصفح</string>
<string name="play_audio">الصوت</string>
@ -38,15 +38,15 @@
<string name="settings">الإعدادات</string>
<string name="settings_category_appearance_title">المظهر</string>
<string name="settings_category_other_title">اخرى</string>
<string name="settings_category_video_audio_title">الفيديو &amp; الصوتيات</string>
<string name="settings_category_video_audio_title">الفيديو و الصوتيات</string>
<string name="share">مشاركة</string>
<string name="share_dialog_title">مشاركة بواسطة</string>
<string name="show_next_and_similar_title">عرض مقاطع الفيديو \"التالية\" و \"شبيه\"</string>
<string name="show_next_and_similar_title">عرض مقاطع الفيديو \"التالية\" و \"المشابهة\"</string>
<string name="show_play_with_kodi_summary">عرض خيار لتشغيل الفيديو بواسطة مشغل كودي</string>
<string name="show_play_with_kodi_title">عرض خيار التشغيل بواسطة كودي</string>
<string name="theme_title">السمة</string>
<string name="upload_date_text">تم النشر يوم %1$s</string>
<string name="url_not_supported_toast">رابط غير معتمد URL</string>
<string name="url_not_supported_toast">رابط URL غير معتمد</string>
<string name="use_external_audio_player_title">استخدام مشغل صوت خارجي</string>
<string name="use_external_video_player_title">استخدام مشغل فيديو خارجي</string>
<string name="use_tor_summary">(إختبارية) إجراء التنزيلات من خلال استخدام بروكسي Tor لزيادة الخصوصية ( تشغيل الفيديو المباشر غير مدعوم حتى الأن ).</string>
@ -58,19 +58,17 @@
<string name="general_error">خطأ</string>
<string name="parsing_error">تعذرت عملية تحليل الموقع</string>
<string name="youtube_signature_decryption_error">تعذر فك تشفير توقيع رابط الفيديو</string>
<string name="main_bg_subtitle">اضغط بحث للبدء</string>
<string name="main_bg_subtitle">اضغط بحث للبدء</string>
<string name="subscribe_button_title">اشتراك</string>
<string name="subscribed_button_title">مشترك</string>
<string name="tab_main">الرئيسية</string>
<string name="tab_subscriptions">الاشتراكات</string>
<string name="fragment_whats_new">ما الجديد</string>
<string name="controls_background_title">في الخلفية</string>
<string name="autoplay_by_calling_app_title">تشغيل تلقائي</string>
<string name="black_theme_title">اسود</string>
<string name="enable_watch_history_title">التاريخ وذاكرة التخزين المؤقت</string>
<string name="settings_category_history_title">التاريخ &amp; ذاكرة التخزين المؤقت</string>
<string name="settings_category_history_title">التاريخ و ذاكرة التخزين المؤقت</string>
<string name="content">المحتوى</string>
<string name="downloads">التنزيلات</string>
<string name="downloads_title">التنزيلات</string>
@ -83,14 +81,12 @@
<string name="title_activity_history">التاريخ</string>
<string name="action_history">التاريخ</string>
<string name="open_in_popup_mode">افتح في وضع النافذة المنبثقة</string>
<string name="use_external_video_player_summary">يزيل الصوت في بعض القرارات</string>
<string name="use_external_video_player_summary">يزيل الصوت في بعض الخيارات</string>
<string name="popup_mode_share_menu_title">وضع النوافذ المنبثقة NewPipe</string>
<string name="channel_unsubscribed">تم إلغاء الاشتراك في القناة</string>
<string name="subscription_change_failed">تعذر تغيير حالة الاشتراك</string>
<string name="subscription_update_failed">تعذر تحديث الاشتراك</string>
<string name="controls_popup_title">نافذة المنبثقة</string>
<string name="autoplay_by_calling_app_summary">تشغيل مقطع الفيديو عند إستدعاء NewPipe من تطبيق آخر</string>
<string name="default_popup_resolution_title">الدقة الافتراضية لنوافذ المنبثقة</string>
<string name="show_higher_resolutions_title">"عرض أعلى جودة "</string>
@ -130,22 +126,18 @@
<string name="best_resolution">أفضل دقة</string>
<string name="undo">تراجع</string>
<string name="play_all">تشغيل الكل</string>
<string name="notification_channel_name">تنبيهات NewPipe</string>
<string name="notification_channel_description">تنبيهات مشغل NewPipe للخلفية والنوافذ المنبثقة</string>
<string name="unknown_content">[غير معروف]</string>
<string name="light_parsing_error">لا يمكن تحليل الموقع بشكل كلي</string>
<string name="could_not_setup_download_menu">تعذرت عملية إعداد قائمة التنزيل</string>
<string name="live_streams_not_supported">لبث المباشر غير مدعوم حتى الآن</string>
<string name="live_streams_not_supported">البث المباشر غير مدعوم حتى الآن</string>
<string name="could_not_get_stream">تعذر الحصول على أي بث</string>
<string name="could_not_load_image">تعذرت عملية تحميل الصورة</string>
<string name="app_ui_crash">تعطل التطبيق / واجهة المستخدم</string>
<string name="player_stream_failure">لا يمكن تشغيل هذا البث</string>
<string name="player_unrecoverable_failure">حدث خطأ للمشغل غير قابل للاسترداد</string>
<string name="player_recoverable_failure">استرداد المشغل من الخطأ</string>
<string name="sorry_string">عذرا، لا ينبغي أن يحدث ذلك.</string>
<string name="error_report_button_text">الإبلاغ عن خطأ عبر البريد الإلكتروني</string>
<string name="error_snackbar_message">عذرا، حدثت بعض الأخطاء.</string>
@ -155,31 +147,25 @@
<string name="info_labels">ماذا:\\nطلب:\\nيحتوى اللغة:\\nSالخدمات:\\nتوقيت غرينتش:\\nحزمة:\\nالإصدار:\\nOS إصدار نظام التشغيل:</string>
<string name="your_comment">تعليقك (باللغة الإنجليزية):</string>
<string name="error_details_headline">التفاصيل:</string>
<string name="report_error">الإبلاغ عن خطأ</string>
<string name="user_report">تقرير المستخدم</string>
<string name="search_no_results">لم يتم العثور على نتائج</string>
<string name="empty_subscription_feed_subtitle">لا شيء هنا غير الصراصير</string>
<string name="audio">الصوت</string>
<string name="retry">إعادة المحاولة</string>
<string name="storage_permission_denied">تم رفض إذن الوصول إلى التخزين</string>
<string name="short_thousand">ألف</string>
<string name="short_million">مليون</string>
<string name="short_billion">بليون</string>
<string name="no_subscribers">ليس هناك مشترِكون</string>
<plurals name="subscribers">
<item quantity="zero">%s لا يوجد مشترك</item>
<item quantity="one">%s مشترك</item>
<item quantity="two">%s اثنتين مشتركين</item>
<item quantity="few">%s اشتراكات</item>
<item quantity="many">%s مشتركين</item>
<item quantity="other">%s مشتركون</item>
</plurals>
<item quantity="zero">%s لا يوجد مشترك</item>
<item quantity="one">%s مشترك</item>
<item quantity="two">%s اثنتين مشتركين</item>
<item quantity="few">%s اشتراكات</item>
<item quantity="many">%s مشتركين</item>
<item quantity="other">%s مشتركون</item>
</plurals>
<string name="no_views">دون مشاهدات</string>
<string name="no_videos">لاتوجد فيديوهات</string>
<string name="start">ابدأ</string>
@ -187,10 +173,8 @@
<string name="view">شغل</string>
<string name="delete">حذف</string>
<string name="checksum">التوقيع</string>
<string name="add">مهمة جديدة</string>
<string name="finish">حسناً</string>
<string name="msg_name">اسم الملف</string>
<string name="msg_threads">التقسيم</string>
<string name="msg_error">الخطأ</string>
@ -204,15 +188,12 @@
<string name="no_available_dir">الرجاء تحديد مجلد لحفظ التنزيلات</string>
<string name="msg_popup_permission">هذا الإذن مطلوب
\nللفتح في وضع النافذة المنبثقة</string>
<string name="reCaptchaActivity">اختبار reCAPTCHA</string>
<string name="settings_file_charset_title">السماح بالرموز في أسماء الملفات</string>
<string name="settings_file_replacement_character_summary">يتم استبدال الرموز غير المسموح بها بهذه القيمة</string>
<string name="settings_file_replacement_character_title">استبدال الحرف</string>
<string name="charset_letters_and_digits">الحروف والأرقام</string>
<string name="charset_most_special_characters">معظم الأحرف الخاصة</string>
<string name="title_activity_about">عن تطبيق نيوپايپ</string>
<string name="action_settings">الإعدادات</string>
<string name="title_licenses">تراخيص الجهات الخارجية</string>
@ -231,8 +212,6 @@
<string name="website_encouragement">قم بزيارة موقع NewPipe لمزيد من المعلومات والمستجدات.</string>
<string name="app_license_title">تراخيص NewPipe</string>
<string name="read_full_license">قراءة الرخصة</string>
<string name="title_history_search">التي تم البحث عنها</string>
<string name="title_history_view">تمت مشاهدتها</string>
<string name="history_disabled">تم تعطيل السجل</string>
@ -240,7 +219,6 @@
<string name="history_cleared">تم مسح التاريخ</string>
<string name="item_deleted">تم حذف العنصر</string>
<string name="delete_item_search_history">هل تريد حذف هذا العنصر من سجل البحث؟</string>
<string name="main_page_content">محتوى الشاشة الرئيسية</string>
<string name="blank_page_summary">صفحة فارغة</string>
<string name="subscription_page_summary">صفحة الاشتراك</string>
@ -258,82 +236,67 @@
<string name="play_queue_audio_settings">الإعدادات الصوتية</string>
<string name="start_here_on_main">تشغيل هنا</string>
<string name="start_here_on_popup">تشغيل هنا في وضع النافذة المنبثقة</string>
<string name="reCaptcha_title">تحدي الكابتشا</string>
<string name="reCaptcha_title">تحدي الكابتشا</string>
<string name="hold_to_append">اضغط للإدراج في قائمة الانتظار</string>
<plurals name="views">
<item quantity="zero">بدون مشاهدات</item>
<item quantity="one">%s مشاهدة</item>
<item quantity="two">%s مشاهدتين</item>
<item quantity="few">%s مشاهدون</item>
<item quantity="many">%s مشاهدات</item>
<item quantity="other">%s مشاهدين</item>
</plurals>
<item quantity="zero">بدون مشاهدات</item>
<item quantity="one">%s مشاهدة</item>
<item quantity="two">%s مشاهدتين</item>
<item quantity="few">%s مشاهدون</item>
<item quantity="many">%s مشاهدات</item>
<item quantity="other">%s مشاهدين</item>
</plurals>
<plurals name="videos">
<item quantity="zero">%s فيديو</item>
<item quantity="one">%s فيديو</item>
<item quantity="two">%s فيديوهان</item>
<item quantity="few">%s فيديو</item>
<item quantity="many">%s فيديوهات</item>
<item quantity="other">%s فيديو</item>
</plurals>
<item quantity="zero">%s فيديو</item>
<item quantity="one">%s فيديو</item>
<item quantity="two">%s فيديوهان</item>
<item quantity="few">%s فيديو</item>
<item quantity="many">%s فيديوهات</item>
<item quantity="other">%s فيديو</item>
</plurals>
<string name="recaptcha_request_toast">طلب اختبار الكابتشا مطلوب</string>
<string name="copyright" formatted="true">© %1$sبواسطة%2$sتحت%3$s</string>
<string name="kiosk_page_summary">صفحة الكشك</string>
<string name="select_a_kiosk">حدد كشك</string>
<string name="kiosk">الكشك</string>
<string name="enqueue_on_background">إدراج في قائمة الانتظار في الخلفية</string>
<string name="enqueue_on_popup">إدراج في قائمة الانتظار على المنبثقة</string>
<string name="start_here_on_background">تشغيل في الخلفية</string>
<string name="default_content_country_title">المحتوى الإفتراضي حسب البلد</string>
<string name="default_content_country_title">المحتوى الإفتراضي حسب البلد</string>
<string name="toggle_orientation">تغيير الإتجاه</string>
<string name="switch_to_background">الإنتقال إلى التشغيل في الخلفية</string>
<string name="switch_to_popup">الإنتقال إلى التشغيل في النافذة المنبثقة</string>
<string name="switch_to_main">الإنتقال إلى الرئيسية</string>
<string name="service_title">الخدمة</string>
<string name="drawer_open">فتح الدرج</string>
<string name="drawer_close">إغلاق الدرج</string>
<string name="always">دائماً</string>
<string name="just_once">مرة واحدة فقط</string>
<string name="invalid_url_toast">العنوان خاطئ</string>
<string name="no_player_found_toast">لم يتم العثور على مشغل تدفق (يمكنك تثبيت VLC وتشغيله).</string>
<string name="no_player_found_toast">لم يتم العثور على مشغل الفيديو (يمكنك تثبيت VLC وتشغيله).</string>
<string name="import_data_title">استيراد قاعدة البيانات</string>
<string name="export_data_title">تصدير قاعدة البيانات</string>
<string name="import_data_summary">"الكتابة فوق سجل التاريخ والاشتراكات الحالية "</string>
<string name="export_data_summary">تصدير السجل، الإشتراكات وقوائم التشغيل</string>
<string name="show_info">عرض المعلومات</string>
<string name="controls_add_to_playlist_title">إضافة إلى</string>
<string name="settings_category_debug_title">تحليل</string>
<string name="video_streams_empty">لم يتم العثور على أي بث مرئي</string>
<string name="audio_streams_empty">لم يتم العثور على أي بث صوتي</string>
<string name="detail_drag_description">إسحب للقيام بالترتيب</string>
<string name="create">إنشاء</string>
<string name="delete_one">إحذف واحدة</string>
<string name="delete_all">حذف الكل</string>
<string name="dismiss">إلغاء</string>
<string name="rename">إعادة التسمية</string>
<string name="export_complete_toast">تمت عملية التصدير</string>
<string name="import_complete_toast">إكتَملَت عملية الإستيراد</string>
<string name="could_not_import_all_files">تنبيه : تعذرت عملية استيراد كافة الملفات.</string>
<string name="drawer_header_action_paceholder_text">سوف يظهر شيء هنا قريبا ;D</string>
<string name="video_player">مشغل الفيديو</string>
<string name="always_ask_open_action">السؤال دائماً</string>
<string name="preferred_player_fetcher_notification_title">الحصول على المعلومات …</string>
<string name="preferred_player_fetcher_notification_message">تحميل المحتوى المطلوب</string>
<string name="create_playlist">إنشاء قائمة تشغيل جديدة</string>
<string name="delete_playlist">حذف قائمة التشغيل</string>
<string name="rename_playlist">"إعادة تسمية قائمة التشغيل "</string>
@ -343,60 +306,52 @@
<string name="playlist_creation_success">تم إنشاء قائمة التشغيل</string>
<string name="playlist_add_stream_success">تمت إضافتها إلى قائمة التشغيل</string>
<string name="playlist_delete_failure">لا يمكن حذف قائمة التشغيل.</string>
<string name="resize_fill">ملئ الشاشة</string>
<string name="resize_zoom">تكبير</string>
<string name="caption_font_size_settings_title">حجم خط التسمية</string>
<string name="smaller_caption_font_size">أصغر خط</string>
<string name="normal_caption_font_size">خط عادي</string>
<string name="larger_caption_font_size">خط ذو حجم كبير</string>
<string name="live_sync">مُزامَنة</string>
<string name="controls_download_desc">تنزيل ملف البث</string>
<string name="tab_bookmarks">الإشارات المرجعية</string>
<string name="use_inexact_seek_title">استعمال التقديم السريع الغير دقيق</string>
<string name="use_inexact_seek_summary">"التقديم الغير دقيق يسمح للمشغل بالإطلاع الى الأماكن بشكل اسرع مع دقة اقل "</string>
<string name="download_thumbnail_title">تحميل الصور المصغرة</string>
<string name="thumbnail_cache_wipe_complete_notice">تم إفراغ مساحة ذاكرة التخزين المؤقتة الخاصة بالصور</string>
<string name="file">الملف</string>
<string name="invalid_directory">لا يوجد مثل هذا المجلد</string>
<string name="file_name_empty_error">لا يمكن أن يكون اسم الملف فارغا</string>
<string name="error_occurred_detail">طرأ هناك خطأ: %1$s</string>
<string name="no_valid_zip_file">ملف مضغوط ZIP غير صالح</string>
<string name="unbookmark_playlist">إزالة الفواصل المرجعية</string>
<string name="resize_fit">تناسب مع الشاشة</string>
<string name="caption_auto_generated">توليد تلقائي</string>
<string name="import_export_title">إستيراد او تصدير</string>
<string name="import_title">إستيراد</string>
<string name="import_from">إستعادة مِن</string>
<string name="export_to">تصدير إلى</string>
<string name="import_ongoing">عملية الإستعادة جارية …</string>
<string name="export_ongoing">عملية التصدير جارية …</string>
<string name="import_file_title">إستيراد ملف</string>
<string name="import_soundcloud_instructions_hint">"معرفك , soundcloud.com/ الخاص بك "</string>
<string name="download_thumbnail_summary">عند إيقاف تحميل أي صور مصغرة ، وتوفير البيانات واستخدام الذاكرة. تعمل التغييرات على محو ذاكرة التخزين المؤقت للصورة الموجودة على الذاكرة أو على القرص.</string>
<string name="playback_default">إفتراضي</string>
<string name="download_thumbnail_summary">عند إيقاف تحميل أي صور مصغرة ، وتوفير البيانات واستخدام الذاكرة. تعمل التغييرات على محو ذاكرة التخزين المؤقت للصورة الموجودة على الذاكرة أو على القرص.</string>
<string name="metadata_cache_wipe_title">امسح البيانات الوصفية المخزنة مؤقتًا</string>
<string name="metadata_cache_wipe_summary">إزالة جميع بيانات صفحات الويب المخزنة مؤقتًا</string>
<string name="metadata_cache_wipe_complete_notice">تم محو ذاكرة التخزين المؤقت للبيانات الوصفية</string>
<string name="auto_queue_title">وضع البث القادم تلقائيا في قائمة الإنتظار</string>
<string name="auto_queue_summary">رفض التدفق-التلقائي المشابه في حال كان التدفق السابق يعمل في-حالة عدم التكرار.</string>
<string name="set_as_playlist_thumbnail">إضافة صورة مصغرة إلى قائمة التشغيل</string>
<string name="bookmark_playlist">تفضيل قائمة التشغيل</string>
<string name="playlist_thumbnail_change_success">تم تغيير الصورة المصغرة لقائمة التشغيل.</string>
<string name="caption_none">بدون تسميات توضيحية</string>
<string name="caption_setting_title">تسميات توضيحية</string>
<string name="caption_setting_description">تعديل مشغل نص التسمية التوضيحية وأنماط الخلفية. يتطلب إعادة تشغيل التطبيق لتصبح التغييرات سارية المفعول.</string>
<string name="enable_leak_canary_title">تمكين LeakCanary</string>
<string name="enable_leak_canary_summary">قد تتسبب مراقبة تسرب الذاكرة في عدم استجابة التطبيق عند تفريغ السجلات</string>
<string name="enable_disposed_exceptions_title">تقرير الأخطاء خارج دورة الحياة</string>
<string name="enable_disposed_exceptions_summary">فرض الإبلاغ عن استثناءات Rx غير القابلة للتسليم خارج دورة حياة الجزء أو النشاط بعد التخلص منها</string>
<string name="clear_views_history_title">محو سجل المشاهدة</string>
<string name="clear_views_history_summary">احذف سِجل الفيديوهات التي تم تشغيلها</string>
<string name="delete_view_history_alert">حذف سجل المشاهدة بالكامل\?</string>
@ -409,29 +364,21 @@
<string name="invalid_source">لا يوجد مثل هذا الملف/مصدر المحتوى</string>
<string name="invalid_file">الملف غير موجود أو الإذن بالقراءة أو الكتابة إليه غير موجود</string>
<string name="no_streams_available_download">لا يوجد بث متاح للتنزيل</string>
<string name="one_item_deleted">تم حذف عنصر واحد.</string>
<string name="toast_no_player">لم يتم تثبيت أي تطبيق لتشغيل هذا الملف</string>
<string name="app_license">NewPipe هو برنامج مفتوح المصدر حقوق متروكة: يمكنك استخدام الكود ودراسته وتحسينه كما شئت. و على وجه التحديد يمكنك إعادة توزيعه / أو تعديله تحت شروط رخصة GNU العمومية والتي نشرتها مؤسسة البرمجيات الحرة، سواء الإصدار 3 من الرخصة، أو (باختيارك) أي إصدار جديد.</string>
<string name="app_license">NewPipe هو برنامج مفتوح المصدر و بحقوق متروكة: يمكنك استخدام الكود ودراسته وتحسينه كما شئت. و على وجه التحديد يمكنك إعادة توزيعه / أو تعديله تحت شروط رخصة GNU العمومية والتي نشرتها مؤسسة البرمجيات الحرة، سواء الإصدار 3 من الرخصة، أو (باختيارك) أي إصدار جديد.</string>
<string name="delete_stream_history_prompt">هل تريد حذف هذا العنصر من سجل المشاهدة؟</string>
<string name="delete_all_history_prompt">هل أنت متأكد من أنك تريد حذف كل العناصر من السجل؟</string>
<string name="title_last_played">آخر ما تم تشغيله</string>
<string name="title_most_played">الأكثر تشغيلا</string>
<string name="override_current_data">هذا سوف يُزيل إعداداتك الحالية.</string>
<string name="preferred_open_action_settings_title">طريقة \'التشغيل\' المفضلة</string>
<string name="preferred_open_action_settings_summary">"الإجراء الافتراضي عند فتح المحتوى — %s"</string>
<string name="background_player">مشغل الخلفية</string>
<string name="popup_player">المشغل المنبثق</string>
<string name="previous_export">نسخة احتياطية</string>
<string name="subscriptions_import_unsuccessful">تعذر استيراد الاشتراكات</string>
<string name="subscriptions_export_unsuccessful">لا يمكن تصدير الاشتراكات</string>
<string name="import_youtube_instructions">استيراد اشتراكات YouTube عن طريق تنزيل ملف التصدير:
\n
\n1. انتقل إلى عنوان URL هذا: %1$s
@ -446,13 +393,11 @@
<string name="import_network_expensive_warning">ضع في اعتبارك أن هذه العملية يمكن أن تكون مكلفة اذا كنت تستخدم بيانات اشتراك انترنت.
\n
\nهل تريد الاستمرار؟</string>
<string name="playback_speed_control">ضوابط سرعة التشغيل</string>
<string name="playback_tempo">سرعة الأداء</string>
<string name="playback_pitch">تردد الصوت</string>
<string name="unhook_checkbox">نزع الإرتباط (قد يسبب تشويه)</string>
<string name="import_settings">هل تريد أيضا استيراد الإعدادات؟</string>
<string name="privacy_policy_title">"سياسة الخصوصية في NewPipe "</string>
<string name="privacy_policy_encouragement">يأخذ مشروع NewPipe خصوصيتك على محمل الجد. لذلك ، لا يجمع التطبيق أي بيانات دون موافقتك.
\nتوضح سياسة خصوصية NewPipe بالتفصيل البيانات التي يتم إرسالها وتخزينها عند إرسال تقرير الأعطال.</string>
@ -461,20 +406,17 @@
\nو يجب عليك قبولها لإرسال تقرير الأخطاء إلينا.</string>
<string name="accept">قبول</string>
<string name="decline">رفض</string>
<string name="limit_data_usage_none_description">لا حدود</string>
<string name="limit_mobile_data_usage_title">الحد من جودة الفيديو عند استخدام بيانات الهاتف المحمول</string>
<string name="skip_silence_checkbox">تسريع إلى الأمام أثناء الصمت</string>
<string name="playback_step">خطوة</string>
<string name="playback_reset">إعادة تعيين</string>
<string name="minimize_on_exit_title">تصغير عند تبديل التطبيق</string>
<string name="minimize_on_exit_summary">الإجراء عند التبديل إلى تطبيق آخر من مشغل الفيديو الرئيسي — %s</string>
<string name="minimize_on_exit_none_description">لاشيء</string>
<string name="minimize_on_exit_background_description">تصغير إلى مشغل الخلفية</string>
<string name="minimize_on_exit_popup_description">تصغير إلى مشغل منبثق</string>
<string name="channels">القنوات</string>
<string name="channels">القنوات</string>
<string name="playlists">قوائم التشغيل</string>
<string name="tracks">المسارات</string>
<string name="users">المستخدمين</string>
@ -490,8 +432,8 @@
<string name="volume_gesture_control_title">إيماءة التحكم بالصوت</string>
<string name="events">الأحداث</string>
<string name="app_update_notification_channel_description">التنبيه بإصدارات newpipe الجديدة</string>
<string name="download_to_sdcard_error_title">ذاكرة التخزين الخارجي غير متوفر</string>
<string name="download_to_sdcard_error_message">تحميل إلى بطاقة SD الخارجية ليس متاحا حتى الآن. إعادة تعيين موقع مجلد التحميل؟</string>
<string name="download_to_sdcard_error_title">ذاكرة التخزين الخارجي غير متوفرة</string>
<string name="download_to_sdcard_error_message">التحميل إلى بطاقة الذاكرة الخارجية ليس متاحا حتى الآن. إعادة تعيين موقع مجلد التحميل؟</string>
<string name="saved_tabs_invalid_json">باستخدام علامات الجدولة الافتراضية، حدث خطأ أثناء قراءة علامات التبويب المحفوظة</string>
<string name="restore_defaults">استعادة الافتراضيات</string>
<string name="restore_defaults_confirmation">هل تريد استعادة الإعدادات الافتراضية؟</string>
@ -509,10 +451,10 @@
<string name="app_update_notification_content_title">يتوفر تحديث ل newpipe!</string>
<string name="app_update_notification_content_text">اضغط لتنزيل</string>
<string name="missions_header_finished">انتهى</string>
<string name="missions_header_pending">في قائمة الانتظار</string>
<string name="missions_header_pending">ريثما</string>
<string name="paused">متوقف</string>
<string name="queued">في قائمة الانتظار</string>
<string name="post_processing">بعد المعالجة</string>
<string name="post_processing">قيد المعالجة</string>
<string name="enqueue">قائمة الانتظار</string>
<string name="permission_denied">تم رفضها من قبل النظام</string>
<string name="download_failed">فشل التنزيل</string>
@ -520,12 +462,12 @@
<string name="download_finished_more">%s أنتهى التحميل</string>
<string name="generate_unique_name">إنشاء اسم فريد</string>
<string name="overwrite">الكتابة فوق</string>
<string name="overwrite_warning">يوجد ملف تحميل بهذا الاسم موجود مسبقاً</string>
<string name="overwrite_finished_warning">يوجد ملف تحميل بهذا الاسم موجود مسبقاً</string>
<string name="download_already_running">هنالك تحميل قيد التقدم بهذا الاسم</string>
<string name="show_error">إظهار خطأ</string>
<string name="label_code">كود</string>
<string name="error_path_creation">لا يمكن إنشاء الملف</string>
<string name="error_file_creation">لا يمكن إنشاء المجلد الوجهة</string>
<string name="error_file_creation">لا يمكن إنشاء الملف</string>
<string name="error_path_creation">لا يمكن إنشاء المجلد الوجهة</string>
<string name="error_permission_denied">تم رفضها من قبل النظام</string>
<string name="error_ssl_exception">فشل اتصال الأمن</string>
<string name="error_unknown_host">تعذر العثور على الخادم</string>
@ -535,7 +477,7 @@
<string name="error_http_requested_range_not_satisfiable">عدم استيفاء النطاق المطلوب</string>
<string name="error_http_not_found">غير موجود</string>
<string name="error_postprocessing_failed">فشلت المعالجة الاولية</string>
<string name="clear_finished_download">حذف التنزيل المنتهية</string>
<string name="clear_finished_download">حذف التنزيلات المنتهية</string>
<string name="msg_pending_downloads">"قم بإستكمال %s حيثما يتم التحويل من التنزيلات"</string>
<string name="stop">توقف</string>
<string name="max_retry_msg">أقصى عدد للمحاولات</string>

View File

@ -134,8 +134,6 @@
<string name="later">Más sero</string>
<string name="disabled">Desactivóse</string>
<string name="use_old_player_title">Usar reproductor vieyu</string>
<string name="short_thousand">M</string>
<string name="short_million">Mill</string>
@ -168,8 +166,7 @@
<string name="settings_category_popup_title">Ventanu emerxente</string>
<string name="popup_resizing_indicator_title">Redimensionáu</string>
<string name="use_old_player_summary">Reproductor vieyu integráu de Mediaframework</string>
<string name="subscribe_button_title">Soscribise</string>
<string name="subscribe_button_title">Soscribise</string>
<string name="subscribed_button_title">Soscribiéstite</string>
<string name="channel_unsubscribed">Desoscribiéstite de la canal</string>
<string name="subscription_change_failed">Nun pue camudase la resolución</string>
@ -325,8 +322,7 @@
<string name="video_player">Reproductor de videu</string>
<string name="background_player">Reproductor en segundu planu</string>
<string name="popup_player">Reproductor en ventanu</string>
<string name="always_ask_player">Entrugar siempres</string>
<string name="preferred_player_fetcher_notification_title">Consiguiendo información…</string>
<string name="preferred_player_fetcher_notification_message">Ta cargando\'l conteníu solicitáu</string>
<string name="controls_download_desc">Baxa\'l ficheru del fluxu.</string>

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources><string name="main_bg_subtitle">Націсніце пошук, каб пачаць</string>
<resources>
<string name="main_bg_subtitle">Націсніце пошук, каб пачаць</string>
<string name="view_count_text">%1$s праглядаў</string>
<string name="upload_date_text">Апублікавана %1$s</string>
<string name="no_player_found">Патокавы плэер не знойдзены. Усталяваць VLC?</string>
@ -27,25 +28,19 @@
<string name="subscription_change_failed">Не атрымалася змяніць падпіску</string>
<string name="subscription_update_failed">Не атрымалася абнавіць падпіску</string>
<string name="show_info">Паказаць звесткі</string>
<string name="tab_main">Галоўная</string>
<string name="tab_subscriptions">Падпіскі</string>
<string name="tab_bookmarks">Адзначаныя плэйлісты</string>
<string name="fragment_whats_new">Што новага</string>
<string name="controls_background_title">У фоне</string>
<string name="controls_popup_title">У акне</string>
<string name="controls_add_to_playlist_title">Дадаць да</string>
<string name="download_path_title">Шлях загрузкі відэа</string>
<string name="download_path_summary">Папка для захоўвання загружаных відэа</string>
<string name="download_path_dialog_title">Увядзіце шлях да папкі для загрузкі відэа</string>
<string name="download_path_audio_title">Тэчка загрузкі аўдыё</string>
<string name="download_path_audio_summary">"Сюды захоўваецца загружанае аўдыё "</string>
<string name="download_path_audio_dialog_title">Увядзіце шлях да папкі для загрузкі аўдыё</string>
<string name="autoplay_by_calling_app_title">Аўтапрайграванне</string>
<string name="autoplay_by_calling_app_summary">Прайграваць відэа пры выкліку NewPipe з іншага прыкладання</string>
<string name="default_resolution_title">Разрознянне па змаўчанні</string>
@ -59,8 +54,6 @@
<string name="play_audio">Аўдыё</string>
<string name="default_audio_format_title">Фармат аўдыё па змаўчанні</string>
<string name="default_video_format_title">Фармат відэа па змаўчанні</string>
<string name="webm_description">WebM - свабодны</string>
<string name="m4a_description">M4A - вышэй якасць</string>
<string name="theme_title">Тэма</string>
<string name="light_theme_title">Светлая</string>
<string name="dark_theme_title">Цёмная</string>
@ -136,17 +129,13 @@
<string name="always">Заўсёды</string>
<string name="just_once">Толькі цяпер</string>
<string name="file">Файл</string>
<string name="notification_channel_name">Апавяшчэнне NewPipe</string>
<string name="notification_channel_description">Апавяшчэнні для NewPipe ў фоне і ва ўсплываючым акне</string>
<string name="unknown_content">[Невядома]</string>
<string name="toggle_orientation">Пераключыць арыентацыю</string>
<string name="switch_to_background">Перайсці ў фон</string>
<string name="switch_to_popup">Перайсці ў акно</string>
<string name="switch_to_main">Перайсці ў галоўнае акно</string>
<string name="import_data_title">Імпарт дадзеных</string>
<string name="export_data_title">Экспарт дадзеных</string>
<string name="import_data_summary">Ваша бягучая гісторыя і падпіскі перазапішуцца</string>
@ -185,7 +174,6 @@
<string name="file_name_empty_error">Імя файла не можа быць пустым</string>
<string name="error_occurred_detail">Адбылася памылка: %1$s</string>
<string name="no_streams_available_download">Няма патокаў, даступных для загрузкі</string>
<string name="sorry_string">Прабачце, гэта не павінна было адбыцца.</string>
<string name="error_report_button_text">Адправіць справаздачу па e-mail</string>
<string name="error_snackbar_message">Прабачце, адбыліся памылкі.</string>
@ -195,8 +183,6 @@
<string name="info_labels">Што:\\nЗапыт:\\nМова кантэнту:\\nСэрвіс:\\nЧас па Грынвічы:\\nПакет:\\nВерсія:\\nВерсія АС:</string>
<string name="your_comment">Ваш каментар (English):</string>
<string name="error_details_headline">Падрабязнасці:</string>
<string name="list_thumbnail_view_description">Мініяцюра відэа-прэв\'ю</string>
<string name="detail_thumbnail_view_description">Мініяцюра відэа-прэв\'ю</string>
<string name="detail_uploader_thumbnail_view_description">Мініяцюра аватара карыстальніка</string>
@ -209,42 +195,33 @@
<string name="search_no_results">Няма вынікаў</string>
<string name="empty_subscription_feed_subtitle">Нічога няма</string>
<string name="detail_drag_description">Перацягніце, каб змяніць парадак</string>
<string name="err_dir_create">Не атрымалася стварыць папку для загрузкі \"%1$s\"</string>
<string name="info_dir_created">Створана папка для загрузак \"%1$s\"</string>
<string name="video">Відэа</string>
<string name="audio">Аўдыё</string>
<string name="retry">Паспрабаваць зноў</string>
<string name="storage_permission_denied">Няма доступу да носьбіта</string>
<string name="use_old_player_title">Стары плэер</string>
<string name="use_old_player_summary">Стары убудаваны плэер на Mediaframework</string>
<string name="short_thousand">тыс.</string>
<string name="short_million">млн.</string>
<string name="short_billion">млрд.</string>
<string name="no_subscribers">Няма падпісчыкаў</string>
<plurals name="subscribers">
<item quantity="one">%s падпісчык</item>
<item quantity="few">%s падпісчыка</item>
<item quantity="many">%s падпісчыкаў</item>
</plurals>
<item quantity="one">%s падпісчык</item>
<item quantity="few">%s падпісчыка</item>
<item quantity="many">%s падпісчыкаў</item>
</plurals>
<string name="no_views">Няма праглядаў</string>
<plurals name="views">
<item quantity="one">%s прагляд</item>
<item quantity="few">%s прагляда</item>
<item quantity="many">%s праглядаў</item>
</plurals>
<item quantity="one">%s прагляд</item>
<item quantity="few">%s прагляда</item>
<item quantity="many">%s праглядаў</item>
</plurals>
<string name="no_videos">Няма відэа</string>
<plurals name="videos">
<item quantity="one">%s відэа</item>
<item quantity="few">%s відэа</item>
<item quantity="many">%s відэа</item>
</plurals>
<item quantity="one">%s відэа</item>
<item quantity="few">%s відэа</item>
<item quantity="many">%s відэа</item>
</plurals>
<string name="start">Пачаць</string>
<string name="pause">Паўза</string>
<string name="view">Прайграць</string>
@ -255,10 +232,8 @@
<string name="checksum">Кантрольная сума</string>
<string name="dismiss">Адхіліць</string>
<string name="rename">Перайменаваць</string>
<string name="add">Новая мэта</string>
<string name="finish">ОК</string>
<string name="msg_name">Імя файла</string>
<string name="msg_threads">Патокі</string>
<string name="msg_error">Памылка</string>
@ -273,21 +248,16 @@
<string name="msg_popup_permission">Гэтае разрозненне трэба для
\nпрайгравання ў акне</string>
<string name="one_item_deleted">1 элемент выдалены.</string>
<string name="reCaptchaActivity">reCAPTCHA</string>
<string name="reCaptcha_title">Запыт reCAPTCHA</string>
<string name="recaptcha_request_toast">Запытаны ўвод reCAPTCHA</string>
<string name="settings_category_downloads_title">Загрузкі</string>
<string name="settings_file_charset_title">Дапушчальныя сімвалы назвы файлаў</string>
<string name="settings_file_replacement_character_summary">Недапушчальныя сімвалы замяняюцца на гэтыя</string>
<string name="settings_file_replacement_character_title">Сімвал для замены</string>
<string name="charset_letters_and_digits">Літары і лічбы</string>
<string name="charset_most_special_characters">Большасць спецзнакаў</string>
<string name="toast_no_player">Прыкладанне для прайгравання гэтага файла не ўстаноўлена</string>
<string name="title_activity_about">Аб NewPipe</string>
<string name="action_settings">Налады</string>
<string name="action_about">Аб дадатку</string>
@ -314,8 +284,6 @@
<string name="app_license_title">Ліцэнзія NewPipe</string>
<string name="app_license">NewPipe - свабоднае праграмнае забеспячэнне: вы можаце выкарыстоўваць, вывучаць і паляпшаць яго па сваім меркаванні. У прыватнасці, вы можаце распаўсюджваць і / або змяняць яго ў адпаведнасці з умовамі GNU General Public License, апублікаванай Free Software Foundation, альбо версіі 3, альбо (па вашаму выбару) любой больш позняй версіі.</string>
<string name="read_full_license">Прачытаць ліцэнзію</string>
<string name="title_activity_history">Гісторыя</string>
<string name="title_history_search">Гісторыя пошуку</string>
<string name="title_history_view">Прагледжана</string>
@ -329,7 +297,6 @@
<string name="delete_all_history_prompt">Выдаліць усе элементы з гісторыі?</string>
<string name="title_last_played">Нядаўна прайграныя</string>
<string name="title_most_played">Часта прайграваемыя</string>
<string name="main_page_content">Кантэнт галоўнай старонкі</string>
<string name="blank_page_summary">Пустая старонка</string>
<string name="kiosk_page_summary">Старонка кіёска</string>
@ -345,7 +312,6 @@
<string name="could_not_import_all_files">Увага: не ўсе файлы былі імпартаваныя.</string>
<string name="override_current_data">Бягучыя дадзеныя будуць замененыя.</string>
<string name="import_settings">Хочаце імпартаваць налады?</string>
<string name="kiosk">Кіёск</string>
<string name="trending">Трэнды</string>
<string name="top_50">Топ 50</string>
@ -357,74 +323,55 @@
<string name="play_queue_audio_settings">Налады аўдыё</string>
<string name="hold_to_append">Зацісніце, каб дадаць у чаргу</string>
<string name="enqueue_on_background">У чаргу \"У фоне\"</string>
<string name="enqueue_on_popup">У чаргу \"У фоне\"</string>
<string name="enqueue_on_popup">У чаргу \"У акне\"</string>
<string name="start_here_on_main">Відэаплэер</string>
<string name="start_here_on_background">Фонавы плэер</string>
<string name="start_here_on_popup">Плэер у акне</string>
<string name="drawer_open">Адкрыць бакавую панэль</string>
<string name="drawer_close">Зачыніць бакавую панэль</string>
<string name="drawer_header_action_paceholder_text">Хутка тут сёе-тое з\'явіцца ;D</string>
<string name="preferred_open_action_settings_title">Пры адкрыцці кантэнту</string>
<string name="preferred_open_action_settings_summary">Пры адкрыцці спасылкі на кантэнт — %s</string>
<string name="video_player">Відэаплэер</string>
<string name="background_player">Фонавы плэер</string>
<string name="popup_player">Плэер у акне</string>
<string name="always_ask_open_action">Заўсёды пытацца</string>
<string name="preferred_player_fetcher_notification_title">Атрыманне звестак…</string>
<string name="preferred_player_fetcher_notification_message">Загрузка запытанага кантэнту</string>
<string name="create_playlist">Стварыць плэйліст</string>
<string name="delete_playlist">Выдаліць плэйліст</string>
<string name="rename_playlist">Перайменаваць плэйліст</string>
<string name="playlist_name_input">Імя</string>
<string name="append_playlist">Дадаць у плэйліст</string>
<string name="set_as_playlist_thumbnail">На мініяцюру плэйліста</string>
<string name="bookmark_playlist">Дадаць плэйліст у закладкі</string>
<string name="unbookmark_playlist">Выдаліць закладку</string>
<string name="delete_playlist_prompt">Выдаліць гэты плэйліст?</string>
<string name="playlist_creation_success">Плэйліст створаны</string>
<string name="playlist_add_stream_success">Дададзена ў плэйліст</string>
<string name="playlist_thumbnail_change_success">Мініяцюра плэйліста зменена</string>
<string name="playlist_delete_failure">Не атрымалася выдаліць плэйліст</string>
<string name="caption_none">Без тытраў</string>
<string name="resize_fit">Падагнаць</string>
<string name="resize_fill">Запоўніць</string>
<string name="resize_zoom">Наблізіць</string>
<string name="caption_auto_generated">Створаны аўтаматычна</string>
<string name="caption_setting_title">Тытры</string>
<string name="caption_setting_description">Змяніць памер і фон тытраў. Змены ўступяць у сілу пасля перазапуску</string>
<string name="enable_leak_canary_title">Уключыць LeakCanary</string>
<string name="enable_leak_canary_summary">Маніторынг уцечкі памяці можа прывесці да завісання прыкладання</string>
<string name="enable_disposed_exceptions_title">Паведамляць пра памылкі жыццёвага цыклу</string>
<string name="enable_disposed_exceptions_summary">Прымусова паведамляць пра недастаўляемыя Rx-выключэнні па-за фрагментам або жыццёвым цыкле пасля выдалення</string>
<string name="import_export_title">Імпарт/Экспарт</string>
<string name="import_title">Імпарт</string>
<string name="import_from">Імпарт з</string>
<string name="export_to">Экспарт у</string>
<string name="import_ongoing">Імпарт…</string>
<string name="export_ongoing">Экспарт…</string>
<string name="import_file_title">Імпарт файла</string>
<string name="previous_export">Папярэдні экспарт</string>
<string name="subscriptions_import_unsuccessful">Не атрымалася імпартаваць падпіскі</string>
<string name="subscriptions_export_unsuccessful">Не атрымалася экспартаваць падпіскі</string>
<string name="import_youtube_instructions">Імпарт падпісак з YouTube загрузкай файла экспарту:
\n
\n1. Перайдзіце на: %1$s
@ -437,11 +384,9 @@
\n3. Увайдзіце, калі неабходна
\n4. Скапіруйце адрас з адраснага радка.</string>
<string name="import_soundcloud_instructions_hint">вашID, soundcloud.com/вашID</string>
<string name="import_network_expensive_warning">Гэтае дзеянне можа выклікаць вялікі расход трафіку.
\n
\nПрацягнуць?</string>
<string name="playback_speed_control">Кіраванне хуткасцю прайгравання</string>
<string name="playback_tempo">Тэмп</string>
<string name="playback_pitch">Тон</string>
@ -449,12 +394,10 @@
<string name="skip_silence_checkbox">Прапускаць цішыню</string>
<string name="playback_step">Крок</string>
<string name="playback_reset">Скід</string>
<string name="start_accept_privacy_policy">У адпаведнасці з Агульным рэгламентам па абароне дадзеных ЕС (GDPR), звяртаем вашу ўвагу на палітыку прыватнасці NewPipe. Калі ласка, уважліва азнаёмцеся з ёй.
\nВам неабходна прыняць яе ўмовы, каб адправіць нам справаздачу пра памылку.</string>
<string name="accept">Прыняць</string>
<string name="decline">Адмовіцца</string>
<string name="limit_data_usage_none_description">Без абмежаванняў</string>
<string name="limit_mobile_data_usage_title">Ліміт разрознення ў мабільнай сетцы</string>
<string name="minimize_on_exit_title">Пры згортванні плэера</string>
@ -462,5 +405,5 @@
<string name="minimize_on_exit_none_description">Нічога не рабіць</string>
<string name="minimize_on_exit_background_description">Фонавы плэер</string>
<string name="minimize_on_exit_popup_description">Плэер у акне</string>
<string name="unsubscribe">Адпісацца</string>
</resources>

View File

@ -156,8 +156,6 @@
<string name="audio">Аудио</string>
<string name="retry">Опитай отново</string>
<string name="storage_permission_denied">Достъпа до хранилището е отказан</string>
<string name="use_old_player_title">Използвай стария плейър</string>
<string name="use_old_player_summary">Използваю стария вграден Mediaframewoek плейър</string>
<plurals name="subscribers">
<item quantity="one">%s абонат</item>

View File

@ -1,4 +1,4 @@
<?xml version='1.0' encoding='UTF-8'?>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="main_bg_subtitle">শুরু করতে অনুসন্ধান এ আলতো চাপ</string>
<string name="view_count_text">%1$s বার দেখা হয়েছে</string>
@ -8,30 +8,26 @@
<string name="cancel">"বাদ দিন "</string>
<!-- <string name="fdroid_vlc_url" translatable="false">https://f-droid.org/repository/browse/?fdfilter=vlc&amp;fdid=org.videolan.vlc</string> -->
<string name="open_in_browser">"ব্রাউজারে ওপেন করো "</string>
<string name="open_in_popup_mode">"popup মোডে Open করো "</string>
<string name="open_in_popup_mode">"পপ-আপ মোডে ওপেন করো "</string>
<string name="share">শেয়ার</string>
<string name="download">ডাউনলোড</string>
<string name="search">োঁজ</string>
<string name="settings">"সেটিংস "</string>
<string name="download">ডাউনলো</string>
<string name="search">ুঁজুন</string>
<string name="settings">সেটিংস</string>
<string name="did_you_mean">আপনি কি বুঝিয়েছেনঃ %1$s ?</string>
<string name="share_dialog_title">শেয়ার কর</string>
<string name="choose_browser">ব্রাউজার পছন্দ কর</string>
<string name="share_dialog_title">শেয়ার করুন</string>
<string name="choose_browser">ব্রাউজার বাছাই করুন</string>
<string name="screen_rotation">রোটেশন</string>
<string name="use_external_video_player_title">বাহ্যিক ভিডিও প্লেয়ার ব্যবহার করো</string>
<string name="use_external_audio_player_title">াহ্যিক অডিও প্লেয়ার ব্যবহার করো</string>
<string name="use_external_video_player_title">বাইরের ভিডিও প্লেয়ার ব্যবহার করুন</string>
<string name="use_external_audio_player_title">হির্গত অডিও প্লেয়ার ব্যবহার করুন</string>
<string name="popup_mode_share_menu_title">NewPipe পপআপ মোড</string>
<string name="controls_background_title">ব্যাকগ্রাউন্ড</string>
<string name="controls_popup_title">পপআপ</string>
<string name="download_path_title">ভিডিও ডাউনলোড করার পাথ</string>
<string name="download_path_summary">ডাউনলোড করা ভিডিওগুলো রাখার ফোল্ডার</string>
<string name="download_path_dialog_title">ভিডিওগুলির জন্য ডাউনলোডের পাথ প্রবেশ করাও</string>
<string name="download_path_audio_title">অডিও ডাউনলোড পাথ</string>
<string name="download_path_audio_summary">ডাউনলোড করা অডিও সঞ্চয় করার পাথ</string>
<string name="download_path_audio_dialog_title">অডিও ফাইলগুলির জন্য ডাউনলোডের পাথ প্রবেশ করাও</string>
<string name="autoplay_by_calling_app_title">স্বয়ংক্রিয়ভাবে প্লে করো যখন অন্য অ্যাপ্লিকেশন থেকে চালু করা হয়</string>
<string name="autoplay_by_calling_app_summary">স্বয়ংক্রিয়ভাবে একটি ভিডিও প্লে করো যখন NewPipe অন্য অ্যাপ্লিকেশন থেকে চালু করা হয়।</string>
<string name="default_resolution_title">ডিফল্ট রেজোল্যুশন</string>
@ -52,7 +48,6 @@
<string name="black_theme_title">কালো</string>
<string name="popup_remember_size_pos_title">পপআপ আকার এবং অবস্থান মনে রাখো</string>
<string name="popup_remember_size_pos_summary">শেষ আকার এবং পপআপ সেট অবস্থান মনে রাখো</string>
<string name="download_dialog_title">ডাউনলোড</string>
<string name="next_video_title">পরবর্তী ভিডিও</string>
<string name="show_next_and_similar_title">পরবর্তী এবং অনুরূপ ভিডিওগুলি দেখাও</string>
@ -83,7 +78,6 @@
<string name="refresh">রিফ্রেশ</string>
<string name="clear">পরিষ্কার</string>
<string name="popup_resizing_indicator_title">আকার পরিবর্তন</string>
<!-- error strings -->
<string name="general_error">ত্রুটি</string>
<string name="network_error">নেটওয়ার্ক ত্রুটি</string>
@ -108,8 +102,6 @@
<string name="what_happened_headline">কি হয়েছিল:</string>
<string name="your_comment">তোমার মন্তব্য (ইংরেজিতে):</string>
<string name="error_details_headline">বর্ণনা:</string>
<!-- Content descriptions (for better accessibility) -->
<string name="list_thumbnail_view_description">ভিডিও প্রাকদর্শন থাম্বনেইল</string>
<string name="detail_thumbnail_view_description">ভিডিও প্রাকদর্শন থাম্বনেইল</string>
@ -120,34 +112,24 @@
<string name="use_tor_summary">(পরীক্ষামূলক) গোপনীয়তা বর্ধিত করতে টর এর মাধ্যমে ডাউনলোড ট্রাফিক জোরপুর্বক পাঠাও (ভিডিওগুলি স্ট্রিমিং এ সমর্থিত নয়)।</string>
<string name="report_error">একটি ত্রুটি রিপোর্ট করো</string>
<string name="user_report">ব্যবহারকারীর প্রতিবেদন</string>
<string name="err_dir_create">\'%1$s\' ডাউনলোড ডিরেক্টরি তৈরি করতে পারছে না</string>
<string name="info_dir_created">\'%1$s\' ডাউনলোড ডিরেক্টরি তৈরি করা হয়েছে</string>
<string name="video">ভিডিও</string>
<string name="audio">অডিও</string>
<string name="retry">পুনরায় চেষ্টা করো</string>
<string name="storage_permission_denied">স্টোরেজ অ্যাক্সেস করার অনুমতি অস্বীকার করা হয়েছে</string>
<string name="use_old_player_title">পুরানো প্লেয়ার ব্যবহার করো</string>
<string name="use_old_player_summary">মিডিয়াফ্রেমওয়ার্ক প্লেয়ারের পুরানো বিল্ড।</string>
<string name="short_thousand">K</string>
<string name="short_million">M</string>
<string name="short_billion">B</string>
<!-- Missions -->
<string name="start">শুরু</string>
<string name="pause">বিরতি</string>
<string name="view">প্রদর্শন</string>
<string name="delete">ডিলেট</string>
<string name="checksum">চেকসাম</string>
<!-- Fragment -->
<string name="add">নতুন মিশন</string>
<string name="finish">ঠিক আছে</string>
<!-- Msg -->
<string name="msg_name">ফাইলের নাম</string>
<string name="msg_threads">থ্রেড</string>
@ -161,24 +143,18 @@
<string name="msg_copied">ক্লিপবোর্ডে অনুলিপি করা হয়েছে।</string>
<string name="no_available_dir">অনুগ্রহ করে একটি উপলব্ধ ডাউনলোড ডিরেক্টরি নির্বাচন করো।</string>
<string name="msg_popup_permission">এই অনুমতিটি পপআপ মোডে খুলতে প্রয়োজন</string>
<!-- Checksum types -->
<!-- <string name="md5" translatable="false">MD5</string> -->
<!-- <string name="sha1" translatable="false">SHA1</string> -->
<string name="reCaptchaActivity">রিক্যাপচা</string>
<string name="reCaptcha_title">reCAPTCHA চ্যালেঞ্জ</string>
<string name="recaptcha_request_toast">reCAPTCHA চ্যালেঞ্জ অনুরোধ করা হয়েছে</string>
<!-- End of GigaGet's Strings -->
<string name="info_labels">কি:\\nঅনুরোধ:\\nকন্টেন্ট ভাষা:\\nসার্ভিস:\\nসময়(GMT এ):\\nপ্যাকেজ:\\nসংস্করণ:\\nওএস সংস্করণ:\\nআইপি পরিসর:</string>
<string name="controls_download_desc">Stream file ডাউনলোড করুন।</string>
<string name="show_info">তথ্য দেখান</string>
<string name="controls_download_desc">স্ট্রিম ফাইল ডাউনলোড করুন।</string>
<string name="show_info">তথ্য দেখুন</string>
<string name="fragment_whats_new">কি নতুন</string>
<string name="controls_add_to_playlist_title">যুক্ত করুন</string>
<string name="enable_search_history_title">খোজ ইতিহাস</string>
<string name="enable_watch_history_title">ইতিহাস</string>
<string name="service_title">সেবা</string>
@ -189,25 +165,23 @@
<string name="playlist">প্লেলিস্ট</string>
<string name="always">সবসময়</string>
<string name="just_once">একবার মাত্র</string>
<string name="unknown_content">[অজানা]</string>
<string name="no_views">কোন ভিউ নেই</string>
<string name="rename">নাম পরিবর্তন করুন</string>
<string name="action_settings">সেটিংস</string>
<string name="action_open_website">ওয়েব সাইট খুলুন</string>
<string name="website_title">ওয়েব সাইট</string>
<string name="no_player_found_toast">"কোন স্ট্রিম প্লেয়ার পাওয়া যায়নি (প্লে করতে VLC ইন্সটল করতে পারেন) "</string>
<string name="use_external_video_player_summary">যদি এই অপশন অন থাকে তবে কিছু ভিডিওর অডিও কাজ নাও করতে পারে</string>
<string name="no_player_found_toast">কোন স্ট্রিম প্লেয়ার পাওয়া যায়নি (প্লে করতে VLC ইন্সটল করতে পারেন)</string>
<string name="use_external_video_player_summary">কিছু রেজোলিউশনে ভিডিওর অডিও কাজ করে না</string>
<string name="subscribe_button_title">সাবস্ক্রাইব</string>
<string name="subscribed_button_title">সাবস্ক্রাইব করা আছে</string>
<string name="channel_unsubscribed">চ্যানেল সাবস্ক্রাইব করা হয়েছে</string>
<string name="subscription_change_failed">সাবস্ক্রিপশন পরিবর্তন করা য়নি</string>
<string name="subscription_update_failed">সাবস্ক্রিপশন আপডেট করতে ব্যার্থ হয়েছে</string>
<string name="channel_unsubscribed">চ্যানেল থেকে আনসাবস্ক্রাইব্ড</string>
<string name="subscription_change_failed">সাবস্ক্রিপশন পরিবর্তন করা যায়নি</string>
<string name="subscription_update_failed">সাবস্ক্রিপশন আপডেটে ব্যার্থ</string>
<string name="tab_main">প্রধান</string>
<string name="tab_subscriptions">সাবস্ক্রিপশন</string>
<string name="tab_bookmarks">বুকমার্কস</string>
<string name="tab_bookmarks">বুকমার্ককৃত প্লেলিস্টসমূহ</string>
<string name="use_inexact_seek_title">দ্রুত টানা ব্যাবহার করুন</string>
</resources>
<string name="unsubscribe">আনসাবস্ক্রাইব</string>
<string name="tab_new">নতুন ট্যাব</string>
</resources>

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources><string name="install">Instal·la</string>
<resources>
<string name="install">Instal·la</string>
<string name="cancel">Cancel·la</string>
<string name="open_in_browser">Obre al navegador</string>
<string name="share">Comparteix</string>
@ -10,12 +11,9 @@
<string name="subscribe_button_title">Subscriu-t\'hi</string>
<string name="subscribed_button_title">Subscrit</string>
<string name="show_info">Mostra la informació</string>
<string name="tab_subscriptions">Subscripcions</string>
<string name="tab_bookmarks">Llistes de reproducció desades</string>
<string name="fragment_whats_new">Novetats</string>
<string name="download_path_title">Ruta de baixada dels vídeos</string>
<string name="download_path_audio_title">Carpeta de baixada dels fitxers d\'àudio</string>
<string name="autoplay_by_calling_app_title">Reproducció automàtica</string>
@ -39,7 +37,7 @@
<string name="settings_category_debug_title">Depuració</string>
<string name="content">Contingut</string>
<string name="show_age_restricted_content_title">Desactiva les restriccions per edat</string>
<string name="video_is_age_restricted">Vídeo restringit per edat. Podeu permetre aquesta mena de continguts des de la configuració.</string>
<string name="video_is_age_restricted">Mostra el vídeo restringit per edat. Podeu permetre aquesta mena de continguts des de la configuració.</string>
<string name="duration_live">EN DIRECTE</string>
<string name="downloads">Baixades</string>
<string name="downloads_title">Baixades</string>
@ -54,9 +52,7 @@
<string name="always">Sempre</string>
<string name="just_once">Només una vegada</string>
<string name="file">Fitxer</string>
<string name="unknown_content">[Desconegut]</string>
<string name="import_data_title">Importa una base de dades</string>
<string name="export_data_title">Exporta una base de dades</string>
<string name="export_data_summary">Exporta l\'historial, les subscripcions i les llistes de reproducció</string>
@ -65,12 +61,10 @@
<string name="video">Vídeo</string>
<string name="audio">Àudio</string>
<plurals name="subscribers">
<item quantity="one">%s subscriptor</item>
<item quantity="other">%s subscriptors</item>
</plurals>
<item quantity="one">%s subscriptor</item>
<item quantity="other">%s subscriptors</item>
</plurals>
<string name="finish">D\'acord</string>
<string name="msg_name">Nom de fitxer</string>
<string name="msg_error">Error</string>
<string name="reCaptchaActivity">reCAPTCHA</string>
@ -87,8 +81,6 @@
<string name="website_title">Lloc web</string>
<string name="app_license_title">Llicència del NewPipe</string>
<string name="read_full_license">Llegeix la llicència</string>
<string name="title_activity_history">Historial</string>
<string name="history_disabled">L\'historial està desactivat</string>
<string name="action_history">Historial</string>
@ -111,7 +103,6 @@
<string name="background_player">Reproductor en segon pla</string>
<string name="popup_player">Reproductor emergent</string>
<string name="always_ask_open_action">Demana-ho sempre</string>
<string name="create_playlist">Crea una llista de reproducció</string>
<string name="delete_playlist">Elimina</string>
<string name="rename_playlist">Canvia el nom</string>
@ -120,13 +111,11 @@
<string name="import_title">Importa</string>
<string name="import_from">Importa des de</string>
<string name="export_to">Exporta a</string>
<string name="import_ongoing">S\'està important…</string>
<string name="export_ongoing">S\'està exportant…</string>
<string name="import_file_title">Importa un fitxer</string>
<string name="playback_default">Per defecte</string>
<string name="view_count_text">%1$s reproduccions</string>
<string name="view_count_text">%1$s reproduccions</string>
<string name="upload_date_text">Publicat el %1$s</string>
<string name="no_player_found">No s\'ha trobat un reproductor de fluxos. Voleu instal·lar el VLC?</string>
<string name="no_player_found_toast">No s\'ha trobat cap reproductor de fluxos (podeu instal·lar el VLC per reproduir-lo).</string>
@ -144,13 +133,10 @@
<string name="controls_background_title">Segon pla</string>
<string name="controls_popup_title">Emergent</string>
<string name="controls_add_to_playlist_title">Afegeix a</string>
<string name="download_path_summary">Ruta on es desaran els vídeos baixats</string>
<string name="download_path_dialog_title">Introduïu una ruta de baixada per als vídeos</string>
<string name="download_path_audio_summary">Els fitxers d\'àudio baixats es desaran aquí</string>
<string name="download_path_audio_dialog_title">Introduïu una ruta de baixada per als fitxers d\'àudio</string>
<string name="autoplay_by_calling_app_summary">Reprodueix un vídeo quan el NewPipe s\'executa des d\'una altra aplicació</string>
<string name="default_popup_resolution_title">Resolució per defecte del mode emergent</string>
<string name="show_higher_resolutions_title">Mostra resolucions superiors</string>
@ -186,7 +172,6 @@
<string name="play_btn_text">Reprodueix</string>
<string name="notification_channel_name">Notificació del NewPipe</string>
<string name="notification_channel_description">Notificacions dels reproductors en segon pla o emergents del NewPipe</string>
<string name="could_not_load_thumbnails">No s\'han pogut carregar totes les miniatures</string>
<string name="youtube_signature_decryption_error">No s\'ha pogut desencriptar la signatura de l\'URL del vídeo</string>
<string name="parsing_error">No s\'ha pogut processar el lloc web</string>
@ -216,8 +201,6 @@
<string name="what_happened_headline">Què ha passat:</string>
<string name="your_comment">Comentari (en anglès):</string>
<string name="error_details_headline">Detalls:</string>
<string name="list_thumbnail_view_description">Miniatura de previsualització del vídeo</string>
<string name="detail_thumbnail_view_description">Miniatura de previsualització del vídeo</string>
<string name="detail_uploader_thumbnail_view_description">Miniatura de l\'avatar del propietari</string>
@ -231,25 +214,19 @@
<string name="empty_subscription_feed_subtitle">No hi ha res aquí</string>
<string name="err_dir_create">No s\'ha pogut crear el directori de baixades «%1$s»</string>
<string name="info_dir_created">S\'ha creat el directori de baixades «%1$s»</string>
<string name="retry">Torna a intentar-ho</string>
<string name="storage_permission_denied">S\'ha denegat el permís d\'accés a l\'emmagatzematge</string>
<string name="use_old_player_title">Fes servir el reproductor antic</string>
<string name="use_old_player_summary">Antic reproductor integrat de Mediaframework</string>
<string name="no_subscribers">Sense subscriptors</string>
<string name="no_views">Sense reproduccions</string>
<plurals name="views">
<item quantity="one">%s reproducció</item>
<item quantity="other">%s reproduccions</item>
</plurals>
<item quantity="one">%s reproducció</item>
<item quantity="other">%s reproduccions</item>
</plurals>
<string name="no_videos">Sense vídeos</string>
<plurals name="videos">
<item quantity="one">%s vídeo</item>
<item quantity="other">%s vídeos</item>
</plurals>
<item quantity="one">Vídeo</item>
<item quantity="other">Vídeos</item>
</plurals>
<string name="pause">Pausa</string>
<string name="view">Reprodueix</string>
<string name="create">Crea</string>
@ -259,7 +236,6 @@
<string name="checksum">Suma de verificació</string>
<string name="dismiss">Tanca</string>
<string name="rename">Canvia el nom</string>
<string name="msg_threads">Fils</string>
<string name="msg_server_unsupported">Servidor incompatible</string>
<string name="msg_exists">El fitxer ja existeix</string>
@ -276,7 +252,6 @@
<string name="website_encouragement">Per a més informació i notícies, visiteu el nostre lloc web.</string>
<string name="title_last_played">Última reproducció</string>
<string name="title_most_played">Més reproduïts</string>
<string name="kiosk_page_summary">Pàgina d\'un quiosc</string>
<string name="feed_page_summary">Pàgina de novetats</string>
<string name="channel_page_summary">Pàgina d\'un canal</string>
@ -284,7 +259,6 @@
<string name="no_valid_zip_file">El fitxer no té un format ZIP vàlid</string>
<string name="could_not_import_all_files">Avís: No s\'han pogut importar tots els fitxers.</string>
<string name="override_current_data">Això sobreescriurà la configuració actual.</string>
<string name="kiosk">Quiosc</string>
<string name="trending">Tendències</string>
<string name="top_50">Els millors 50</string>
@ -297,10 +271,8 @@
<string name="drawer_close">Tanca el calaix</string>
<string name="preferred_player_fetcher_notification_title">S\'està obtenint la informació…</string>
<string name="preferred_player_fetcher_notification_message">S\'està carregant el contingut seleccionat</string>
<string name="delete_playlist_prompt">Voleu eliminar aquesta llista de reproducció?</string>
<string name="playlist_delete_failure">No s\'ha pogut eliminar la llista de reproducció.</string>
<string name="import_export_title">Importació i exportació</string>
<string name="playback_speed_control">Controls de la velocitat de reproducció</string>
<string name="playback_tempo">Tempo</string>
@ -323,31 +295,24 @@
<string name="switch_to_background">Canvia al mode en segon pla</string>
<string name="switch_to_popup">Canvia al mode emergent</string>
<string name="switch_to_main">Canvia al mode principal</string>
<string name="import_data_summary">Sobreescriu l\'historial i les subscripcions actuals</string>
<string name="player_recoverable_failure">S\'està recuperant el reproductor després de l\'error</string>
<string name="sorry_string">Ho sentim, això no hauria d\'haver ocorregut.</string>
<string name="detail_drag_description">Arrossegueu per a reordenar la llista</string>
<string name="short_thousand">mil</string>
<string name="short_million">milions</string>
<string name="short_billion">mil milions</string>
<string name="start">Inicia</string>
<string name="add">Nova missió</string>
<string name="msg_url_malform">L\'URL té un format incorrecte o no hi ha connexió a internet</string>
<string name="msg_running_detail">Toqueu aquí per a més detalls</string>
<string name="no_available_dir">Trieu una carpeta de baixades disponible</string>
<string name="msg_popup_permission">Es necessita aquest permís per a obrir el mode emergent</string>
<string name="reCaptcha_title">Camp reCAPTCHA</string>
<string name="recaptcha_request_toast">S\'ha sol·licitat l\'emplenament d\'un camp reCAPTCHA</string>
<string name="settings_file_replacement_character_summary">Se substituiran els caràcters no vàlids amb aquest valor</string>
<string name="settings_file_replacement_character_title">Caràcter de substitució</string>
<string name="charset_most_special_characters">Principals caràcters especials</string>
<string name="contribution_encouragement">Ja siguin idees, traduccions, canvis en el disseny, una neteja del codi o canvis importants de programació, la vostra ajuda sempre és benvinguda. Com més feina feta hi hagi, millor!</string>
<string name="donation_encouragement">El NewPipe està desenvolupat per voluntaris que fan servir el seu temps lliure per a oferir-vos la millor experiència possible. Feu una aportació per assegurar que els nostres desenvolupadors puguin millorar encara més el NewPipe mentre fan un cafè.</string>
<string name="give_back">Fes la teva aportació</string>
@ -358,33 +323,25 @@
<string name="hold_to_append">Manteniu premut per afegir a la cua</string>
<string name="start_here_on_background">Reprodueix aquí en segon pla</string>
<string name="start_here_on_popup">Reprodueix aquí en mode emergent</string>
<string name="set_as_playlist_thumbnail">Defineix com a miniatura de la llista de reproducció</string>
<string name="bookmark_playlist">Afegeix la llista de reproducció a les adreces d\'interès</string>
<string name="unbookmark_playlist">Elimina l\'adreça d\'interès</string>
<string name="playlist_creation_success">S\'ha creat la llista de reproducció</string>
<string name="playlist_add_stream_success">S\'ha afegit a la llista de reproducció</string>
<string name="playlist_thumbnail_change_success">S\'ha canviat la miniatura de la llista de reproducció.</string>
<string name="caption_none">Sense subtítols</string>
<string name="resize_fit">Ajusta</string>
<string name="resize_fill">Omple</string>
<string name="resize_zoom">Escala</string>
<string name="caption_auto_generated">Generats automàticament</string>
<string name="caption_font_size_settings_title">Mida dels subtítols</string>
<string name="smaller_caption_font_size">Mida més petita</string>
<string name="normal_caption_font_size">Mida normal</string>
<string name="larger_caption_font_size">Mida més gran</string>
<string name="enable_leak_canary_title">Habilita el LeakCanary</string>
<string name="previous_export">Darrera exportació</string>
<string name="subscriptions_import_unsuccessful">No s\'han pogut importar les subscripcions</string>
<string name="subscriptions_export_unsuccessful">No s\'han pogut exportar les subscripcions</string>
<string name="unhook_checkbox">Desvincula (pot provocar distorsió)</string>
<string name="playback_nightcore">Nightcore</string>
<string name="metadata_cache_wipe_summary">Elimina totes les dades de llocs web de la memòria cau</string>
@ -393,16 +350,11 @@
<string name="show_hold_to_append_summary">Mostra un missatge d\'ajuda quan el botó de mode en segon pla o emergent estigui premut a la pàgina de detalls d\'un vídeo</string>
<string name="info_labels">Què ha passat:\\nPetició:\\nIdioma del contingut:\\nServei:\\nHora GMT:\\nPaquet:\\nVersió:\\nVersió del SO:</string>
<string name="drawer_header_action_paceholder_text">Aviat hi haurà novetats aquí ;D</string>
<string name="preferred_open_action_settings_title">Acció d\'obertura preferida</string>
<string name="preferred_open_action_settings_summary">Acció per defecte en obrir continguts — %s</string>
<string name="enable_leak_canary_summary">"La supervisió de fugues de memòria pot fer que l\'aplicació deixi de respondre mentre es bolca la memòria "</string>
<string name="enable_disposed_exceptions_title">Informa d\'errors fora del cicle de vida</string>
<string name="enable_disposed_exceptions_summary">Força l\'informe d\'excepcions Rx que no es puguin transmetre que tinguin lloc fora del cicle de vida d\'un fragment o activitat després de disposar-los</string>
<string name="import_youtube_instructions">Importeu les vostres subscripcions de YouTube mitjançant el fitxer d\'exportació:
\n
\n1. Aneu a aquesta URL: %1$s
@ -415,18 +367,13 @@
\n3. Inicieu sessió al vostre compte quan se us demani
\n4. Copieu l\'URL de la pàgina on se us redireccioni</string>
<string name="import_soundcloud_instructions_hint">identificador, soundcloud.com/identificador</string>
<string name="import_network_expensive_warning">Tingueu en compte que això pot comportar un ús intensiu de la xarxa.
\n
\nVoleu continuar?</string>
<string name="no_streams_available_download">No hi ha vídeos que es puguin baixar</string>
<string name="caption_setting_title">Subtítols</string>
<string name="caption_setting_description">Modifica la mida del text i el fons dels subtítols. Cal reiniciar l\'aplicació per aplicar els canvis.</string>
<string name="toast_no_player">No s\'ha trobat cap aplicació que pugui reproduir aquest fitxer</string>
<string name="clear_views_history_title">Esborra l\'historial de reproduccions</string>
<string name="clear_views_history_summary">Esborra l\'historial dels vídeos que s\'han reproduït</string>
<string name="delete_view_history_alert">Voleu esborrar tot l\'historial de reproduccions\?</string>
@ -436,10 +383,8 @@
<string name="delete_search_history_alert">Voleu esborrar tot l\'historial de cerca\?</string>
<string name="search_history_deleted">S\'ha esborrat l\'historial de cerca.</string>
<string name="one_item_deleted">S\'ha esborrat 1 element.</string>
<string name="app_license">NewPipe és programari lliure sota llicència copyleft: podeu fer-lo servir, estudiar-lo, compartir-lo i millorar-lo al vostre gust. En concret, podeu redistribuir-lo i/o modificar-lo d\'acord amb els termes de la llicència GNU GPL publicada per la Free Software Foundation, ja sigui la versió 3 o (segons vulgueu) qualsevol altra versió posterior.</string>
<string name="import_settings">Voleu importar també la configuració?</string>
<string name="privacy_policy_title">Política de privacitat del NewPipe</string>
<string name="privacy_policy_encouragement">El projecte NewPipe es pren molt seriosament la vostra privacitat. Per aquesta raó, l\'aplicació no emmagatzema cap mena de dades sense el vostre consentiment.
\nLa política de privacitat del NewPipe descriu detalladament quines dades s\'envien i s\'emmagatzemen quan envieu un informe d\'error.</string>
@ -448,18 +393,16 @@
\nSi voleu enviar-nos un informe d\'error, l\'haureu d\'acceptar.</string>
<string name="accept">Accepta</string>
<string name="decline">Rebutja</string>
<string name="limit_data_usage_none_description">Sense restriccions</string>
<string name="limit_data_usage_none_description">Sense restriccions</string>
<string name="limit_mobile_data_usage_title">Restringeix la resolució quan es facin servir dades mòbils</string>
<string name="minimize_on_exit_title">Minimitza en canviar d\'aplicació</string>
<string name="minimize_on_exit_summary">Acció en canviar a una altra aplicació des del reproductor de vídeo principal — %s</string>
<string name="minimize_on_exit_none_description">Cap</string>
<string name="minimize_on_exit_background_description">Minimitza al reproductor en segon pla</string>
<string name="minimize_on_exit_popup_description">Minimitza al reproductor emergent</string>
<string name="skip_silence_checkbox">Avança ràpid durant el silenci</string>
<string name="skip_silence_checkbox">Avança ràpid durant el silenci</string>
<string name="playback_step">Pas</string>
<string name="playback_reset">Reinicialitza</string>
<string name="channels">Canals</string>
<string name="playlists">Llistes de reproducció</string>
<string name="tracks">Pistes</string>
@ -482,14 +425,37 @@
<string name="auto">Automàtic</string>
<string name="switch_view">Canvia la vista</string>
<string name="app_update_notification_content_title">Està disponible una nova actualització del NewPipe!</string>
<string name="missions_header_pending">A la cua</string>
<string name="missions_header_pending">Pendent</string>
<string name="paused">en pausa</string>
<string name="queued">a la cua</string>
<string name="enqueue">Afegeix a la cua</string>
<string name="generate_unique_name">Genera un nom únic</string>
<string name="show_error">Mostra l\'error</string>
<string name="label_code">Codi</string>
<string name="error_path_creation">No es pot crear el fitxer</string>
<string name="error_file_creation">No es pot crear la carpeta de destinació</string>
<string name="error_file_creation">No es pot crear el fitxer</string>
<string name="error_path_creation">No es pot crear la carpeta de destinació</string>
<string name="stop">Atura</string>
<string name="events">Esdeveniments</string>
<string name="app_update_notification_channel_description">Notificacions de noves versions del NewPipe</string>
<string name="subscribers_count_not_available">El nombre de subscriptors no està disponible</string>
<string name="main_page_content_summary">Quines pestanyes es mostren a la pàgina principal</string>
<string name="conferences">Conferències</string>
<string name="list_view_mode">Mode de vista de llista</string>
<string name="missions_header_finished">Finalitzades</string>
<string name="post_processing">post-processament</string>
<string name="download_failed">Ha fallat la baixada</string>
<string name="download_finished">Baixada finalitzada</string>
<string name="download_finished_more">%s baixades finalitzades</string>
<string name="overwrite_finished_warning">Ja existeix un fitxer baixat amb aquest nom</string>
<string name="overwrite_unrelated_warning">Ja existeix un fitxer amb aquest nom</string>
<string name="download_already_running">Hi ha una baixada en curs amb aquest nom</string>
<string name="error_ssl_exception">Ha fallat la connexió segura</string>
<string name="error_unknown_host">No s\'ha pogut trobar el servidor</string>
<string name="error_connect_host">No s\'ha pogut connectar amb el servidor</string>
<string name="error_postprocessing_failed">Ha fallat el post-processament</string>
<string name="clear_finished_download">Neteja les baixades finalitzades</string>
<string name="max_retry_msg">Intents màxims</string>
<string name="max_retry_desc">Nombre màxim d\'intents abans de cancel·lar la baixada</string>
<string name="pause_downloads_on_mobile">Pausa en canviar a dades mòbils</string>
<string name="pause_downloads_on_mobile_desc">Les baixades que no es puguin pausar es tornaran a iniciar</string>
</resources>

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources><string name="main_bg_subtitle">点击搜索按钮即可开始使用</string>
<resources>
<string name="main_bg_subtitle">点击搜索按钮即可开始使用</string>
<string name="view_count_text">%1$s 次观看</string>
<string name="upload_date_text">发布于 %1$s</string>
<string name="no_player_found">找不到媒体播放器。您要安装 VLC 吗?</string>
@ -26,26 +27,20 @@
<string name="channel_unsubscribed">退订成功</string>
<string name="subscription_change_failed">无法更改订阅</string>
<string name="subscription_update_failed">无法更新订阅</string>
<string name="show_info">显示详情</string>
<string name="show_info">显示信息</string>
<string name="tab_main">主页</string>
<string name="tab_subscriptions">订阅</string>
<string name="tab_bookmarks">已添加书签到播放列表</string>
<string name="fragment_whats_new">新功能</string>
<string name="controls_background_title">转到后台</string>
<string name="controls_popup_title">悬浮窗</string>
<string name="controls_add_to_playlist_title">添加到</string>
<string name="download_path_title">视频下载路径</string>
<string name="download_path_summary">储存视频文件的路径</string>
<string name="download_path_dialog_title">输入视频的下载地址</string>
<string name="download_path_audio_title">音频下载的路径</string>
<string name="download_path_audio_summary">下载音频的储存路径</string>
<string name="download_path_audio_dialog_title">输入音频的下载路径</string>
<string name="autoplay_by_calling_app_title">自动播放</string>
<string name="autoplay_by_calling_app_summary">NewPipes被其它程序调用时播放视频</string>
<string name="default_resolution_title">默认分辨率</string>
@ -55,7 +50,7 @@
<string name="play_with_kodi_title">用 Kodi 播放</string>
<string name="kore_not_found">没找到 Kore 应用,需要安装它吗?</string>
<string name="show_play_with_kodi_title">显示“用 Kodi 播放”选项</string>
<string name="show_play_with_kodi_summary">显示用 Kodi媒体中心 播放视频的选项</string>
<string name="show_play_with_kodi_summary">显示以 Kodi 媒体中心播放视频的选项</string>
<string name="play_audio">音频</string>
<string name="default_audio_format_title">默认音频格式</string>
<string name="default_video_format_title">默认视频格式</string>
@ -64,14 +59,11 @@
<string name="dark_theme_title">酷黑</string>
<string name="black_theme_title">黑色</string>
<string name="popup_remember_size_pos_title">记住悬浮窗的尺寸与位置</string>
<string name="m4a_description">M4A — 更好的音质</string>
<string name="popup_remember_size_pos_summary">记住上一次悬浮窗的位置以及大小</string>
<string name="thumbnail_cache_wipe_complete_notice">已清除图像缓存</string>
<string name="minimize_on_exit_popup_description">最小化悬浮窗播放器</string>
<string name="clear_views_history_title">清除观看历史</string>
<string name="search_history_deleted">已删除搜索历史</string>
<string name="clear_views_history_title">清除观看历史</string>
<string name="search_history_deleted">搜索记录已删除。</string>
<string name="general_error">错误</string>
<string name="network_error">网络错误</string>
<string name="report_error">举报错误</string>
@ -85,7 +77,6 @@
<string name="add">新任务</string>
<string name="finish">
\n</string>
<string name="msg_error">错误
\n</string>
<string name="msg_server_unsupported">不支持的服务器</string>
@ -94,34 +85,28 @@
<string name="msg_wait">请稍等…</string>
<string name="charset_letters_and_digits">字母与数字</string>
<string name="charset_most_special_characters">最特别的字符</string>
<string name="toast_no_player">这个文件里没有已下载应用程式</string>
<string name="title_activity_about">关于NewPipe</string>
<string name="action_settings">设置</string>
<string name="action_about">关于</string>
<string name="title_licenses">第三方执照</string>
<string name="action_open_website">打开网页</string>
<string name="unbookmark_playlist">删除书签</string>
<string name="delete_playlist_prompt">确定要删除该播放列表吗?</string>
<string name="playlist_creation_success">已创建播放列表</string>
<string name="playlist_add_stream_success">播放列表</string>
<string name="playback_step">步骤</string>
<string name="playback_reset">重置</string>
<string name="start_accept_privacy_policy">为了遵守欧洲通用数据保护法规GDPR,我们请你注意NewPipe的隐私政策.请仔细阅读.
\n你必须接受它才能将错误报告发送给我们.</string>
<string name="accept">接受</string>
<string name="decline">拒绝</string>
<string name="limit_data_usage_none_description">没有限制</string>
<string name="limit_mobile_data_usage_title">使用移动数据时的解析度限制</string>
<string name="minimize_on_exit_title">最小化应用程序切换</string>
<string name="minimize_on_exit_summary">从主视频播放器切换到其他应用时的操作 - %s</string>
<string name="minimize_on_exit_none_description">没有</string>
<string name="minimize_on_exit_background_description">最小化后台播放</string>
<string name="webm_description">WebM — 自由视频格式</string>
<string name="use_inexact_seek_title">使用快速粗略定位</string>
<string name="use_inexact_seek_summary">粗略定位功能允许播放器以略低的精确度为代价换取更快的定位速度</string>
<string name="download_thumbnail_title">下载缩略图</string>
@ -256,26 +241,24 @@
<string name="audio">音频</string>
<string name="retry">重试</string>
<string name="storage_permission_denied">手机存储访问权限被拒绝</string>
<string name="use_old_player_title">使用旧的播放器</string>
<string name="use_old_player_summary">旧的内置 Mediaframework 播放器</string>
<string name="short_thousand"></string>
<string name="short_million"></string>
<string name="short_billion">亿</string>
<string name="no_subscribers">没有订阅者</string>
<plurals name="subscribers">
<item quantity="one">%s 位订阅者</item>
<item quantity="other"/>
</plurals>
<item quantity="one">%s 位订阅者</item>
<item quantity="other"/>
</plurals>
<string name="no_views">无观看次数</string>
<plurals name="views">
<item quantity="one">%s 次观看</item>
<item quantity="other"/>
</plurals>
<item quantity="one">%s 次观看</item>
<item quantity="other"/>
</plurals>
<string name="no_videos">没有视频</string>
<plurals name="videos">
<item quantity="one">部视频</item>
<item quantity="other"></item>
</plurals>
<item quantity="one">部视频</item>
<item quantity="other"/>
</plurals>
<string name="delete_one">删除</string>
<string name="checksum">校验</string>
<string name="dismiss">退出</string>
@ -289,7 +272,7 @@
<string name="msg_popup_permission">在悬浮窗模式打开
\n需要此权限</string>
<string name="one_item_deleted">已删除一个项目。</string>
<string name="reCaptchaActivity">reCAPTCHA</string>
<string name="reCaptchaActivity">reCAPTCHA 验证</string>
<string name="reCaptcha_title">reCAPTCHA 验证</string>
<string name="recaptcha_request_toast">需完成 reCAPTCHA 验证</string>
<string name="settings_category_downloads_title">下载</string>
@ -412,7 +395,7 @@
\n2.移至该网址:%1$s
\n3.当被询问时登入帐号
\n4.复制您重定向的配置文件到网址。</string>
<string name="import_soundcloud_instructions_hint">yourID, soundcloud.com/yourid</string>
<string name="import_soundcloud_instructions_hint">您的 IDsoundcloud.com/yourid</string>
<string name="import_network_expensive_warning">请记住,此操作可能造成昂贵的网络花费。
\n
\n您是否要继续</string>
@ -443,7 +426,7 @@
<string name="auto">自动</string>
<string name="app_update_notification_content_text">轻按以下载</string>
<string name="missions_header_finished">已完成</string>
<string name="missions_header_pending">于队列中</string>
<string name="missions_header_pending">有待</string>
<string name="paused">已暂停</string>
<string name="queued">已加入队列</string>
<string name="post_processing">后处理</string>
@ -451,14 +434,14 @@
<string name="permission_denied">系统拒绝该行动</string>
<string name="download_failed">下载失败</string>
<string name="download_finished">下载完成</string>
<string name="download_finished_more">%已下载完毕</string>
<string name="download_finished_more">%s已下载完毕</string>
<string name="generate_unique_name">生成独特的名字</string>
<string name="overwrite">覆写</string>
<string name="overwrite_warning">同名的已下载文件已经存在</string>
<string name="overwrite_finished_warning">同名的已下载文件已经存在</string>
<string name="download_already_running">同名下载进行中</string>
<string name="show_error">显示错误</string>
<string name="label_code">代码</string>
<string name="error_path_creation">无法创建该文件</string>
<string name="error_file_creation">无法创建该文件</string>
<string name="error_permission_denied">系统拒绝此批准</string>
<string name="error_ssl_exception">安全连接失败</string>
<string name="error_unknown_host">找不到服务器</string>
@ -481,9 +464,9 @@
<string name="grid">网格</string>
<string name="switch_view">切换视图</string>
<string name="app_update_notification_content_title">NewPipe 更新可用!</string>
<string name="error_file_creation">无法创建目标文件夹</string>
<string name="error_path_creation">无法创建目标文件夹</string>
<string name="error_http_unsupported_range">服务器不接受多线程下载, 请重试使用 @string/msg_threads = 1</string>
<string name="error_http_requested_range_not_satisfiable">请求的范围不满足</string>
<string name="error_http_requested_range_not_satisfiable">请求范围无法满足</string>
<string name="msg_pending_downloads">继续进行%s个待下载转移</string>
<string name="pause_downloads_on_mobile_desc">将重新启动无法暂停的下载</string>
<string name="pause_downloads_on_mobile_desc">无法暂停的下载将重新开始</string>
</resources>

View File

@ -15,10 +15,8 @@
<string name="screen_rotation">otočení</string>
<string name="use_external_video_player_title">Použít externí video přehrávač</string>
<string name="use_external_audio_player_title">Použít externí audio přehrávač</string>
<string name="download_path_audio_summary">Stažené audio je uloženo zde</string>
<string name="download_path_audio_dialog_title">Zadejte umístění pro stažené audio soubory</string>
<string name="download_path_audio_title">Složka pro stažené audio</string>
<string name="default_resolution_title">Výchozí rozlišení</string>
<string name="play_with_kodi_title">Přehrát pomocí Kodi</string>
@ -27,7 +25,6 @@
<string name="download_path_title">Umístění pro stažené video</string>
<string name="download_path_summary">Cesta, kam se uloží stažené video</string>
<string name="download_path_dialog_title">Zadejte umístění pro stažená videa</string>
<string name="show_play_with_kodi_title">Zobrazit možnost \"Přehrát pomocí Kodi\"</string>
<string name="show_play_with_kodi_summary">Zobrazit možnost přehrání videa pomocí multimediálního centra Kodi</string>
<string name="play_audio">Zvuk</string>
@ -35,7 +32,6 @@
<string name="theme_title">Téma</string>
<string name="dark_theme_title">Tmavé</string>
<string name="light_theme_title">Světlé</string>
<string name="download_dialog_title">Stáhnout</string>
<string name="next_video_title">Další videa</string>
<string name="show_next_and_similar_title">Zobrazovat \'další\' a \'podobná\' videa</string>
@ -53,7 +49,6 @@
<string name="parsing_error">Nebylo možné analyzovat stránku</string>
<string name="content_not_available">Obsah není k dispozici</string>
<string name="blocked_by_gema">Obsah blokuje GEMA</string>
<string name="list_thumbnail_view_description">Náhled videa</string>
<string name="detail_thumbnail_view_description">Náhled videa</string>
<string name="detail_uploader_thumbnail_view_description">Náhled avataru uploadera</string>
@ -61,7 +56,6 @@
<string name="detail_dislikes_img_view_description">To se mi nelíbí</string>
<string name="use_tor_title">Použít Tor</string>
<string name="use_tor_summary">(Experimentální) Vynutit stahování skrz Tor pro zvýšené soukromí (streamovaná videa zatím nepodporována).</string>
<string name="err_dir_create">Nebylo možné vytvořit složku pro stažené soubory \'%1$s\'</string>
<string name="info_dir_created">Vytvořena složka pro stažené soubory \'%1$s\'</string>
<string name="autoplay_by_calling_app_title">Automaticky přehrávat</string>
@ -70,7 +64,6 @@
<string name="show_age_restricted_content_title">Věkově omezený obsah</string>
<string name="video_is_age_restricted">Zobrazit video s věkovým omezením. Povolit tento obsah lze v \"Nastavení\".</string>
<string name="duration_live">ŽIVĚ</string>
<string name="light_parsing_error">Nebylo možné kompletně analyzovat stránku</string>
<string name="main_bg_subtitle">Začni stiskem hledat</string>
<string name="msg_copied">Zkopírováno do schránky</string>
@ -85,15 +78,12 @@
<string name="msg_threads">Vlákna</string>
<string name="pause">Zastavit</string>
<string name="delete">Smazat</string>
<string name="start">Start</string>
<string name="retry">Zkusit znovu</string>
<string name="video">Video</string>
<string name="audio">Zvuk</string>
<string name="report_error">Nahlásit chybu</string>
<string name="error_details_headline">Podrobnosti:</string>
<string name="what_happened_headline">Co se stalo:</string>
<string name="error_snackbar_action">NAHLÁSIT</string>
<string name="sorry_string">Omlouváme se, tohle se nemělo stát.</string>
@ -105,7 +95,6 @@
<string name="could_not_get_stream">Nepodařilo se dostat žádný stream</string>
<string name="could_not_setup_download_menu">Nepodařilo se nastavit menu stahování</string>
<string name="error_report_title">Nahlásit chybu</string>
<string name="downloads">Stažené soubory</string>
<string name="downloads_title">Stažené soubory</string>
<string name="what_device_headline">Info:</string>
@ -114,35 +103,24 @@
<string name="view">Přehrát</string>
<string name="add">Nová mise</string>
<string name="finish">OK</string>
<string name="reCaptchaActivity">reCAPTCHA</string>
<string name="reCaptcha_title">Výzva reCAPTCHA</string>
<string name="recaptcha_request_toast">Požadována výzva reCAPTCHA</string>
<string name="black_theme_title">Černé</string>
<string name="checksum">Kontrolní součet</string>
<string name="no_available_dir">Prosím vyberte dostupnou složku pro stahování</string>
<string name="user_report">Hlášení uživatele</string>
<string name="info_labels">Co:\\nŽádost:\\nJazyk obsahu:\\nSlužba:\\nČas GMT:\\nBalíček:\\nVerze:\\nVerze OS:</string>
<string name="all">Vše</string>
<string name="channel">Kanál</string>
<string name="yes">Ano</string>
<string name="later">Později</string>
<string name="short_thousand">tis.</string>
<string name="open_in_popup_mode">Otevřít ve vyskakovacím okně</string>
<string name="short_million">mil.</string>
<string name="msg_popup_permission">Toto oprávnění je vyžadováno pro
otevření ve vyskakovacím okně</string>
<string name="use_old_player_title">Použít starý přehrávač</string>
<string name="use_external_video_player_summary">Odstraňuje zvuk v některých rozlišeních</string>
<string name="use_external_video_player_summary">Odstraňuje zvuk v některých rozlišeních</string>
<string name="show_higher_resolutions_title">Zobrazovat vyšší rozlišení</string>
<string name="show_higher_resolutions_summary">Pouze některá zařízení podporují přehrávání 2K/4K videí</string>
<string name="default_video_format_title">Výchozí formát videa</string>
@ -154,15 +132,11 @@ otevření ve vyskakovacím okně</string>
<string name="channel_unsubscribed">Odběr zrušen</string>
<string name="subscription_change_failed">Nelze změnit odběr</string>
<string name="subscription_update_failed">Nelze aktualizovat odběr</string>
<string name="tab_main">Hlavní</string>
<string name="tab_subscriptions">Odběry</string>
<string name="fragment_whats_new">Co je nového</string>
<string name="controls_background_title">Na pozadí</string>
<string name="controls_popup_title">V okně</string>
<string name="default_popup_resolution_title">Výchozí rozlišení vyskakovacího okna</string>
<string name="player_gesture_controls_title">Ovládání přehrávače gesty</string>
<string name="player_gesture_controls_summary">Používat gesta pro nastavení jasu a hlasitosti přehrávače</string>
@ -187,46 +161,35 @@ otevření ve vyskakovacím okně</string>
<string name="popup_resizing_indicator_title">Změna velikosti</string>
<string name="best_resolution">Nejlepší rozlišení</string>
<string name="undo">Vrátit</string>
<string name="notification_channel_name">NewPipe notifikace</string>
<string name="notification_channel_description">Notifikace pro NewPipe přehrávače v pozadí a v okně</string>
<string name="search_no_results">Žádné výsledky</string>
<string name="empty_subscription_feed_subtitle">Je tu sranda jak v márnici</string>
<string name="use_old_player_summary">Starý zabudovaný Mediaframework přehrávač</string>
<string name="short_billion">mld.</string>
<string name="no_subscribers">Žádní odběratelé</string>
<plurals name="subscribers">
<item quantity="one">%s odběratel</item>
<item quantity="few">%s odběratelé</item>
<item quantity="other">%s odběratelů</item>
</plurals>
<item quantity="one">%s odběratel</item>
<item quantity="few">%s odběratelé</item>
<item quantity="other">%s odběratelů</item>
</plurals>
<string name="no_views">Žádná zhlédnutí</string>
<plurals name="views">
<item quantity="one">%s zhlédnutí</item>
<item quantity="few">%s zhlédnutí</item>
<item quantity="other">%s zhlédnutí</item>
</plurals>
<item quantity="one">%s zhlédnutí</item>
<item quantity="few">%s zhlédnutí</item>
<item quantity="other">%s zhlédnutí</item>
</plurals>
<string name="no_videos">Žádná videa</string>
<plurals name="videos">
<item quantity="one">%s video</item>
<item quantity="few">%s videa</item>
<item quantity="other">%s videí</item>
</plurals>
<item quantity="one">%s video</item>
<item quantity="few">%s videa</item>
<item quantity="other">%s videí</item>
</plurals>
<string name="settings_category_downloads_title">Stahování</string>
<string name="settings_file_charset_title">Povolené znaky v názvech souborů</string>
<string name="settings_file_replacement_character_summary">Neplatné znaky budou nahrazeny těmito</string>
<string name="settings_file_replacement_character_title">Náhradní znak</string>
<string name="charset_letters_and_digits">Písmena a číslice</string>
<string name="charset_most_special_characters">Většina speciálních znaků</string>
<string name="title_activity_about">O NewPipe</string>
<string name="action_settings">Nastavení</string>
<string name="action_about">O aplikaci</string>
@ -243,7 +206,6 @@ otevření ve vyskakovacím okně</string>
<string name="contribution_encouragement">Pokud máte nápady na zlepšení jako; překlad, změny designu, vylepšování kódu nebo opravdu velké změny kódu - pomoc je vždy vítána. Čím více se udělá, tím lepší to bude!</string>
<string name="read_full_license">Přečíst licenci</string>
<string name="contribution_title">Podílet se</string>
<string name="title_activity_history">Historie</string>
<string name="title_history_search">Vyhledáváno</string>
<string name="title_history_view">Zhlédnuto</string>
@ -252,18 +214,15 @@ otevření ve vyskakovacím okně</string>
<string name="history_empty">Historie je prázdná</string>
<string name="history_cleared">Historie vymazána</string>
<string name="item_deleted">Položka byla odstraněna</string>
<string name="show_hold_to_append_title">Zobrazovat tip \"Podržet pro přidání\"</string>
<string name="show_hold_to_append_title">Zobrazovat tip \"Podržet pro přidání\"</string>
<string name="show_hold_to_append_summary">Zobrazí se po stisku tlačítek přehrát na pozadí nebo přehrát v okně na stránce s videem</string>
<string name="background_player_append">Ve frontě přehrávače na pozadí</string>
<string name="popup_playing_append">Ve frontě přehrávače v okně</string>
<string name="play_all">Přehrát vše</string>
<string name="player_stream_failure">Tento stream nelze přehrát</string>
<string name="player_unrecoverable_failure">Došlo k neobnovitelné chybě přehrávače</string>
<string name="player_recoverable_failure">Obnovování z chyby přehrávače</string>
<string name="delete_item_search_history">Odstranit tuto položku z historie vyhledávání?</string>
<string name="main_page_content">Obsah úvodní obrazovky</string>
<string name="blank_page_summary">Prázdná stránka</string>
<string name="kiosk_page_summary">Kiosek</string>
@ -273,7 +232,6 @@ otevření ve vyskakovacím okně</string>
<string name="select_a_channel">Zvolte kanál</string>
<string name="no_channel_subscribed_yet">Žádný kanál dosud neodebírán</string>
<string name="select_a_kiosk">Zvolte kiosek</string>
<string name="kiosk">Kiosek</string>
<string name="trending">Trendy</string>
<string name="top_50">Top 50</string>
@ -284,14 +242,13 @@ otevření ve vyskakovacím okně</string>
<string name="play_queue_stream_detail">Podrobnosti</string>
<string name="play_queue_audio_settings">Nastavení zvuku</string>
<string name="hold_to_append">Podrž pro zařazení do fronty</string>
<string name="unknown_content">[Neznámý]</string>
<string name="unknown_content">[Neznámý]</string>
<string name="enqueue_on_background">Do fronty na pozadí</string>
<string name="enqueue_on_popup">Do fronty v okně</string>
<string name="start_here_on_main">Začne hrát zde</string>
<string name="start_here_on_background">Začne zde, když na pozadí</string>
<string name="start_here_on_popup">Začne zde v okně</string>
<string name="donation_title">Donate</string>
<string name="donation_title">Donate</string>
<string name="donation_encouragement">NewPipe je vyvíjen dobrovolníky, kteří tráví svůj čas, aby vaše zkušenost s aplikací byla co nejlepší. Vraťte vývojářům něco zpět, aby mohli NewPipe dále zlepšovat a zároveň si vychutnat šálek kávy.</string>
<string name="give_back">Daruj</string>
<string name="website_title">Webová stránka</string>
@ -302,13 +259,11 @@ otevření ve vyskakovacím okně</string>
<string name="switch_to_background">Na pozadí</string>
<string name="switch_to_popup">Do okna</string>
<string name="switch_to_main">Přepnout na hlavní</string>
<string name="drawer_open">Otevřít Drawer</string>
<string name="drawer_close">Zavřít Drawer</string>
<string name="no_player_found_toast">Nenalezen přehrávač streamu (pro přehrání můžete nainstalovat např. VLC).</string>
<string name="always">Vždy</string>
<string name="just_once">Pouze jednou</string>
<string name="import_data_title">Importovat databázi</string>
<string name="export_data_title">Exportovat databázi</string>
<string name="import_data_summary">Přepíše vaši dosavadní historii a odběry</string>
@ -317,67 +272,49 @@ otevření ve vyskakovacím okně</string>
<string name="invalid_url_toast">Neplatná URL</string>
<string name="video_streams_empty">Nenalezeny žádné video streamy</string>
<string name="audio_streams_empty">Nenalezeny žádné audio streamy</string>
<string name="export_complete_toast">Exportováno</string>
<string name="import_complete_toast">Importováno</string>
<string name="no_valid_zip_file">Žádný platný soubor ZIP</string>
<string name="could_not_import_all_files">Upozornění: Nelze importovat všechny soubory.</string>
<string name="override_current_data">Tímto se anuluje vaše aktuální nastavení.</string>
<string name="video_player">Video přehrávač</string>
<string name="background_player">Přehrávač na pozadí</string>
<string name="popup_player">Přehrávač v okně</string>
<string name="always_ask_player">Vždy se ptát</string>
<string name="preferred_player_fetcher_notification_title">Získávám informace…</string>
<string name="preferred_player_fetcher_notification_message">Načítání požadovaného obsahu</string>
<string name="controls_download_desc">Stáhnout soubor streamu</string>
<string name="controls_download_desc">Stáhnout soubor streamu</string>
<string name="show_info">Ukázat informace</string>
<string name="tab_bookmarks">Uložené playlisty</string>
<string name="controls_add_to_playlist_title">Přidat do</string>
<string name="detail_drag_description">Táhnout pro přeskupení</string>
<string name="create">Vytvořit</string>
<string name="delete_one">Smazat jeden</string>
<string name="delete_all">Smazat vše</string>
<string name="dismiss">Zahodit</string>
<string name="rename">Přejmenovat</string>
<string name="delete_stream_history_prompt">Přejete si smazat tuto položku z historie shlédnutí?</string>
<string name="delete_all_history_prompt">Jste si jisti, že chcete odstranit všechny položky z historie?</string>
<string name="title_last_played">Poslední přehráno</string>
<string name="title_most_played">Nejvíce přehráno</string>
<string name="drawer_header_action_paceholder_text">Zde se brzy něco objeví ;D</string>
<string name="always_ask_open_action">Vždy se zeptat</string>
<string name="create_playlist">Nový playlist</string>
<string name="delete_playlist">Vymazat</string>
<string name="rename_playlist">Přejmenovat</string>
<string name="playlist_name_input">Jméno</string>
<string name="append_playlist">Přidat do playlistu</string>
<string name="set_as_playlist_thumbnail">Nastavit jako náhled playlistu</string>
<string name="bookmark_playlist">Založit playlist</string>
<string name="bookmark_playlist">Přidat playlist do záložek</string>
<string name="unbookmark_playlist">Smazat záložku</string>
<string name="delete_playlist_prompt">Smazat tento playlist\?</string>
<string name="playlist_creation_success">Playlist vytvořen</string>
<string name="playlist_add_stream_success">V playlistu</string>
<string name="playlist_thumbnail_change_success">Náhled playlistu změněn.</string>
<string name="playlist_delete_failure">Playlist nelze smazat.</string>
<string name="caption_none">Žádné titulky</string>
<string name="caption_none">Bez titulků</string>
<string name="resize_fit">Přizpůsobit</string>
<string name="resize_fill">Vyplnit</string>
<string name="resize_zoom">Zvětšit</string>
<string name="caption_font_size_settings_title">Velikost písma nadpisu</string>
<string name="smaller_caption_font_size">Menší písmo</string>
<string name="normal_caption_font_size">Normální písmo</string>
@ -385,19 +322,17 @@ otevření ve vyskakovacím okně</string>
<string name="toggle_leak_canary">Sledovat únik paměti</string>
<string name="disable_leak_canary_notice">Sledování úniku paměti vypnuto</string>
<string name="enable_leak_canary_notice">Sledování úniku paměti povoleno, aplikace může při zátěži přestat reagovat</string>
<string name="enable_leak_canary_notice">Sledování úniku paměti povoleno, aplikace může při zátěži přestat reagovat</string>
<string name="settings_category_debug_title">Ladění</string>
<string name="caption_auto_generated">"Automaticky generováno "</string>
<string name="enable_leak_canary_title">Povolit službu LeakCanary</string>
<string name="enable_leak_canary_summary">Monitoring úniku paměti může způsobit nereagování aplikace při heap dumpingu</string>
<string name="enable_disposed_exceptions_title">Nahlásit mimo-cyklické chyby</string>
<string name="enable_disposed_exceptions_summary">Vynutit vykazování výjimek Rx mimo fragment nebo životnost cyklu po odstranění</string>
<string name="use_inexact_seek_title">Použít rychlé nepřesné hledání</string>
<string name="use_inexact_seek_title">Použít rychlé nepřesné hledání</string>
<string name="use_inexact_seek_summary">Nepřesné hledání umožní přehrávači posouvat se rychleji, ale se sníženou přesností</string>
<string name="download_thumbnail_title">Načítat náhledy</string>
<string name="download_thumbnail_summary">Po vypnutí se nestahují náhledy a tím se šetří data a využití paměti. Změna tohoto nastavení vyčistí mezipamět obrázků.</string>
<string name="download_thumbnail_summary">Vypnout, aby se zabránilo načítání náhledů a tím se ušetřily data a používání paměti. Změna tohoto nastavení vyčistí mezipamět obrázků v paměti i na disku.</string>
<string name="thumbnail_cache_wipe_complete_notice">Mezipaměť obrázků vymazána</string>
<string name="metadata_cache_wipe_title">Vymazat metadata v mezipaměti</string>
<string name="metadata_cache_wipe_summary">Odebrat všechna data uložená v mezipaměti</string>
@ -405,13 +340,11 @@ otevření ve vyskakovacím okně</string>
<string name="auto_queue_title">Automatická fronta dalšího streamu</string>
<string name="auto_queue_summary">Automaticky připojí související stream při přehrávání posledního streamu v neopakující se frontě.</string>
<string name="file">Soubor</string>
<string name="invalid_directory">Neexistující složka</string>
<string name="invalid_source">Neexistující zdroj souboru/obsahu</string>
<string name="invalid_file">Soubor neexistuje nebo chybí oprávnění k jeho čtení či zápisu</string>
<string name="file_name_empty_error">Název souboru nesmí být prázdný</string>
<string name="error_occurred_detail">Došlo k chybě: %1$s</string>
<string name="import_export_title">Import/export
\n</string>
<string name="import_title">Importovat
@ -419,16 +352,12 @@ otevření ve vyskakovacím okně</string>
<string name="import_from">Importovat z
\n</string>
<string name="export_to">Exportovat do</string>
<string name="import_ongoing">Importuji…</string>
<string name="export_ongoing">Exportuji…</string>
<string name="import_file_title">Import souboru</string>
<string name="previous_export">Předchozí export</string>
<string name="subscriptions_import_unsuccessful">Odběry nelze importovat</string>
<string name="subscriptions_export_unsuccessful">Odběry nelze exportovat</string>
<string name="import_youtube_instructions">Importovat YouTube odběry stáhnutím exportního souboru:
\n
\n1. Přejděte na tuto URL adresu: %1$s
@ -441,27 +370,21 @@ otevření ve vyskakovacím okně</string>
\n3. Na vyžádání se přihlašte
\n4. Zkopírujte URL adresu profilu, na kterou jste byli přesměrováni.</string>
<string name="import_soundcloud_instructions_hint">vašeID, soundcloud.com/yourid</string>
<string name="import_network_expensive_warning">Pamatujte, že tato operace může být náročná na data.
\n
\nChcete pokračovat?</string>
<string name="playback_speed_control">Ovládání rychlosti přehrávání</string>
<string name="playback_tempo">Rychlost</string>
<string name="playback_pitch">Stupeň tónu</string>
<string name="playback_pitch">Výška tónu</string>
<string name="unhook_checkbox">Rozpojit (může způsobit zkreslení)</string>
<string name="playback_nightcore">Nightcore mód</string>
<string name="playback_default">Výchozí nastavení</string>
<string name="no_streams_available_download">Ke stažení nejsou dostupné žádné streamy</string>
<string name="no_streams_available_download">Ke stažení nejsou dostupné žádné streamy</string>
<string name="preferred_open_action_settings_title">Preferovaná \'otevřít\' akce</string>
<string name="preferred_open_action_settings_summary">Výchozí chování při otevírání obsahu — %s</string>
<string name="caption_setting_title">Titulky</string>
<string name="caption_setting_description">Upravuje velikost textu titulků a styly pozadí. Změny se projeví po restartu aplikace.</string>
<string name="toast_no_player">K přehrání tohoto souboru chybí vhodná aplikace</string>
<string name="clear_views_history_title">Vymazat historii sledování</string>
<string name="clear_views_history_summary">Vymaže historii přehrávaných streamů</string>
<string name="delete_view_history_alert">Vymazat celkovou historii sledování\?</string>
@ -471,7 +394,6 @@ otevření ve vyskakovacím okně</string>
<string name="delete_search_history_alert">Vymazat celkovou historii vyhledávání\?</string>
<string name="search_history_deleted">Historie vyhledávání smazána.</string>
<string name="one_item_deleted">Jedna položka smazána.</string>
<string name="app_license">NewPipe je copyleft libre software: Můžete jej používat, sdílet a vylepšovat dle vaší vůle. Redistribuovat a/nebo upravovat lze za podmínek GNU General Public Licence zveřejňované nadací Free Software Foundation, a to buď za podmínek licence verze 3 nebo (dle vaší volby) jakékoli pozdější verze.</string>
<string name="channels">kanály</string>
<string name="playlists">Playlisty</string>
@ -482,16 +404,13 @@ otevření ve vyskakovacím okně</string>
\nZásady ochrany soukromí NewPipe podrobně vysvětlují, jaké údaje jsou odesílány a ukládány, když odešlete zprávu o pádu aplikace.</string>
<string name="read_privacy_policy">Přečíst zásady ochrany soukromí</string>
<string name="import_settings">Chcete také přenést nastavení?</string>
<string name="skip_silence_checkbox">Zrychleně vpřed během ticha</string>
<string name="playback_step">Krok</string>
<string name="playback_reset">Reset</string>
<string name="start_accept_privacy_policy">Abychom vyhověli Obecnému nařízení o ochraně osobních údajů (GDPR), upozorňujeme vás na zásady ochrany soukromí v NewPipe. Přečtěte si je prosím pozorně.
\nJe potřeba je odsouhlasit, abyste nám mohli odeslat hlášení chyb.</string>
<string name="accept">Přijmout</string>
<string name="decline">Odmítnout</string>
<string name="limit_data_usage_none_description">Bez omezení</string>
<string name="limit_mobile_data_usage_title">Omezit rozlišení při použití mobilních dat</string>
<string name="minimize_on_exit_title">Minimalizovat při přepínání aplikací</string>
@ -511,4 +430,56 @@ otevření ve vyskakovacím okně</string>
<string name="app_update_notification_channel_name">Notifikace aktualizace aplikace</string>
<string name="app_update_notification_channel_description">Notifikace pro novou verzi NewPipe</string>
<string name="download_to_sdcard_error_title">Externí úložiště není k dispozici</string>
<string name="saved_tabs_invalid_json">Chyba při načítání uložených karet, použijí se výchozí karty</string>
<string name="restore_defaults">Obnovit do výchozího nastavení</string>
<string name="restore_defaults_confirmation">Chcete obnovit výchozí nastavení\?</string>
<string name="subscribers_count_not_available">Počet odběratelů není k dispozici</string>
<string name="main_page_content_summary">Karty, které jsou zobrazeny na hlavní stránce</string>
<string name="selection">Výběr</string>
<string name="updates_setting_title">Aktualizace</string>
<string name="events">Události</string>
<string name="conferences">Konference</string>
<string name="updates_setting_description">Zobrazit oznámení s výzvou k aktualizaci aplikace, když je k dispozici nová verze</string>
<string name="list_view_mode">Režim zobrazení seznamu</string>
<string name="list">Seznam</string>
<string name="grid">Mřížka</string>
<string name="auto">Automaticky</string>
<string name="switch_view">Přepnout zobrazení</string>
<string name="app_update_notification_content_title">K dispozici je aktualizace aplikace NewPipe!</string>
<string name="app_update_notification_content_text">Klepněte pro stažení</string>
<string name="missions_header_finished">Hotovo</string>
<string name="missions_header_pending">Ve frontě</string>
<string name="paused">Pozastaveno</string>
<string name="queued">ve frontě</string>
<string name="post_processing">post-processing</string>
<string name="enqueue">Fronta</string>
<string name="permission_denied">Akce odmítnuta systémem</string>
<string name="download_failed">Stahování se nezdařilo</string>
<string name="download_finished">Stahování dokončeno</string>
<string name="download_finished_more">% s stahování dokončeno</string>
<string name="generate_unique_name">Vytvořit jedinečný název</string>
<string name="overwrite">Přepsat</string>
<string name="overwrite_unrelated_warning">Stažený soubor s tímto názvem již existuje</string>
<string name="overwrite_finished_warning">Stažený soubor s tímto názvem již existuje</string>
<string name="download_already_running">Stahování s tímto názvem již probíhá</string>
<string name="show_error">Zobrazit chybu</string>
<string name="label_code">Kód</string>
<string name="error_path_creation">Soubor nelze vytvořit</string>
<string name="error_file_creation">Cílovou složku nelze vytvořit</string>
<string name="error_permission_denied">Oprávnění odepřeno systémem</string>
<string name="error_ssl_exception">Zabezpečené připojení selhalo</string>
<string name="error_unknown_host">Server se nepodařilo najít</string>
<string name="error_connect_host">Nelze se připojit k serveru</string>
<string name="error_http_no_content">Server neposílá data</string>
<string name="error_http_unsupported_range">Server neakceptuje vícevláknové stahování, opakujte akci s @string/msg_threads = 1</string>
<string name="error_http_requested_range_not_satisfiable">Požadovaný rozsah nelze splnit</string>
<string name="error_http_not_found">Nenalezeno</string>
<string name="error_postprocessing_failed">Post-processing selhal</string>
<string name="clear_finished_download">Vyčistit dokončená stahování</string>
<string name="msg_pending_downloads">Pokračovat ve stahování %s souborů, čekajících na stažení</string>
<string name="stop">Zastavit</string>
<string name="max_retry_msg">Maximální počet pokusů o opakování</string>
<string name="max_retry_desc">Maximální počet pokusů před zrušením stahování</string>
<string name="pause_downloads_on_mobile">Pozastavit při přepnutí na mobilní data</string>
<string name="pause_downloads_on_mobile_desc">Stahování, která nelze pozastavit, budou restartována</string>
</resources>

File diff suppressed because it is too large Load Diff

View File

@ -2,9 +2,10 @@
<resources>
<string name="view_count_text">%1$s Aufrufe</string>
<string name="upload_date_text">Veröffentlicht am %1$s</string>
<string name="no_player_found">Keinen Streamplayer gefunden. Möchtest du VLC installieren?</string>
<string name="no_player_found">Keinen Stream-Player gefunden. Möchtest Du VLC installieren\?</string>
<string name="install">Installieren</string>
<string name="cancel">Abbrechen</string>
<string name="cancel">Abbrechen
\n</string>
<string name="open_in_browser">Im Browser öffnen</string>
<string name="share">Teilen</string>
<string name="download">Download</string>
@ -39,19 +40,15 @@
<string name="use_external_audio_player_title">Externen Audio-Player verwenden</string>
<string name="background_player_playing_toast">Spiele im Hintergrund ab</string>
<string name="play_btn_text">Abspielen</string>
<string name="use_tor_title">Benutze Tor</string>
<string name="use_tor_summary">(Experimentell) Erzwinge das Herunterladen über Tor für verbesserte Privatsphäre (Videostream werden noch nicht unterstützt).</string>
<string name="network_error">Netzwerkfehler</string>
<string name="download_path_audio_title">Downloadverzeichnis für Audiodateien</string>
<string name="download_path_audio_summary">Heruntergeladene Audiodateien werden hier gespeichert</string>
<string name="download_path_audio_dialog_title">Downloadverzeichnis für Audiodateien angeben</string>
<string name="theme_title">Design</string>
<string name="dark_theme_title">Dunkel</string>
<string name="light_theme_title">Hell</string>
<string name="settings_category_appearance_title">Aussehen</string>
<string name="settings_category_other_title">Andere</string>
<string name="err_dir_create">Kann Downloadverzeichnis \'%1$s\' nicht anlegen</string>
@ -62,15 +59,11 @@
<string name="parsing_error">Konnte Webseite nicht analysieren</string>
<string name="content_not_available">Inhalt nicht verfügbar</string>
<string name="blocked_by_gema">Durch die GEMA gesperrt</string>
<string name="content">Inhalt</string>
<string name="show_age_restricted_content_title">Altersbeschränkte Inhalte</string>
<string name="video_is_age_restricted">Altersbeschränktes Video anzeigen. Das Zulassen dieses Materials ist von den Einstellungen aus möglich.</string>
<string name="could_not_setup_download_menu">Konnte Download-Menü nicht einrichten</string>
<string name="live_streams_not_supported">Live-Streams werden noch nicht unterstützt</string>
<string name="light_parsing_error">Konnte Webseite nicht vollständig analysieren</string>
<string name="error_report_button_text">Fehler via E-Mail melden</string>
<string name="error_snackbar_action">MELDEN</string>
@ -78,7 +71,6 @@
<string name="what_happened_headline">Dies ist passiert:</string>
<string name="info_labels">Was:\\nAnfrage:\\nSprache des Inhalts:\\nDienst:\\nZeit (GMT):\\nPaket:\\nVersion:\\nOS-Version:</string>
<string name="error_details_headline">Details:</string>
<string name="video">Video</string>
<string name="audio">Audio</string>
<string name="retry">Wiederholen</string>
@ -87,34 +79,26 @@
<string name="error_snackbar_message">Entschuldigung. Es sind einige Fehler aufgetreten.</string>
<string name="your_comment">Dein Kommentar (auf englisch):</string>
<string name="could_not_get_stream">Konnte keinen Stream abrufen</string>
<string name="autoplay_by_calling_app_title">Autoplay</string>
<string name="autoplay_by_calling_app_summary">Spiele ein Video ab, wenn NewPipe von einer anderen App aufgerufen wurde</string>
<string name="autoplay_by_calling_app_title">Automatische Wiedergabe</string>
<string name="autoplay_by_calling_app_summary">Wiedergabe eines Videos, wenn NewPipe von einer anderen App aufgerufen wurde</string>
<string name="report_error">Einen Fehler melden</string>
<string name="user_report">Anwenderbericht</string>
<string name="duration_live">LIVE</string>
<string name="main_bg_subtitle">„Suchen“ antippen, um zu beginnen</string>
<string name="main_bg_subtitle">Suchen antippen, um zu beginnen</string>
<string name="downloads">Downloads</string>
<string name="downloads_title">Downloads</string>
<string name="error_report_title">Fehlerbericht</string>
<string name="delete">Löschen</string>
<string name="checksum">Prüfsumme</string>
<string name="short_thousand">Tsd.</string>
<string name="short_million">Mio.</string>
<string name="short_billion">Mrd.</string>
<string name="msg_name">Dateiname</string>
<string name="msg_error">Fehler</string>
<string name="msg_exists">Datei existiert bereits</string>
<string name="msg_wait">Bitte warten…</string>
<string name="msg_copied">In Zwischenablage kopiert</string>
<string name="no_available_dir">Bitte wähle ein verfügbares Downloadverzeichnis</string>
<string name="start">Starten</string>
<string name="pause">Pause</string>
<string name="view">Abspielen</string>
@ -126,53 +110,39 @@
<string name="msg_threads">Threads</string>
<string name="msg_running">NewPipe lädt herunter</string>
<string name="msg_running_detail">Für Details antippen</string>
<string name="msg_url_malform">Ungültige URL oder Internet nicht verfügbar</string>
<string name="reCaptchaActivity">reCAPTCHA</string>
<string name="black_theme_title">Schwarz</string>
<string name="reCaptcha_title">reCAPTCHA-Aufgabe</string>
<string name="recaptcha_request_toast">reCAPTCHA-Aufgabe angefordert</string>
<string name="later">Später</string>
<string name="yes">Ja</string>
<string name="all">Alle</string>
<string name="channel">Kanal</string>
<string name="disabled">Deaktiviert</string>
<string name="use_old_player_title">Alten Player benutzen</string>
<string name="open_in_popup_mode">Im Pop-up-Modus öffnen</string>
<string name="default_video_format_title">Bevorzugtes Videoformat</string>
<string name="popup_playing_toast">Spiele im Pop-up Modus ab</string>
<string name="popup_mode_share_menu_title">NewPipe-Pop-up-Modus</string>
<string name="msg_popup_permission">Diese Berechtigung ist für das Öffnen im Pop-up-Modus erforderlich</string>
<string name="use_old_player_summary">Alter eingebauter Mediaframework-Player</string>
<string name="default_popup_resolution_title">Standardauflösung des Pop-ups</string>
<string name="show_higher_resolutions_title">Höhere Auflösungen anzeigen</string>
<string name="show_higher_resolutions_summary">Nur manche Geräte unterstützen das Abspielen von 2K-/4K-Videos</string>
<string name="controls_background_title">Hintergrund</string>
<string name="controls_popup_title">Pop-up</string>
<string name="popup_remember_size_pos_title">Größe und Position des Pop-ups merken</string>
<string name="use_external_video_player_summary">Entfernt Tonspur bei manchen Auflösungen</string>
<string name="use_external_video_player_summary">Entfernt Tonspur bei manchen Auflösungen</string>
<string name="popup_remember_size_pos_summary">Letzte Größe und Position des Pop-ups merken</string>
<string name="player_gesture_controls_title">Gestensteuerung</string>
<string name="player_gesture_controls_summary">Helligkeit und Lautstärke mittels Gesten einstellen</string>
<string name="show_search_suggestions_title">Suchvorschläge</string>
<string name="show_search_suggestions_summary">Beim Suchen Vorschläge anzeigen</string>
<string name="settings_category_popup_title">Pop-up</string>
<string name="filter">Filter</string>
<string name="refresh">Aktualisieren</string>
<string name="clear">Löschen</string>
<string name="popup_resizing_indicator_title">Größenänderung</string>
<string name="best_resolution">Beste Auflösung</string>
<string name="action_about">Über</string>
<string name="title_activity_about">Über NewPipe</string>
<string name="action_open_website">Website öffnen</string>
@ -189,19 +159,16 @@
<string name="title_licenses">Drittanbieter-Lizenzen</string>
<string name="view_on_github">Auf GitHub ansehen</string>
<string name="contribution_title">Beitragen</string>
<string name="settings_category_downloads_title">Download</string>
<string name="settings_category_downloads_title">Download</string>
<string name="settings_file_charset_title">Erlaubte Zeichen im Dateinamen</string>
<string name="settings_file_replacement_character_summary">Ungültige Zeichen werden durch dieses Zeichen ersetzt</string>
<string name="settings_file_replacement_character_title">Ersetzungszeichen</string>
<string name="charset_letters_and_digits">Buchstaben und Zahlen</string>
<string name="subscribe_button_title">Abonnieren</string>
<string name="subscribed_button_title">Abonniert</string>
<string name="channel_unsubscribed">Abonnement beendet</string>
<string name="tab_subscriptions">Abos</string>
<string name="fragment_whats_new">Neuigkeiten</string>
<string name="enable_search_history_title">Suchverlauf</string>
<string name="enable_search_history_summary">Suchanfragen lokal speichern</string>
<string name="enable_watch_history_title">Verlauf &amp; Cache</string>
@ -213,56 +180,44 @@
<string name="action_history">Verlauf</string>
<string name="history_empty">Der Verlauf ist leer</string>
<string name="history_cleared">Verlauf bereinigt</string>
<string name="subscription_change_failed">Abonnement konnte nicht geändert werden</string>
<string name="subscription_change_failed">Abonnement konnte nicht geändert werden</string>
<string name="subscription_update_failed">Abonnement konnte nicht aktualisiert werden</string>
<string name="resume_on_audio_focus_gain_summary">Nach Unterbrechungen (z.B. Telefonaten) Wiedergabe fortsetzen</string>
<string name="notification_channel_name">NewPipe-Benachrichtigung</string>
<string name="notification_channel_description">Benachrichtigungen für NewPipe-Hintergrund- und Pop-up Wiedergabe</string>
<string name="tab_main">Hauptmenü</string>
<string name="settings_category_player_behavior_title">Verhalten</string>
<string name="settings_category_history_title">Verlauf &amp; Cache</string>
<string name="playlist">Wiedergabeliste</string>
<string name="undo">Rückgängig machen</string>
<string name="search_no_results">Keine Ergebnisse</string>
<string name="no_subscribers">Keine Abonnenten</string>
<plurals name="subscribers">
<item quantity="one">%s Abonnent</item>
<item quantity="other">%s Abonnenten</item>
</plurals>
<item quantity="one">%s Abonnent</item>
<item quantity="other">%s Abonnenten</item>
</plurals>
<string name="no_views">Keine Aufrufe</string>
<plurals name="views">
<item quantity="one">%s Aufruf</item>
<item quantity="other">%s Aufrufe</item>
</plurals>
<item quantity="one">%s Aufruf</item>
<item quantity="other">%s Aufrufe</item>
</plurals>
<string name="no_videos">Keine Videos</string>
<plurals name="videos">
<item quantity="one">Video</item>
<item quantity="other">Videos</item>
</plurals>
<item quantity="one">Video</item>
<item quantity="other">Videos</item>
</plurals>
<string name="charset_most_special_characters">Die meisten Sonderzeichen</string>
<string name="item_deleted">Element gelöscht</string>
<string name="resume_on_audio_focus_gain_title">Fortsetzen bei erneutem Fokussieren</string>
<string name="settings_category_player_title">Player</string>
<string name="empty_subscription_feed_subtitle">Nichts hier außer das Zirpen der Grillen</string>
<string name="delete_item_search_history">Möchtest du dieses Element aus dem Suchverlauf löschen?</string>
<string name="blank_page_summary">Leere Seite</string>
<string name="blank_page_summary">Leere Seite</string>
<string name="select_a_channel">Wähle einen Kanal aus</string>
<string name="no_channel_subscribed_yet">Noch keine Kanalabonnements vorhanden</string>
<string name="trending">Trends</string>
<string name="popup_playing_append">In der Warteschlange der Pop-up-Wiedergabe</string>
<string name="play_all">Alles abspielen</string>
<string name="play_queue_remove">Entfernen</string>
<string name="play_queue_audio_settings">Audio-Einstellungen</string>
<string name="player_stream_failure">Konnte diesen Stream nicht abspielen</string>
@ -276,24 +231,21 @@
<string name="top_50">Top 50</string>
<string name="player_unrecoverable_failure">Nicht behebbarer Wiedergabefehler aufgetreten</string>
<string name="player_recoverable_failure">Wiederherstellen nach einem Wiedergabefehler</string>
<string name="kiosk_page_summary">Kiosk-Seite</string>
<string name="select_a_kiosk">Kiosk auswählen</string>
<string name="kiosk">Kiosk</string>
<string name="show_hold_to_append_summary">Tipp anzeigen, wenn der Hintergrundwiedergabe- oder Pop-up-Button auf der Videodetailseite gedrückt gehalten wird</string>
<string name="background_player_append">In der Warteschlange der Hintergrundwiedergabe</string>
<string name="new_and_hot">Neu &amp; Heiß</string>
<string name="hold_to_append">Halten, um zur Wiedergabeliste hinzuzufügen</string>
<string name="show_hold_to_append_title">\"Gedrückt halten, um hinzuzufügen\" Tipp anzeigen</string>
<string name="show_hold_to_append_title">\"Gedrückt halten, um hinzuzufügen\" Tipp anzeigen</string>
<string name="unknown_content">[Unbekannt]</string>
<string name="enqueue_on_background">In Warteschlange für Hintergrundwiedergabe</string>
<string name="enqueue_on_popup">In Warteschlange für Pop-up</string>
<string name="start_here_on_main">Ab hier wiedergeben</string>
<string name="start_here_on_background">Ab hier im Hintergrundmodus</string>
<string name="start_here_on_popup">Ab hier im Pop-up</string>
<string name="donation_title">Spenden</string>
<string name="donation_title">Spenden</string>
<string name="give_back">Zurückgeben</string>
<string name="website_title">Website</string>
<string name="website_encouragement">Besuche die NewPipe Website für weitere Informationen und Neuigkeiten.</string>
@ -303,71 +255,53 @@
<string name="default_content_country_title">Bevorzugtes Land des Inhalts</string>
<string name="always">Immer</string>
<string name="just_once">Nur einmal</string>
<string name="toggle_orientation">Ausrichtung umschalten</string>
<string name="switch_to_background">In den Hintergrund wechseln</string>
<string name="switch_to_popup">Zum Pop-up wechseln</string>
<string name="switch_to_main">Zur normalen Wiedergabe wechseln</string>
<string name="external_player_unsupported_link_type">Externe Player unterstützen diese Art von Links nicht</string>
<string name="invalid_url_toast">Ungültige URL</string>
<string name="video_streams_empty">Keine Video-Streams gefunden</string>
<string name="audio_streams_empty">Keine Audio-Streams gefunden</string>
<string name="drawer_open">Navigationsleiste öffnen</string>
<string name="drawer_close">Navigationsleiste schließen</string>
<string name="video_player">Video-Player</string>
<string name="background_player">Hintergrund-Player</string>
<string name="popup_player">Popup-Player</string>
<string name="always_ask_player">Immer fragen</string>
<string name="preferred_player_fetcher_notification_title">Informationen werden abgerufen…</string>
<string name="preferred_player_fetcher_notification_message">Gewünschten Inhalt laden</string>
<string name="import_data_title">Datenbank importieren</string>
<string name="import_data_title">Datenbank importieren</string>
<string name="export_data_title">Datenbank exportieren</string>
<string name="import_data_summary">Überschreibt deinen aktuellen Verlauf und deine Abonnements</string>
<string name="export_data_summary">Verlauf, Abonnements und Wiedergabelisten exportieren</string>
<string name="no_valid_zip_file">Keine gültige ZIP-Datei</string>
<string name="could_not_import_all_files">Warnung: Nicht alle Dateien konnten importiert werden.</string>
<string name="override_current_data">Dies wird deine aktuellen Einstellungen überschreiben.</string>
<string name="show_info">Info anzeigen</string>
<string name="tab_bookmarks">Lesezeichen für Wiedergabelisten</string>
<string name="controls_add_to_playlist_title">Hinzufügen zu</string>
<string name="detail_drag_description">Zum Neuordnen ziehen</string>
<string name="create">Erstellen</string>
<string name="delete_one">Einen löschen</string>
<string name="delete_all">Alle löschen</string>
<string name="rename">Umbenennen</string>
<string name="delete_stream_history_prompt">Möchtest du dieses Element aus dem Wiedergabeverlauf löschen?</string>
<string name="delete_all_history_prompt">Bist du sicher, dass du alle Elemente aus dem Verlauf löschen möchtest?</string>
<string name="title_last_played">Zuletzt wiedergegeben</string>
<string name="title_most_played">Am häufigsten wiedergegeben</string>
<string name="always_ask_open_action">Immer fragen</string>
<string name="create_playlist">Neue Wiedergabeliste</string>
<string name="delete_playlist">Löschen</string>
<string name="rename_playlist">Umbenennen</string>
<string name="append_playlist">Zur Wiedergabeliste hinzufügen</string>
<string name="set_as_playlist_thumbnail">Als Vorschaubild der Wiedergabeliste festlegen</string>
<string name="unbookmark_playlist">Lesezeichen entfernen</string>
<string name="delete_playlist_prompt">Diese Wiedergabeliste löschen?</string>
<string name="playlist_creation_success">Wiedergabeliste erstellt</string>
<string name="playlist_add_stream_success">Zur Wiedergabeliste hinzugefügt</string>
<string name="playlist_thumbnail_change_success">Vorschaubild der Wiedergabeliste geändert.</string>
<string name="playlist_delete_failure">Konnte Wiedergabeliste nicht löschen.</string>
<string name="caption_none">Keine Untertitel</string>
<string name="caption_font_size_settings_title">Schriftgröße der Untertitel</string>
<string name="dismiss">Abbrechen</string>
<string name="normal_caption_font_size">Normale Schriftgröße</string>
@ -375,30 +309,24 @@
<string name="use_inexact_seek_title">Schnelle, ungenaue Suche verwenden</string>
<string name="use_inexact_seek_summary">Mit ungenauem Suchen kann die Abspielposition schneller erreicht werden, aber auf Kosten der Genauigkeit</string>
<string name="file">Datei</string>
<string name="invalid_directory">Verzeichnis existiert nicht</string>
<string name="invalid_file">Die Datei existiert nicht oder die Rechte zum Lesen oder Schreiben fehlen</string>
<string name="file_name_empty_error">Dateiname darf nicht leer sein</string>
<string name="error_occurred_detail">Ein Fehler ist aufgetreten: %1$s</string>
<string name="caption_auto_generated">Automatisch erzeugt</string>
<string name="smaller_caption_font_size">Kleinere Schrift</string>
<string name="larger_caption_font_size">Größere Schrift</string>
<string name="enable_leak_canary_title">LeakCanary aktivieren</string>
<string name="import_from">Import von</string>
<string name="export_to">Export nach</string>
<string name="import_ongoing">Importiere…</string>
<string name="export_ongoing">Exportiere…</string>
<string name="import_file_title">Datei importieren</string>
<string name="previous_export">Vorheriger Export</string>
<string name="import_network_expensive_warning">Beachte, dass diese Aktion das Netzwerk stark belasten kann.
\n
\nMöchtest du fortfahren?</string>
<string name="download_thumbnail_title">Vorschaubilder laden</string>
<string name="download_thumbnail_title">Vorschaubilder laden</string>
<string name="thumbnail_cache_wipe_complete_notice">Bilder-Cache gelöscht</string>
<string name="metadata_cache_wipe_title">Zwischengespeicherte Metadaten löschen</string>
<string name="metadata_cache_wipe_summary">Alle zwischengespeicherten Website-Daten entfernen</string>
@ -412,29 +340,23 @@
<string name="import_title">Import</string>
<string name="subscriptions_import_unsuccessful">Abonnements konnten nicht importiert werden</string>
<string name="subscriptions_export_unsuccessful">Abonnements konnten nicht exportiert werden</string>
<string name="playback_speed_control">Wiedergabegeschwindigkeitsregler</string>
<string name="playback_tempo">Geschwindigkeit</string>
<string name="playback_pitch">Tonhöhe</string>
<string name="unhook_checkbox">Verknüpfung aufheben (kann zu Verzerrungen führen)</string>
<string name="playback_nightcore">Nightcore</string>
<string name="playback_default">Standard</string>
<string name="download_thumbnail_summary">Abschalten, um das Laden von Miniaturansichten zu verhindern, was Daten- und Speicherverbrauch spart. Änderungen löschen den Bildzwischenspeicher sowohl im Arbeitsspeicher als auch auf der Festplatte.</string>
<string name="download_thumbnail_summary">Abschalten, um das Laden von Miniaturansichten zu verhindern, was Daten- und Speicherverbrauch spart. Änderungen löschen den Bildzwischenspeicher sowohl im Arbeitsspeicher als auch auf dem internen Speicher.</string>
<string name="auto_queue_title">Nächsten Stream automatisch einreihen</string>
<string name="auto_queue_summary">Automatisches Anhängen eines verwandten Streams beim Abspielen des letzten Streams in einer nicht wiederholten Warteschlange.</string>
<string name="auto_queue_summary">Automatisches Anhängen eines verwandten Streams beim Abspielen des letzten Streams in einer nicht wiederholten Warteschlange</string>
<string name="drawer_header_action_paceholder_text">Hier wird bald etwas stehen ;D</string>
<string name="bookmark_playlist">Wiedergabeliste mit Lesezeichen versehen</string>
<string name="resize_fit">Anpassen</string>
<string name="resize_fill">Füllen</string>
<string name="resize_zoom">Vergrößern</string>
<string name="enable_leak_canary_summary">Speicherlecküberwachung kann dazu führen, dass die App beim Heap-Dumping nicht mehr reagiert</string>
<string name="enable_disposed_exceptions_title">Fehler außerhalb des Lebenszyklus melden</string>
<string name="enable_disposed_exceptions_summary">Erzwingen der Meldung unzustellbarer Rx-Ausnahmen außerhalb des Lebenszyklus von Fragmenten oder Aktivitäten nach der Entsorgung</string>
<string name="import_youtube_instructions">Importiere YouTube-Abonnements, indem du die Exportdatei herunterlädst:
\n
\n1. Gehe zu dieser URL: %1$s
@ -447,17 +369,12 @@
\n3. Melden dich an, falls du dazu aufgefordert wirst
\n4. Kopiere die Profil-URL, zu der du weitergeleitet wurdest.</string>
<string name="import_soundcloud_instructions_hint">yourID, soundcloud.com/yourid</string>
<string name="no_streams_available_download">Keine Streams zum Download verfügbar</string>
<string name="preferred_open_action_settings_title">Bevorzugte \'Öffnen\' Aktion</string>
<string name="preferred_open_action_settings_summary">Standardaktion beim Öffnen von Inhalten - %s</string>
<string name="caption_setting_title">Untertitel</string>
<string name="caption_setting_description">Textgröße und Hintergrund der Untertitel im Player anpassen. Wird erst nach Neustart der App wirksam.</string>
<string name="toast_no_player">Keine App zum Abspielen dieser Datei installiert</string>
<string name="clear_views_history_title">Wiedergabeverlauf löschen</string>
<string name="clear_views_history_summary">Löscht den Verlauf der abgespielten Streams</string>
<string name="delete_view_history_alert">Den ganzen Wiedergabeverlauf löschen\?</string>
@ -467,17 +384,15 @@
<string name="delete_search_history_alert">Den gesamten Suchverlauf löschen\?</string>
<string name="search_history_deleted">Suchverlauf gelöscht.</string>
<string name="one_item_deleted">1 Element gelöscht.</string>
<string name="app_license">NewPipe ist freie Copyleft-Software: Du kannst sie nach Belieben benutzen, untersuchen, mit anderen teilen und verbessern. Insbesondere kannst du sie unter den von der Free Software Foundation veröffentlichten Bedingungen der GNU General Public License, in der Version 3 der Lizenz oder (nach deiner Wahl) jeder späteren Version, weitergeben und/oder verändern.</string>
<string name="import_settings">Möchtest du auch Einstellungen importieren?</string>
<string name="privacy_policy_title">NewPipe-Datenschutzbestimmungen</string>
<string name="privacy_policy_encouragement">Dem NewPipe-Projekt ist Datenschutz sehr wichtig. Deshalb sammelt diese App keine Daten ohne deine Zustimmung.
\nNewPipes Datenschutzbestimmungen erklären im Detail, welche Daten beim Absenden eines Absturzberichtes verschickt und gespeichert werden.</string>
<string name="read_privacy_policy">Datenschutzbestimmungen lesen</string>
<string name="accept">Akzeptieren</string>
<string name="decline">Ablehnen</string>
<string name="start_accept_privacy_policy">Um der europäischen Datenschutz-Grundverordnung (DSGVO) gerecht zu werden, weisen wir hiermit auf NewPipe\'s Datenschutzerklärung hin. Bitte lies sie sorgfältig durch.
<string name="start_accept_privacy_policy">Um der europäischen Datenschutz-Grundverordnung (DSGVO) gerecht zu werden, weisen wir hiermit auf NewPipe\'s Datenschutzerklärung hin. Bitte lies sie sorgfältig durch.
\nDu musst den Datenschutzrichtlinien zustimmen, um den Fehlerbericht an uns zu senden.</string>
<string name="limit_data_usage_none_description">Unbegrenzt</string>
<string name="limit_mobile_data_usage_title">Auflösung bei Verwendung mobiler Daten begrenzen</string>
@ -486,15 +401,13 @@
<string name="minimize_on_exit_none_description">Keine</string>
<string name="minimize_on_exit_background_description">Zum Hintergrund-Player minimieren</string>
<string name="minimize_on_exit_popup_description">Zum Popup-Player minimieren</string>
<string name="skip_silence_checkbox">Vorspulen während der Stille</string>
<string name="skip_silence_checkbox">Vorspulen während der Stille</string>
<string name="playback_step">Schritt</string>
<string name="playback_reset">Zurücksetzen</string>
<string name="channels">Kanäle</string>
<string name="playlists">Wiedergabelisten</string>
<string name="tracks">Titel</string>
<string name="users">Nutzer</string>
<string name="users">Benutzer</string>
<string name="unsubscribe">Deabonnieren</string>
<string name="tab_new">Neuer Tab</string>
<string name="tab_choose">Tab wählen</string>
@ -524,7 +437,7 @@
<string name="app_update_notification_content_title">NewPipe-Aktualisierung verfügbar!</string>
<string name="app_update_notification_content_text">Zum Herunterladen antippen</string>
<string name="missions_header_finished">Fertig</string>
<string name="missions_header_pending">In der Warteschlange</string>
<string name="missions_header_pending">Ausstehend</string>
<string name="paused">pausiert</string>
<string name="queued">eingereiht</string>
<string name="post_processing">Nachbearbeitung</string>
@ -535,19 +448,19 @@
<string name="download_finished_more">%s heruntergeladen</string>
<string name="generate_unique_name">Eindeutigen Namen erzeugen</string>
<string name="overwrite">Überschreiben</string>
<string name="overwrite_warning">Eine heruntergeladene Datei dieses Namens existiert bereits</string>
<string name="download_already_running">Eine Datei dieses Namens wird gerade heruntergeladen</string>
<string name="overwrite_unrelated_warning">Eine Datei mit diesem Namen existiert bereits</string>
<string name="download_already_running">Eine heruntergeladene Datei mit diesem Namen existiert bereits</string>
<string name="show_error">Fehler anzeigen</string>
<string name="label_code">Code</string>
<string name="error_path_creation">Die Datei kann nicht erstellt werden</string>
<string name="error_file_creation">Der Zielordner kann nicht erstellt werden</string>
<string name="error_file_creation">Die Datei kann nicht erstellt werden</string>
<string name="error_path_creation">Der Zielordner kann nicht erstellt werden</string>
<string name="error_permission_denied">System verweigert den Zugriff</string>
<string name="error_ssl_exception">Sichere Verbindung fehlgeschlagen</string>
<string name="error_unknown_host">Der Server konnte nicht gefunden werden</string>
<string name="error_connect_host">Kann nicht mit dem Server verbinden</string>
<string name="error_http_no_content">Der Server sendet keine Daten</string>
<string name="error_http_unsupported_range">Der Server erlaubt kein mehrfädiges Herunterladen wiederhole mit @string/msg_threads = 1</string>
<string name="error_http_requested_range_not_satisfiable">Angefragter Bereich nicht bedienbar</string>
<string name="error_http_requested_range_not_satisfiable">Gewünschter Bereich ist nicht verfügbar</string>
<string name="error_http_not_found">Nicht gefunden</string>
<string name="error_postprocessing_failed">Nachbearbeitung fehlgeschlagen</string>
<string name="clear_finished_download">Um fertige Downloads bereinigen</string>
@ -559,4 +472,5 @@
<string name="pause_downloads_on_mobile_desc">Downloads, die nicht pausiert werden können, werden wiederholt</string>
<string name="conferences">Konferenzen</string>
<string name="events">Ereignisse</string>
<string name="error_timeout">Verbindungszeitüberschreitung</string>
</resources>

View File

@ -16,15 +16,12 @@
<string name="screen_rotation">περιστροφή</string>
<string name="use_external_video_player_title">Χρήση εξωτερικής εφαρμογής αναπαραγωγής βίντεο</string>
<string name="use_external_audio_player_title">Χρήση εξωτερικής συσκευής αναπαραγωγής ήχου</string>
<string name="download_path_title">Διαδρομή λήψης βίντεο</string>
<string name="download_path_summary">Διαδρομή για αποθήκευση των βίντεο</string>
<string name="download_path_dialog_title">Εισάγετε διαδρομή για λήψη των βίντεο</string>
<string name="download_path_audio_title">Διαδρομή λήψης αρχείων ήχου</string>
<string name="download_path_audio_summary">Αυτή είναι η διαδρομή για την αποθήκευση αρχείων ήχου</string>
<string name="download_path_audio_dialog_title">Εισάγετε διαδρομή για λήψη αρχείων ήχου</string>
<string name="default_resolution_title">Προεπιλεγμένη ανάλυση</string>
<string name="play_with_kodi_title">Αναπαραγωγή με το Kodi</string>
<string name="kore_not_found">Η εφαρμογή Kore δεν βρέθηκε. Εγκατάσταση της;</string>
@ -32,12 +29,9 @@
<string name="show_play_with_kodi_summary">Προβολή μιας επιλογής για αναπαραγωγή με το Kodi media center</string>
<string name="play_audio">Ήχος</string>
<string name="default_audio_format_title">Προεπιλεγμένη μορφή ήχου</string>
<string name="webm_description">WebM — δωρεάν μορφή</string>
<string name="m4a_description">Μ4Α — καλύτερη ποιότητα</string>
<string name="theme_title">Θέμα</string>
<string name="dark_theme_title">Σκοτεινό</string>
<string name="light_theme_title">Φωτεινό</string>
<string name="download_dialog_title">Λήψη</string>
<string name="next_video_title">Επόμενο</string>
<string name="show_next_and_similar_title">Εμφάνιση \"Επόμενου\" και \"Σχετικών\" βίντεο</string>
@ -49,7 +43,6 @@
<string name="background_player_playing_toast">Αναπαραγωγή στο υπόβαθρο</string>
<string name="play_btn_text">Αναπαραγωγή</string>
<string name="network_error">Σφάλμα δικτύου</string>
<string name="list_thumbnail_view_description">Μικρογραφία προεπισκόπισης βίντεο</string>
<string name="detail_thumbnail_view_description">Μικρογραφία προεπισκόπησης βίντεο</string>
<string name="detail_uploader_thumbnail_view_description">Μικρογραφία εικόνας προφίλ του χρήστη</string>
@ -57,11 +50,9 @@
<string name="detail_dislikes_img_view_description">Dislike</string>
<string name="use_tor_title">Χρήση του Tor</string>
<string name="use_tor_summary">(Πειραματικό) Αναγκάζει την κίνηση λήψης μέσω Tor για αυξημένη προστασία προσωπικών δεδομένων (η αναπαραγωγή δεν υποστηρίζεται ακόμη).</string>
<string name="err_dir_create">Δεν μπόρεσε να δημιουργηθεί ο φάκελος \'%1$s\'</string>
<string name="info_dir_created">Δημιουργήθηκε ο φάκελος \'%1$s\'</string>
<string name="short_billion">Δ</string>
<string name="short_billion">Δις</string>
<string name="open_in_popup_mode">Άνοιγμα σε αναδυόμενο παράθυρο</string>
<string name="subscribe_button_title">Εγγραφή</string>
<string name="subscribed_button_title">Εγγεγραμμένος</string>
@ -82,8 +73,6 @@
<string name="what_happened_headline">Τι συνέβη:</string>
<string name="your_comment">Το σχόλιό σας (στα Αγγλικά):</string>
<string name="error_details_headline">Λεπτομέρειες:</string>
<string name="report_error">Αναφορά Σφάλματος</string>
<string name="video">Βίντεο</string>
<string name="audio">Ήχος</string>
@ -100,8 +89,7 @@
<string name="title_activity_history">Ιστορικό</string>
<string name="action_history">Ιστορικό</string>
<string name="show_info">Εμφάνιση πληροφοριών</string>
<string name="main_bg_subtitle">Πατήστε στην αναζήτηση για να ξεκινήσετε</string>
<string name="main_bg_subtitle">Πατήστε αναζήτηση για να ξεκινήσετε</string>
<string name="no_player_found_toast">Δε βρέθηκε πρόγραμμα αναπαραγωγής ροής δεδομένων (μπορείτε να εγκαταστήσετε το VLC για να κάνετε αναπαραγωγή).</string>
<string name="controls_download_desc">Κατέβασμα του αρχείου ροής</string>
<string name="use_external_video_player_summary">Αφαίρεση του ήχου από κάποιες αναλύσεις</string>
@ -110,15 +98,12 @@
<string name="subscription_change_failed">Αδύνατη η αλλαγή της εγγραφής</string>
<string name="subscription_update_failed">Αδύνατη η ενημέρωση της εγγραφής</string>
<string name="tab_main">Κύριο</string>
<string name="tab_subscriptions">Εγγραφές</string>
<string name="tab_subscriptions">Συνδρομές</string>
<string name="tab_bookmarks">Αγαπημένες λίστες αναπαραγωγής</string>
<string name="fragment_whats_new">Νέα</string>
<string name="controls_background_title">Στο παρασκήνιο</string>
<string name="controls_popup_title">Αναδυόμενο παράθυρο</string>
<string name="controls_add_to_playlist_title">Προσθήκη σε</string>
<string name="autoplay_by_calling_app_title">Αυτόματη αναπαραγωγή</string>
<string name="autoplay_by_calling_app_summary">Αναπαραγωγή του βίντεο όταν το NewPipe καλείται από άλλη εφαρμογή</string>
<string name="default_popup_resolution_title">Προεπιλεγμένη ανάλυση αναδυόμενου παραθύρου</string>
@ -129,7 +114,7 @@
<string name="use_inexact_seek_title">Χρήση γρήγορης μη-ακριβούς αναζήτησης</string>
<string name="use_inexact_seek_summary">Η μη-ακριβής αναζήτηση επιτρέπει στην εφαρμογή να αναζητεί θέσεις στο βίντεο γρηγορότερα με μειωμένη ακρίβεια</string>
<string name="download_thumbnail_title">Φόρτωση thumbnails</string>
<string name="download_thumbnail_summary">Αν η επιλογή είναι απενεργοποιημένη δεν φορτώνονται οι μικρογραφίες, χρησιμοποιώντας λιγότερα δεδομένα και μνήμη. Οι αλλαγές σβήνουν την προσωρινή μνήμη των εικόνων.</string>
<string name="download_thumbnail_summary">Με την απενεργοποίηση δεν φορτώνονται οι μικρογραφίες, χρησιμοποιώντας λιγότερα δεδομένα και μνήμη. Οι αλλαγές σβήνουν τις προσωρινά αποθηκευμένες εικόνες στην μνήμη.</string>
<string name="thumbnail_cache_wipe_complete_notice">Εκκαθαρίστηκε η προσωρινή μνήμη εικονών</string>
<string name="metadata_cache_wipe_title">Εκκαθάριση προσωρινά αποθηκευμένων μεταδεδομένων</string>
<string name="metadata_cache_wipe_summary">Αφαίρεση όλων των προσωρινά αποθηκευμένων δεδομένων ιστοσελίδων</string>
@ -158,7 +143,7 @@
<string name="popup_playing_append">Προστέθηκε στη λίστα αναπαραγωγής αναδυόμενου παραθύρου</string>
<string name="content">Περιεχόμενο</string>
<string name="show_age_restricted_content_title">Περιεχόμενο περιορισμένης ηλικίας</string>
<string name="video_is_age_restricted">Βίντεο περιορισμένης πρόσβασης. Για να επιτρέπετε περιερχόμενο τέτοιου είδους, ενεργοποιήστε το στις \"Ρυθμίσεις\".</string>
<string name="video_is_age_restricted">Βίντεο ηλικιακά περιορισμένης πρόσβασης. Για να επιτρέπετε περιερχόμενο τέτοιου είδους, ενεργοποιήστε το στις \"Ρυθμίσεις\".</string>
<string name="duration_live">ΖΩΝΤΑΝΑ</string>
<string name="error_report_title">Αναφορά σφαλμάτων</string>
<string name="channels">Κανάλια</string>
@ -176,17 +161,13 @@
<string name="always">Πάντα</string>
<string name="just_once">Μόνο μία φορά</string>
<string name="file">Αρχείο</string>
<string name="notification_channel_name">Ειδοποίηση NewPipe</string>
<string name="notification_channel_description">Ειδοποιήσεις για την αναπαραγωγή Παρασκηνίου και Αναδυόμενου Παραθύρου</string>
<string name="unknown_content">[Άγνωστο]</string>
<string name="toggle_orientation">Αλλαγή προσανατολισμού</string>
<string name="switch_to_background">Αλλαγή σε Παρασκήνιο</string>
<string name="switch_to_popup">Αλλαγή σε Αναδυόμενο Παράθυρο</string>
<string name="switch_to_main">Αλλαγή σε Κύριο</string>
<string name="import_data_title">Εισαγωγή βάσης δεδομένων</string>
<string name="export_data_title">Εξαγωγή βάσης δεδομένων</string>
<string name="import_data_summary">Θα παρακάμψει το τρέχον ιστορικό και εγγραφές σας</string>
@ -223,7 +204,6 @@
<string name="file_name_empty_error">Το όνομα αρχείου δεν μπορεί να είναι κενό</string>
<string name="error_occurred_detail">Προέκυψε ένα σφάλμα: %1$s</string>
<string name="no_streams_available_download">Δεν υπάρχουν διαθέσιμες ροές για λήψη</string>
<string name="sorry_string">Λυπούμαστε, αυτό δεν έπρεπε να έχει συμβεί.</string>
<string name="error_report_button_text">Αναφορά σφάλματος με ηλεκτρονικό ταχυδρομίο</string>
<string name="error_snackbar_message">Λυπούμαστε, συνέβησαν κάποια σφάλματα.</string>
@ -232,32 +212,25 @@
<string name="search_no_results">Κανένα αποτέλεσμα</string>
<string name="empty_subscription_feed_subtitle">Δεν υπάρχει τίποτα εδώ</string>
<string name="detail_drag_description">Σύρετε για ταξινόμηση</string>
<string name="retry">Προσπάθεια εκ νέου</string>
<string name="storage_permission_denied">Δεν δώθηκε άδεια εγγραφής στην εσωτερική μνήμη</string>
<string name="use_old_player_title">Χρήση παλαιάς συσκευής αναπαραγωγής</string>
<string name="use_old_player_summary">Παλαιά συσκευή αναπαραγωγής Mediaframework</string>
<string name="short_thousand">Κ</string>
<string name="short_million">Μ</string>
<string name="short_thousand">χιλ</string>
<string name="short_million">Εκ</string>
<string name="no_subscribers">Κανένας εγγεγραμένος χρήστης</string>
<plurals name="subscribers">
<item quantity="one">%s εγγεγραμένος χρήστης</item>
<item quantity="other">%s εγγεγραμένοι χρήστες</item>
</plurals>
<item quantity="one">%s εγγεγραμένος χρήστης</item>
<item quantity="other">%s εγγεγραμένοι χρήστες</item>
</plurals>
<string name="no_views">Καμία προβολή</string>
<plurals name="views">
<item quantity="one">%s προβολή</item>
<item quantity="other">%s προβολές</item>
</plurals>
<item quantity="one">%s προβολή</item>
<item quantity="other">%s προβολές</item>
</plurals>
<string name="no_videos">Κανένα βίντεο</string>
<plurals name="videos">
<item quantity="one">%s βίντεο</item>
<item quantity="other">"%s βίντεο "</item>
</plurals>
<item quantity="one">Βίντεο</item>
<item quantity="other">Βίντεο</item>
</plurals>
<string name="start">Εκκίνηση</string>
<string name="view">Αναπαραγωγή</string>
<string name="create">Δημιουργία</string>
@ -266,10 +239,8 @@
<string name="checksum">Άθροισμα ελέγχου</string>
<string name="dismiss">Αγνόηση</string>
<string name="rename">Μετονομασία</string>
<string name="add">Νέα αποστολη</string>
<string name="finish">ΟΚ</string>
<string name="msg_name">Όνομα αρχείου</string>
<string name="msg_threads">Νήματα</string>
<string name="msg_server_unsupported">Ο εξυπηρετητής δεν υποστηρίζεται</string>
@ -281,19 +252,14 @@
<string name="msg_popup_permission">Αυτή η άδεια είναι απαραίτητη για
\nτο άνοιγμα αναδυόμενων παραθύρων</string>
<string name="one_item_deleted">1 αντικείμενο διαγράφηκε.</string>
<string name="reCaptchaActivity">Αυτόματο τεστ</string>
<string name="reCaptcha_title">Πρόκληση reCAPTCHA</string>
<string name="recaptcha_request_toast">Ζητήθηκε πρόκληση reCAPTCHA</string>
<string name="settings_file_charset_title">Επιτρεπτοί χαρακτήρες σε ονόματα αρχείων</string>
<string name="settings_file_charset_title">Επιτρεπόμενοι χαρακτήρες σε ονόματα αρχείων</string>
<string name="settings_file_replacement_character_summary">Οι μη έγκυροι χαρακτήρες αντικαθίστανται με αυτήν την τιμή</string>
<string name="settings_file_replacement_character_title">Αντικαταστάτης χαρακτήρας</string>
<string name="charset_most_special_characters">Οι περισσότεροι ειδικοί χαρακτήρες</string>
<string name="toast_no_player">Δεν υπάρχει εφαρμογή εγκατεστημένη για την αναπαραγωγή αυτού του αρχείου</string>
<string name="title_activity_about">Σχετικά με το NewPipe</string>
<string name="action_about">Περί</string>
<string name="title_licenses">Άδειες Τρίτων</string>
@ -317,10 +283,8 @@
<string name="app_license_title">Η άδεια του NewPipe</string>
<string name="app_license">Το NewPipe είναι copylelft ελεύθερο λογισμικό: Μπορείτε να το χρησιμοποιήσετε, να το μελετήσετε, να το μοιραστείτε και να το βελτιώσετε κατά βούληση. Ειδικότερα, μπορείτε να το αναδιανείμετε ή/και να το τροποποιήσετε υπό την άδεια GNU General Public Licence όπως αυτή εκδόθηκε από το Free Software Foundation, είτε υπό την έκδοση 3 της Άδειας είτε (προεραιτικά) υπό οποιαδήποτε μεταγενέστερη άδεια.</string>
<string name="read_full_license">Διαβάστε την άδεια</string>
<string name="title_history_search">Αναζητημένα</string>
<string name="title_history_view">Έχει γίνει προβολή</string>
<string name="title_history_search">Αναζητήθηκαν</string>
<string name="title_history_view">Προβλήθηκαν</string>
<string name="history_disabled">Το ιστορικό έχει απενεργοποιηθεί</string>
<string name="history_empty">Το ιστορικό είναι κενό</string>
<string name="history_cleared">Το ιστορικό εκκαθαρίστηκε</string>
@ -330,7 +294,6 @@
<string name="delete_all_history_prompt">Είστε σίγουροι ότι θέλετε να σβήσετε όλα τα αντικείμενα από το ιστορικό;</string>
<string name="title_last_played">Τελευταία αναπαραγωγή</string>
<string name="title_most_played">Αναπαράχθηκε περισσότερο</string>
<string name="main_page_content">Περιεχόμενο της κεντρικής σελίδας</string>
<string name="blank_page_summary">Κενή σελίδα</string>
<string name="kiosk_page_summary">Σελίδα περιπτέρου</string>
@ -345,7 +308,6 @@
<string name="could_not_import_all_files">Προσοχή: Δεν ήταν δυνατή η εισαγωγή όλων των αρχείων.</string>
<string name="override_current_data">Αυτό θα παρακάμψει τις τρέχουσες ρυθμίσεις σας.</string>
<string name="import_settings">Θέλετε επίσης να εισάγετε ρυθμίσεις;</string>
<string name="kiosk">Περίπτερο</string>
<string name="title_activity_background_player">Συσκευή αναπαραγωγής Παρασκηνίου</string>
<string name="title_activity_popup_player">Συσκευή αναπαραγωγής Αναδυόμενου παραθύρου</string>
@ -358,71 +320,52 @@
<string name="start_here_on_main">Εκκίνηση Αναπαραγωγής εδώ</string>
<string name="start_here_on_background">Εκκίνηση εδώ όταν είναι στο Παρασκήνιο</string>
<string name="start_here_on_popup">Εκκίνηση εδώ όταν είναι στο Αναδυόμενο Παράθυρο</string>
<string name="drawer_open">Άνοιγμα Συρταριού</string>
<string name="drawer_close">Κλείσιμο Συρταριού</string>
<string name="drawer_header_action_paceholder_text">Κάτι θα παιχτεί εδω σύντομα ;D</string>
<string name="top_50">Τοπ 50</string>
<string name="new_and_hot">Καινούρια &amp; δημοφιλή</string>
<string name="preferred_open_action_settings_title">Προτιμώμενη ενέργεια ανοίγματος</string>
<string name="preferred_open_action_settings_summary">Προεπιλεγμένη ενέργεια για το άνοιγμα περιεχομένου — %s</string>
<string name="video_player">Συσκευή αναπαραγωγής βίντεο</string>
<string name="background_player">Αναπαραγωγή Παρασκηνίου</string>
<string name="popup_player">Αναπαραγωγή σε Αναδυόμενο Παράθυρο</string>
<string name="always_ask_open_action">Πάντα ερώτηση</string>
<string name="preferred_player_fetcher_notification_title">Γίνεται λήψη πληροφοριών…</string>
<string name="preferred_player_fetcher_notification_message">Γίνεται φόρτωση του ζητούμενου περιεχομένου</string>
<string name="create_playlist">Νέα Λίστα Αναπαραγωγής</string>
<string name="delete_playlist">Διαγραφή</string>
<string name="rename_playlist">Μετονομασία</string>
<string name="playlist_name_input">Όνομα</string>
<string name="append_playlist">Προσθήκη στη Λίστα</string>
<string name="set_as_playlist_thumbnail">Ορισμός ως μικρογραφία λίστας αναπαραγωγής</string>
<string name="bookmark_playlist">Προσθήκη Σελιδοδείκτη στη Λίστα</string>
<string name="unbookmark_playlist">Διαγραφή Σελιδοδείκτη</string>
<string name="delete_playlist_prompt">Διαγραφή αυτής της λίστας αναπαραγωγής;</string>
<string name="playlist_creation_success">Η λίστα αναπαραγωγής δημιουργήθηκε</string>
<string name="playlist_add_stream_success">Προστέθηκε στη λίστα αναπαραγωγής</string>
<string name="playlist_thumbnail_change_success">Η μικρογραφία της λίστας αναπαραγωγής άλλαξε.</string>
<string name="playlist_delete_failure">Δεν ήταν δυνατή η διαγραφή της λίστας.</string>
<string name="caption_none">Δεν υπάρχουν υπότιτλοι</string>
<string name="caption_none">Χωρίς υπότιτλους</string>
<string name="resize_fit">Προσαρμογή</string>
<string name="resize_fill">Γέμισμα</string>
<string name="resize_zoom">Μεγέθυνση</string>
<string name="caption_auto_generated">Αυτόματοι</string>
<string name="caption_setting_title">Υπότιτλοι</string>
<string name="caption_setting_description">Τροποποίηση του μεγέθους και του φόντου των υπότιτλων. Απαιτεί επανεκκίνηση της εφαρμογής.</string>
<string name="enable_leak_canary_title">Ενεργοποίηση του LeakCanary</string>
<string name="enable_leak_canary_summary">Η παρακολούθηση των διαρροών μνήμης μπορεί να προκαλέσει την διακοπή της εφαρμογής</string>
<string name="enable_disposed_exceptions_summary">Υποχρεωτική αναφορά μη παραδοτέων Rx εξαιρέσεων έξω από το κομμάτι ή τον κύκλο δραστηριότητας μετά από απόρριψη</string>
<string name="import_export_title">Εισαγωγή/Εξαγωγή</string>
<string name="import_title">Εισαγωγή</string>
<string name="import_from">Εισαγωγή από</string>
<string name="export_to">Εξαγωγή σε</string>
<string name="import_ongoing">Γίνεται εισαγωγή…</string>
<string name="export_ongoing">Γίνεται εξαγωγή…</string>
<string name="import_file_title">Εισαγωγή αρχείου</string>
<string name="previous_export">Προηγούμενη εξαγωγή</string>
<string name="subscriptions_import_unsuccessful">Δεν ήταν δυνατή η εισαγωγή των εγγραφών</string>
<string name="subscriptions_export_unsuccessful">Δεν ήταν δυνατή η εισαγωγή των εγγραφών</string>
<string name="import_youtube_instructions">Κάντε εισαγωγή των εγγραφών σας στο YouTube κατεβάζοντας το εξής αρχείο:
\n
\n1. Πλοηγηθήτε στο: %1$s
@ -437,7 +380,6 @@
<string name="import_network_expensive_warning">Αυτή η διαδικασία μπορεί να χρησιμοποιήσει μεγάλο όγκο δεδομένων.
\n
\nΕπιθυμείτε να συνεχίσετε;</string>
<string name="playback_speed_control">Έλεγχος ταχύτητας αναπαραγωγής</string>
<string name="playback_tempo">Τέμπο</string>
<string name="playback_pitch">Τόνος</string>
@ -446,22 +388,83 @@
<string name="trending">Δημοφιλή</string>
<string name="enable_disposed_exceptions_title">Αναφορά σφαλμάτων εκτός κύκλου ζωής</string>
<string name="import_soundcloud_instructions_hint">Το όνομα χρήστη σας, soundcloud.com/όνομαχρήστη</string>
<string name="unhook_checkbox">Αποσύνδεση (μπορεί να προκαλέσει παραμόρφωση)</string>
<string name="skip_silence_checkbox">Επιτάχυνση αναπαραγωγής κατά τη διάρκεια σιωπής</string>
<string name="playback_step">Βήμα</string>
<string name="playback_reset">Επαναφορά</string>
<string name="start_accept_privacy_policy">Προς συμμόρφωση με τον Ευρωπαϊκό Γενικό Κανονισμό για την Προστασία Δεδομένων (GDPR), σας επιστούμε την προσοχή στην πολιτική προστασίας προσωπικών δεδομένων του NewPipe. Παραλούμε, διαβάστε την προσεκτικά.
\nΘα πρέπει να την αποδεχτέιτε προκειμένου να μας αποστείλετε την αναφορά σφάλματος.</string>
<string name="accept">Αποδοχή</string>
<string name="decline">Απόρριψη</string>
<string name="limit_data_usage_none_description">Χωρίς όριο</string>
<string name="limit_mobile_data_usage_title">Περιορισμός της ανάλυσης όταν γίνεται χρήση δεδομένων</string>
<string name="minimize_on_exit_title">Ελαχιστοποίηση κατά την εναλλαγή εφαρμογών</string>
<string name="minimize_on_exit_none_description">Καμία</string>
<string name="minimize_on_exit_background_description">Ελαχιστοποίηση στο παρασκήνιο</string>
<string name="minimize_on_exit_popup_description">Ελαχιστοποίηση σε αναδυόμενο παράθυρο</string>
<string name="unsubscribe">Απεγγραφή</string>
<string name="tab_new">Νέα Καρτέλα</string>
<string name="tab_choose">Επιλογή Καρτέλας</string>
<string name="volume_gesture_control_title">Ρυθμίσεις χειρονομιών ήχου</string>
<string name="volume_gesture_control_summary">Χρησιμοποιήστε χειρονομίες για τον έλεγχο της έντασης του ήχου</string>
<string name="brightness_gesture_control_title">Ρυθμίσεις χειρονομιών φωτεινότητας</string>
<string name="brightness_gesture_control_summary">Χρησιμοποιήστε χειρονομίες για τον έλεγχο της φωτεινότητας</string>
<string name="settings_category_updates_title">Ενημερώσεις</string>
<string name="events">Συμβάντα</string>
<string name="file_deleted">Το αρχείο διαγράφηκε</string>
<string name="app_update_notification_channel_name">Ειδοποίηση Ενημέρωσης Εφαρμογής</string>
<string name="app_update_notification_channel_description">Ειδοποίηση για νεότερη έκδοση του NewPipe</string>
<string name="download_to_sdcard_error_title">Εξωτερική μνήμη αποθήκευσης μη διαθέσιμη</string>
<string name="download_to_sdcard_error_message">Η αποθήκευση στην εξωτερική μνήμη απέτυχε. Επαναφορά στην αρχική τοποθεσία λήψης;</string>
<string name="saved_tabs_invalid_json">Χρήση προεπιλεγμένων καρτέλων, σφάλμα κατα την ανάγνωση των αποθηκευμένων καρτέλων</string>
<string name="restore_defaults">Επαναφορά προεπιλεγμένων ρυθμίσεων</string>
<string name="restore_defaults_confirmation">Θέλετε να επαναφέρετε τις προεπιλεγμένες ρυθμίσεις;</string>
<string name="subscribers_count_not_available">Το πλήθος των συνδρομητών δεν είναι διαθέσιμο</string>
<string name="main_page_content_summary">Ποιές καρτέλες θα εμφανίζονται στην αρχική σελίδα</string>
<string name="selection">Επιλογή</string>
<string name="conferences">Συνέδρια</string>
<string name="updates_setting_title">Ενημερώσεις</string>
<string name="updates_setting_description">Εμφάνιση ειδοποίησης όταν μια υπάρχει μια νεότερη έκδοση</string>
<string name="list_view_mode">Λειτουργία προβολής ως λίστα</string>
<string name="list">Λίστα</string>
<string name="grid">Πλέγμα</string>
<string name="auto">Αυτόματα</string>
<string name="switch_view">Αλλαγή τρόπου προβολής</string>
<string name="app_update_notification_content_title">Νεά Έκδοση NewPipe Διαθέσιμη!</string>
<string name="app_update_notification_content_text">Πατήστε για λήψη</string>
<string name="missions_header_finished">Ολοκληρώθηκε</string>
<string name="missions_header_pending">Στην ουρά αναμονής</string>
<string name="paused">Παύση</string>
<string name="queued">στην ουρά</string>
<string name="post_processing">Μετεπεξεργασία</string>
<string name="enqueue">Ουρά</string>
<string name="permission_denied">Η δράση απορρίφθηκε από το σύστημα</string>
<string name="download_failed">Η λήψη απέτυχε</string>
<string name="download_finished">Η λήψη ολοκληρώθηκε</string>
<string name="download_finished_more">%s λήψεις ολοκρηρώθηκαν</string>
<string name="generate_unique_name">Δημιουργία μοναδικού ονόματος</string>
<string name="overwrite">Αντικατάσταση</string>
<string name="overwrite_unrelated_warning">Ένα αρχείο με αυτό το όνομα υπάρχει ήδη</string>
<string name="overwrite_finished_warning">Ένα αρχείο που έχει ληφθεί με αυτό το όνομα υπάρχει ήδη</string>
<string name="download_already_running">Υπάρχει μια λήψη σε εξέλιξη με αυτό το όνομα</string>
<string name="show_error">Εμφάνιση σφάλματος</string>
<string name="label_code">Κωδικός</string>
<string name="error_path_creation">Το αρχείο δεν μπορεί να δημιουργηθεί</string>
<string name="error_file_creation">Αδυναμία δημιουργίας φάκελου προορισμού</string>
<string name="error_permission_denied">Η αδειοδότηση απορρίφθηκε απο το σύστημα</string>
<string name="error_ssl_exception">Δημιουργία ασφαλής σύνδεσης απέτυχε</string>
<string name="error_unknown_host">Αδυναμία εύρεσης του εξυπηρετητή</string>
<string name="error_connect_host">Αδυναμία σύνδεσης με τον εξυπηρετητή</string>
<string name="error_http_no_content">Ο εξυπηρετητής δεν μπορεί να στείλει τα δεδομένα</string>
<string name="error_http_unsupported_range">Ο εξυπηρετητής δέν υποστηρίζει πολυνηματικές λήψεις, ξαναπροσπαθήστε με @string/msg_threads = 1</string>
<string name="error_http_requested_range_not_satisfiable">Το ζητούμενο εύρος δεν μπορεί να εξυπηρετηθεί</string>
<string name="error_http_not_found">Δεν βρέθηκε</string>
<string name="error_postprocessing_failed">Μετεπεξεργασία απέτυχε</string>
<string name="clear_finished_download">Εκκαθάριση ολοκληρωμένων λήψεων</string>
<string name="msg_pending_downloads">Συνέχιση των %s εκκρεμών σας λήψεων</string>
<string name="stop">Διακοπή</string>
<string name="max_retry_msg">Μέγιστες επαναπροσπάθειες</string>
<string name="max_retry_desc">Μέγιστος αριθμός προσπαθειών προτού γίνει ακύρωση της λήψης</string>
<string name="pause_downloads_on_mobile">Παύση με την εναλλαγή του δικτύου σε δεδομένα</string>
<string name="pause_downloads_on_mobile_desc">Οι λήψεις που δεν δέχονται παύση θα επανεκκινηθούν</string>
</resources>

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,6 @@
<?xml version='1.0' encoding='UTF-8'?>
<resources><string name="main_bg_subtitle">Alustuseks puuduta otsingut</string>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="main_bg_subtitle">Alustuseks puuduta otsingut</string>
<string name="view_count_text">%1$s vaatamist</string>
<string name="upload_date_text">Avaldatud %1$s</string>
<string name="no_player_found">Voogesituseks puudub pleier. Kas paigaldada VLC?</string>
@ -27,24 +28,18 @@
<string name="subscription_change_failed">Tellimust ei saanud muuta</string>
<string name="subscription_update_failed">Tellimust ei õnnestunud uuendada</string>
<string name="show_info">Kuva info</string>
<string name="tab_subscriptions">Tellimused</string>
<string name="tab_bookmarks">Esitusloendid järjehoidjates</string>
<string name="fragment_whats_new">Mis on uut</string>
<string name="controls_background_title">Taust</string>
<string name="controls_popup_title">Hüpikaken</string>
<string name="controls_add_to_playlist_title">"Lisa "</string>
<string name="download_path_title">Video allalaadimise kaust</string>
<string name="download_path_summary">Kaust allalaetud videote hoiustamiseks</string>
<string name="download_path_dialog_title">Sisesta videote allalaadimise rada</string>
<string name="download_path_audio_title">Audio allalaadimise kaust</string>
<string name="download_path_audio_summary">Siia salvestatakse alla laaditud audio</string>
<string name="download_path_audio_dialog_title">Sisesta audio allalaadimise rada</string>
<string name="autoplay_by_calling_app_title">Automaatesitus</string>
<string name="autoplay_by_calling_app_summary">Esita video, kui NewPipe käivitub teise rakenduse kaudu</string>
<string name="default_resolution_title">Vaikelahutus</string>
@ -67,15 +62,15 @@
<string name="use_inexact_seek_title">Kasuta ebatäpset kerimist</string>
<string name="use_inexact_seek_summary">Ebatäpne kerimine lubab pleieril otsida asukohta kiiremini täpsuse arvel</string>
<string name="download_thumbnail_title">Laadi pisipildid</string>
<string name="download_thumbnail_summary">Välujalülitatult ei toimu pisipiltide laadimist, salvestamist ja puhverdamist. Muutmine puhastab vahemälu nii kettal kui ka mälus.</string>
<string name="download_thumbnail_summary">Lülita välja, et keelata pisipiltide laadimist, andmete salvestamist ja mälu kasutust. Muutmine puhastab vahemälu nii kettal kui ka mälus.</string>
<string name="thumbnail_cache_wipe_complete_notice">Pildid kustutati vahemälust</string>
<string name="metadata_cache_wipe_title">Kustuta metaandmed vahemälust</string>
<string name="metadata_cache_wipe_summary">Kustuta veebilehtede andmed vahemälust</string>
<string name="metadata_cache_wipe_complete_notice">Metaandmed kustutati vahemälust</string>
<string name="auto_queue_title">Järgmine voog automaatselt järjekorda</string>
<string name="auto_queue_summary">Lisa seotud voog automaatselt, kui esitusel on viimane voog mittekorduvast järjekorrast.</string>
<string name="player_gesture_controls_title">Pleieri juhtimise viiped</string>
<string name="player_gesture_controls_summary">Luba viiped helitugevuse ja ereduse juhtimiseks</string>
<string name="player_gesture_controls_title">Pleieri juhtimine viibetega</string>
<string name="player_gesture_controls_summary">Kasuta helitugevuse ja ereduse reguleerimiseks viipeid</string>
<string name="show_search_suggestions_title">Kuva soovitused</string>
<string name="show_search_suggestions_summary">Kuva otsingu ajal soovitusi</string>
<string name="enable_search_history_title">Otsinguajalugu</string>
@ -108,7 +103,7 @@
<string name="play_btn_text">Esita</string>
<string name="content">Sisu</string>
<string name="show_age_restricted_content_title">Vanusepiiranguga sisu</string>
<string name="video_is_age_restricted">Kuva vanusepiiranguga sisu. Sellise materjali saab lubada \"seadetes\".</string>
<string name="video_is_age_restricted">Kuva vanusepiiranguga video. Sellist sisu saab lubada seadetes.</string>
<string name="duration_live">OTSE</string>
<string name="downloads">Allalaadimised</string>
<string name="downloads_title">Allalaadimised</string>
@ -129,12 +124,9 @@
<string name="always">Alati</string>
<string name="just_once">Üks kord</string>
<string name="file">Fail</string>
<string name="notification_channel_name">NewPipe teavitus</string>
<string name="notification_channel_description">Teavitused NewPipe tausta- ja hüpikpleierile</string>
<string name="unknown_content">[Tundmatu]</string>
<string name="toggle_orientation">Vaheta suunda</string>
<string name="switch_to_background">Lülita taustale</string>
<string name="switch_to_popup">Lülita hüpikpleierile</string>
@ -176,7 +168,6 @@
<string name="file_name_empty_error">Tühi failinimi pole lubatud</string>
<string name="error_occurred_detail">Ilmnes viga: %1$s</string>
<string name="no_streams_available_download">Allalaaditavaid videovooge pole</string>
<string name="sorry_string">Vabandust, seda poleks pidanud juhtuma.</string>
<string name="error_report_button_text">Teata veast e-posti kaudu</string>
<string name="error_snackbar_message">Vabandust, ilmnesid mõned vead.</string>
@ -186,8 +177,6 @@
<string name="info_labels">Mis:\\nPäring:\\nSisu Keel:\\nTeenus:\\nGMT aeg:\\nPakett:\\nVersioon:\\nOS versioon:</string>
<string name="your_comment">Oma kommentaar (inglise keeles):</string>
<string name="error_details_headline">Üksikasjad:</string>
<string name="list_thumbnail_view_description">Video eelvaate pisipilt</string>
<string name="detail_thumbnail_view_description">Video eelvaate pisipilt</string>
<string name="detail_uploader_thumbnail_view_description">Üleslaadiaja avatari pisipilt</string>
@ -200,39 +189,30 @@
<string name="search_no_results">Tulemusi pole</string>
<string name="empty_subscription_feed_subtitle">Siin pole veel midagi</string>
<string name="detail_drag_description">Lohista järjestuse muutmiseks</string>
<string name="err_dir_create">Allalaadimiskataloogi \'%1$s\' loomine nurjus</string>
<string name="info_dir_created">Loodi allalaadimiskataloog \'%1$s\'</string>
<string name="video">Video</string>
<string name="audio">Audio</string>
<string name="retry">Proovi uuesti</string>
<string name="storage_permission_denied">Pääsuõigused salvestile puuduvad</string>
<string name="use_old_player_title">Kasuta vana pleierit</string>
<string name="use_old_player_summary">Vana sisseehitatud mediaframework pleier</string>
<string name="short_thousand">K</string>
<string name="short_million">M</string>
<string name="short_billion">B</string>
<string name="no_subscribers">Tellijaid pole</string>
<plurals name="subscribers">
<item quantity="one">%s tellija</item>
<item quantity="other">%s tellijat</item>
</plurals>
<item quantity="one">%s tellija</item>
<item quantity="other">%s tellijat</item>
</plurals>
<string name="no_views">Pole vaadatud</string>
<plurals name="views">
<item quantity="one">%s vaatamine</item>
<item quantity="other">%s vaatamist</item>
</plurals>
<item quantity="one">%s vaatamine</item>
<item quantity="other">%s vaatamist</item>
</plurals>
<string name="no_videos">Videoid pole</string>
<plurals name="videos">
<item quantity="one">%s video</item>
<item quantity="other">%s videot</item>
</plurals>
<item quantity="one">%s video</item>
<item quantity="other">%s videot</item>
</plurals>
<string name="start">"Start "</string>
<string name="pause">Paus</string>
<string name="view">Esita</string>
@ -243,10 +223,8 @@
<string name="checksum">Kontrollsumma</string>
<string name="dismiss">Loobu</string>
<string name="rename">Nimeta ümber</string>
<string name="add">Uus ülesanne</string>
<string name="finish">OK</string>
<string name="msg_name">Faili nimi</string>
<string name="msg_threads">Lõimed</string>
<string name="msg_error">Viga</string>
@ -261,18 +239,14 @@
<string name="msg_popup_permission">Need õigused on vajalikud
\nhüpikakna avamiseks</string>
<string name="one_item_deleted">Kustutati 1 element.</string>
<string name="reCaptchaActivity">"reCAPTCHA "</string>
<string name="settings_category_downloads_title">Laadi alla</string>
<string name="settings_file_charset_title">Lubatud tähemärgid failinimedes</string>
<string name="settings_file_replacement_character_summary">Vigased tähemärgid asendatakse selle väärtusega</string>
<string name="settings_file_replacement_character_title">Asendustähemärk</string>
<string name="charset_letters_and_digits">Tähed ja numbrid</string>
<string name="charset_most_special_characters">Erimärgid</string>
<string name="toast_no_player">Selle faili esitamiseks puudub rakendus</string>
<string name="title_activity_about">NewPipe rakendusest</string>
<string name="action_settings">Seaded</string>
<string name="action_about">Programmist</string>
@ -291,8 +265,6 @@
<string name="read_privacy_policy">Loe privaatsuspoliitikat</string>
<string name="app_license_title">NewPipe litsents</string>
<string name="read_full_license">Loe litsentsi</string>
<string name="title_activity_history">Ajalugu</string>
<string name="title_history_search">Otsitud</string>
<string name="title_history_view">Vaadatud</string>
@ -306,7 +278,6 @@
<string name="delete_all_history_prompt">Kas kustutada kõik kirjed ajaloost?</string>
<string name="title_last_played">Viimati esitatud</string>
<string name="title_most_played">Enim esitatud</string>
<string name="main_page_content">Avalehe sisu</string>
<string name="blank_page_summary">Tühi leht</string>
<string name="kiosk_page_summary">Kioski leht</string>
@ -322,7 +293,6 @@
<string name="could_not_import_all_files">Hoiatus: Kõiki faile ei õnnestunud importida.</string>
<string name="override_current_data">See alistab praeguse seadistuse.</string>
<string name="import_settings">Kas importida ka seadistused?</string>
<string name="kiosk">"Kiosk "</string>
<string name="trending">Trendid</string>
<string name="top_50">"Top 50 "</string>
@ -338,66 +308,48 @@
<string name="start_here_on_main">Alusta taasesitust siit</string>
<string name="start_here_on_background">Alusta siit olles taustal</string>
<string name="start_here_on_popup">Alusta siit uue hüpikaknaga</string>
<string name="drawer_open">Ava sahtel</string>
<string name="drawer_close">Sulge sahtel</string>
<string name="drawer_header_action_paceholder_text">Siia ilmub varsti midagi ;D</string>
<string name="preferred_open_action_settings_title">Lingi avamine</string>
<string name="preferred_open_action_settings_summary">Vaikimisi tegevus sisu avamisel — %s</string>
<string name="video_player">Videopleier</string>
<string name="background_player">Taustapleier</string>
<string name="popup_player">Hüpikpleier</string>
<string name="always_ask_open_action">Küsi alati</string>
<string name="preferred_player_fetcher_notification_title">Info hankimine…</string>
<string name="preferred_player_fetcher_notification_message">Soovitud sisu laadimine</string>
<string name="create_playlist">Uus pleilist</string>
<string name="delete_playlist">Kustuta</string>
<string name="rename_playlist">Nimeta ümber</string>
<string name="playlist_name_input">Nimi</string>
<string name="append_playlist">Lisa pleilisti</string>
<string name="set_as_playlist_thumbnail">Määra pleilisti pisipildiks</string>
<string name="bookmark_playlist">Lisa pleilist järjehoidjaks</string>
<string name="unbookmark_playlist">Eemalda järjehoidja</string>
<string name="delete_playlist_prompt">Kas kustutada see pleilist?</string>
<string name="playlist_creation_success">Pleilist loodud</string>
<string name="playlist_add_stream_success">Lisati pleilisti</string>
<string name="playlist_thumbnail_change_success">Pleilisti pisipilt muudetud.</string>
<string name="playlist_delete_failure">Pleilisti kustutamine nurjus.</string>
<string name="caption_none">Subtiitriteta</string>
<string name="resize_fit">Mahuta</string>
<string name="resize_fill">Täida</string>
<string name="resize_zoom">Suumi</string>
<string name="caption_auto_generated">Automaatselt loodud</string>
<string name="caption_setting_title">Subtiitrid</string>
<string name="caption_setting_description">Kohanda pleieri subtiitrite teksti suurust ja tausta. Jõustamiseks tuleb rakendus taaskäivitada.</string>
<string name="enable_leak_canary_summary">Mälulekke seire võib põhjustada rakenduse hangumise</string>
<string name="import_export_title">Import/eksport</string>
<string name="import_title">Import</string>
<string name="import_from">Impordi asukohast</string>
<string name="export_to">Ekspordi asukohta</string>
<string name="import_ongoing">Import…</string>
<string name="export_ongoing">Eksport…</string>
<string name="import_file_title">Impordi fail</string>
<string name="previous_export">Eelmine eksport</string>
<string name="subscriptions_import_unsuccessful">Tellimuste import nurjus</string>
<string name="subscriptions_export_unsuccessful">Tellimuste eksport nurjus</string>
<string name="import_youtube_instructions">Impordi YouTube tellimused eksportfaili abil:
\n
\n1. Ava URL: %1$s
@ -406,14 +358,11 @@
<string name="import_network_expensive_warning">See toiming võib põhjustada suurt võrguliiklust.
\n
\nKas jätkata?</string>
<string name="playback_speed_control">Taasesituse kiiruse juhtimine</string>
<string name="playback_tempo">"Tempo "</string>
<string name="playback_default">Vaikimisi</string>
<string name="accept">Nõustu</string>
<string name="decline">Keeldu</string>
<string name="limit_data_usage_none_description">Piiranguta</string>
<string name="limit_mobile_data_usage_title">Piira lahutust mobiilse andmeside kasutamisel</string>
<string name="tab_main">Peamenüü</string>
@ -422,10 +371,8 @@
<string name="tracks">Lood</string>
<string name="users">Kasutajad</string>
<string name="switch_to_main">Lülitu peamisele</string>
<string name="reCaptcha_title">reCAPTCHA nõue</string>
<string name="recaptcha_request_toast">reCAPTCHA nõude taotlus</string>
<string name="copyright" formatted="true">© %1$s %2$s %3$s alla</string>
<string name="app_description">Vaba kergekaaluline Androidi voogesitus.</string>
<string name="contribution_encouragement">Kui sul on ideid kujunduse muutmisest, koodi puhastamisest või suurtest koodi muudatustest - abi on alati teretulnud. Mida rohkem tehtud, seda paremaks läheb!</string>
@ -443,13 +390,11 @@
\n3. Logi sisse
\n4. Kopeeri suunatud profiili URL.</string>
<string name="import_soundcloud_instructions_hint">sinu_ID, soundcloud.com/sinu_id</string>
<string name="playback_pitch">Toon</string>
<string name="unhook_checkbox">Tühista ühendus (võib põhjustada moonutusi)</string>
<string name="skip_silence_checkbox">Keri helitu koht edasi</string>
<string name="playback_step">Samm</string>
<string name="playback_reset">Lähtesta</string>
<string name="start_accept_privacy_policy">Selleks, et täita Euroopa Üldist Andmekaitse Määrust (GDPR), juhime tähelepanu NewPipe\'i privaatsuspoliitikale. Palun lugege seda hoolikalt.
\nMeile veateate saatmiseks tuleb sellega nõustuda.</string>
<string name="minimize_on_exit_title">Minimeeri, kui kasutad teisi rakendusi</string>
@ -457,7 +402,70 @@
<string name="minimize_on_exit_none_description">Pole</string>
<string name="minimize_on_exit_background_description">Esita taustal</string>
<string name="minimize_on_exit_popup_description">Minimeeri hüpikpleierisse</string>
<string name="enable_disposed_exceptions_summary">Jõusta väljaspool fragmenti või elutsüklit olevate kättetoimetamatute Rx erindite raporteerimine nende vabastamise järgselt</string>
</resources>
<string name="enable_disposed_exceptions_summary">Jõusta väljaspool fragmenti või elutsüklit olevate kättetoimetamatute Rx erindite raporteerimine nende vabastamise järgselt</string>
<string name="unsubscribe">Lõpeta tellimine</string>
<string name="tab_new">Uus vahekaart</string>
<string name="tab_choose">Vali vahekaart</string>
<string name="volume_gesture_control_title">Helitugevuse juhtimine viibetega</string>
<string name="volume_gesture_control_summary">Kasuta helitugevuse reguleerimiseks viipeid</string>
<string name="brightness_gesture_control_title">Ereduse reguleerimine viibetega</string>
<string name="brightness_gesture_control_summary">Kasuta ereduse reguleerimiseks viipeid</string>
<string name="settings_category_updates_title">Uuendused</string>
<string name="events">Sündmused</string>
<string name="file_deleted">Fail kustutati</string>
<string name="app_update_notification_channel_name">Rakenduse värskenduse teatis</string>
<string name="app_update_notification_channel_description">NewPipe uuest versioonist teavitamine</string>
<string name="download_to_sdcard_error_title">Väline andmekandja pole saadaval</string>
<string name="download_to_sdcard_error_message">Allalaadimine välisele SD-kaardile ei ole veel võimalik. Kas lähtestada allalaadimiste kataloogi asukoht\?</string>
<string name="saved_tabs_invalid_json">Tõrge salvestatud vahekaaride lugemisel. Kasutatakse vaikeväärtusi</string>
<string name="restore_defaults">Taasta vaikeväärtused</string>
<string name="restore_defaults_confirmation">Kas taastada vaikeväärtused\?</string>
<string name="subscribers_count_not_available">Tellijate arv ei ole saadaval</string>
<string name="main_page_content_summary">Esilehel kuvatavad vahekaardid</string>
<string name="selection">Valik</string>
<string name="conferences">Konverentsid</string>
<string name="updates_setting_title">Uuendused</string>
<string name="updates_setting_description">Kuva teavitus, kui uus versioon on saadaval</string>
<string name="list_view_mode">Nimekirjavaate režiim</string>
<string name="list">Nimekiri</string>
<string name="grid">Võrgustik</string>
<string name="auto">Auto</string>
<string name="switch_view">Vaheta vaadet</string>
<string name="app_update_notification_content_title">NewPipe värskendus on saadaval!</string>
<string name="app_update_notification_content_text">Allalaadimiseks puuduta</string>
<string name="missions_header_finished">Lõpetatud</string>
<string name="missions_header_pending">Järjekorras</string>
<string name="paused">peatatud</string>
<string name="queued">järjekorras</string>
<string name="post_processing">järeltöötlus</string>
<string name="enqueue">Järjekord</string>
<string name="permission_denied">Tegevus keelati süsteemi poolt</string>
<string name="download_failed">Allalaadimine nurjus</string>
<string name="download_finished">Allalaadimine lõpetatud</string>
<string name="download_finished_more">%s allalaadimist lõppenud</string>
<string name="generate_unique_name">Loo kordumatu nimi</string>
<string name="overwrite">Kirjuta üle</string>
<string name="overwrite_unrelated_warning">Sellise nimega fail on juba olemas</string>
<string name="overwrite_finished_warning">Selle nimega allalaaditud fail on juba olemas</string>
<string name="download_already_running">Selle nimega allalaadimine on käimas</string>
<string name="show_error">Näita viga</string>
<string name="label_code">Kood</string>
<string name="error_path_creation">Faili ei saa luua</string>
<string name="error_file_creation">Sihtkausta ei saa luua</string>
<string name="error_permission_denied">Tegevus keelati süsteemi poolt</string>
<string name="error_ssl_exception">Turvaline ühendus nurjus</string>
<string name="error_unknown_host">Serverit ei leitud</string>
<string name="error_connect_host">Serveriga ei saadud ühendust</string>
<string name="error_http_no_content">Server ei saada andmeid</string>
<string name="error_http_unsupported_range">Server ei toeta mitmelõimelisi allalaadimisi. Proovi uuesti kasutades @string/msg_threads = 1</string>
<string name="error_http_requested_range_not_satisfiable">Taotletud vahemik ei ole rahuldatav</string>
<string name="error_http_not_found">Ei leitud</string>
<string name="error_postprocessing_failed">Järeltöötlemine nurjus</string>
<string name="clear_finished_download">Eemalda lõpetatud allalaadimised</string>
<string name="msg_pending_downloads">Jätka %s pooleliolevat allalaadimist</string>
<string name="stop">Stopp</string>
<string name="max_retry_msg">Korduskatseid</string>
<string name="max_retry_desc">Suurim katsete arv enne allalaadimise tühistamist</string>
<string name="pause_downloads_on_mobile">Paus üleminekul mobiilsele andmesidele</string>
<string name="pause_downloads_on_mobile_desc">Allalaadimised, mida ei saa peatada, taaskäivitatakse</string>
</resources>

View File

@ -29,7 +29,6 @@
<string name="content_language_title">Edukiaren hizkuntz lehenetsia</string>
<string name="settings_category_video_audio_title">Bideoa eta Audioa</string>
<string name="play_btn_text">Erreproduzitu</string>
<string name="list_thumbnail_view_description">Bideoaren aurreikuspen argazkitxoa</string>
<string name="detail_thumbnail_view_description">Bideoaren aurreikuspen argazkitxoa</string>
<string name="detail_uploader_thumbnail_view_description">Igotzailearen abatarraren iruditxoa</string>
@ -45,20 +44,17 @@
<string name="main_bg_subtitle">Ukitu bilaketa hasteko</string>
<string name="download_path_audio_title">Audioa deskargatzeko karpeta</string>
<string name="download_path_audio_dialog_title">Zehaztu audioa deskargatzeko bide-izena</string>
<string name="download_path_audio_summary">Deskargatutako audioa hemen gordetzen da</string>
<string name="autoplay_by_calling_app_title">Erreprodukzio automatikoa</string>
<string name="autoplay_by_calling_app_summary">Bideoa abiatzen du NewPipe beste aplikazio batek deitu badu</string>
<string name="dark_theme_title">Iluna</string>
<string name="light_theme_title">Argia</string>
<string name="settings_category_appearance_title">Itxura</string>
<string name="open_in_popup_mode">Ireki laster-leiho moduan</string>
<string name="open_in_popup_mode">Ireki laster-leiho moduan</string>
<string name="use_external_video_player_summary">Audioa kentzen du bereizmen batzuetan</string>
<string name="popup_mode_share_menu_title">NewPipe laster-leiho modua</string>
<string name="controls_background_title">Bigarren planoa</string>
<string name="controls_popup_title">Laster-leihoa</string>
<string name="default_popup_resolution_title">Laster-leihoaren lehenetsitako bereizmena</string>
<string name="show_higher_resolutions_title">Erakutsi bereizmen altuagoak</string>
<string name="show_higher_resolutions_summary">Gailu batzuk besterik ez dute onartzen 2K/4K bideoak erreproduzitzea</string>
@ -71,7 +67,6 @@
<string name="player_gesture_controls_summary">Erabili keinuak erreproduzigailuaren distira eta bolumena kontrolatzeko</string>
<string name="show_search_suggestions_title">Bilaketa-iradokizunak</string>
<string name="show_search_suggestions_summary">Erakutsi iradokizunak bilatzean</string>
<string name="settings_category_popup_title">Laster-leihoa</string>
<string name="settings_category_other_title">Besteak</string>
<string name="popup_playing_toast">Laster-leiho moduan erreproduzitzen</string>
@ -92,7 +87,6 @@
<string name="clear">Garbitu</string>
<string name="popup_resizing_indicator_title">Tamainaz aldatzen</string>
<string name="best_resolution">Bereizmen onena</string>
<string name="general_error">Errorea</string>
<string name="network_error">Sare-errorea</string>
<string name="could_not_load_thumbnails">Ezin izan dira iruditxo guztiak deskargatu</string>
@ -115,35 +109,24 @@
<string name="info_labels">Zer:\\nEskaria:\\nEdukiaren hizkuntza:\\nZerbitzua:\\nGMT Ordua:\\nPaketea:\\nBertsioa:\\nSE bertsioa:</string>
<string name="your_comment">Zure iruzkina (Ingelesez):</string>
<string name="error_details_headline">Xehetasunak:</string>
<string name="report_error">Eman errore baten berri</string>
<string name="user_report">Erabiltzaile-txostena</string>
<string name="err_dir_create">Ezin izan da \'%1$s\' karpeta sortu deskargetarako</string>
<string name="info_dir_created">\'%1$s\' karpeta sortu da deskargetarako</string>
<string name="video">Bideoa</string>
<string name="audio">Audioa</string>
<string name="retry">Saiatu berriro</string>
<string name="storage_permission_denied">Biltegia atzitzeko baimena ukatu da</string>
<string name="use_old_player_title">Erabili erreproduzigailu zaharra</string>
<string name="use_old_player_summary">Barne Media Framework erreproduzigailu zaharra</string>
<string name="short_thousand">K</string>
<string name="short_million">M</string>
<string name="short_billion">MM</string>
<string name="start">Hasi</string>
<string name="pause">Pausatu</string>
<string name="view">Jo</string>
<string name="delete">Ezabatu</string>
<string name="checksum">Egiaztaketa-batura</string>
<string name="add">Misio berria</string>
<string name="finish">Ados</string>
<string name="msg_name">Fitxategi-izena</string>
<string name="msg_threads">Hariak</string>
<string name="msg_error">Errorea</string>
@ -157,11 +140,9 @@
<string name="no_available_dir">Aukeratu eskuragarri dagoen karpeta bat deskargetarako</string>
<string name="msg_popup_permission">Baimen hau beharrezkoa da
\nlaster-leiho moduan irekitzeko</string>
<string name="reCaptchaActivity">reCAPTCHA</string>
<string name="reCaptcha_title">reCAPTCHA erronka</string>
<string name="recaptcha_request_toast">reCAPTCHA erronka eskatu da</string>
<string name="title_activity_about">NewPipe aplikazioari buruz</string>
<string name="action_settings">Ezarpenak</string>
<string name="action_about">Honi buruz</string>
@ -178,28 +159,22 @@
<string name="contribution_encouragement">Ideiak, itzulpenak, diseinu aldaketak, kode garbiketak, kode aldaketa sakonak badituzu, laguntza beti da ongi etorria. Eginaz hobetzen da!</string>
<string name="read_full_license">Irakurri lizentzia</string>
<string name="contribution_title">Hartu parte</string>
<string name="subscribe_button_title">Harpidetu</string>
<string name="subscribe_button_title">Harpidetu</string>
<string name="subscribed_button_title">Harpidetuta</string>
<string name="channel_unsubscribed">Kanaletik harpidetza kenduta</string>
<string name="subscription_change_failed">Ezin izan da harpidetza aldatu</string>
<string name="subscription_update_failed">Ezin izan da harpidetza eguneratu</string>
<string name="tab_main">Nagusia</string>
<string name="tab_subscriptions">Harpidetzak</string>
<string name="fragment_whats_new">Zer dago berri</string>
<string name="resume_on_audio_focus_gain_title">Jarraitu fokua irabaztean</string>
<string name="resume_on_audio_focus_gain_summary">Jarraitu etenaldiak eta gero (adib. telefono deiak)</string>
<string name="settings_category_downloads_title">Deskargatu</string>
<string name="settings_category_downloads_title">Deskargak</string>
<string name="settings_file_charset_title">Fitxategi-izenetan baimendutako karaktereak</string>
<string name="settings_file_replacement_character_summary">Karaktere baliogabeak balio honekin ordezkatzen dira</string>
<string name="settings_file_replacement_character_title">Ordezko karakterea</string>
<string name="charset_letters_and_digits">Hizkiak eta zenbakiak</string>
<string name="charset_most_special_characters">Karaktere berezi gehienak</string>
<string name="enable_search_history_title">Bilaketa historiala</string>
<string name="enable_search_history_summary">Gorde bilaketak lokalki</string>
<string name="enable_watch_history_title">Historiala eta katxea</string>
@ -207,33 +182,27 @@
<string name="notification_channel_name">NewPipe jakinarazpena</string>
<string name="settings_category_player_title">Erreproduzigailua</string>
<string name="settings_category_player_behavior_title">Portaera</string>
<string name="settings_category_history_title">Historia eta cache-a</string>
<string name="settings_category_history_title">Historia eta cachea</string>
<string name="playlist">Erreprodukzio-zerrenda</string>
<string name="undo">Desegin</string>
<string name="notification_channel_description">Atzeko planoko eta laster-leihoko NewPipe erreproduzigailuen jakinarazpenak</string>
<string name="search_no_results">Emaitzarik ez</string>
<string name="empty_subscription_feed_subtitle">Kilkerrak besterik ez daude hemen</string>
<string name="no_subscribers">Harpidedunik ez</string>
<plurals name="subscribers">
<item quantity="one">Harpidedun %s</item>
<item quantity="other">%s harpidedun</item>
</plurals>
<item quantity="one">Harpidedun %s</item>
<item quantity="other">%s harpidedun</item>
</plurals>
<string name="no_views">Ikustaldirik ez</string>
<plurals name="views">
<item quantity="one">ikustaldi %s</item>
<item quantity="other">%s ikustaldi</item>
</plurals>
<item quantity="one">ikustaldi %s</item>
<item quantity="other">%s ikustaldi</item>
</plurals>
<string name="no_videos">Bideorik ez</string>
<plurals name="videos">
<item quantity="one">Bideoa</item>
<item quantity="other">Bideoak</item>
</plurals>
<item quantity="one">Bideoa</item>
<item quantity="other">Bideoak</item>
</plurals>
<string name="title_activity_history">Historiala</string>
<string name="title_history_search">Bilatuta</string>
<string name="title_history_view">Ikusita</string>
@ -242,32 +211,27 @@
<string name="history_empty">Historiala hutsik dago</string>
<string name="history_cleared">Historiala garbitu da</string>
<string name="item_deleted">Elementua ezabatuta</string>
<string name="show_hold_to_append_title">Erakutsi \"mantendu eransteko\" aholkua</string>
<string name="show_hold_to_append_title">Erakutsi \"mantendu eransteko\" aholkua</string>
<string name="show_hold_to_append_summary">Erakutsi aholkua bigarren planoko eta laster-leihoko botoia sakatzean bideoaren xehetasunen orrian</string>
<string name="default_content_country_title">Lehenetsitako edukiaren herrialdea</string>
<string name="service_title">Zerbitzua</string>
<string name="background_player_append">Bigarren planoko erreproduzigailuaren ilaran</string>
<string name="popup_playing_append">Laster-leiho erreproduzigailuaren ilaran</string>
<string name="play_all">Jo denak</string>
<string name="unknown_content">[Ezezaguna]</string>
<string name="toggle_orientation">Txandakatu orientazioa</string>
<string name="switch_to_background">Aldatu bigarren planora</string>
<string name="switch_to_popup">Aldatu laster-leihora</string>
<string name="switch_to_main">Aldatu nagusira</string>
<string name="player_stream_failure">Ezin izan da jario hau erreproduzitu</string>
<string name="player_unrecoverable_failure">Erreproduzigailuaren errore berreskuraezina gertatu da</string>
<string name="player_recoverable_failure">Erreproduzigailuaren erroretik berreskuratzen</string>
<string name="donation_title">Dohaintza</string>
<string name="donation_encouragement">NewPipe zuri esperientziarik onena ekartzeko denbora ematen duten boluntarioek garatzen dute. Emaiezu zerbait garatzaileei NewPipe kafe bat hartzen duten bitartean hobetu ahal izan dezaten.</string>
<string name="give_back">Egin dohaintza</string>
<string name="website_title">Webgunea</string>
<string name="website_encouragement">Bisitatu NewPipe webgunea informazio gehiagorako eta berriak irakurtzeko.</string>
<string name="delete_item_search_history">Elementu hau bilaketen historialetik ezabatu nahi duzu?</string>
<string name="main_page_content">Orri nagusiko edukia</string>
<string name="blank_page_summary">Orri hutsa</string>
<string name="kiosk_page_summary">Kioskoaren orria</string>
@ -277,7 +241,6 @@
<string name="select_a_channel">Hautatu kanal bat</string>
<string name="no_channel_subscribed_yet">Ez zara inolako kanalera harpidetu oraindik</string>
<string name="select_a_kiosk">Hautatu kiosko bat</string>
<string name="kiosk">Kioskoa</string>
<string name="trending">Joerak</string>
<string name="top_50">Lehen 50ak</string>
@ -293,43 +256,34 @@
<string name="start_here_on_main">Hasi hemen erreproduzitzen</string>
<string name="start_here_on_background">Hasi hemen bigarren planoan</string>
<string name="start_here_on_popup">Hasi hemen laster-leihoan</string>
<string name="drawer_open">"Ireki tiradera "</string>
<string name="drawer_close">Itxi tiradera</string>
<string name="no_player_found_toast">Ez da jarioen erreproduzigailurik aurkitu (VLC instalatu dezakezu).</string>
<string name="always">Beti</string>
<string name="just_once">Behin besterik ez</string>
<string name="external_player_unsupported_link_type">Kanpo erreproduzigailuek ez dituzte mota honetako estekak onartzen</string>
<string name="invalid_url_toast">URL baliogabea</string>
<string name="video_streams_empty">Ez da bideo jariorik aurkitu</string>
<string name="audio_streams_empty">Ez da audio jariorik aurkitu</string>
<string name="video_player">Bideo erreproduzigailua</string>
<string name="background_player">Bigarren planoko erreproduzigailua</string>
<string name="popup_player">Laster-leiho erreproduzigailua</string>
<string name="always_ask_player">Galdetu beti</string>
<string name="preferred_player_fetcher_notification_title">Informazioa eskuratzen…</string>
<string name="preferred_player_fetcher_notification_message">Kargatzen eskatutako edukia</string>
<string name="controls_download_desc">Deskargatu jario fitxategia</string>
<string name="controls_download_desc">Deskargatu jario fitxategia</string>
<string name="show_info">Erakutsi informazioa</string>
<string name="tab_bookmarks">Gogoko erreprodukzio-zerrendak</string>
<string name="controls_add_to_playlist_title">Gehitu hona</string>
<string name="use_inexact_seek_title">Erabili bilaketa azkar ez zehatza</string>
<string name="download_thumbnail_title">Kargatu iruditxoak</string>
<string name="thumbnail_cache_wipe_complete_notice">Irudien cache-a ezabatuta</string>
<string name="metadata_cache_wipe_title">Ezabatu cache-ko metadatuak</string>
<string name="metadata_cache_wipe_summary">Kendu cache-ko wegbuneen datu guztiak</string>
<string name="metadata_cache_wipe_complete_notice">Metadatuen cache-a ezabatuta</string>
<string name="thumbnail_cache_wipe_complete_notice">Irudien cachea ezabatuta</string>
<string name="metadata_cache_wipe_title">Ezabatu cacheko metadatuak</string>
<string name="metadata_cache_wipe_summary">Kendu cachetik webguneen datu guztiak</string>
<string name="metadata_cache_wipe_complete_notice">Metadatuen cachea ezabatuta</string>
<string name="auto_queue_title">Gehitu ilarara hurrengo jarioa</string>
<string name="auto_queue_summary">Gehitu erlazionatutako jario bat azken jarioa jo bitartean errepikapenik gabeko ilara batean.</string>
<string name="settings_category_debug_title">Arazketa</string>
<string name="file">Fitxategia</string>
<string name="import_data_title">Inportatu datu-basea</string>
<string name="export_data_title">Esportatu datu-basea</string>
<string name="import_data_summary">Zure uneko historiala eta harpidetzak gainidazten ditu</string>
@ -348,83 +302,60 @@
<string name="file_name_empty_error">Fitxategi izena ezin da hutsik egon</string>
<string name="error_occurred_detail">Errore bat gertatu da: %1$s</string>
<string name="no_streams_available_download">Ez dago jariorik deskargatzeko eskuragarri</string>
<string name="detail_drag_description">Arrastatu ordena aldatzeko</string>
<string name="create">Sortu</string>
<string name="delete_one">Ezabatu bat</string>
<string name="delete_all">Ezabatu guztiak</string>
<string name="dismiss">Baztertu</string>
<string name="rename">Aldatu izena</string>
<string name="one_item_deleted">Elementu 1 ezabatuta.</string>
<string name="toast_no_player">Ez dago fitxategi hau erreproduzitzeko aplikaziorik instalatuta</string>
<string name="delete_stream_history_prompt">Elementu hau ikusitakoen historialetik ezabatu nahi duzu?</string>
<string name="delete_all_history_prompt">Ziur elementu guztiak ezabatu nahi dituzula historialetik?</string>
<string name="title_last_played">Jotako azkena</string>
<string name="title_most_played">Ikusiena</string>
<string name="export_complete_toast">Esportatuta</string>
<string name="import_complete_toast">Inportatuta</string>
<string name="no_valid_zip_file">Ez da baliozko ZIP fitxategia</string>
<string name="could_not_import_all_files">Ebisua: Ezin izan dira fitxategi guztiak inportatu.</string>
<string name="override_current_data">Honek oraingo ezarpenak gainidatziko ditu.</string>
<string name="drawer_header_action_paceholder_text">Laster hemen zerbait egongo da ;D</string>
<string name="preferred_open_action_settings_title">\'Ireki\' ekintza hobetsia</string>
<string name="preferred_open_action_settings_summary">Lehenetsitako ekintza edukia irekitzean — %s</string>
<string name="always_ask_open_action">Galdetu beti</string>
<string name="create_playlist">Erreprodukzio-zerrenda berria</string>
<string name="delete_playlist">Ezabatu</string>
<string name="rename_playlist">Aldatu izena</string>
<string name="playlist_name_input">Izena</string>
<string name="append_playlist">Gehitu erreprodukzio-zerrendara</string>
<string name="set_as_playlist_thumbnail">Ezarri erreprodukzio-zerrendaren iruditxo gisa</string>
<string name="bookmark_playlist">Gogoko erreprodukzio-zerrenda</string>
<string name="unbookmark_playlist">Kendu gogokoa</string>
<string name="delete_playlist_prompt">Erreprodukzio zerrenda hau ezabatu\?</string>
<string name="playlist_creation_success">Erreprodukzio-zerrenda sortuta</string>
<string name="playlist_add_stream_success">Erreprodukzio-zerrendatua</string>
<string name="playlist_thumbnail_change_success">Erreprodukzio zerrendaren iruditxoa aldatuta.</string>
<string name="playlist_delete_failure">Ezin izan da erreprodukzio-zerrenda ezabatu.</string>
<string name="caption_none">Azpititulurik ez</string>
<string name="resize_fit">Doitu</string>
<string name="resize_fill">Bete</string>
<string name="resize_zoom">Zoom</string>
<string name="caption_auto_generated">Automatikoki sortuak</string>
<string name="caption_setting_title">Azpitituluak</string>
<string name="caption_setting_description">Aldatu azpitituluen testuaren eskala eta atzealdeko estiloa. Aplikazioa berrabiarazi behar da aldaketak aplikatzeko.</string>
<string name="enable_leak_canary_title">Gaitu LeakCanary</string>
<string name="enable_leak_canary_summary">Memoria galeren monitorizazioa. Aplikazioak agian ez du erantzungo memoriaren aitortza egin bitartean</string>
<string name="enable_disposed_exceptions_title">Eman bizitza-ziklo kanpoko erroreen berri</string>
<string name="import_export_title">Inportatu/esportatu</string>
<string name="import_title">Inportatu</string>
<string name="import_from">Inportatu hemendik</string>
<string name="export_to">Esportatu hona</string>
<string name="import_ongoing">Inportatzen…</string>
<string name="export_ongoing">Esportatzen…</string>
<string name="import_file_title">Inportatu fitxategia</string>
<string name="previous_export">Aurreko esportazioa</string>
<string name="subscriptions_import_unsuccessful">Ezin izan dira harpidetzak inportatu</string>
<string name="subscriptions_export_unsuccessful">Ezin izan dira harpidetzak esportatu</string>
<string name="import_youtube_instructions">Inporttu YouTube harpidetzak esportazio fitxategia deskargatuz:
\n
\n1. Joan URL honetara: %1$s
@ -437,24 +368,20 @@
\n3. Hasi saioa eskatzen zaizunean
\n4. Kopiatu profilaren URL-a eraman zaizun orritik.</string>
<string name="import_soundcloud_instructions_hint">zureID,soundcloud.com/zureid</string>
<string name="import_network_expensive_warning">Eragiketa honek sarearen erabilera handia egin lezake.
\n
\nJarraitu nahi duzu?</string>
<string name="playback_speed_control">Erreprodukzio-abiaduraren kontrolak</string>
<string name="playback_tempo">Tempoa</string>
<string name="playback_pitch">Tonua</string>
<string name="unhook_checkbox">Deslotu (distortsioa sor lezake)</string>
<string name="playback_nightcore">Nightcore</string>
<string name="playback_default">Lehenetsia</string>
<string name="import_settings">Ezarpenak ere inportatu nahi dituzu?</string>
<string name="import_settings">Ezarpenak ere inportatu nahi dituzu?</string>
<string name="use_inexact_seek_summary">Bilaketa ez zehatzak posizioak azkarrago baina prezisio gutxiagoz bilatzea ahalbidetzen du</string>
<string name="download_thumbnail_summary">Desgaitu koadro txikiak ez kargatzeko, datuak eta memoria aurreztuz. Aldaketak memoria eta diskoko irudien cache-ak garbituko ditu.</string>
<string name="download_thumbnail_summary">Desgaitu koadro txikiak ez kargatzeko, datuak eta memoria aurreztuz. Aldaketak memoria eta diskoko irudien cacheak garbituko ditu.</string>
<string name="app_license">NewPipe Software Librea eta Copyleft da: Erabili, ikertu, partekatu eta hobetu dezakezu. Zehazki, elkarbanatzea eta aldatzea Free Software Foundation-ek argitaratutako GNU General Public License-ren 3. bertsioa edo berriagoren baten terminoen arabera egiteko baimena duzu.</string>
<string name="enable_disposed_exceptions_summary">Behartu aktibitatearen bizitza ziklotik kanpo baztertu eta gero entregatu ezin diren Rx salbuespenen inguruko txostena</string>
<string name="privacy_policy_title">NewPipe pribatutasun politika</string>
<string name="privacy_policy_encouragement">NewPipe proiektuak aintzat hartzen du zure pribatutasuna. Aplikazioak ez du zure baimenik gabe daturik jasotzen.
\nNewPipe pribatutasun politikak azaltzen du zehazki bidali eta gordetako informazioa zein den kraskatze txosten bat bidaltzen duzunean.</string>
@ -463,20 +390,17 @@
\nAkats txosten bat bidali ahal izateko onartu behar duzu."</string>
<string name="accept">Onartu</string>
<string name="decline">Ukatu</string>
<string name="limit_data_usage_none_description">Mugagabea</string>
<string name="limit_mobile_data_usage_title">Mugatu bereizmena datu mugikorrak erabiltzean</string>
<string name="skip_silence_checkbox">Aurreratu azkar isilunea dagoenean</string>
<string name="playback_step">Urratsa</string>
<string name="playback_reset">Leheneratu</string>
<string name="minimize_on_exit_title">Minimizatu app-a aldatzean</string>
<string name="minimize_on_exit_summary">Ekintza bideo erreproduzigailu nagusitik beste app batera aldatzean — %s</string>
<string name="minimize_on_exit_none_description">Bat ere ez</string>
<string name="minimize_on_exit_background_description">Minimizatu bigarren planoko erreproduzigailura</string>
<string name="minimize_on_exit_popup_description">Minimizatu laster-liho erreproduzigailura</string>
<string name="channels">Kanalak</string>
<string name="channels">Kanalak</string>
<string name="playlists">Erreprodukzio-zerrendak</string>
<string name="tracks">Pistak</string>
<string name="users">Erabiltzaileak</string>
@ -511,7 +435,7 @@
<string name="app_update_notification_content_title">NewPipe eguneraketa eskuragarri!</string>
<string name="app_update_notification_content_text">Sakatu deskargatzeko</string>
<string name="missions_header_finished">Amaituta</string>
<string name="missions_header_pending">Ilaran</string>
<string name="missions_header_pending">Zain</string>
<string name="paused">pausatuta</string>
<string name="queued">ilaran</string>
<string name="post_processing">post-prozesua</string>
@ -522,12 +446,12 @@
<string name="download_finished_more">%s deskarga amaituta</string>
<string name="generate_unique_name">Sortu izen bakana</string>
<string name="overwrite">Gainidatzi</string>
<string name="overwrite_warning">Badago izen bera duen deskargatutako fitxategi bat</string>
<string name="overwrite_finished_warning">Badago izen bera duen deskargatutako fitxategi bat</string>
<string name="download_already_running">Badago izen bera duen deskarga bat abian</string>
<string name="show_error">Erakutsi errorea</string>
<string name="label_code">Kodea</string>
<string name="error_path_creation">Ezin da fitxategia sortu</string>
<string name="error_file_creation">Ezin da helburu karpeta sortu</string>
<string name="error_file_creation">Ezin da fitxategia sortu</string>
<string name="error_path_creation">Ezin da helburu karpeta sortu</string>
<string name="error_permission_denied">Sistemak baimena ukatu du</string>
<string name="error_ssl_exception">Konexio seguruak huts egin du</string>
<string name="error_unknown_host">Ezin izan da zerbitzaria aurkitu</string>
@ -540,8 +464,9 @@
<string name="clear_finished_download">Garbitu amaitutako deskargak</string>
<string name="msg_pending_downloads">Berrekin burutzeke dauden %s transferentzia deskargetatik</string>
<string name="stop">Gelditu</string>
<string name="max_retry_msg">Saiakerak gehienez</string>
<string name="max_retry_msg">Gehienezko saiakerak</string>
<string name="max_retry_desc">Deskarga ezeztatu aurretik saiatu beharreko aldi kopurua</string>
<string name="pause_downloads_on_mobile">Pausatu datu mugikorretara aldatzean</string>
<string name="pause_downloads_on_mobile_desc">Pausatu ezin daitezkeen deskargak berrekingo dira</string>
<string name="error_timeout">Konexioaren denbora muga</string>
</resources>

View File

@ -17,15 +17,12 @@
<string name="screen_rotation">چرخش</string>
<string name="use_external_video_player_title">استفاده از پخش‌کنندهٔ ویدیوی خارجی</string>
<string name="use_external_audio_player_title">استفاده از پخش‌کنندهٔ صدای خارجی</string>
<string name="download_path_title">مسیر بارگیری ویدیو</string>
<string name="download_path_summary">مسیر ذخیرهٔ ویدیوهای بارگیری شده</string>
<string name="download_path_dialog_title">مسیر بارگیری را برای ویدیوها وارد کنید</string>
<string name="download_path_audio_title">پوشه بارگیری صدا</string>
<string name="download_path_audio_summary">صدای بارگیری شده در این‌جا نگه داشته می‌شود</string>
<string name="download_path_audio_dialog_title">مسیر بارگیری را برای صداها وارد کنید</string>
<string name="autoplay_by_calling_app_title">پخش خودکار</string>
<string name="autoplay_by_calling_app_summary">هنگامی که نیوپایپ از کارهٔ دیگری فراخوانی می‌شود، ویدیوی به طور خودکار پخش شود</string>
<string name="default_resolution_title">وضوح پیش‌گزیده</string>
@ -35,12 +32,9 @@
<string name="show_play_with_kodi_summary">نمایش گزینه‌ای برای پخش ویدیو با مرکز رسانهٔ کودی</string>
<string name="play_audio">صدا</string>
<string name="default_audio_format_title">قالب صدای پیش‌گزیده</string>
<string name="webm_description">قالب آزاد — WebM</string>
<string name="m4a_description">کیفیت بهتر — M4A</string>
<string name="theme_title">زمینه</string>
<string name="dark_theme_title">تیره</string>
<string name="light_theme_title">روشن</string>
<string name="download_dialog_title">بارگیری</string>
<string name="next_video_title">بعدی</string>
<string name="show_next_and_similar_title">نماش ویدیوهای «بعدی» و «مشابه»</string>
@ -58,7 +52,6 @@
<string name="downloads">بارگیری‌ها</string>
<string name="downloads_title">بارگیری‌ها</string>
<string name="error_report_title">گزارش خطا</string>
<string name="general_error">خطا</string>
<string name="network_error">خطای شبکه</string>
<string name="could_not_load_thumbnails">نمی‌توان تمام بندانگشتی‌ها را بار کرد</string>
@ -78,8 +71,6 @@
<string name="what_happened_headline">چه روی داد:</string>
<string name="your_comment">توضیح شما (به انگلیسی):</string>
<string name="error_details_headline">جزییات:</string>
<string name="list_thumbnail_view_description">بندانگشتی پیش‌نمایش ویدیو</string>
<string name="detail_thumbnail_view_description">بندانگشتی پیش‌نمایش ویدیو</string>
<string name="detail_uploader_thumbnail_view_description">بندانگشتی کاربر بارگذار</string>
@ -89,24 +80,19 @@
<string name="use_tor_summary">(آزمایشی) اجبار ترافیک بارگیری از مسیر تور برای محرمانگی بیش‌تر (هنوز پخش جریانی پشتیبانی نمی‌شود).</string>
<string name="report_error">گزارش یک خطا</string>
<string name="user_report">گزارش کاربر</string>
<string name="err_dir_create">نمی‌توان شاخهٔ بارگیری «%1$s» را ایجاد کرد</string>
<string name="info_dir_created">شاخهٔ بارگیری «%1$s» ایجاد شد</string>
<string name="video">ویدیو</string>
<string name="audio">صدا</string>
<string name="retry">تلاش دوباره</string>
<string name="storage_permission_denied">اجازهٔ دسترسی به انبار ذخیره رد شد</string>
<string name="start">شروع</string>
<string name="pause">مکث</string>
<string name="view">نمایش</string>
<string name="delete">حذف</string>
<string name="checksum">مجموع مقابله‌ای</string>
<string name="add">مآموریت جدید</string>
<string name="finish">قبول</string>
<string name="msg_name">نام پرونده</string>
<string name="msg_threads">رشته‌ها</string>
<string name="msg_error">خطا</string>
@ -118,8 +104,7 @@
<string name="msg_wait">لطفاً صبر کنید…</string>
<string name="msg_copied">در حافظه رونوشت شد.</string>
<string name="no_available_dir">لطفاً یک شاخهٔ بارگیری موجود را برگزینید.</string>
<string name="no_player_found_toast">هیچ پخش کننده جریانی پیدا نشد (شما می‌توانید برنامه وی‌ال‌سی را برای پخش آن نصب کنید).</string>
<string name="no_player_found_toast">هیچ پخش کننده جریانی پیدا نشد (شما می‌توانید برنامه وی‌ال‌سی را برای پخش آن نصب کنید).</string>
<string name="controls_download_desc">بارگیری پرونده جریان</string>
<string name="use_external_video_player_summary">حذف صدا در برخی کیفیت‌ها</string>
<string name="subscribe_button_title">اشتراک</string>
@ -128,16 +113,12 @@
<string name="subscription_change_failed">ناتوانی در تغییر وضعیت اشتراک</string>
<string name="subscription_update_failed">ناتوانی در به‌روزرسانی اشتراک</string>
<string name="show_info">نمایش اطلاعات</string>
<string name="tab_main">اصلی</string>
<string name="tab_subscriptions">اشتراک‌ها</string>
<string name="tab_bookmarks">فهرست‌های پخش دارای نشانک</string>
<string name="fragment_whats_new">موارد جدید</string>
<string name="controls_background_title">پس زمینه</string>
<string name="controls_add_to_playlist_title">افزودن به</string>
<string name="show_higher_resolutions_title">نمایش کیفیت بالاتر</string>
<string name="show_higher_resolutions_summary">تنها برخی دستگاه‌ها توانایی پخش ویدئوهای 2K و 4K را دارند</string>
<string name="default_video_format_title">قالب ویدئوی پیش‌فرض</string>
@ -168,10 +149,8 @@
<string name="always">همیشه</string>
<string name="just_once">فقط یک‌بار</string>
<string name="file">پرونده</string>
<string name="notification_channel_name">اعلان نیوپایپ</string>
<string name="unknown_content">[ناشناخته]</string>
<string name="import_data_title">وارد کردن پایگاه‌داده</string>
<string name="export_data_title">"صادرکردن "</string>
<string name="import_data_summary">تاریخچه و اشتراک‌های شما بازنویسی خواهند شد</string>
@ -181,17 +160,13 @@
<string name="import_title">وارد کردن</string>
<string name="import_from">وارد کردن از</string>
<string name="export_to">صادر کردن به</string>
<string name="import_ongoing">در حال وارد کردن…</string>
<string name="export_ongoing">در حال صدور…</string>
<string name="subscriptions_import_unsuccessful">ناتوانی در ورود اشتراک‌ها</string>
<string name="subscriptions_export_unsuccessful">ناتوانی در صدور اشتراک‌ها</string>
<string name="playback_speed_control">کنترل‌های سرعت پخش</string>
<string name="accept">قبول</string>
<string name="decline">رد</string>
<string name="limit_data_usage_none_description">بدون محدودیت</string>
<string name="minimize_on_exit_none_description">هیچ</string>
<string name="best_resolution">بهترین وضوح</string>
@ -211,47 +186,36 @@
<string name="file_name_empty_error">نام پرونده نمی‌تواند خالی باشد</string>
<string name="error_occurred_detail">خطایی رخ داد: %1$s</string>
<string name="no_streams_available_download">جریانی برای بارگیری در دسترس نیست</string>
<string name="search_no_results">بدون نتیجه</string>
<string name="use_old_player_title">استفاده از پخش‌کننده قدیمی</string>
<string name="short_thousand">K</string>
<string name="short_million">M</string>
<string name="short_billion">B</string>
<plurals name="subscribers">
<item quantity="one">%s مشترک</item>
<item quantity="other">%s مشترک</item>
</plurals>
<item quantity="one">%s مشترک</item>
<item quantity="other">%s مشترک</item>
</plurals>
<string name="no_views">بدون بازدید</string>
<plurals name="views">
<item quantity="one">%s بازدید</item>
<item quantity="other">%s بازدید</item>
</plurals>
<item quantity="one">%s بازدید</item>
<item quantity="other">%s بازدید</item>
</plurals>
<string name="no_videos">بدون ویدئو</string>
<plurals name="videos">
<item quantity="one">ویدئو</item>
<item quantity="other">ویدئو</item>
</plurals>
<item quantity="one">ویدئو</item>
<item quantity="other">ویدئو</item>
</plurals>
<string name="create">ایجاد</string>
<string name="delete_one">پاک کردن یک مورد</string>
<string name="delete_all">پاک‌کردن همه</string>
<string name="dismiss">صرف نظر</string>
<string name="rename">تغییر نام</string>
<string name="one_item_deleted">یک مورد پاک شد.</string>
<string name="settings_file_charset_title">نویسه‌های مجاز در نام پرونده‌ها</string>
<string name="settings_file_replacement_character_summary">نویسه‌های نامعتبر با این مقدار جایگزین شدند</string>
<string name="settings_file_replacement_character_title">نویسه جایگزین</string>
<string name="charset_letters_and_digits">حروف و اعداد</string>
<string name="charset_most_special_characters">مهم‌ترین نویسه‌های خاص</string>
<string name="toast_no_player">کاره‌ای برای پخش این پرونده نصب نشده است</string>
<string name="title_activity_about">درباره نیوپایپ</string>
<string name="action_settings">تنظیمات</string>
<string name="action_about">درباره</string>
@ -269,8 +233,6 @@
<string name="read_privacy_policy">خواندن سیاست حریم خصوصی</string>
<string name="app_license_title">پروانه نیوپایپ</string>
<string name="read_full_license">خواندن پروانه</string>
<string name="title_activity_history">تاریخچه</string>
<string name="title_history_search">جستجو شده</string>
<string name="title_history_view">دیده‌شده</string>
@ -284,7 +246,6 @@
<string name="delete_all_history_prompt">می‌خواهید همه موارد را از تاریخچه پاک کنید؟</string>
<string name="title_last_played">آخرین پخش‌شده</string>
<string name="title_most_played">بیشترین پخش‌شده</string>
<string name="main_page_content">محتوای صفحه اصلی</string>
<string name="blank_page_summary">صفحه خالی</string>
<string name="kiosk_page_summary">صفحه کیوسک</string>
@ -305,25 +266,20 @@
<string name="video_player">پخش‌کننده ویدئو</string>
<string name="background_player">پخش‌کننده پس‌زمینه</string>
<string name="always_ask_open_action">همیشه بپرس</string>
<string name="preferred_player_fetcher_notification_title">در حال دریافت اطلاعات…</string>
<string name="preferred_player_fetcher_notification_message">بارگذری محتوای درخواستی</string>
<string name="create_playlist">فهرست پخش جدید</string>
<string name="delete_playlist">پاک‌کردن</string>
<string name="rename_playlist">تغییر نام</string>
<string name="playlist_name_input">نام</string>
<string name="append_playlist">افزودن به فهرست پخش</string>
<string name="set_as_playlist_thumbnail">استفاده به عنوان تصویر فهرست پخش</string>
<string name="delete_playlist_prompt">این فهرست پخش پاک شود؟</string>
<string name="playlist_creation_success">فهرست پخش ایجاد شد</string>
<string name="playlist_add_stream_success">به فهرست پخش افزوده شد</string>
<string name="playlist_thumbnail_change_success">تصویر فهرست پخش تغییر کرد.</string>
<string name="playlist_delete_failure">ناتوانی در پاک‌کردن فهرست پخش.</string>
<string name="caption_none">بدون توضیحات</string>
<string name="caption_setting_title">توضحیات</string>
<string name="unsubscribe">لغو اشتراک</string>
<string name="tab_new">زبان جدید</string>
@ -332,4 +288,12 @@
<string name="settings_category_history_title">تاریخچه و حافظه نهان</string>
<string name="settings_category_debug_title">اشکال‌زدایی</string>
<string name="settings_category_updates_title">به‌روزرسانی‌ها</string>
<string name="open_in_popup_mode">در پنجره جداگانه باز شود</string>
<string name="popup_mode_share_menu_title">حالت پنجره مجزا</string>
<string name="default_popup_resolution_title">اندازه پیش فرض پنجره جداگانه</string>
<string name="controls_popup_title">پنجره جداگانه</string>
<string name="popup_remember_size_pos_title">به یاد داشتن اندازه و موقعیت پنجره جداگانه</string>
<string name="popup_remember_size_pos_summary">به یاد داشتن آخرین اندازه و موقعیت قبلی پنجره جداگانه</string>
<string name="use_inexact_seek_title">زمان فعلی پخش کننده را به صورت تقریبی و سریع جلو ببر</string>
<string name="use_inexact_seek_summary">این گزینه باعث می شود هنگام جلو/عقب کردن زمان تصویر، به جای زمان دقیق انتخاب شده، به زمان غیر دقیق و نزدیک به مکان انتخاب شده برود که این کار سریع تر انجام می شود</string>
</resources>

View File

@ -148,8 +148,6 @@
<string name="audio">Ääni</string>
<string name="retry">Toista uudelleen</string>
<string name="storage_permission_denied">Oikeus tallennustilan hallintaan evätty</string>
<string name="use_old_player_title">Käytä vanhaa soitinta</string>
<string name="use_old_player_summary">Käytä vanhaa sisäänrakennettua Mediaframework-soitinta</string>
<string name="short_thousand">t.</string>
<string name="short_million">milj.</string>

View File

@ -30,7 +30,6 @@
<string name="url_not_supported_toast">URL non supportée</string>
<string name="settings_category_video_audio_title">Vidéo &amp; audio</string>
<string name="settings_category_other_title">Autre</string>
<string name="list_thumbnail_view_description">Miniature daperçu vidéo</string>
<string name="detail_thumbnail_view_description">Miniature daperçu vidéo</string>
<string name="detail_dislikes_img_view_description">Je naime pas</string>
@ -41,32 +40,26 @@
<string name="use_external_audio_player_title">Utiliser un lecteur audio externe</string>
<string name="background_player_playing_toast">Lecture en arrière-plan</string>
<string name="play_btn_text">Lire</string>
<string name="use_tor_title">Utiliser Tor</string>
<string name="use_tor_summary">(Expérimental) Rediriger le trafic de téléchargement via Tor pour plus de confidentialité (streaming non supporté pour le moment).</string>
<string name="theme_title">Thème</string>
<string name="dark_theme_title">Sombre</string>
<string name="light_theme_title">Clair</string>
<string name="settings_category_appearance_title">Apparence</string>
<string name="network_error">Erreur réseau</string>
<string name="download_path_audio_title">Dossier de téléchargement audio</string>
<string name="download_path_audio_summary">L\'audio téléchargé est stocké ici</string>
<string name="download_path_audio_dialog_title">Entrez le chemin de téléchargement des fichiers audio</string>
<string name="err_dir_create">Impossible de créer le répertoire de téléchargement « %1$s»</string>
<string name="info_dir_created">Répertoire de téléchargement « %1$s» créé</string>
<string name="general_error">Erreur</string>
<string name="parsing_error">Impossible d\'analyser le site web</string>
<string name="content_not_available">Contenu non disponible</string>
<string name="blocked_by_gema">Bloqué par GEMA</string>
<string name="error_snackbar_message">Désolé, des erreurs se sont produites.</string>
<string name="content">Contenu</string>
<string name="show_age_restricted_content_title">Contenu avec limite d\'âge</string>
<string name="duration_live">EN DIRECT</string>
<string name="could_not_load_thumbnails">Impossible de charger toutes les miniatures</string>
<string name="youtube_signature_decryption_error">Impossible de déchiffrer la signature URL de la vidéo</string>
<string name="light_parsing_error">Impossible d\'analyser complètement le site web</string>
@ -78,8 +71,6 @@
<string name="what_happened_headline">Ce qui s\'est passé :</string>
<string name="your_comment">Votre commentaire (en anglais) :</string>
<string name="error_details_headline">Détails :</string>
<string name="report_error">Signaler une erreur</string>
<string name="video">Vidéo</string>
<string name="audio">Audio</string>
@ -89,23 +80,19 @@
<string name="autoplay_by_calling_app_title">Lecture automatique</string>
<string name="video_is_age_restricted">Afficher les vidéos soumises à une limite d\'âge. Autoriser ce type de contenu est possible depuis les paramètres.</string>
<string name="user_report">Rapport utilisateur</string>
<string name="error_snackbar_action">SIGNALER</string>
<string name="could_not_setup_download_menu">Impossible de configurer le menu de téléchargement</string>
<string name="could_not_get_stream">Impossible d\'obtenir un flux</string>
<string name="downloads">Téléchargements</string>
<string name="downloads_title">Téléchargements</string>
<string name="error_report_title">Rapport d\'erreur</string>
<string name="start">Lire</string>
<string name="pause">Pause</string>
<string name="view">Lire</string>
<string name="delete">Supprimer</string>
<string name="checksum">Somme de contrôle</string>
<string name="add">Nouveau</string>
<string name="finish">OK</string>
<string name="msg_name">Nom du fichier</string>
<string name="msg_threads">Threads</string>
<string name="msg_error">Erreur</string>
@ -117,71 +104,51 @@
<string name="msg_wait">Veuillez patienter…</string>
<string name="msg_copied">Copié dans le presse-papiers</string>
<string name="no_available_dir">Sélectionner un dossier de téléchargement disponible</string>
<string name="could_not_load_image">Impossible de charger l\'image</string>
<string name="app_ui_crash">Lapplication a crashé</string>
<string name="reCaptchaActivity">reCAPTCHA</string>
<string name="black_theme_title">Noir</string>
<string name="all">Tout</string>
<string name="channel">Chaîne</string>
<string name="reCaptcha_title">Défi reCAPTCHA</string>
<string name="recaptcha_request_toast">Défi reCAPTCHA demandé</string>
<string name="open_in_popup_mode">Ouvrir en mode fenêtré</string>
<string name="popup_mode_share_menu_title">Mode fenêtré NewPipe</string>
<string name="popup_playing_toast">Lecture en mode fenêtré</string>
<string name="yes">Oui</string>
<string name="later">Plus tard</string>
<string name="disabled">Désactivé</string>
<string name="info_labels">Quoi :\\nRequête :\\nLangue du contenu :\\nService :\\nHeure GMT :\\nPaquet :\\nVersion :\\nVersion du système :</string>
<string name="use_old_player_title">Utiliser l\'ancien lecteur</string>
<string name="use_old_player_summary">Ancienne version du lecteur Mediaframework</string>
<string name="short_thousand">K</string>
<string name="short_million">M</string>
<string name="msg_popup_permission">Cette autorisation est nécessaire pour
\nutiliser le mode fenêtré</string>
<string name="controls_background_title">Arrière-plan</string>
<string name="controls_popup_title">Fenêtre</string>
<string name="default_popup_resolution_title">Résolution de la fenêtre par défaut</string>
<string name="show_higher_resolutions_title">Afficher résolutions plus élevées</string>
<string name="show_higher_resolutions_summary">Seulement certains appareils supportent la lecture 2K/4K</string>
<string name="default_video_format_title">Format vidéo par défaut</string>
<string name="popup_remember_size_pos_title">Mémoriser la taille et la position de la fenêtre</string>
<string name="popup_remember_size_pos_summary">Mémoriser la dernière taille et position de la fenêtre</string>
<string name="settings_category_popup_title">Fenêtre</string>
<string name="filter">Filtre</string>
<string name="refresh">Actualiser</string>
<string name="clear">Effacer</string>
<string name="popup_resizing_indicator_title">Redimensionner</string>
<string name="short_billion">B</string>
<string name="use_external_video_player_summary">Supprime l\'audio à CERTAINES résolutions</string>
<string name="player_gesture_controls_summary">Utiliser les gestes pour contrôler la luminosité et le volume du lecteur</string>
<string name="show_search_suggestions_title">Suggestions de recherche</string>
<string name="show_search_suggestions_summary">Afficher les suggestions lors d\'une recherche</string>
<string name="player_gesture_controls_title">Gestes pour contrôler la lecture</string>
<string name="player_gesture_controls_title">Gestes pour contrôler la lecture</string>
<string name="best_resolution">Meilleure résolution</string>
<string name="subscribe_button_title">S\'abonner</string>
<string name="subscribed_button_title">Abonné</string>
<string name="channel_unsubscribed">Désabonné de la chaîne</string>
<string name="tab_main">Principal</string>
<string name="tab_subscriptions">Abonnements</string>
<string name="fragment_whats_new">Nouveautés</string>
<string name="settings_category_downloads_title">Téléchargement</string>
<string name="action_settings">Paramètres</string>
<string name="action_about">À propos</string>
@ -196,19 +163,16 @@
<string name="app_license_title">Licence de NewPipe</string>
<string name="read_full_license">Lire la licence</string>
<string name="contribution_title">Contribuer</string>
<string name="charset_letters_and_digits">Lettres et chiffres</string>
<string name="charset_letters_and_digits">Lettres et chiffres</string>
<string name="title_activity_about">À propos de NewPipe</string>
<string name="copyright" formatted="true">© %1$s par %2$s sous %3$s</string>
<string name="contribution_encouragement">Que ce soit pour des idées, traductions, changements de design, nettoyage ou gros changements de code, l\'aide est toujours la bienvenue. Plus on contribue, meilleur il devient !</string>
<string name="subscription_change_failed">Impossible de modifier l\'abonnement</string>
<string name="subscription_update_failed">Impossible d\'actualiser l\'abonnement</string>
<string name="resume_on_audio_focus_gain_summary">Continuer la lecture après les interruptions (ex : appels)</string>
<string name="settings_file_charset_title">Caractères autorisés dans les noms de fichiers</string>
<string name="settings_file_replacement_character_summary">Les caractères invalides sont remplacés par cette valeur</string>
<string name="settings_file_replacement_character_title">Caractère de remplacement</string>
<string name="enable_search_history_title">Historique de recherche</string>
<string name="enable_search_history_summary">Conserver les recherches sur l\'appareil</string>
<string name="enable_watch_history_title">Historique et cache</string>
@ -219,10 +183,8 @@
<string name="action_history">Historique</string>
<string name="history_empty">L\'historique est vide</string>
<string name="history_cleared">Historique supprimé</string>
<string name="notification_channel_name">Notification NewPipe</string>
<string name="notification_channel_name">Notification NewPipe</string>
<string name="undo">Annuler</string>
<string name="enable_watch_history_summary">Garder une trace des vidéos regardées</string>
<string name="resume_on_audio_focus_gain_title">Reprendre sur le gain de focus</string>
<string name="settings_category_player_title">Lecteur</string>
@ -230,33 +192,27 @@
<string name="settings_category_history_title">Historique &amp; cache</string>
<string name="playlist">Liste de lecture</string>
<string name="notification_channel_description">Notifications pour les lecteurs \"arrière-plan\" et \"fenêtre\" de NewPipe</string>
<string name="search_no_results">Aucun résultat</string>
<string name="empty_subscription_feed_subtitle">Aucun contenu</string>
<string name="no_subscribers">Aucun abonné</string>
<plurals name="subscribers">
<item quantity="one">%s abonné</item>
<item quantity="other">%s abonnés</item>
</plurals>
<item quantity="one">%s abonné</item>
<item quantity="other">%s abonnés</item>
</plurals>
<string name="no_views">Aucune vue</string>
<plurals name="views">
<item quantity="one">%s vue</item>
<item quantity="other">%s vues</item>
</plurals>
<item quantity="one">%s vue</item>
<item quantity="other">%s vues</item>
</plurals>
<string name="no_videos">Aucune vidéo</string>
<plurals name="videos">
<item quantity="one">Vidéo</item>
<item quantity="other">Vidéos</item>
</plurals>
<item quantity="one">Vidéo</item>
<item quantity="other">Vidéos</item>
</plurals>
<string name="charset_most_special_characters">Caractères spéciaux</string>
<string name="item_deleted">Élément effacé</string>
<string name="delete_item_search_history">Voulez-vous supprimer cet élément de l\'historique de recherche ?</string>
<string name="main_page_content">Contenu de la page principale</string>
<string name="delete_item_search_history">Voulez-vous supprimer cet élément de l\'historique de recherche ?</string>
<string name="main_page_content">Contenu de la page principale</string>
<string name="blank_page_summary">Page vide</string>
<string name="subscription_page_summary">Abonnements</string>
<string name="feed_page_summary">Page de Flux</string>
@ -265,10 +221,9 @@
<string name="trending">Populaires</string>
<string name="top_50">Top 50</string>
<string name="new_and_hot">Nouveau &amp; populaire</string>
<string name="background_player_append">En file d\'attente sur le lecteur en arrière-plan</string>
<string name="background_player_append">En file d\'attente sur le lecteur en arrière-plan</string>
<string name="popup_playing_append">En file d\'attente sur le lecteur en fenêtré</string>
<string name="play_all">Tout lire</string>
<string name="player_stream_failure">Impossible de jouer ce flux</string>
<string name="player_unrecoverable_failure">Une erreur irrécupérable du lecteur s\'est produite</string>
<string name="no_channel_subscribed_yet">Pas encore d\'abonnements de chaînes</string>
@ -280,12 +235,9 @@
<string name="show_hold_to_append_title">Afficher l\'astuce « Maintenir pour ajouter »</string>
<string name="show_hold_to_append_summary">Afficher l\'aide \"Appui long pour mettre en file d\'attente\" en appuyant sur les boutons \"Arrière-plan\" et \"Fenêtre\" sur la page de détails d\'une vidéo</string>
<string name="unknown_content">[Inconnu]</string>
<string name="player_recoverable_failure">Récupération de l\'erreur du lecteur</string>
<string name="kiosk_page_summary">Page Kiosque</string>
<string name="select_a_kiosk">Sélectionner un kiosque</string>
<string name="kiosk">Kiosque</string>
<string name="hold_to_append">Appui long pour mettre en file d\'attente</string>
<string name="enqueue_on_background">Mettre en file d\'attente en arrière-plan</string>
@ -293,7 +245,7 @@
<string name="start_here_on_main">Commencer la lecture ici</string>
<string name="start_here_on_background">Démarrer ici en arrière-plan</string>
<string name="start_here_on_popup">Démarrer ici en fenêtré</string>
<string name="donation_title">Donner</string>
<string name="donation_title">Donner</string>
<string name="donation_encouragement">NewPipe est développé par des volontaires sur leur temps libre afin de vous proposer la meilleure expérience possible. Vous pouvez leur offrir un café pour les soutenir dans leurs efforts et rendre NewPipe encore meilleur.</string>
<string name="website_title">Site</string>
<string name="website_encouragement">Visitez le site internet de NewPipe pour plus d\'informations et de nouvelles.</string>
@ -303,24 +255,19 @@
<string name="switch_to_background">Arrière-plan</string>
<string name="switch_to_popup">Fenêtré</string>
<string name="switch_to_main">Normal</string>
<string name="service_title">Service</string>
<string name="drawer_open">Ouvrir le menu</string>
<string name="drawer_close">Fermer le menu</string>
<string name="no_player_found_toast">Aucun lecteur de flux trouvé (vous pouvez installer VLC pour le lire).</string>
<string name="always">Toujours</string>
<string name="just_once">Une seule fois</string>
<string name="external_player_unsupported_link_type">Les lecteurs externes ne supportent pas ces types de liens</string>
<string name="invalid_url_toast">Lien non valide</string>
<string name="video_streams_empty">Aucun flux vidéo trouvé</string>
<string name="audio_streams_empty">Aucun flux audio trouvé</string>
<string name="video_player">Lecteur vidéo</string>
<string name="background_player">Lecteur en arrière-plan</string>
<string name="popup_player">Lecteur en fenêtré</string>
<string name="always_ask_player">Toujours demander</string>
<string name="preferred_player_fetcher_notification_title">Obtention des infos…</string>
<string name="preferred_player_fetcher_notification_message">Chargement du contenu</string>
<string name="import_data_title">Importer les données</string>
@ -332,100 +279,75 @@
<string name="no_valid_zip_file">Aucun fichier ZIP valide</string>
<string name="could_not_import_all_files">Avertissement: Impossible d\'importer tous les fichiers.</string>
<string name="override_current_data">Cela effacera vos paramètres actuels</string>
<string name="show_info">Afficher les infos</string>
<string name="tab_bookmarks">Marque-pages</string>
<string name="controls_add_to_playlist_title">Ajouter à</string>
<string name="detail_drag_description">Faites glisser pour réorganiser</string>
<string name="create">Créer</string>
<string name="dismiss">Ignorer</string>
<string name="rename">Renommer</string>
<string name="title_last_played">Dernière lecture</string>
<string name="delete_all">Tout supprimer</string>
<string name="delete_stream_history_prompt">Voulez-vous supprimer cet élément de votre historique \?</string>
<string name="delete_all_history_prompt">Êtes-vous sûr de supprimer tout votre historique \?</string>
<string name="title_most_played">Vidéos les plus regardées</string>
<string name="always_ask_open_action">Toujours demander</string>
<string name="create_playlist">Nouvelle liste de lecture</string>
<string name="delete_playlist">Supprimer</string>
<string name="rename_playlist">Renommer</string>
<string name="playlist_name_input">Nom</string>
<string name="append_playlist">Ajouter à la playlist</string>
<string name="set_as_playlist_thumbnail">Enregistrer la playlist en local</string>
<string name="bookmark_playlist">Marquer cette playlist</string>
<string name="unbookmark_playlist">Retirer la marque</string>
<string name="delete_playlist_prompt">Supprimer cette liste de lecture \?</string>
<string name="playlist_creation_success">Liste de lecture créée</string>
<string name="playlist_add_stream_success">Ajouté à la liste de lecture</string>
<string name="playlist_thumbnail_change_success">Miniature de la liste de lecture changée.</string>
<string name="playlist_delete_failure">Impossible de supprimer la liste de lecture.</string>
<string name="caption_none">Aucuns sous-titres</string>
<string name="resize_fit">Ajuster</string>
<string name="resize_zoom">Zoom</string>
<string name="caption_font_size_settings_title">Taille des sous-titres</string>
<string name="smaller_caption_font_size">Petite</string>
<string name="normal_caption_font_size">Normale</string>
<string name="larger_caption_font_size">Grande</string>
<string name="use_inexact_seek_title">Recherche rapide approximative</string>
<string name="use_inexact_seek_summary">Permettre au lecteur d\'accéder plus rapidement à une position au détriment de la précision</string>
<string name="download_thumbnail_title">Charger les miniatures</string>
<string name="download_thumbnail_summary">Désactivez pour empêcher le chargement des miniatures afin de réduire lutilisation de bande passante et de mémoire. Modifier cette option vide le cache dimages en mémoire vive et sur le disque.</string>
<string name="download_thumbnail_summary">Désactivez pour empêcher le chargement des miniatures afin de réduire lutilisation de bande passante et de mémoire. Ce changement vide le cache dimages en mémoire vive et sur le disque.</string>
<string name="thumbnail_cache_wipe_complete_notice">Images en cache effacées</string>
<string name="metadata_cache_wipe_title">Effacer les données en cache</string>
<string name="metadata_cache_wipe_summary">Effacer toutes les pages web mises en cache</string>
<string name="metadata_cache_wipe_complete_notice">Données en cache effacées</string>
<string name="file">Fichier</string>
<string name="invalid_directory">Aucun dossier de ce type</string>
<string name="invalid_source">Aucun fichier/contenu de ce type</string>
<string name="invalid_file">Le fichier nexiste pas ou nest pas accessible en lecture/écriture</string>
<string name="file_name_empty_error">Le nom du fichier ne peut être vide</string>
<string name="error_occurred_detail">Une erreur s\'est produite: %1$s</string>
<string name="delete_one">Supprimer un seul média</string>
<string name="drawer_header_action_paceholder_text">Quelque chose va bien bientôt arriver ;D</string>
<string name="controls_download_desc">Télécharger le fichier de flux</string>
<string name="auto_queue_title">Vidéo suivante en file d\'attente</string>
<string name="auto_queue_summary">Ajout automatique d\'un morceau suggéré lors de la lecture du dernier morceau dans une file d\'attente non bouclée.</string>
<string name="settings_category_debug_title">Débogage</string>
<string name="resize_fill">Remplir</string>
<string name="caption_auto_generated">Générés automatiquement</string>
<string name="enable_leak_canary_title">Activer LeakCanary</string>
<string name="enable_leak_canary_summary">La surveillance de la mémoire peut mettre temporairement l\'application en pause pendant les nettoyages</string>
<string name="enable_disposed_exceptions_title">Signaler les erreurs de développement hors cycle</string>
<string name="enable_disposed_exceptions_summary">Forcer le signalement des exceptions Rx qui surviennent hors activité</string>
<string name="import_export_title">Importer/exporter</string>
<string name="import_title">Importer</string>
<string name="import_from">Importer de</string>
<string name="export_to">Exporter vers</string>
<string name="import_ongoing">Importation en cours…</string>
<string name="export_ongoing">Exporation en cours…</string>
<string name="import_file_title">Importer fichier</string>
<string name="previous_export">Export précédent</string>
<string name="subscriptions_import_unsuccessful">Impossible d\'importer des abonnements</string>
<string name="subscriptions_export_unsuccessful">Impossible d\'exporter les abonnements</string>
<string name="import_youtube_instructions">"Pour importer vos abonnements YouTube vous devez d\'abord télécharger un fichier spécial de YouTube, selon les modalités suivantes :
\n
\n1. Suivez ce lien : %1$s
@ -438,27 +360,21 @@
\n3. Connectez-vous à votre compte.
\n4. Copier lURL vers lequel vous venez dêtre redirigé.</string>
<string name="import_soundcloud_instructions_hint">votreID, soundcloud.com/votreid</string>
<string name="import_network_expensive_warning">Cette opération peut consommer beaucoup de données mobiles.
\n
\nSouhaitez-vous continuer ?</string>
<string name="playback_speed_control">Vitesse de lecture</string>
<string name="playback_tempo">Cadence</string>
<string name="unhook_checkbox">Détacher (déformations possibles)</string>
<string name="playback_default">Défaut</string>
<string name="preferred_open_action_settings_title">Ouvrir de préférence avec</string>
<string name="preferred_open_action_settings_title">Ouvrir de préférence avec</string>
<string name="preferred_open_action_settings_summary">Action par défaut lors de l\'ouverture de contenu - %s</string>
<string name="no_streams_available_download">Aucun flux disponible au téléchargement</string>
<string name="caption_setting_title">Sous-titres</string>
<string name="caption_setting_description">Modifier la taille du texte et les styles d\'arrière-plan du lecteur. Redémarrage requis pour prendre effet.</string>
<string name="playback_pitch">Ton</string>
<string name="playback_nightcore">Nightcore</string>
<string name="toast_no_player">Aucune application installée pour lire ce fichier</string>
<string name="clear_views_history_title">Effacer l\'historique</string>
<string name="clear_views_history_summary">Supprimer l\'historique des flux regardés</string>
<string name="delete_view_history_alert">Supprimer tout l\'historique regardé \?</string>
@ -468,15 +384,13 @@
<string name="delete_search_history_alert">Supprimer tout l\'historique de recherche \?</string>
<string name="search_history_deleted">Historique des recherches effacé.</string>
<string name="one_item_deleted">1 élément supprimé.</string>
<string name="app_license">"NewPipe est un logiciel sous licence libre : Vous pouvez l\'utiliser, l\'étudier, le partager et l\'améliorer comme bon vous semble. Vous pouvez le redistribuer et/ou le modifier sous les termes de la licence générale publique GNU, comme publiée par la Free Software Foundation, dans sa version 3, ou, à votre convenance, dans une version plus récente."</string>
<string name="privacy_policy_title">Politique de confidentialité de NewPipe</string>
<string name="read_privacy_policy">Lire la politique de confidentialité</string>
<string name="import_settings">Voulez-vous également importer des paramètres\?</string>
<string name="accept">Accepter</string>
<string name="decline">Refuser</string>
<string name="privacy_policy_encouragement">Le projet NewPipe prend votre vie privée très à cœur. Ainsi, lapplication nenvoie aucune donnée sans votre consentement.
<string name="privacy_policy_encouragement">Le projet NewPipe prend votre vie privée très à cœur. Ainsi, lapplication nenvoie aucune donnée sans votre consentement.
\nLa politique de confidentialité de NewPipe explique en détail quelles données sont envoyées et stockées lorsque vous envoyez un rapport de plantage.</string>
<string name="start_accept_privacy_policy">Afin de se conformer au Règlement Général sur la Protection des Données (RGPD ou GDPR), nous attirons votre attention sur la politique de vie privée de NewPipe. Merci de la lire attentivement.
\nVous devez l\'accepter pour nous envoyer le rapport de bug.</string>
@ -489,7 +403,6 @@
<string name="skip_silence_checkbox">Accélérer pendant les silences</string>
<string name="playback_step">Étape</string>
<string name="playback_reset">Réinitialiser</string>
<string name="minimize_on_exit_title">Minimiser lors du changement d\'application</string>
<string name="minimize_on_exit_summary">Action lors du changement d\'application depuis le lecteur vidéo —%s</string>
<string name="minimize_on_exit_none_description">Aucune</string>
@ -524,7 +437,40 @@
<string name="app_update_notification_content_title">Une mise à jour de NewPipe disponible !</string>
<string name="app_update_notification_content_text">Appuyez pour télécharger</string>
<string name="missions_header_finished">Terminé</string>
<string name="missions_header_pending">En file</string>
<string name="missions_header_pending">Dans la file d\'attente</string>
<string name="paused">En pause</string>
<string name="download_failed">Téléchargement échoué</string>
<string name="error_timeout">Délai de connection dépassé</string>
<string name="conferences">Conférences</string>
<string name="download_finished">Téléchargement terminé</string>
<string name="download_finished_more">%s téléchargements terminés</string>
<string name="queued">Ajouté à la file d\'attente</string>
<string name="generate_unique_name">Générer un nom unique</string>
<string name="overwrite">Écraser</string>
<string name="overwrite_unrelated_warning">Un fichier avec ce nom existe déjà</string>
<string name="overwrite_finished_warning">Un fichier téléchargé avec ce nom existe déjà</string>
<string name="download_already_running">Il y a un téléchargement en cours avec ce nom</string>
<string name="show_error">Afficher l\'erreur</string>
<string name="label_code">Code</string>
<string name="error_path_creation">Le fichier ne peut pas être créé</string>
<string name="error_file_creation">Le dossier de destination ne peut pas être créé</string>
<string name="error_permission_denied">Autorisation refusée par le système</string>
<string name="error_ssl_exception">Échoué de la connexion sécurisée</string>
<string name="error_unknown_host">Le serveur est introuvable</string>
<string name="error_connect_host">Impossible de se connecter au serveur</string>
<string name="error_http_no_content">Le serveur nenvoie pas de données</string>
<string name="error_http_not_found">Introuvable</string>
<string name="clear_finished_download">Effacer les téléchargements terminés</string>
<string name="pause_downloads_on_mobile">Mettre en pause lors du passage en données mobiles</string>
<string name="pause_downloads_on_mobile_desc">Les téléchargements qui ne peuvent pas être mis en pause seront redémarrés</string>
<string name="list_view_mode">Mode liste</string>
<string name="post_processing">post-traitement</string>
<string name="enqueue">File dattente</string>
<string name="permission_denied">Action refusée par le système</string>
<string name="error_postprocessing_failed">Échec du post-traitement</string>
<string name="max_retry_msg">Nombre maximum de tentatives</string>
<string name="max_retry_desc">Nombre maximum de tentatives avant d\'annuler le téléchargement</string>
<string name="saved_tabs_invalid_json">Utilisation des onglets par défaut, erreur lors de la lecture des onglets enregistrés</string>
<string name="error_http_unsupported_range">Le serveur n\'accepte pas les téléchargements multi-threads, réessayez avec @string/msg_threads = 1</string>
<string name="msg_pending_downloads">Continuer vos %s transferts en attente depuis Téléchargement</string>
</resources>

View File

@ -59,8 +59,6 @@
<string name="play_audio">Audio</string>
<string name="default_audio_format_title">Formato de audio predeterminado</string>
<string name="default_video_format_title">Formato de vídeo predeterminado</string>
<string name="webm_description">WebM — formato libre</string>
<string name="m4a_description">M4A — mellor calidade</string>
<string name="theme_title">Tema</string>
<string name="light_theme_title">Claro</string>
<string name="dark_theme_title">Escuro</string>
@ -218,8 +216,6 @@
<string name="audio">Audio</string>
<string name="retry">Tentar de novo</string>
<string name="storage_permission_denied">A permisión de acceso ao almacenamento foi denegada</string>
<string name="use_old_player_title">Usar o reprodutor antigo</string>
<string name="use_old_player_summary">Versión interna anticuada do reprodutor Mediaframework</string>
<string name="short_thousand">K</string>
<string name="short_million">M</string>

View File

@ -22,15 +22,12 @@
<string name="popup_mode_share_menu_title">מצב חלון צף של NewPipe</string>
<string name="controls_background_title">רקע</string>
<string name="controls_popup_title">חלון צף</string>
<string name="download_path_title">נתיב להורדת סרטונים</string>
<string name="download_path_summary">נתיב מיקום לאחסון סרטונים</string>
<string name="download_path_dialog_title">נא להקליד נתיב לשמירת סרטונים</string>
<string name="download_path_audio_title">תיקיית הורדות שמע</string>
<string name="download_path_audio_summary">הורדות שמע נשמרות כאן</string>
<string name="download_path_audio_dialog_title">נא להקליד נתיב לשמירת קובצי שמע</string>
<string name="autoplay_by_calling_app_title">ניגון אוטומטי</string>
<string name="autoplay_by_calling_app_summary">מנגן סרטון כאשר NewPipe נפתח דרך יישומון אחר</string>
<string name="default_resolution_title">רזולוציית בררת המחדל</string>
@ -54,7 +51,6 @@
<string name="player_gesture_controls_summary">שימוש במחוות כדי לשלוט בבהירות ובעצמת השמע של הנגן</string>
<string name="show_search_suggestions_title">הצעות חיפוש</string>
<string name="show_search_suggestions_summary">הצגת הצעות בעת החיפוש</string>
<string name="download_dialog_title">הורדה</string>
<string name="next_video_title">הבא</string>
<string name="show_next_and_similar_title">להציג סרטונים דומים ובאים בתור</string>
@ -69,7 +65,7 @@
<string name="play_btn_text">נגינה</string>
<string name="content">תוכן</string>
<string name="show_age_restricted_content_title">תוכן עם הגבלת גיל</string>
<string name="video_is_age_restricted">הצגת סרטונים עם הגבלת גיל. ניתן לאפשר תכנים שכאלה דרך ההגדרות.</string>
<string name="video_is_age_restricted">הצגת סרטונים עם הגבלת גיל. ניתן לאפשר תכנים שכאלו דרך ההגדרות.</string>
<string name="duration_live">חי</string>
<string name="downloads">הורדות</string>
<string name="downloads_title">הורדות</string>
@ -83,7 +79,6 @@
<string name="refresh">רענון</string>
<string name="clear">פינוי</string>
<string name="popup_resizing_indicator_title">שינוי גודל</string>
<string name="general_error">שגיאה</string>
<string name="network_error">שגיאת רשת</string>
<string name="could_not_load_thumbnails">אין אפשרות לטעון את כל התמונות הממוזערות</string>
@ -104,17 +99,14 @@
<string name="what_device_headline">מידע:</string>
<string name="what_happened_headline">מה קרה:</string>
<string name="info_labels">מה:\\nבקשה:\\nשפת התוכן:\\nשירות:\\nשעון גריניץ׳:\\nחבילה:\\nגרסה:\\nגרסת מערכת ההפעלה:</string>
<string name="subscribe_button_title">עריכת מינוי</string>
<string name="subscribe_button_title">עריכת מינוי</string>
<string name="subscribed_button_title">נרשמת</string>
<string name="channel_unsubscribed">ביטול מינוי לערוץ</string>
<string name="subscription_change_failed">לא הצלחתי לשנות מינוי</string>
<string name="subscription_update_failed">לא ניתן לעדכן את המינוי</string>
<string name="tab_main">ראשי</string>
<string name="tab_subscriptions">מינויים</string>
<string name="fragment_whats_new">מה חדש</string>
<string name="enable_search_history_title">היסטוריית חיפוש</string>
<string name="enable_search_history_summary">שמירת שאילתות החיפוש מקומית</string>
<string name="enable_watch_history_title">היסטוריה ומטמון</string>
@ -132,20 +124,14 @@
<string name="best_resolution">רזולוציה מיטבית</string>
<string name="undo">ביטול</string>
<string name="play_all">לנגן הכול</string>
<string name="notification_channel_name">התראה מ־NewPipe</string>
<string name="notification_channel_description">התראות עבור נגן הרקע והנגן הצף של NewPipe</string>
<string name="unknown_content">[לא ידוע]</string>
<string name="player_stream_failure">נגינת התזרים לא הצליחה</string>
<string name="player_unrecoverable_failure">אירעה תקלה בנגן ממנה לא ניתן להשתקם</string>
<string name="player_recoverable_failure">מתבצעת החלמה משגיאת נגן</string>
<string name="your_comment">ההערה שלך (באנגלית):</string>
<string name="error_details_headline">פרטים:</string>
<string name="list_thumbnail_view_description">תמונה ממוזערת לתצוגה המקדימה של הסרטון</string>
<string name="detail_thumbnail_view_description">תמונות ממוזערות לתצוגה המקדימה של הסרטון</string>
<string name="detail_uploader_thumbnail_view_description">תמונה ייצוגית של המפרסם</string>
@ -157,54 +143,43 @@
<string name="user_report">דוח משתמש</string>
<string name="search_no_results">אין תוצאות</string>
<string name="empty_subscription_feed_subtitle">אין כאן כלום מלבד צרצרים</string>
<string name="err_dir_create">לא ניתן ליצור את תיקיית ההורדות %1$s</string>
<string name="info_dir_created">תיקיית ההורדות %1$s נוצרה</string>
<string name="video">סרטון</string>
<string name="audio">שמע</string>
<string name="retry">ניסיון חוזר</string>
<string name="storage_permission_denied">הגישה לאחסון נדחתה</string>
<string name="use_old_player_title">השתמש בנגן הישן</string>
<string name="use_old_player_summary">השתמש בנגן המובנה Mediaframework</string>
<string name="short_thousand">K</string>
<string name="short_million">M</string>
<string name="short_billion">B</string>
<string name="no_subscribers">אין מנויים</string>
<plurals name="subscribers">
<item quantity="one">מנוי אחד</item>
<item quantity="two">שני מנויים</item>
<item quantity="many">%s מנויים</item>
<item quantity="other">%s מנויים</item>
</plurals>
<item quantity="one">מנוי אחד</item>
<item quantity="two">שני מנויים</item>
<item quantity="many">%s מנויים</item>
<item quantity="other">%s מנויים</item>
</plurals>
<string name="no_views">אין צפיות</string>
<plurals name="views">
<item quantity="one">צפייה אחת</item>
<item quantity="two">שתי צפיות</item>
<item quantity="many">%s צפיות</item>
<item quantity="other">%s צפיות</item>
</plurals>
<item quantity="one">צפייה אחת</item>
<item quantity="two">שתי צפיות</item>
<item quantity="many">%s צפיות</item>
<item quantity="other">%s צפיות</item>
</plurals>
<string name="no_videos">אין סרטונים</string>
<plurals name="videos">
<item quantity="one">סרטון</item>
<item quantity="two">שני סרטונים</item>
<item quantity="many">%s סרטונים</item>
<item quantity="other">%s סרטונים</item>
</plurals>
<item quantity="one">סרטון</item>
<item quantity="two">שני סרטונים</item>
<item quantity="many">%s סרטונים</item>
<item quantity="other">%s סרטונים</item>
</plurals>
<string name="start">התחלה</string>
<string name="pause">השהיה</string>
<string name="view">נגינה</string>
<string name="delete">מחיקה</string>
<string name="checksum">גיבוב לאימות</string>
<string name="add">משימה חדשה</string>
<string name="finish">אישור</string>
<string name="msg_name">שם קובץ</string>
<string name="msg_threads">תת־דיונים</string>
<string name="msg_error">שגיאה</string>
@ -218,19 +193,15 @@
<string name="no_available_dir">נא לבחור תיקיית הורדה זמינה</string>
<string name="msg_popup_permission">הרשאה זו נדרשת לטובת
\nפתיחה בחלון צף</string>
<string name="reCaptchaActivity">reCAPTCHA</string>
<string name="reCaptcha_title">אתגר reCAPTCHA</string>
<string name="recaptcha_request_toast">התקבלה בקשה לאתגר reCAPTCHA</string>
<string name="settings_category_downloads_title">הורדה</string>
<string name="settings_file_charset_title">רשימת תווים אפשרית בשמות קבצים</string>
<string name="settings_file_replacement_character_summary">תווים לא נתמכים מוחלפים בערך הזה</string>
<string name="settings_file_replacement_character_title">תו חלופי</string>
<string name="charset_letters_and_digits">אותיות וספרות</string>
<string name="charset_most_special_characters">רוב התווים המיוחדים</string>
<string name="title_activity_about">על אודות NewPipe</string>
<string name="action_settings">הגדרות</string>
<string name="action_about">על אודות</string>
@ -252,8 +223,6 @@
<string name="website_encouragement">מומלץ לבקר באתר של NewPipe לפרטים נוספים ולחדשות.</string>
<string name="app_license_title">הרישיון של NewPipe</string>
<string name="read_full_license">הצגת הרישיון</string>
<string name="title_activity_history">היסטוריה</string>
<string name="title_history_search">נשלח כחיפוש</string>
<string name="title_history_view">נצפו</string>
@ -263,7 +232,6 @@
<string name="history_cleared">ההיסטוריה התרוקנה</string>
<string name="item_deleted">פריט נמחק</string>
<string name="delete_item_search_history">למחוק את הפריט הזה מהיסטוריית החיפושים\?</string>
<string name="main_page_content">תוכן הדף הראשי</string>
<string name="blank_page_summary">דף ריק</string>
<string name="kiosk_page_summary">דף גישה מזדמנת</string>
@ -273,7 +241,6 @@
<string name="select_a_channel">נא לבחור ערוץ</string>
<string name="no_channel_subscribed_yet">אין עדיין מינויים לערוצים</string>
<string name="select_a_kiosk">נא לבחור סוג גישה מזדמנת</string>
<string name="kiosk">גישה מזדמנת</string>
<string name="trending">החמים</string>
<string name="top_50">50 המובילים</string>
@ -289,29 +256,24 @@
<string name="start_here_on_main">להתחיל לנגן מכאן</string>
<string name="start_here_on_background">"להתחיל מכאן כאשר נגן הרקע מופעל"</string>
<string name="start_here_on_popup">להתחיל כאן בנגן הצף</string>
<string name="controls_download_desc">הורדת קובץ הזרמה</string>
<string name="controls_download_desc">הורדת קובץ הזרמה</string>
<string name="show_info">הצגת מידע</string>
<string name="tab_bookmarks">רשימות נגינה מסומנות</string>
<string name="controls_add_to_playlist_title">הוספה אל</string>
<string name="default_content_country_title">מדינת תוכן כבררת מחדל</string>
<string name="service_title">שירות</string>
<string name="settings_category_debug_title">ניפוי שגיאות</string>
<string name="always">תמיד</string>
<string name="just_once">חד פעמי</string>
<string name="import_data_title">ייבוא מסד נתונים</string>
<string name="export_data_title">ייצוא מסד נתונים</string>
<string name="external_player_unsupported_link_type">נגנים חיצוניים לא תומכים בסוגי קישורים כאלה</string>
<string name="invalid_url_toast">כתובת שגויה</string>
<string name="file">קובץ</string>
<string name="switch_to_background">העברה לרקע</string>
<string name="switch_to_popup">העברה לחלון צף</string>
<string name="no_player_found_toast">לא נמצא נגן צפייה ישירה (ניתן להתקין את VLC כדי לתקן זאת).</string>
<string name="thumbnail_cache_wipe_complete_notice">מטמון התמונות התרוקן</string>
<string name="thumbnail_cache_wipe_complete_notice">תמונות מטמון נמחקו</string>
<string name="metadata_cache_wipe_title">ניקוי מטמון נתוני העל</string>
<string name="metadata_cache_wipe_complete_notice">מטמון נתוני העל התרוקן</string>
<string name="export_data_summary">ייצוא היסטוריה, מינויים ורשימות נגינה</string>
@ -322,61 +284,48 @@
<string name="invalid_file">הקובץ אינו קיים או שחסרה הרשאה לקרוא אותו או לכתוב אליו</string>
<string name="file_name_empty_error">שם הקובץ אינו יכול להיות ריק</string>
<string name="detail_drag_description">ניתן לסדר מחדש בגרירה</string>
<string name="create">יצירה</string>
<string name="delete_one">למחוק אחד</string>
<string name="delete_all">למחוק הכול</string>
<string name="dismiss">התעלמות</string>
<string name="rename">שינוי שם</string>
<string name="one_item_deleted">פריט אחד נמחק.</string>
<string name="toast_no_player">לא מותקן יישומון שמתאים לנגינת הקובץ הזה</string>
<string name="delete_stream_history_prompt">למחוק את הפריט הזה מהיסטוריית הצפייה שלך\?</string>
<string name="delete_all_history_prompt">למחוק את כל הפריטים מההיסטוריה\?</string>
<string name="export_complete_toast">הייצוא הסתיים</string>
<string name="import_complete_toast">הייבוא הסתיים</string>
<string name="no_valid_zip_file">אין קובץ ZIP תקין</string>
<string name="video_player">נגן וידאו</string>
<string name="video_player">נגן סרטונים</string>
<string name="background_player">נגן רקע</string>
<string name="popup_player">נגן צף</string>
<string name="always_ask_open_action">לשאול תמיד</string>
<string name="preferred_player_fetcher_notification_title">המידע מתקבל…</string>
<string name="preferred_player_fetcher_notification_message">התוכן המבוקש בטעינה</string>
<string name="create_playlist">רשימת נגינה חדשה</string>
<string name="delete_playlist">מחיקה</string>
<string name="rename_playlist">שינוי שם</string>
<string name="playlist_name_input">שם</string>
<string name="append_playlist">הוספה לרשימת נגינה</string>
<string name="bookmark_playlist">הוספה רשימת השמעה לסימניות</string>
<string name="bookmark_playlist">הוספת רשימת נגינה לסימניות</string>
<string name="unbookmark_playlist">הסרת סימנייה</string>
<string name="delete_playlist_prompt">למחוק רשימת נגינה זו\?</string>
<string name="playlist_creation_success">רשימת הנגינה נוצרה</string>
<string name="playlist_add_stream_success">נוסף לרשימת הנגינה</string>
<string name="playlist_thumbnail_change_success">תמונת רשימת הנגינה הוחלפה.</string>
<string name="resize_fill">מילוי</string>
<string name="resize_zoom">תקריב</string>
<string name="caption_auto_generated">נוצרו אוטומטית</string>
<string name="import_export_title">ייבוא/ייצוא</string>
<string name="import_title">ייבוא</string>
<string name="import_from">ייבוא מ־</string>
<string name="export_to">ייצוא אל</string>
<string name="import_ongoing">מתבצע ייבוא…</string>
<string name="export_ongoing">מתבצע ייצוא…</string>
<string name="import_file_title">ייבוא קובץ</string>
<string name="previous_export">ייצוא קודם</string>
<string name="subscriptions_import_unsuccessful">לא ניתן לייבא את המינויים</string>
<string name="subscriptions_export_unsuccessful">לא ניתן לייצא את המינויים</string>
<string name="import_youtube_instructions">כדי לייבא את רשימת המינויים שלך מ־YouTube עליך להוריד את קובץ הייצוא:
\n
\n1. לעבור לכתובת הזו: %1$s
@ -384,16 +333,15 @@
\n3. ההורדה אמורה להתחיל (זה קובץ הייצוא)</string>
<string name="playback_tempo">קצב</string>
<string name="playback_default">ברירת מחדל</string>
<string name="use_inexact_seek_title">שימוש בחיפוש מהיר גס</string>
<string name="use_inexact_seek_title">שימוש בחיפוש מהיר ולא מדויק</string>
<string name="use_inexact_seek_summary">חיפוש גס מאפשר לנגן לחפש נקודת זמן מהר יותר, ברמת דיוק נמוכה יותר</string>
<string name="download_thumbnail_title">טעינת תמונות ממוזערות</string>
<string name="download_thumbnail_summary">כיבוי האפשרות מונע את טעינת התמונות הממוזערות, חוסך בתקשורת נתונים ובניצולת הזיכרון. שינויים באפשרות זו מוחקים את המטמון בזיכרון ובכונן.</string>
<string name="metadata_cache_wipe_summary">הסרת כל נתוני העמודים שבמטמון</string>
<string name="auto_queue_title">הוספת התזרים הבא לרשימת הנגינה אוטומטית</string>
<string name="auto_queue_summary">להוסיף אוטומטית תזרים דומה בעת נגינת התזרים האחרון בתור שאינו מחזורי.</string>
<string name="auto_queue_summary">להוסיף אוטומטית תזרים דומה בעת נגינת התזרים האחרון בתור שאינו מחזורי</string>
<string name="toggle_orientation">החלפת כיווניות</string>
<string name="switch_to_main">העברה לראשי</string>
<string name="import_data_summary">משכתב את ההיסטוריה והמינויים הנוכחיים שלך</string>
<string name="clear_views_history_summary">מחיקת היסטוריית התזרימים שהתנגנו</string>
<string name="channels">ערוצים</string>
@ -403,13 +351,12 @@
<string name="delete_view_history_alert">למחוק את כל היסטוריית הצפייה\?</string>
<string name="clear_search_history_summary">מחיקת היסטוריית מילות החיפוש</string>
<string name="delete_search_history_alert">למחוק את כל היסטוריית החיפוש\?</string>
<string name="video_streams_empty">לא נמצא תזרימי וידאו</string>
<string name="audio_streams_empty">לא נמצא תזרימי שמע</string>
<string name="video_streams_empty">לא נמצאו תזרימי וידאו</string>
<string name="audio_streams_empty">לא נמצאו תזרימי שמע</string>
<string name="invalid_directory">אין תיקייה כזו</string>
<string name="invalid_source">אין מקור תיקייה/תוכן</string>
<string name="error_occurred_detail">אירעה שגיאה: %1$s</string>
<string name="no_streams_available_download">אין תזרימים זמינים להורדה</string>
<string name="privacy_policy_title">מדיניות הפרטיות של NewPipe</string>
<string name="privacy_policy_encouragement">מיזם NewPipe שומר על הפרטיות שלך בצורה מאוד קפדנית. לפיכך, היישומון אינו אוסף נתונים ללא הסכמתך.
\nמדיניות הפרטיות של NewPipe מסבירה בפרטי פרטים אילו נתונים נשלחים ומאוחסנים בעת שליחת דיווח על תקלה.</string>
@ -417,29 +364,20 @@
<string name="app_license">NewPipe הוא יישומון חופשי בהתאם לרישיון קופילפט: מותר לך להשתמש, לחקור, לשתף ולשפר בכל דרך שנראית לך. במיוחד מותר לך להפיץ מחדש ו/או לשנות תחת תנאי הרישיון הציבורי הכללי של GNU כפי שמופץ על ידי קרן התכנה החופשית, בין אם גרסה 3 של הרישיון או (לשיקולך) כל גרסה עדכנית יותר שלו.</string>
<string name="title_last_played">התנגנו אחרונים</string>
<string name="title_most_played">הכי נצפים</string>
<string name="could_not_import_all_files">אזהרה: ייבוא חלק מהקבצים נכשל.</string>
<string name="override_current_data">פעולה זו תדרוס את ההגדרות הקיימות.</string>
<string name="import_settings">לייבא גם הגדרות\?</string>
<string name="drawer_open">פתיחת מגירה</string>
<string name="drawer_close">סגירת מגירה</string>
<string name="drawer_header_action_paceholder_text">משהו יופיע כאן בקרוב ;D</string>
<string name="preferred_open_action_settings_title">פעולת ‚פתיחה’ מועדפת</string>
<string name="preferred_open_action_settings_summary">פעולת בררת מחדל בעת פתיחת תוכן - %s</string>
<string name="set_as_playlist_thumbnail">הגדרה כתמונת רשימת הנגינה</string>
<string name="playlist_delete_failure">לא ניתן למחוק רשימת נגינה.</string>
<string name="caption_none">אין כתוביות</string>
<string name="resize_fit">התאמה</string>
<string name="caption_setting_title">כתוביות</string>
<string name="caption_setting_description">שינוי גודל כותרת הנגן וסגנונות הרקע. נדרשת הפעלה מחדש כדי ששינויים אלה יכנסו לתוקף.</string>
<string name="enable_leak_canary_title">הפעלת LeakCanary</string>
<string name="enable_leak_canary_summary">מעקב אחר זליגת זיכרון עשויה לגרום ליישומון להיות בלתי זמין בזמן העתקת תוכן הזיכרון לקובץ</string>
<string name="import_soundcloud_instructions_hint">המזהה שלך, soundcloud.com/המזהה שלך</string>
@ -479,7 +417,7 @@
<string name="selection">בחירה</string>
<string name="events">אירועים</string>
<string name="conferences">כנסים</string>
<string name="enable_disposed_exceptions_title">דיווח על שגיאות של חריגה ממחזור חיים</string>
<string name="enable_disposed_exceptions_title">דיווח על שגיאות שמחוץ למחזור החיים</string>
<string name="enable_disposed_exceptions_summary">אילוץ דיווח על חריגות מחוץ למקטעים או למחזור חיי הפעילות לאחר ההשלכה בתשדורת יוצאת</string>
<string name="import_soundcloud_instructions">ניתן לייבא פרופיל SoundCloud על ידי הקלדת הכתובת או המזהה שלך:
\n
@ -502,7 +440,6 @@
<string name="app_update_notification_content_title">יצא עדכון ל־NewPipe!</string>
<string name="app_update_notification_content_text">יש לגעת כדי להוריד</string>
<string name="missions_header_finished">הסתיים</string>
<string name="missions_header_pending">בתור</string>
<string name="paused">מושהה</string>
<string name="queued">בתור</string>
<string name="post_processing">עיבוד מאוחר</string>
@ -513,12 +450,12 @@
<string name="download_finished_more">%s הורדות הסתיימו</string>
<string name="generate_unique_name">יצירת שם ייחודי</string>
<string name="overwrite">שכתוב</string>
<string name="overwrite_warning">כבר קיים קובץ בשם הזה</string>
<string name="overwrite_finished_warning">כבר קיים קובץ בשם הזה</string>
<string name="download_already_running">אחת ההורדות הפעילות כבר נושאת את השם הזה</string>
<string name="show_error">הצגת שגיאה</string>
<string name="label_code">קוד</string>
<string name="error_path_creation">לא ניתן ליצור את הקובץ</string>
<string name="error_file_creation">לא ניתן ליצור את תיקיית היעד</string>
<string name="error_file_creation">לא ניתן ליצור את הקובץ</string>
<string name="error_path_creation">לא ניתן ליצור את תיקיית היעד</string>
<string name="error_permission_denied">ההרשאה נדחתה על ידי המערכת</string>
<string name="error_ssl_exception">החיבור המאובטח נכשל</string>
<string name="error_unknown_host">לא ניתן למצוא את השרת</string>
@ -535,4 +472,5 @@
<string name="max_retry_desc">מספר הניסיונות החוזרים המרבי בטרם ביטול ההורדה</string>
<string name="pause_downloads_on_mobile">להשהות בעת מעבר לתקשורת נתונים סלולרית</string>
<string name="pause_downloads_on_mobile_desc">הורדות שלא ניתן להשהות יופעלו מחדש</string>
<string name="missions_header_pending">בהמתנה</string>
</resources>

View File

@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="view_count_text">%1$s दृश्य</string>
<string name="view_count_text">%1$s दृश्य</string>
<string name="upload_date_text">%1$s को प्रकाशित</string>
<string name="no_player_found">कोई स्ट्रीम प्लेयर नहीं मिला। क्या आप VLC इंस्टॉल करना चाहते हैं?</string>
<string name="install">इंस्टॉल करें</string>
<string name="open_in_browser">ब्राउज़र में खोलें</string>
<string name="open_in_popup_mode">पॉपअप मोड में खोलें</string>
<string name="share">शेयर करें</string>
<string name="share">साझा करें</string>
<string name="download">डाउनलोड</string>
<string name="search">खोजें</string>
<string name="settings">सेटिंग्स</string>
@ -17,15 +17,13 @@
<string name="subscribed_button_title">सदस्यता ली</string>
<string name="channel_unsubscribed">चैनल सदस्यता रद्द करी गयी</string>
<string name="tab_subscriptions">सदस्यता</string>
<string name="controls_background_title">पीछे</string>
<string name="controls_popup_title">पॉपअप</string>
<string name="autoplay_by_calling_app_title">ऑटोप्‍ले करें</string>
<string name="play_audio">ऑडियो</string>
<string name="light_theme_title">हलका</string>
<string name="black_theme_title">काली</string>
<string name="enable_watch_history_title">पूर्व और कैश</string>
<string name="enable_watch_history_title">इतिहास व कॅशे</string>
<string name="download_dialog_title">डाउनलोड</string>
<string name="next_video_title">अगला</string>
<string name="settings_category_video_audio_title">वीडियो और ऑडियो</string>
@ -44,7 +42,6 @@
<string name="app_license_title">न्यूपाइप का लाइसेंस</string>
<string name="read_full_license">लाइसेंस पढ़ें</string>
<string name="contribution_title">योगदान करें</string>
<string name="title_activity_history">इतिहास</string>
<string name="title_history_search">खोजा जा चूका है</string>
<string name="title_history_view">विडियो जो देख लिए गए है</string>
@ -60,22 +57,18 @@
<string name="did_you_mean">क्या आप का मतलब %1$s है?</string>
<string name="share_dialog_title">शेयर करें</string>
<string name="use_external_video_player_title">अन्य वीडियो प्लेयर उपयोग करें</string>
<string name="use_external_video_player_summary">कुछ रेसोल्युशनस में नहीं आएगी</string>
<string name="use_external_video_player_summary">कुछ प्रस्तावों पर ऑडियो निकालता है</string>
<string name="use_external_audio_player_title">अन्य ऑडियो प्लेयर उपयोग करें</string>
<string name="tab_main">मुख्य</string>
<string name="subscription_change_failed">सदस्यता को बदलने में असमर्थ है</string>
<string name="subscription_update_failed">सदस्यता को अपडेट करने में असमर्थ है</string>
<string name="subscription_change_failed">सदस्यता नहीं बदला जा सका</string>
<string name="subscription_update_failed">सदस्यता का अद्यतन नहीं हो सका</string>
<string name="fragment_whats_new">देखे की क्या नया है</string>
<string name="download_path_title">विडियो को डाउनलोड करने के लिए फाइल की जगह</string>
<string name="download_path_summary">डाउनलोड किए गए विडियो फाइल को रखने की जगह</string>
<string name="download_path_dialog_title">वीडियो के लिए डाउनलोड पथ दर्ज करें</string>
<string name="download_path_audio_title">ऑडियो डाउनलोड फ़ोल्डर</string>
<string name="download_path_audio_summary">डाउनलोड किये गए ऑडियो यहाँ है</string>
<string name="download_path_audio_dialog_title">ऑडियो फाइल डाउनलोड करने के लिए जगह दर्ज करें</string>
<string name="autoplay_by_calling_app_summary">अन्य अप्प के द्वारा NewPipe के आह्वान पर वीडियो तुरंत चले</string>
<string name="default_resolution_title">वीडियो का डिफ़ॉल्ट रिज़ॉल्यूशन</string>
<string name="default_popup_resolution_title">विडियो पॉपअप का डिफ़ॉल्ट रिज़ॉल्यूशन</string>
@ -84,11 +77,9 @@
<string name="play_with_kodi_title">Kodi से चलाये</string>
<string name="kore_not_found">Kore एप्प नहीं मिला, इसे इनस्टॉल करें?</string>
<string name="show_play_with_kodi_title">\"Kodi से चलाये\" वाला विकल्प दिखाए</string>
<string name="show_play_with_kodi_summary">उस विकल्प को दिखाए जिसमे Kodi Media Center के जरिये विडियो प्ले किया जाता है</string>
<string name="show_play_with_kodi_summary">कोडी मीडिया सेंटर के माध्यम से वीडियो चलाने के लिए एक विकल्प प्रदर्शित करें</string>
<string name="default_audio_format_title">डिफ़ॉल्ट ऑडियो का फॉर्मेट</string>
<string name="default_video_format_title">डिफ़ॉल्ट विडियो का फॉर्मेट</string>
<string name="webm_description">WebM - libre फॉर्मेट</string>
<string name="m4a_description">M4A - बेहतर क्वालिटी</string>
<string name="theme_title">एप्प का नया रूप</string>
<string name="dark_theme_title">काला</string>
<string name="popup_remember_size_pos_title">विडियो पॉपअप की आकर और उसकी स्थति को याद रखे</string>
@ -99,15 +90,14 @@
<string name="show_search_suggestions_summary">जब कुछ ढूंड रहे हो तो सुझाव दिखाये</string>
<string name="enable_search_history_title">खोज के इतिहास को देखे</string>
<string name="enable_search_history_summary">खोज के query को फ़ोन की मेमोरी में ही रखे</string>
<string name="enable_watch_history_summary">देखे हुए वीडियोस का रिकॉर्ड रखें</string>
<string name="resume_on_audio_focus_gain_title">जब फोकस मिले तो विडियो resume हो</string>
<string name="resume_on_audio_focus_gain_summary">रूकावट आने पर भी विडियो को जारी रखे (जैसे - फ़ोन कॉल आये)</string>
<string name="enable_watch_history_summary">देखे हुए विडियो की सूची रखे</string>
<string name="resume_on_audio_focus_gain_title">फोकस मिलने पर विडियो पुनः आगे चले</string>
<string name="resume_on_audio_focus_gain_summary">रूकावट आने पर भी विडियो को जारी रखे (जैसे - फ़ोन कॉल आये)</string>
<string name="show_next_and_similar_title">\'अगला\' और \'पहले समान\' वीडियो दिखाए</string>
<string name="show_hold_to_append_title">\"जोड़ने के लिए पकड़ें रहे\" दिखाए</string>
<string name="show_hold_to_append_summary">जब बैकग्राउंड और पॉपअप बटन विडियो के विवरण पन्ने में दबाई जाए तो tip को दिखाए</string>
<string name="url_not_supported_toast">ये वाला URL इसमें नहीं चलेगा</string>
<string name="content_language_title">डिफ़ॉल्ट विषय की भाषा</string>
<string name="settings_category_player_title">प्लेयर</string>
<string name="settings_category_player_behavior_title">चाल चलन</string>
<string name="settings_category_popup_title">पॉपअप</string>
@ -119,7 +109,7 @@
<string name="play_btn_text">चलाये</string>
<string name="content">विषयवस्तु</string>
<string name="show_age_restricted_content_title">उम्र प्रतिबंधित विषय वस्तु</string>
<string name="video_is_age_restricted">उम्र प्रतिबंदित विडियो है .इस प्रकार की विषयवस्तु को अनुमति देने के लिए Setting से संभव है |</string>
<string name="video_is_age_restricted">उम्र प्रतिबंदित विडियो है .इस प्रकार की विषयवस्तु को अनुमति देने के लिए सेटिंग से संभव है |</string>
<string name="duration_live">सीधा प्रसारण</string>
<string name="downloads">डाउनलोड</string>
<string name="downloads_title">डाउनलोड</string>
@ -137,12 +127,9 @@
<string name="best_resolution">बेहतर विडियो की क्वालिटी</string>
<string name="undo">वापस जाए</string>
<string name="play_all">सारे प्ले करे</string>
<string name="notification_channel_name">NewPipe की अधिसूचना</string>
<string name="notification_channel_description">NewPipe के बैकग्राउंड में चल रहे विडियो और पॉपअप विडियो के लिए अधिसूचना</string>
<string name="unknown_content">[नहीं जानते]</string>
<string name="general_error">त्रुटी</string>
<string name="network_error">नेटवर्क में त्रुटी</string>
<string name="could_not_load_thumbnails">सारे thumbnail(फोटो जो फ़ोन की मेमोरी में है ) भरे नहीं जा सकते</string>
@ -159,7 +146,6 @@
<string name="player_stream_failure">इस विडियो को चलाने में असफल हुए</string>
<string name="player_unrecoverable_failure">कभी ठीक न होने वाले विडियो प्लेयर की त्रुटी आ रही है</string>
<string name="player_recoverable_failure">विडियो प्लेयर त्रुटी से ठीक हो रहा है</string>
<string name="sorry_string">खेद है की, ऐसा होना नहीं चाहिए था.</string>
<string name="error_report_button_text">त्रुटी की रिपोर्ट को ईमेल से भेजे</string>
<string name="error_snackbar_message">माफ़ करे , कुछ त्रुटियाँ हो रही है</string>
@ -169,8 +155,6 @@
<string name="info_labels">क्या:\\nमांग:\\nविषयवस्तु की भाषा:\\nसेवा:\\nजीएमटी समय:\\nपैकेज:\\nसंस्करण:\\nOS संस्करण:</string>
<string name="your_comment">आपकी टिप्पणी:</string>
<string name="error_details_headline">विवरण:</string>
<string name="list_thumbnail_view_description">विडियो के thumbnail के पूर्व दर्शन</string>
<string name="detail_thumbnail_view_description">विडियो के thumbnail के पूर्व दर्शन</string>
<string name="detail_uploader_thumbnail_view_description">अपलोडर के thumbnail वाले फोटो</string>
@ -182,50 +166,39 @@
<string name="user_report">उपयोगकर्ता की रिपोर्ट</string>
<string name="search_no_results">कोई परिणाम नहीं मिला</string>
<string name="empty_subscription_feed_subtitle">यंहा कुछ नहीं है</string>
<string name="err_dir_create">"डाउनलोड वाली डायरेक्टरी को बना नहीं सकते \'%1$s\'"</string>
<string name="info_dir_created">डाउनलोड की डायरेक्टरी बना दी गई है \'%1$s\'</string>
<string name="info_dir_created">डाउनलोड की निर्देशिका बना दी गई है \'%1$s\'</string>
<string name="video">विडियो</string>
<string name="audio">ऑडियो</string>
<string name="retry">फिर से कोशिश करे</string>
<string name="storage_permission_denied">स्टोरेज में प्रवेश के लिए अनुमति नहीं मिली</string>
<string name="use_old_player_title">पुराना विडियो प्लेयर प्रयोग करे</string>
<string name="use_old_player_summary">पुराना Mediaframework Player जो फ़ोन में बना हुआ है</string>
<string name="short_thousand">हज़ार</string>
<string name="short_million">करोड़</string>
<string name="short_billion">अरब</string>
<string name="no_subscribers">कोई भी सदस्य नहीं है</string>
<plurals name="subscribers">
<item quantity="one">%s सदस्य</item>
<item quantity="other">%s सदस्यो</item>
</plurals>
<item quantity="one">%s सदस्य</item>
<item quantity="other">%s सदस्यो</item>
</plurals>
<plurals name="views">
<item quantity="one">%s दर्शक</item>
<item quantity="other">%s दर्शके</item>
</plurals>
<item quantity="one">%s दर्शक</item>
<item quantity="other">%s दर्शके</item>
</plurals>
<plurals name="videos">
<item quantity="one">%s विडियो</item>
<item quantity="other">%s वीडियो</item>
</plurals>
<item quantity="one">%s विडियो</item>
<item quantity="other">%s वीडियो</item>
</plurals>
<string name="start">शुरू</string>
<string name="pause">रोके</string>
<string name="view">चलाये</string>
<string name="delete">मिटाए</string>
<string name="checksum">checksum</string>
<string name="add">नया मिशन</string>
<string name="finish">ठीक है</string>
<string name="msg_name">फाइल का नाम</string>
<string name="msg_threads">मेसेज के thread</string>
<string name="msg_error">त्रुटी</string>
<string name="msg_server_unsupported">server ठीक से चल नहीं रहा</string>
<string name="msg_server_unsupported">असमर्थित सर्वर</string>
<string name="msg_exists">फाइल पहले से ही बनी हुई है</string>
<string name="msg_url_malform">URL सही नहीं है या फिर हो सकता है इन्टरनेट उपलब्ध नहीं है</string>
<string name="msg_running">न्यूपाइप डाउनलोड हो रहा है</string>
@ -234,26 +207,21 @@
<string name="msg_copied">क्लिपबोर्ड पर कॉपी हो गया है</string>
<string name="no_available_dir">कृपया उपलब्ध डाउनलोड फोल्डर को चुने</string>
<string name="msg_popup_permission">पॉपअप के तरीके में खोलने के लिए अनुमति की जरुरत है</string>
<string name="reCaptchaActivity">reCAPTCHA</string>
<string name="reCaptcha_title">reCAPTCHA चुनोती</string>
<string name="recaptcha_request_toast">reCAPTCHA चुनोती के लिए निवेदन</string>
<string name="reCaptcha_title">reCAPTCHA चुनौती</string>
<string name="recaptcha_request_toast">reCAPTCHA चुनौती का अनुरोध किया</string>
<string name="settings_category_downloads_title">डाउनलोड</string>
<string name="settings_file_charset_title">फाइल के नाम के लिए आवश्यक characters(जैसे - १२३, abc) की अनुमति है</string>
<string name="settings_file_replacement_character_summary">अमान्य characters इस value से बदल जायेंगे</string>
<string name="settings_file_replacement_character_title">रिप्लेसमेंट करैक्टर</string>
<string name="charset_letters_and_digits">वर्ण और अंक</string>
<string name="charset_most_special_characters">विशेष वर्ण</string>
<string name="copyright" formatted="true">%2$s के द्वारा © %1$s जो %3$s के अधीन आते है</string>
<string name="error_unable_to_load_license">लाइसेंस load नहीं हो रहा</string>
<string name="tab_contributors">सहयोगकर्ता</string>
<string name="app_description">एंड्राइड के लिए हल्का और मुफ्त स्ट्रीमिंग एप्लिकेशन|</string>
<string name="contribution_encouragement">अगर आपके पास कोई सुझाव हो जैसे -अनुवाद , डिजाईन में बदलाव ,code को साफ़ रखना , या फिर code में जायदा बदलाव लाना हो तो - साहयता के लिए आपका स्वागत है . जितना ज्यादा होगा उतना बेहतर होगा !</string>
<string name="delete_item_search_history">क्या आप इसको खोज इतिहास के मिटाना चाहते है ?</string>
<string name="main_page_content">मुख्य पेज की विषयवस्तु</string>
<string name="blank_page_summary">खाली पन्ना</string>
<string name="kiosk_page_summary">kiosk पन्ना</string>
@ -263,11 +231,10 @@
<string name="select_a_channel">चैनल को चुने</string>
<string name="no_channel_subscribed_yet">अभी तक किसी भी चैनल के सदस्य नहीं है</string>
<string name="select_a_kiosk">kiosk को चुने</string>
<string name="kiosk">kiosk</string>
<string name="top_50">टॉप 50</string>
<string name="new_and_hot">नया और गरम</string>
<string name="title_activity_background_player">बैकग्राउंड प्लेयर</string>
<string name="title_activity_background_player">पृष्ठभूमि प्लेयर</string>
<string name="title_activity_popup_player">पॉपअप प्लेयर</string>
<string name="play_queue_remove">निकाले</string>
<string name="play_queue_stream_detail">विवरण</string>
@ -277,41 +244,33 @@
<string name="start_here_on_main">यंहा से चलाना शुरू करे</string>
<string name="start_here_on_background">बैकग्राउंड में चलाना शुरू करे</string>
<string name="start_here_on_popup">पॉपअप में चलाना शुरू करे</string>
<string name="no_player_found_toast">स्ट्रीम करने के लिए प्लेयर उपलब्ध नहीं है (आप इसे चलाने के लिए VLC प्लेयर इंस्टॉल कर सकते हैं)।</string>
<string name="no_player_found_toast">स्ट्रीम करने के लिए प्लेयर उपलब्ध नहीं है (आप इसे चलाने के लिए VLC प्लेयर इंस्टॉल कर सकते हैं)।</string>
<string name="controls_download_desc">स्ट्रीम डाउनलोड करें</string>
<string name="show_info">जानकारी दिखाएं</string>
<string name="tab_bookmarks">बुकमार्क किये गए प्लेलिस्टस</string>
<string name="controls_add_to_playlist_title">में जोड़े</string>
<string name="default_content_country_title">डिफ़ॉल्ट देश का विषय</string>
<string name="service_title">सर्विस</string>
<string name="always">हमेशा के लिए</string>
<string name="just_once">सिर्फ एक बार के लिए</string>
<string name="toggle_orientation">टॉगल ओरिएंटेशन</string>
<string name="switch_to_background">बैकग्राउंड में स्विच करें</string>
<string name="switch_to_popup">पॉपअप मोड में जाएं</string>
<string name="switch_to_main">मुख्य पर स्विच करें</string>
<string name="import_data_title">डेटाबेस आयात करें</string>
<string name="export_data_title">डेटाबेस निर्यात करें</string>
<string name="import_data_summary">आपके वर्तमान इतिहास और सब्सक्रिप्शन को ओवरराइड करेगा</string>
<string name="import_data_summary">आपके वर्तमान इतिहास और सब्सक्रिप्शन को अधिभावी करेगा</string>
<string name="export_data_summary">इतिहास, सब्सक्रिप्शन और प्लेलिस्ट निर्यात करें</string>
<string name="external_player_unsupported_link_type">एक्सटर्नल प्लेयर इन प्रकार के लिंक सपोर्ट नहीं करता</string>
<string name="invalid_url_toast">अमान्य URL</string>
<string name="video_streams_empty">कोई वीडियो स्ट्रीम नहीं मिला</string>
<string name="audio_streams_empty">कोई वीडियो स्ट्रीम नहीं मिला</string>
<string name="audio_streams_empty">कोई ऑडियो स्ट्रीम नहीं मिली</string>
<string name="detail_drag_description">फिर से क्रम देने के लिए खींचें</string>
<string name="create">बनाइये</string>
<string name="delete_one">एक को हटाएं</string>
<string name="delete_all">सभी को हटाएँ</string>
<string name="dismiss">ख़ारिज करें</string>
<string name="rename">नाम बदलें</string>
<string name="donation_title">दान करें</string>
<string name="donation_encouragement">NewPipe स्वयंसेवकों द्वारा विकसित किया जाता है जो आपको अच्छा अनुभव देने के लिए अपना खाली समय व्यतीत करते हैं। स्वयंसेवको को मदद भेजे, ताकि वह NewPipe को और अच्छा बना सके।</string>
<string name="give_back">वापस दे</string>
@ -321,66 +280,50 @@
<string name="delete_all_history_prompt">क्या आप वाकई इतिहास से सभी आइटंस हटाना चाहते हैं?</string>
<string name="title_last_played">पिछला चलाया गया</string>
<string name="title_most_played">अधिकतम चलाए गए</string>
<string name="export_complete_toast">निर्यात पूर्ण हुआ</string>
<string name="import_complete_toast">आयात पूर्ण हुआ</string>
<string name="export_complete_toast">निर्यात किए गए</string>
<string name="import_complete_toast">आयातित</string>
<string name="no_valid_zip_file">कोई मांय ज़िप फ़ाइल नहीं</string>
<string name="could_not_import_all_files">चेतावनी: सभी फ़ाइलों को आयात नहीं किया जा सका।</string>
<string name="override_current_data">यह आपके वर्तमान सेटअप को ओवरराइड करेगा ।</string>
<string name="drawer_open">ड्रावर खोलें</string>
<string name="drawer_close">ड्रावर बंद करें</string>
<string name="drawer_header_action_paceholder_text">जल्द ही यहां पर कुछ दिखाई देगा ;D</string>
<string name="video_player">वीडियो प्लेयर</string>
<string name="background_player">बैकग्राउंड प्लेयर</string>
<string name="popup_player">पॉपअप प्लेयर</string>
<string name="always_ask_open_action">हमेशा पूछें</string>
<string name="preferred_player_fetcher_notification_title">जानकारी प्राप्त की जा रही है…</string>
<string name="preferred_player_fetcher_notification_message">अनुरोधित सामग्री लोड कर रहे है</string>
<string name="create_playlist">नई प्लेलिस्ट बनाएं</string>
<string name="delete_playlist">प्लेलिस्ट हटाएं</string>
<string name="rename_playlist">प्लेलिस्ट का नाम बदलें</string>
<string name="playlist_name_input">नाम</string>
<string name="append_playlist">प्लेलिस्ट में जोड़ें</string>
<string name="set_as_playlist_thumbnail">प्लेलिस्ट थंबनेल के रूप में सेट करें</string>
<string name="bookmark_playlist">प्लेलिस्ट बुकमार्क करें</string>
<string name="unbookmark_playlist">बुकमार्क हटायें</string>
<string name="delete_playlist_prompt">क्या आप इस प्लेलिस्ट को हटाना चाहते हैं?</string>
<string name="playlist_creation_success">सूची बना दी गई</string>
<string name="playlist_add_stream_success">प्लेलिस्ट में जोड़ा गया</string>
<string name="playlist_thumbnail_change_success">प्लेलिस्ट का थंबनेल बदल दिया गया है</string>
<string name="playlist_delete_failure">सूची हटाने में असफल</string>
<string name="caption_none">कोई कैप्शन नहीं है</string>
<string name="resize_fit">फिट</string>
<string name="resize_fill">भरें</string>
<string name="resize_zoom">ज़ूम करें</string>
<string name="caption_font_size_settings_title">कैप्शन फ़ॉंट आकार</string>
<string name="smaller_caption_font_size">छोटे फ़ॉंट</string>
<string name="normal_caption_font_size">सामांय फ़ॉंट</string>
<string name="larger_caption_font_size">बड़ा फ़ॉंट</string>
<string name="toggle_leak_canary">मॉनिटर लीक</string>
<string name="enable_leak_canary_notice">मेमोरी लीक मॉनिटरिंग सक्षम है, हीप डंपिंग के समय ऐप अप्रतिसादी हो सकती है</string>
<string name="disable_leak_canary_notice">मेमोरी लीक मॉनिटरिंग अक्षम है</string>
<string name="settings_category_debug_title">डीबग करें</string>
<string name="settings_category_debug_title">डीबग करें</string>
<string name="caption_auto_generated">ऑटो-जनरेटेड</string>
<string name="enable_leak_canary_title">LeakCanary सक्षम करें</string>
<string name="enable_leak_canary_summary">हीप डंप करने के दौरान मेमोरी लीक मॉनिटरिंग ऐप को अनुत्तरदायी बना सकता है</string>
<string name="enable_disposed_exceptions_title">Out-of-Lifecycle त्रुटियों की रिपोर्ट करें</string>
<string name="download_thumbnail_title">छायाप्रारुप लोड करें</string>
<string name="use_inexact_seek_title">तेजी से अचूक तलाश का प्रयोग करें</string>
<string name="use_inexact_seek_summary">अचूक खोज प्लेयर को कम परिशुद्धता के साथ तेजी से पदों की तलाश करने की अनुमति देता है</string>
<string name="download_thumbnail_summary">बंद होने पे छोटी छवियां नहीं दिखेंगी। इससे डेटा और मेमोरी की बचत होगी। इसे बदलने से मेमोरी और डिस्क की छवि का भंडार भी साफ़ हो जाएगा।</string>
<string name="download_thumbnail_summary">लोडिंग थंबनेल, डेटा और मेमोरी उपयोग को रोकने के लिए बंद करें। इन-मेमोरी और ऑन-डिस्क छवि कैश दोनों को बदलता है</string>
<string name="thumbnail_cache_wipe_complete_notice">छवि कैश मिटा दिया</string>
<string name="metadata_cache_wipe_title">कैश मेटाडेटा वाइप करें</string>
<string name="metadata_cache_wipe_summary">सभी कैश किए गए वेबपृष्ठ डेटा हटाएं</string>
@ -388,67 +331,54 @@
<string name="auto_queue_title">अगली स्ट्रीम को स्वचालित रूप से जोड़ें</string>
<string name="auto_queue_summary">गैर-दोहराने वाली कतार में अंतिम स्ट्रीम चलाते समय संबंधित स्ट्रीम को स्वतः संलग्न करें</string>
<string name="file">फाइल</string>
<string name="channels">चेनल्स</string>
<string name="playlists">सूची</string>
<string name="tracks">ट्रेक</string>
<string name="users">उपभोगता</string>
<string name="clear_views_history_title">देखे हुए वीडियो की सूची साफ करें</string>
<string name="clear_views_history_summary">चलाये गए स्ट्रीम का इतिहास साफ करता है</string>
<string name="delete_view_history_alert">देखे गए सभी का इतिहास साफ करें</string>
<string name="delete_view_history_alert">देखे गए सभी का इतिहास साफ करें\?</string>
<string name="view_history_deleted">देखे हुए का इतिहास साफ कर दिया गया।</string>
<string name="clear_search_history_title">ढूंढने के इतिहास को साफ करें</string>
<string name="clear_search_history_summary">ढूंढे गए शब्दो का इतिहास साफ करता है</string>
<string name="delete_search_history_alert">पूरे खोज इतिहास को मिटा दे \?</string>
<string name="search_history_deleted">ढूंढने के इतिहास को साफ कर दिया।</string>
<string name="invalid_directory">एसी कोई भी फ़ोल्डर मौजूद नहीं है</string>
<string name="invalid_source">अमान्य फाइल/कॉन्टेंट उदभावस्थान</string>
<string name="invalid_source">अमान्य फाइल/विषय - वस्तु का स्रोत</string>
<string name="invalid_file">फ़ाइल मौजूद नहीं है या उसे पढ़ने या लिखने की पर्याप्त अनुमति नही़ं है</string>
<string name="file_name_empty_error">फ़ाइल का नाम खाली नहीं हो सकता</string>
<string name="error_occurred_detail">एक भूल हुई: %1$s</string>
<string name="no_streams_available_download">डाउनलोड करने के लिए कोई स्ट्रीम उपलब्ध नही है</string>
<string name="one_item_deleted">एक चीज़ साफ कर दी गई।</string>
<string name="toast_no_player">इस फ़ाइल को चलाने के लिए कोई ऐप स्थापित नही है</string>
<string name="privacy_policy_title">न्यूपाइप की गोपनीयता नीति</string>
<string name="privacy_policy_encouragement">न्यूपाइप परियोजना आपकी गोपनीयता को बहोत गंभीर रूप से लेता है। इसलिए, ऐप आपकी अनुमति के बिना कोई डेटा जमा नही करता।
\nन्यूपाइप की गोपनीयता नीति विस्तार से समज़ाती है कि कोनसा डेटा भेजा या संग्रह किया जाता है जब आप क्रेश विवरण भेजते है।</string>
<string name="read_privacy_policy">गोपनीयता नीति पढ़े</string>
<string name="import_settings">क्या आप सेटिंग्स भी आयात करना चाहते है?</string>
<string name="preferred_open_action_settings_title">पसंदीदा \'खोलने पर\' करवाई</string>
<string name="preferred_open_action_settings_summary">सामग्री खोलते समय डिफ़ॉल्ट कारवाही — %s</string>
<string name="caption_setting_title">केप्सन</string>
<string name="caption_setting_description">प्लेयर केप्शन के शब्दों का परिमाण और पृष्ठभूमि शैलियो को बदले। लागू करने के लिए ऐप को पुनः प्रारम्भ करना जरूरी है।</string>
<string name="import_export_title">आयात/निर्यात</string>
<string name="import_title">आयात</string>
<string name="import_from">से आयात करे</string>
<string name="export_to">पर निर्यात करे</string>
<string name="import_ongoing">आयात किया जा रहा है…</string>
<string name="export_ongoing">निर्यात किया जा रहा है…</string>
<string name="import_file_title">फाइल आयात करे</string>
<string name="previous_export">पहले वाला निर्यात</string>
<string name="subscriptions_import_unsuccessful">सब्सक्रिप्शन आयात नही कर सके</string>
<string name="subscriptions_export_unsuccessful">सब्सक्रिप्शन निर्यात नही कर सके</string>
<string name="import_youtube_instructions">निर्यात की गई फाइल को डाउनलोड करके यूट्यूब सब्सक्रिप्शन को आयात करे:
\n
\n1. इस URL पर जाए: %1$s
\n2. जब कहा जाए, लॉगिन करे
\n3. एक डाउनलोड शुरू होना चाहिए (यही निर्यात की गई फाइल है)</string>
<string name="import_soundcloud_instructions_hint">आपका आई डी, soundcloud.com/yourid</string>
<string name="import_network_expensive_warning">ध्यान रखे, यह तरीका नेटवर्क साधनो के लिए मंहगा हो सकता है।
\n
\nक्या आप आगे बढ़ना चाहते है?</string>
<string name="playback_speed_control">चलाने की गति के नियंत्रण</string>
<string name="playback_tempo">गति</string>
<string name="playback_pitch">ऊंचाई</string>
@ -456,10 +386,8 @@
<string name="skip_silence_checkbox">खामोशी के समय तेज़ी से आगे बढ़े</string>
<string name="playback_step">कदम</string>
<string name="playback_reset">रिसेट</string>
<string name="accept">स्वीकारे</string>
<string name="decline">अस्वीकार करे</string>
<string name="limit_data_usage_none_description">असीमित</string>
<string name="limit_mobile_data_usage_title">मोबाइल डेटा उपयोग करते समय रेसॉल्युसेन मर्यादित करे</string>
<string name="minimize_on_exit_title">ऐप बदलते समय मिनिमाइज करे</string>
@ -468,4 +396,9 @@
<string name="minimize_on_exit_background_description">पृष्ठभूमि प्लेयर जैसे मिनिमाइज करे</string>
<string name="minimize_on_exit_popup_description">पॉप अप प्लेयर जैसे मिनिमाइज करे</string>
<string name="app_license">न्यूपाइप एक काॅपीलेफ़्ट फ़्री साॅफ़्टवेर है: इसे आप अपनी इच्छा के अनुसार इस्तेमाल, जाँच, बाँट तथा और बेहतर बना सकते है। खास तौर पर आप इसे फ़्री साॅफ़्टवेर फ़ाउंडेशन के द्वारा जारी जीएनयू जनरल पब्लिक लाइसेंस के तीसरे या उसके बाद आने वाले कोई भी वर्णन के शर्तों के मुताबिक फिर से बाँट या बदल सकते हैं।</string>
<string name="unsubscribe">सदस्यता वापस ले ली</string>
<string name="tab_new">नया टॅब</string>
<string name="tab_choose">टॅब चुने</string>
<string name="volume_gesture_control_title">वॉल्यूम नियंत्रण</string>
<string name="enqueue">कतार</string>
</resources>

File diff suppressed because it is too large Load Diff

View File

@ -24,8 +24,6 @@
<string name="show_play_with_kodi_summary">Opció mutatása a videók Kodi médiaközponttal való lejátszására</string>
<string name="play_audio">Hang</string>
<string name="default_audio_format_title">Alapértelmezett hang formátum</string>
<string name="webm_description">WebM — szabad formátum</string>
<string name="m4a_description">M4A — jobb minőség</string>
<string name="download_dialog_title">Letöltés</string>
<string name="next_video_title">Következő</string>
<string name="url_not_supported_toast">Nem támogatott webcím</string>
@ -193,7 +191,6 @@
<string name="info_labels">Mi:\\nKérés:\\nTartalom nyelve:\\nSzolgáltatás:\\nGMT Idő:\\nCsomag:\\nVerzió:\\nOperációs Rendszer verzió:</string>
<string name="search_no_results">Nincs találat</string>
<string name="use_old_player_title">Régi lejátszó használata</string>
<string name="controls_download_desc">Adatfolyam fájl letöltése</string>
<string name="controls_add_to_playlist_title">Hozzáadás</string>
@ -236,8 +233,6 @@
<string name="empty_subscription_feed_subtitle">Itt nincs semmi</string>
<string name="detail_drag_description">Húzza az átrendezéshez</string>
<string name="use_old_player_summary">Régi beépített Mediaframework lejátszó</string>
<string name="short_thousand">e</string>
<string name="short_million">M</string>
<string name="short_billion">Mrd</string>

View File

@ -14,15 +14,12 @@
<string name="choose_browser">Pilih peramban</string>
<string name="use_external_video_player_title">Gunakan pemutar video eksternal</string>
<string name="use_external_audio_player_title">Gunakan pemutar audio eksternal</string>
<string name="download_path_title">Lokasi unduhan video</string>
<string name="download_path_summary">Lokasi untuk menyimpan video yang diunduh</string>
<string name="download_path_dialog_title">Masukkan lokasi unduhan video</string>
<string name="download_path_audio_title">Lokasi unduhan audio</string>
<string name="download_path_audio_summary">Audio yang diunduh disimpan di sini</string>
<string name="download_path_audio_dialog_title">Masukkan lokasi unduhan berkas audio</string>
<string name="autoplay_by_calling_app_title">Putar otomatis</string>
<string name="autoplay_by_calling_app_summary">Putar video ketika NewPipe dijalankan dari aplikasi lain</string>
<string name="default_resolution_title">Resolusi</string>
@ -32,11 +29,8 @@
<string name="show_play_with_kodi_summary">Tampilkan opsi untuk memutar video via Kodi</string>
<string name="play_audio">Audio</string>
<string name="default_audio_format_title">Format audio</string>
<string name="webm_description">WebM — format bebas</string>
<string name="m4a_description">M4A — kualitas lebih baik</string>
<string name="dark_theme_title">Gelap</string>
<string name="light_theme_title">Terang</string>
<string name="download_dialog_title">Unduh</string>
<string name="next_video_title">Berikutnya</string>
<string name="show_next_and_similar_title">Tampilkan video \'Berikutnya\' dan \'Serupa\'</string>
@ -58,7 +52,6 @@
<string name="downloads">Unduhan</string>
<string name="downloads_title">Unduhan</string>
<string name="error_report_title">Laporan galat</string>
<string name="general_error">Galat</string>
<string name="parsing_error">Tidak bisa mengurai situs web</string>
<string name="light_parsing_error">Tidak dapat menguraikan situs web sepenuhnya</string>
@ -75,8 +68,6 @@
<string name="what_happened_headline">Yang terjadi:</string>
<string name="your_comment">Komentar anda (dalam bahasa Inggris):</string>
<string name="error_details_headline">Detail:</string>
<string name="list_thumbnail_view_description">Thumbnail pratinjau video</string>
<string name="detail_thumbnail_view_description">Thumbnail pratinjau video</string>
<string name="detail_likes_img_view_description">Suka</string>
@ -87,21 +78,17 @@
<string name="report_error">Laporkan Galat</string>
<string name="err_dir_create">Tidak bisa membuat direktori unduhan \'%1$s\'</string>
<string name="info_dir_created">Direktori unduhan dibuat \'%1$s\'</string>
<string name="video">Video</string>
<string name="audio">Audio</string>
<string name="retry">Ulangi</string>
<string name="storage_permission_denied">Izin akses penyimpanan ditolak</string>
<string name="delete">Hapus</string>
<string name="view">Putar</string>
<string name="start">Mulai</string>
<string name="pause">Jeda</string>
<string name="checksum">Ceksum</string>
<string name="add">Misi baru</string>
<string name="finish">OK</string>
<string name="msg_name">Nama berkas</string>
<string name="msg_error">Galat</string>
<string name="msg_server_unsupported">Server tidak didukung</string>
@ -112,79 +99,55 @@
<string name="msg_wait">Mohon tunggu…</string>
<string name="msg_copied">Disalin ke papan klip</string>
<string name="no_available_dir">Silakan pilih direktori unduhan yang tersedia</string>
<string name="no_player_found">Pemutar stream tidak ditemukan. Apakah anda ingin memasang VLC\?</string>
<string name="youtube_signature_decryption_error">Tidak bisa dekripsi tanda tangan URL video</string>
<string name="app_ui_crash">App/UI rusak</string>
<string name="could_not_get_stream">Tidak bisa mendapatkan stream apapun</string>
<string name="info_labels">Apa:\\nPermintaan:\\nBahasa Konten:\\nLayanan:\\nWaktu GMT:\\nPaket:\\nVersi:\\nVersi OS:</string>
<string name="user_report">Laporan pengguna</string>
<string name="msg_threads">Thread</string>
<string name="reCaptchaActivity">reCAPTCHA</string>
<string name="reCaptcha_title">Tantangan reCAPTCHA</string>
<string name="recaptcha_request_toast">Meminta kode reCAPTCHA</string>
<string name="black_theme_title">Hitam</string>
<string name="all">Semua</string>
<string name="channel">Channel</string>
<string name="short_thousand">R</string>
<string name="short_million">J</string>
<string name="short_billion">T</string>
<string name="yes">Ya</string>
<string name="later">Nanti</string>
<string name="open_in_popup_mode">Buka di mode popup</string>
<string name="msg_popup_permission">Izin ini dibutuhkan untuk
\nmembuka di mode popup</string>
<string name="popup_mode_share_menu_title">Mode popup NewPipe</string>
<string name="popup_playing_toast">Memutar dalam mode popup</string>
<string name="use_old_player_title">Gunakan pemutar lama</string>
<string name="use_old_player_summary">Pemutar Mediaframework bawaan versi lama</string>
<string name="disabled">Dinonaktifkan</string>
<string name="default_video_format_title">Format video</string>
<string name="default_popup_resolution_title">Resolusi popup</string>
<string name="show_higher_resolutions_title">Tampilkan resolusi yang lebih tinggi</string>
<string name="show_higher_resolutions_summary">Hanya perangkat tertentu yang mendukung pemutaran video 2K/4K</string>
<string name="controls_background_title">Latar Belakang</string>
<string name="controls_popup_title">Popup</string>
<string name="refresh">Segarkan</string>
<string name="clear">Bersihkan</string>
<string name="filter">Filter</string>
<string name="use_external_video_player_summary">Menghapus audio pada BEBERAPA resolusi</string>
<string name="popup_remember_size_pos_title">Ingat ukuran dan posisi popup</string>
<string name="popup_remember_size_pos_summary">Ingat ukuran dan posisi terakhir popup</string>
<string name="settings_category_popup_title">Popup</string>
<string name="popup_resizing_indicator_title">Ubah ukuran</string>
<string name="player_gesture_controls_title">Kontrol gestur pemutar</string>
<string name="player_gesture_controls_summary">Gunakan gestur untuk mengontrol kecerahan dan volume pemutar</string>
<string name="show_search_suggestions_title">Saran pencarian</string>
<string name="show_search_suggestions_summary">Tampilkan saran ketika mencari</string>
<string name="best_resolution">Resolusi terbaik</string>
<string name="best_resolution">Resolusi terbaik</string>
<string name="settings_category_downloads_title">Unduh</string>
<string name="settings_file_charset_title">Karakter yang diizinkan sebagai nama berkas</string>
<string name="settings_file_replacement_character_summary">Karakter yang tidak valid akan diganti dengan karakter ini</string>
<string name="settings_file_replacement_character_title">Karakter pengganti</string>
<string name="charset_letters_and_digits">Huruf dan angka</string>
<string name="charset_most_special_characters">Karakter spesial umum</string>
<string name="title_activity_about">Tentang NewPipe</string>
<string name="action_settings">Pengaturan</string>
<string name="action_about">Tentang</string>
@ -195,19 +158,17 @@
<string name="tab_about">Tentang</string>
<string name="tab_contributors">Kontributor</string>
<string name="tab_licenses">Lisensi</string>
<string name="app_description">Aplikasi streaming libre dan ringan untuk Android.</string>
<string name="app_description">Aplikasi streaming bebas dan ringan untuk Android.</string>
<string name="view_on_github">Lihat di GitHub</string>
<string name="app_license_title">Lisensi NewPipe</string>
<string name="contribution_encouragement">Terlepas apakah anda memiliki ide untuk; terjemahan, perubahan desain, pembersihan kode, atau perubahan kode yang signifikan, segala bantuan akan selalu diterima. Semakin banyak akan semakin baik jadinya!</string>
<string name="read_full_license">Baca lisensi</string>
<string name="contribution_title">Kontribusi</string>
<string name="subscribe_button_title">Subscribe</string>
<string name="subscribe_button_title">Subscribe</string>
<string name="subscribed_button_title">Disubscribe</string>
<string name="fragment_whats_new">Apa Yang Baru</string>
<string name="resume_on_audio_focus_gain_title">Lanjutkan saat fokus</string>
<string name="resume_on_audio_focus_gain_summary">Lanjutkan pemutaran setelah interupsi (mis. panggilan telepon)</string>
<string name="tab_main">Utama</string>
<string name="enable_search_history_title">Riwayat pencarian</string>
<string name="enable_search_history_summary">Simpan pencarian secara lokal</string>
@ -241,16 +202,12 @@
<string name="always">Selalu</string>
<string name="just_once">Hanya Sekali</string>
<string name="file">Berkas</string>
<string name="notification_channel_description">Notifikasi untuk pemutar latar belakang dan popup NewPipe</string>
<string name="unknown_content">[Tidak diketahui]</string>
<string name="toggle_orientation">Ubah Orientasi</string>
<string name="switch_to_background">Alihkan ke Latar Belakang</string>
<string name="switch_to_popup">Alihkan ke Popup</string>
<string name="switch_to_main">Alihkan ke Utama</string>
<string name="import_data_title">Impor basis data</string>
<string name="export_data_title">Ekspor basis data</string>
<string name="import_data_summary">Timpa riwayat dan subscription anda saat ini</string>
@ -267,32 +224,26 @@
<string name="invalid_file">Berkas tidak tersedia atau tidak memiliki izin baca atau tulis</string>
<string name="file_name_empty_error">Nama berkas tidak boleh kosong</string>
<string name="error_occurred_detail">Telah terjadi galat: %1$s</string>
<string name="search_no_results">Tidak ada hasil</string>
<string name="empty_subscription_feed_subtitle">Tidak ada apapun disini selain jangkrik</string>
<string name="detail_drag_description">Geser untuk ubah urutan</string>
<string name="no_subscribers">Tidak ada subscriber</string>
<plurals name="subscribers">
<item quantity="other">%s subscriber</item>
</plurals>
<item quantity="other">%s subscriber</item>
</plurals>
<string name="no_views">Belum ditonton</string>
<plurals name="views">
<item quantity="other">%s ditonton</item>
</plurals>
<item quantity="other">%s ditonton</item>
</plurals>
<string name="no_videos">Tidak ada video</string>
<plurals name="videos">
<item quantity="other">Video</item>
</plurals>
<item quantity="other">Video</item>
</plurals>
<string name="create">Buat</string>
<string name="delete_one">Hapus Satu</string>
<string name="delete_all">Hapus Semua</string>
<string name="dismiss">Abaikan</string>
<string name="rename">Ubah nama</string>
<string name="donation_title">Donasi</string>
<string name="donation_encouragement">NewPipe dikembangkan oleh relawan yang menyisihkan waktu untuk memberi anda pengalaman terbaik. Segala dukungan kepada pengembang akan membuat NewPipe menjadi lebih baik sambil menikmati secangkir kopi.</string>
<string name="give_back">Beri dukungan</string>
@ -306,7 +257,6 @@
<string name="delete_all_history_prompt">Apakah Anda yakin ingin menghapus semua item dari riwayat\?</string>
<string name="title_last_played">Terakhir Diputar</string>
<string name="title_most_played">Sering Diputar</string>
<string name="main_page_content">Konten laman utama</string>
<string name="blank_page_summary">Laman Kosong</string>
<string name="kiosk_page_summary">Laman Kiosk</string>
@ -321,7 +271,6 @@
<string name="no_valid_zip_file">Berkas ZIP tidak valid</string>
<string name="could_not_import_all_files">Perhatian: Tidak bisa mengimpor semua berkas.</string>
<string name="override_current_data">Ini akan menimpa pengaturan anda saat ini.</string>
<string name="kiosk">Kiosk</string>
<string name="trending">Trending</string>
<string name="top_50">Top 50</string>
@ -337,58 +286,45 @@
<string name="start_here_on_main">Mulai putar di sini</string>
<string name="start_here_on_background">Mulai dari sini ketika di latar belakang</string>
<string name="start_here_on_popup">Mulai dari sini pada popup baru</string>
<string name="drawer_open">Buka Laci</string>
<string name="drawer_close">Tutup Laci</string>
<string name="drawer_header_action_paceholder_text">Sesuatu akan segera muncul di sini ;D</string>
<string name="video_player">Pemutar video</string>
<string name="background_player">Pemutar latar belakang</string>
<string name="popup_player">Pemutar popup</string>
<string name="always_ask_open_action">Selalu bertanya</string>
<string name="preferred_player_fetcher_notification_title">Mendapatkan info…</string>
<string name="preferred_player_fetcher_notification_message">Memuat konten yang diminta</string>
<string name="create_playlist">Playlist Baru</string>
<string name="delete_playlist">Hapus</string>
<string name="rename_playlist">Ubah Nama</string>
<string name="playlist_name_input">Nama</string>
<string name="append_playlist">Tambahkan Ke Playlist</string>
<string name="set_as_playlist_thumbnail">Atur sebagai Thumbnail Playlist</string>
<string name="bookmark_playlist">Markah Playlist</string>
<string name="unbookmark_playlist">Hapus Markah</string>
<string name="delete_playlist_prompt">Hapus playlist ini\?</string>
<string name="playlist_creation_success">Playlist dibuat</string>
<string name="playlist_add_stream_success">Diplaylist</string>
<string name="playlist_thumbnail_change_success">Thumbnail playlist diubah.</string>
<string name="playlist_delete_failure">Tidak bisa menghapus playlist.</string>
<string name="caption_none">Tidak ada Takarir</string>
<string name="resize_fit">Pas</string>
<string name="resize_fill">Isi</string>
<string name="resize_zoom">Perbesar</string>
<string name="caption_auto_generated">Otomatis dibuat</string>
<string name="caption_font_size_settings_title">Ukuran fon deskripsi</string>
<string name="smaller_caption_font_size">Fon lebih kecil</string>
<string name="normal_caption_font_size">Fon normal</string>
<string name="larger_caption_font_size">Fon lebih besar</string>
<string name="enable_leak_canary_title">Aktifkan LeakCanary</string>
<string name="playback_nightcore">Nightcore</string>
<string name="playback_default">Bawaan</string>
<string name="no_player_found_toast">Pemutar stream tidak ditemukan (anda bisa memasang VLC untuk memutarnya).</string>
<string name="no_player_found_toast">Pemutar stream tidak ditemukan (anda bisa memasang VLC untuk memutarnya).</string>
<string name="controls_download_desc">Unduh berkas stream</string>
<string name="subscription_change_failed">Tidak bisa mengubah subscription</string>
<string name="show_info">Tampilkan info</string>
<string name="controls_add_to_playlist_title">Tambahkan Ke</string>
<string name="clear_views_history_title">Hapus riwayat tontonan</string>
<string name="clear_views_history_summary">Hapus riwayat stream yang telah diputar</string>
<string name="delete_view_history_alert">Hapus seluruh riwayat tontonan\?</string>
@ -398,14 +334,10 @@
<string name="delete_search_history_alert">Hapus seluruh riwayat pencarian\?</string>
<string name="search_history_deleted">Riwayat pencarian dihapus.</string>
<string name="no_streams_available_download">Tidak ada stream yang tersedia untuk diunduh</string>
<string name="one_item_deleted">1 item dihapus.</string>
<string name="toast_no_player">Tidak ada aplikasi terpasang untuk memutar berkas ini</string>
<string name="title_history_view">Ditonton</string>
<string name="tab_bookmarks">Playlist Disimpan</string>
<string name="auto_queue_title">Antre otomatis stream berikutnya</string>
<string name="channel_unsubscribed">Channel berhenti disubscribe</string>
<string name="subscription_update_failed">Tidak bisa memperbarui subscription</string>
@ -414,32 +346,23 @@
<string name="use_inexact_seek_summary">Memungkinkan pengguna memilih posisi waktu video dengan cepat tetapi dengan tingkat presisi yang rendah</string>
<string name="app_license">NewPipe adalah perangkat lunak libre copyleft: Anda bisa menggunakannya, mempelajarinya, berbagi, dan meningkatkannya. Secara khusus anda bisa mendistribusikan ulang dan/atau memodifikasinya dibawah syarat Lisensi Publik Umum GNU yang diterbitkan oleh Free Software Foundation, baik versi 3 dari Lisensi, atau (sesuai pilihan anda) versi yang lebih baru.</string>
<string name="import_settings">Apakah anda juga ingin mengimpor pengaturan\?</string>
<string name="preferred_open_action_settings_title">Tindakan \'buka\' yang diinginkan</string>
<string name="preferred_open_action_settings_summary">Tindakan baku ketika membuka konten — %s</string>
<string name="caption_setting_title">Takarir</string>
<string name="caption_setting_description">Ubah skala teks takarir pemutar dan gaya latar belakang. Perlu memulai ulang apl.</string>
<string name="enable_leak_canary_summary">Pemantauan kebocoran memori dapat menyebabkan apl menjadi tidak responsif saat heap dumping</string>
<string name="enable_disposed_exceptions_title">Laporkan galat out-of-lifecycle</string>
<string name="enable_disposed_exceptions_summary">Paksa pelaporan eksepsi Rx yang tak terkirim di luar fragmen atau siklus hidup aktivitas setelah dibuang</string>
<string name="import_export_title">Impor/ekspor</string>
<string name="import_title">Impor</string>
<string name="import_from">Impor dari</string>
<string name="export_to">Ekspor ke</string>
<string name="import_ongoing">Mengimpor…</string>
<string name="export_ongoing">Mengekspor…</string>
<string name="import_file_title">Impor berkas</string>
<string name="previous_export">Ekspor sebelumnya</string>
<string name="subscriptions_import_unsuccessful">Tidak bisa mengimpor subscription</string>
<string name="subscriptions_export_unsuccessful">Tidak bisa mengekspor subscription</string>
<string name="import_youtube_instructions">Impor subscription YouTube dengan mengunduh berkas yang diekspor:
\n
\n1. Kunjungi URL ini: %1$s
@ -452,11 +375,9 @@
\n3. Masuk ketika ditanya
\n4. Salin URL profil anda ketika dialihkan.</string>
<string name="import_soundcloud_instructions_hint">idAnda, soundcloud.com/idAnda</string>
<string name="import_network_expensive_warning">Perlu diingat operasi ini membutuhkan bandwidth yang besar.
\n
\nApakah anda ingin melanjutkan\?</string>
<string name="playback_speed_control">Kontrol Kecepatan Pemutaran</string>
<string name="playback_tempo">Tempo</string>
<string name="playback_pitch">Nada</string>
@ -472,12 +393,10 @@
<string name="skip_silence_checkbox">Percepat saat diam</string>
<string name="playback_step">Langkah</string>
<string name="playback_reset">Atur ulang</string>
<string name="start_accept_privacy_policy">Agar sesuai dengan Regulasi Perlindungan Data Umum Eropa (GDPR), dengan ini kami tarik perhatian anda ke kebijakan privasi NewPipe. Silakan baca dengan seksama.
\nAnda harus menerimanya untuk mengirimkan laporan bug kepada kami.</string>
<string name="accept">Setuju</string>
<string name="decline">Tolak</string>
<string name="limit_data_usage_none_description">Tanpa batas</string>
<string name="limit_mobile_data_usage_title">Batasi resolusi saat menggunakan data seluler</string>
<string name="minimize_on_exit_title">Minimalkan saat beralih apl</string>
@ -517,7 +436,7 @@
<string name="app_update_notification_content_title">Pembaruan NewPipe Tersedia!</string>
<string name="app_update_notification_content_text">Ketuk untuk mengunduh</string>
<string name="missions_header_finished">Selesai</string>
<string name="missions_header_pending">Di antrian</string>
<string name="missions_header_pending">Tertunda</string>
<string name="paused">dijeda</string>
<string name="queued">antri</string>
<string name="post_processing">pengolahan-pasca</string>
@ -528,12 +447,12 @@
<string name="download_finished_more">%s unduhan selesai</string>
<string name="generate_unique_name">Hasilkan nama unik</string>
<string name="overwrite">Timpa</string>
<string name="overwrite_warning">File yang diunduh dengan nama ini sudah ada</string>
<string name="overwrite_finished_warning">File yang diunduh dengan nama ini sudah ada</string>
<string name="download_already_running">Ada unduhan yang sedang berlangsung dengan nama ini</string>
<string name="show_error">Tunjukkan kesalahan</string>
<string name="label_code">Kode</string>
<string name="error_path_creation">File tidak dapat dibuat</string>
<string name="error_file_creation">Folder tujuan tidak dapat dibuat</string>
<string name="error_file_creation">File tidak dapat dibuat</string>
<string name="error_path_creation">Folder tujuan tidak dapat dibuat</string>
<string name="error_permission_denied">Izin ditolak oleh sistem</string>
<string name="error_ssl_exception">Koneksi aman gagal</string>
<string name="error_unknown_host">Tidak dapat menemukan server</string>
@ -549,5 +468,5 @@
<string name="max_retry_msg">Percobaan maksimum</string>
<string name="max_retry_desc">Jumlah upaya maksimum sebelum membatalkan unduhan</string>
<string name="pause_downloads_on_mobile">Berhenti ketika beralih ke data seluler</string>
<string name="pause_downloads_on_mobile_desc">Unduhan yang tidak dapat dijeda akan dimulai kembali</string>
<string name="pause_downloads_on_mobile_desc">Unduhan yang tidak dapat dijeda akan diulang dari awal</string>
</resources>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,6 @@
<string name="url_not_supported_toast">지원하지 않는 URL 입니다</string>
<string name="content_language_title">기본 컨텐츠 언어</string>
<string name="settings_category_video_audio_title">비디오 &amp; 오디오</string>
<string name="list_thumbnail_view_description">비디오 미리보기 썸네일</string>
<string name="detail_thumbnail_view_description">비디오 미리보기 썸네일</string>
<string name="detail_uploader_thumbnail_view_description">업로더 썸네일</string>
@ -38,24 +37,19 @@
<string name="detail_likes_img_view_description">좋아요</string>
<string name="use_external_video_player_title">외부 비디오 플레이어 사용</string>
<string name="use_external_audio_player_title">외부 오디오 플레이어 사용</string>
<string name="download_path_audio_title">오디오 다운로드 폴더</string>
<string name="download_path_audio_summary">다운로드된 오디오는 여기에 저장됩니다</string>
<string name="download_path_audio_dialog_title">오디오 파일 다운로드 경로를 입력하세요</string>
<string name="theme_title">테마</string>
<string name="dark_theme_title">어두운 테마</string>
<string name="light_theme_title">밝은 테마</string>
<string name="settings_category_appearance_title">외관</string>
<string name="settings_category_other_title">기타</string>
<string name="background_player_playing_toast">백그라운드에서 재생 중</string>
<string name="play_btn_text">재생</string>
<string name="network_error">네트워크 오류</string>
<string name="use_tor_title">Tor 사용</string>
<string name="use_tor_summary">(실험적) 향상된 프라이버시를 위해 다운로드 트래픽을 강제로 Tor를 통해 전송 (스트리밍 비디오는 아직 지원되지 않습니다).</string>
<string name="err_dir_create">다운로드 디렉토리를 만들 수 없습니다 \'%1$s\'</string>
<string name="info_dir_created">다운로드 디렉토리를 만들었습니다 \'%1$s\'</string>
<string name="main_bg_subtitle">검색 버튼을 눌러서 시작하세요</string>
@ -65,7 +59,6 @@
<string name="show_age_restricted_content_title">연령 제한 컨텐츠</string>
<string name="video_is_age_restricted">연령 제한 비디오입니다. 설정 메뉴에서 시청 허용 여부를 변경하실 수 있습니다.</string>
<string name="duration_live">라이브</string>
<string name="general_error">오류</string>
<string name="could_not_load_thumbnails">모든 썸네일을 불러올 수 없습니다</string>
<string name="youtube_signature_decryption_error">비디오 URL 서명을 복호화할 수 없습니다</string>
@ -84,11 +77,8 @@
<string name="what_happened_headline">다음이 발생함:</string>
<string name="your_comment">내용 (영어로 작성):</string>
<string name="error_details_headline">자세한 사항:</string>
<string name="report_error">오류 보고</string>
<string name="user_report">사용자 보고서</string>
<string name="video">비디오</string>
<string name="audio">오디오</string>
<string name="retry">재시도</string>
@ -99,8 +89,7 @@
<string name="pause">일시정지</string>
<string name="delete">삭제</string>
<string name="checksum">체크섬</string>
<string name="open_in_popup_mode">팝업 모드에서 열기</string>
<string name="open_in_popup_mode">팝업 모드에서 열기</string>
<string name="use_external_video_player_summary">일부 해상도에서 소리가 나지 않습니다</string>
<string name="popup_mode_share_menu_title">뉴파이프 팝업 모드</string>
<string name="subscribe_button_title">구독</string>
@ -108,15 +97,11 @@
<string name="channel_unsubscribed">채널 구독 해제됨</string>
<string name="subscription_change_failed">구독 여부를 변경할 수 없음</string>
<string name="subscription_update_failed">구독을 업데이트할 수 없음</string>
<string name="tab_main">메인 화면</string>
<string name="tab_subscriptions">구독</string>
<string name="fragment_whats_new">새로운 영상</string>
<string name="controls_background_title">배경</string>
<string name="controls_popup_title">팝업</string>
<string name="default_popup_resolution_title">기본 팝업 해상도</string>
<string name="show_higher_resolutions_title">높은 해상도 표시</string>
<string name="show_higher_resolutions_summary">일부 기기에서만 2K/4K 해상도 재생이 지원됩니다</string>
@ -157,48 +142,36 @@
<string name="best_resolution">최대 해상도</string>
<string name="undo">되돌리기</string>
<string name="play_all">전부 재생</string>
<string name="notification_channel_name">뉴파이프 알림</string>
<string name="notification_channel_description">뉴파이프 백그라운드 및 팝업 플레이어 알림</string>
<string name="unknown_content">[알 수 없음]</string>
<string name="could_not_load_image">이미지를 불러올 수 없습니다</string>
<string name="app_ui_crash">앱/UI 충돌</string>
<string name="player_stream_failure">이 스트림을 재생할 수 없습니다</string>
<string name="player_unrecoverable_failure">복구할 수 없는 플레이어 오류가 발생했습니다</string>
<string name="player_recoverable_failure">플레이어 오류로부터 복구 중</string>
<string name="info_labels">무엇을:\\n요청:\\n컨텐츠 언어:\\n서비스:\\nGMT 기준 시간:\\n패키지:\\n버전:\\n안드로이드 버전:</string>
<string name="search_no_results">결과 없음</string>
<string name="empty_subscription_feed_subtitle">구독할 항목을 추가하세요</string>
<string name="use_old_player_title">구형 플레이어 사용</string>
<string name="use_old_player_summary">내장된 구형 Mediaframework 플레이어 사용</string>
<string name="short_thousand"></string>
<string name="short_million">백만</string>
<string name="short_billion">10억</string>
<string name="no_subscribers">구독자 없음</string>
<plurals name="subscribers">
<item quantity="other">%s 구독자</item>
</plurals>
<item quantity="other">%s 구독자</item>
</plurals>
<string name="no_views">시청 횟수 없음</string>
<plurals name="views">
<item quantity="other">%s 시청 횟수</item>
</plurals>
<item quantity="other">%s 시청 횟수</item>
</plurals>
<string name="no_videos">비디오 없음</string>
<plurals name="videos">
<item quantity="other">비디오</item>
</plurals>
<item quantity="other">비디오</item>
</plurals>
<string name="view">재생</string>
<string name="add">새로운 미션</string>
<string name="finish">OK</string>
<string name="msg_name">파일명</string>
<string name="msg_threads">쓰레드</string>
<string name="msg_error">오류</string>
@ -212,18 +185,14 @@
<string name="no_available_dir">다운로드 할 폴더를 선택하세요</string>
<string name="msg_popup_permission">이 권한은 팝업 모드에서
\n열기 위해 필요합니다</string>
<string name="reCaptchaActivity">로봇인지 확인 (reCAPTCHA)</string>
<string name="recaptcha_request_toast">reCAPTCHA challenge 요청됨</string>
<string name="settings_category_downloads_title">다운로드</string>
<string name="settings_file_charset_title">파일명에 허용되는 문자</string>
<string name="settings_file_replacement_character_summary">올바르지 않은 문자는 다음 문자로 대체됩니다</string>
<string name="settings_file_replacement_character_title">대체 문자</string>
<string name="charset_letters_and_digits">문자 및 숫자</string>
<string name="charset_most_special_characters">가장 특수한 문자</string>
<string name="title_activity_about">뉴파이프에 대해서</string>
<string name="action_settings">설정</string>
<string name="action_about">뉴파이프</string>
@ -245,8 +214,6 @@
<string name="website_encouragement">뉴파이프에 관한 최신 및 상세 정보를 얻으려면 웹사이트를 방문하세요.</string>
<string name="app_license_title">뉴파이프가 채택한 라이센스</string>
<string name="read_full_license">라이센스 읽기</string>
<string name="title_activity_history">기록</string>
<string name="title_history_search">검색함</string>
<string name="title_history_view">시청함</string>
@ -256,7 +223,6 @@
<string name="history_cleared">기록이 삭제되었습니다</string>
<string name="item_deleted">항목이 삭제되었습니다</string>
<string name="delete_item_search_history">이 항목을 검색 기록에서 삭제할까요?</string>
<string name="main_page_content">메인 화면의 내용</string>
<string name="blank_page_summary">빈 페이지</string>
<string name="kiosk_page_summary">키오스크 페이지</string>
@ -266,7 +232,6 @@
<string name="select_a_channel">채널 선택</string>
<string name="no_channel_subscribed_yet">구독중인 채널이 없습니다</string>
<string name="select_a_kiosk">키오스크 선택</string>
<string name="kiosk">키오스크</string>
<string name="trending">인기 급상승</string>
<string name="top_50">탑 50</string>
@ -276,20 +241,17 @@
<string name="play_queue_remove">제거</string>
<string name="play_queue_stream_detail">상세 정보</string>
<string name="play_queue_audio_settings">오디오 설정</string>
<string name="hold_to_append">눌러서 대기 목록에 추가</string>
<string name="enqueue_on_background">백그라운드 대기</string>
<string name="enqueue_on_popup">팝업에 대기</string>
<string name="hold_to_append">눌러서 대기에 추가</string>
<string name="enqueue_on_background">백그라운드로 갈 경우 대기</string>
<string name="enqueue_on_popup">새 팝업으로 갈 경우 대기</string>
<string name="start_here_on_main">여기서부터 재생</string>
<string name="start_here_on_background">여기서부터 백그라운드에서 재생</string>
<string name="start_here_on_popup">여기서부터 팝업에 재생</string>
<string name="no_player_found_toast">스트리밍 플레이어를 찾을 수 없습니다. VLC를 설치하면 플레이하실 수 있습니다</string>
<string name="start_here_on_background">백그라운드로 갈 경우 여기서부터 재생</string>
<string name="start_here_on_popup">새 팝업으로 갈 경우 여기서부터 재생</string>
<string name="no_player_found_toast">스트리밍 플레이어를 찾을 수 없습니다. VLC를 설치하면 플레이하실 수 있습니다.</string>
<string name="controls_download_desc">스트리밍 파일 다운로드하기</string>
<string name="show_info">정보 보기</string>
<string name="tab_bookmarks">플레이리스트 북마크</string>
<string name="controls_add_to_playlist_title">이곳에 추가</string>
<string name="use_inexact_seek_title">정확하지는 않지만 빠른 탐색</string>
<string name="use_inexact_seek_summary">정확하지 않은 탐색은 빠르게 위치로 탐색할 수 있지만 정확도는 떨어집니다</string>
<string name="auto_queue_title">다음 스트림을 자동으로 재생열에 추가하기</string>
@ -300,12 +262,10 @@
<string name="live">라이브 (LIVE)</string>
<string name="always">항상</string>
<string name="just_once">한번만</string>
<string name="toggle_orientation">디바이스 방향 토글</string>
<string name="switch_to_background">백그라운드로 전환</string>
<string name="switch_to_popup">팝업으로 전환</string>
<string name="switch_to_main">기본으로 전환</string>
<string name="import_data_title">데이터베이스 가져오기</string>
<string name="export_data_title">데이터베이스 내보내기</string>
<string name="import_data_summary">현재 시청 기록 및 구독 목록을 덮어쓰기 합니다</string>
@ -314,102 +274,79 @@
<string name="invalid_url_toast">잘못된 URL</string>
<string name="video_streams_empty">발견된 비디오 스트림 없음</string>
<string name="audio_streams_empty">발견된 오디오 스트림 없음</string>
<string name="detail_drag_description">드래그하여 재배열</string>
<string name="create">만들기</string>
<string name="delete_one">1개 삭제하기</string>
<string name="delete_all">모두 삭제하기</string>
<string name="dismiss">취소</string>
<string name="rename">이름 바꾸기</string>
<string name="reCaptcha_title">로봇인지 확인합니다</string>
<string name="delete_stream_history_prompt">이 항목을 시청 기록에서 삭제하시겠습니까?</string>
<string name="delete_all_history_prompt">모든 항목을 시청 기록에서 삭제하시겠습니까?</string>
<string name="title_last_played">마지막으로 재생</string>
<string name="title_most_played">가장 많이 재생</string>
<string name="export_complete_toast">내보내기 완료</string>
<string name="import_complete_toast">가져오기 완료</string>
<string name="no_valid_zip_file">유효한 ZIP 파일 없음</string>
<string name="could_not_import_all_files">경고: 모든 파일 가져오기를 실패했습니다.</string>
<string name="override_current_data">이것은 현재 설정을 덮어쓸 것입니다.</string>
<string name="drawer_open">드로어 열기</string>
<string name="drawer_close">드로어 닫기</string>
<string name="drawer_header_action_paceholder_text">여기에 무언가가 추가될 거에요~ :D</string>
<string name="video_player">비디오 플레이어</string>
<string name="background_player">백그라운드 플레이어</string>
<string name="popup_player">팝업 플레이어</string>
<string name="always_ask_open_action">항상 묻기</string>
<string name="preferred_player_fetcher_notification_title">정보 가져오는 중…</string>
<string name="preferred_player_fetcher_notification_message">요청한 콘텐츠를 로딩 중입니다</string>
<string name="create_playlist">새로운 재생목록</string>
<string name="delete_playlist">삭제</string>
<string name="rename_playlist">이름 바꾸기</string>
<string name="playlist_name_input">이름</string>
<string name="append_playlist">재생목록에 추가</string>
<string name="set_as_playlist_thumbnail">재생목록 썸네일로 설정</string>
<string name="bookmark_playlist">재생목록 북마크하기</string>
<string name="unbookmark_playlist">북마크 제거하기</string>
<string name="delete_playlist_prompt">이 재생목록을 삭제하시겠습니까?</string>
<string name="playlist_creation_success">재생목록 생성 완료</string>
<string name="playlist_add_stream_success">재생목록에 추가됨</string>
<string name="playlist_thumbnail_change_success">재생목록 썸내일이 바뀜.</string>
<string name="playlist_delete_failure">재생목록을 삭제할 수 없습니다.</string>
<string name="caption_none">자막 없음</string>
<string name="resize_fit">꼭 맞게 하기</string>
<string name="resize_fill">채우기</string>
<string name="resize_zoom">확대</string>
<string name="caption_auto_generated">자동 생성됨</string>
<string name="caption_font_size_settings_title">자막 폰트 크기</string>
<string name="smaller_caption_font_size">작은 폰트</string>
<string name="normal_caption_font_size">보통 폰트</string>
<string name="larger_caption_font_size">큰 폰트</string>
<string name="live_sync">동기화</string>
<string name="enable_leak_canary_title">LeakCanary 할성화</string>
<string name="enable_leak_canary_summary">힙 덤프 중 메모리 누수 점검으로 앱이 불안정해질 수 있습니다</string>
<string name="enable_disposed_exceptions_title">out-of-lifecycle 오류 보고</string>
<string name="enable_disposed_exceptions_summary">프래그먼트 또는 버려진 액티비티 주기 밖에서 일어나는 전달할 수 없는 Rx 예외를 강제적으로 보고하기</string>
<string name="file">파일</string>
<string name="file">파일</string>
<string name="invalid_directory">폴더가 존재하지 않습니다</string>
<string name="invalid_source">잘못된 파일/콘츠 소스</string>
<string name="invalid_source">잘못된 파일/콘텐츠 소스</string>
<string name="invalid_file">파일이 존재하지 않거나 읽기/쓰기 권한이 없습니다</string>
<string name="file_name_empty_error">파일명이 비어 있으면 안됩니다</string>
<string name="error_occurred_detail">오류 발생: %1$s</string>
<string name="import_export_title">가져오기/내보내기</string>
<string name="import_title">가져오기</string>
<string name="import_from">이곳으로부터 가져오기</string>
<string name="export_to">이곳으로 내보내기</string>
<string name="import_ongoing">가져오는 중.…</string>
<string name="export_ongoing">내보내는 중…</string>
<string name="import_file_title">파일 가져오기</string>
<string name="previous_export">이전 내보내기</string>
<string name="subscriptions_import_unsuccessful">구독 목록 가져오기 실패</string>
<string name="subscriptions_export_unsuccessful">구독 목록 내보내기 실패</string>
<string name="import_youtube_instructions">YouTube 구독 목록을 가져오려면 내보내기 파일이 필요합니다. 다운로드 하려면
\n1. 이곳으로 가세요: $1$s
\n2. 로그인이 필요하면 하세요
\n3. 다운로드가 곧 시작 됩니다 (이 파일이 내보내기 파일 입니다)</string>
<string name="import_youtube_instructions">\'YouTube 구독 파일\'을 다운로드해서 구독 목록을 가져올 수 있습니다:
\n
\n1. 이곳으로 가세요: $1$s
\n2. 요청에 따라 로그인을 진행합니다
\n3. 다운로드가 곧 시작 됩니다 (이 파일이 구독 파일입니다)</string>
<string name="import_soundcloud_instructions">SoundCloud 프로필을 가져오시려면 URL 및 ID를 입력해주세요.
\n
\n프로필 URL을 찾으시려면 다음 과정을 따라해 주세요.
@ -418,11 +355,10 @@
\n3. 로그인이 필요하면 하세요.
\n4. 리디렉트된 곳의 URL을 복사하세요. (이 URL이 당신의 프로필 URL 입니다)</string>
<string name="import_soundcloud_instructions_hint">프로필ID, soundcloud.com/프로필ID</string>
<string name="import_network_expensive_warning">경고: 데이터 소모량이 늘어날 수 있습니다.
\n
\n계속하시겠습니까?</string>
<string name="download_thumbnail_title">썸내일 로드하기</string>
<string name="download_thumbnail_title">썸내일 로드하기</string>
<string name="download_thumbnail_summary">동영상 썸네일을 로드하지 않으며, 데이터와 메모리 사용을 최대한 줄입니다. 이 옵션을
\n선택 시 모든 메모리 캐시와 저장소 캐시를 삭제합니다.</string>
<string name="thumbnail_cache_wipe_complete_notice">이미지 캐시 지워짐</string>
@ -435,16 +371,12 @@
<string name="unhook_checkbox">영상과 소리 분리 (소리가 깨질 수 있음)</string>
<string name="playback_nightcore">나이트코어</string>
<string name="playback_default">기본</string>
<string name="no_streams_available_download">다운로드 가능한 스트림이 없습니다</string>
<string name="no_streams_available_download">다운로드 가능한 스트림이 없습니다</string>
<string name="toast_no_player">이 파일을 재생할 수 있는 플레이어 앱이 없습니다</string>
<string name="preferred_open_action_settings_title">선호하는 열기 동작</string>
<string name="preferred_open_action_settings_summary">컨텐츠를 열 때 사용할 기본 동작 — %s</string>
<string name="caption_setting_title">자막</string>
<string name="caption_setting_description">플레이어 자막 텍스트 크기와 배경 스타일을 변경합니다. 효과를 적용하려면 앱을 재시작 해야합니다.</string>
<string name="channels">채널만</string>
<string name="playlists">재생 목록만</string>
<string name="clear_views_history_title">시청 기록 삭제하기</string>
@ -459,15 +391,12 @@
<string name="privacy_policy_encouragement">뉴파이프 프로젝트는 사용자의 개인 정보 보호를 최우선으로 생각하며, 동의 없이 어떠한 정보도 수집하지 않습니다.
\n뉴파이프 개인정보 보호 정책에서는 오류 보고 시 어떠한 정보가 수집되고 저장되는지 자세히 명시되어 있습니다.</string>
<string name="read_privacy_policy">개인정보 보호 정책 읽기</string>
<string name="app_license">뉴파이프는 카피레프트 자유 소프트웨어입니다. 사용자는 이 앱을 사용, 공유, 또는 수정하는 것이 가능하고, 수정 후 재배포 시 자유 소프트웨어 재단의 GNU 라이센스 버전
\n3 또는 그 이상의 버전을 포함해야 합니다.</string>
<string name="app_license">뉴파이프는 카피레프트 자유 소프트웨어입니다. 사용자는 이 앱을 사용, 공유, 또는 수정할 수 있고, 수정 후 재배포 시 자유 소프트웨어 재단의 GNU 라이센스 버전 3 또는 그 이상의 버전을 포함해야 합니다.</string>
<string name="import_settings">앱 설정을 가져오시겠습니까?</string>
<string name="skip_silence_checkbox">무음 구간 스킵</string>
<string name="start_accept_privacy_policy">유럽 연합 일반 데이터 보호 규정 (GDPR) 에 따라, 사용자는 뉴파이프 개인정보 보호 정책을 읽고 꼼꼼히 확인해야 합니다. 버그 리포트를 보내시려면 개인정보 보호 정책에 동의해주세요.</string>
<string name="accept">동의</string>
<string name="decline">동의하지 않음</string>
<string name="limit_data_usage_none_description">데이터 제한 없음</string>
<string name="limit_mobile_data_usage_title">모바일 데이터 사용 시 화질 제한</string>
<string name="unsubscribe">구독 해제</string>
@ -486,4 +415,63 @@
<string name="app_update_notification_channel_description">새 뉴파이프 버전을 알림</string>
<string name="download_to_sdcard_error_title">외부 저장소 없음</string>
<string name="download_to_sdcard_error_message">다운로드할 SD 카드를 찾을 수 없습니다. 다운로드 폴더 경로를 초기화 하시겠습니까\?</string>
<string name="one_item_deleted">1개의 항목이 삭제되었습니다.</string>
<string name="minimize_on_exit_title">앱 전환시 최소화</string>
<string name="minimize_on_exit_summary">비디오 플레이어에서 다른 앱으로 전환 시 다음과 같은 동작 실행 — %s</string>
<string name="minimize_on_exit_none_description">없음</string>
<string name="minimize_on_exit_background_description">백그라운드 플레이어로 최소화</string>
<string name="minimize_on_exit_popup_description">팝업 플레이어로 최소화</string>
<string name="playback_step">단계</string>
<string name="playback_reset">초기화</string>
<string name="saved_tabs_invalid_json">저장된 탭을 읽는 중 오류가 발생하여 기본 탭을 사용합니다</string>
<string name="restore_defaults">기본값 복원</string>
<string name="restore_defaults_confirmation">기본값을 복원할까요\?</string>
<string name="subscribers_count_not_available">구독자 숫자가 없습니다</string>
<string name="main_page_content_summary">메인 화면에 표시할 탭</string>
<string name="selection">선택</string>
<string name="updates_setting_title">업데이트</string>
<string name="updates_setting_description">새 버전이 있을 경우 앱을 업데이트하도록 알림 표시</string>
<string name="list_view_mode">\'목록으로 보기\' 모드</string>
<string name="list">목록</string>
<string name="grid">격자</string>
<string name="auto">자동</string>
<string name="switch_view">보기 방식 전환</string>
<string name="app_update_notification_content_title">NewPipe 업데이트가 있습니다!</string>
<string name="app_update_notification_content_text">여기를 눌러서 다운로드</string>
<string name="missions_header_finished">완료됨</string>
<string name="missions_header_pending">대기열에 있음</string>
<string name="paused">일시중지됨</string>
<string name="queued">대기열에 추가됨</string>
<string name="post_processing">후처리 실행 중</string>
<string name="enqueue">대기열</string>
<string name="permission_denied">시스템에 의해 실행이 거부되었습니다</string>
<string name="download_failed">다운로드 실패</string>
<string name="download_finished">다운로드 완료</string>
<string name="download_finished_more">%s 다운로드 완료됨</string>
<string name="generate_unique_name">별개의 이름 생성</string>
<string name="overwrite">덮어쓰기</string>
<string name="overwrite_unrelated_warning">이 이름을 가진 파일이 이미 있습니다.</string>
<string name="overwrite_finished_warning">이 이름을 가진 다운로드 된 파일이 이미 있습니다.</string>
<string name="download_already_running">해당 이름을 가진 다운로드가 이미 진행중입니다</string>
<string name="show_error">오류 표시</string>
<string name="label_code">코드</string>
<string name="error_path_creation">파일을 만들 수 없습니다</string>
<string name="error_file_creation">지정한 폴더를 만들 수 없습니다</string>
<string name="error_permission_denied">시스템에 의해 권한이 거부되었습니다</string>
<string name="error_ssl_exception">보안 연결 실패</string>
<string name="error_unknown_host">서버를 찾을 수 없습니다</string>
<string name="error_connect_host">서버에 접속할 수 없습니다</string>
<string name="error_http_no_content">서버가 데이터를 전송하지 않고 있습니다</string>
<string name="error_http_unsupported_range">서버가 다중 스레드 다운로드를 받아들이지 않습니다, @string/msg_threads = 1 를 사용해 다시 시도해보세요</string>
<string name="error_http_requested_range_not_satisfiable">요청된 HTTP 범위가 충분하지 않습니다</string>
<string name="error_http_not_found">HTTP 찾을 수 없습니다</string>
<string name="error_postprocessing_failed">후처리 작업이 실패하였습니다</string>
<string name="clear_finished_download">완료된 다운로드 비우기</string>
<string name="msg_pending_downloads">대기중인 %s 다운로드를 지속하세요</string>
<string name="stop">멈추기</string>
<string name="max_retry_msg">최대 재시도 횟수</string>
<string name="max_retry_desc">다운로드를 취소하기 전까지 다시 시도할 최대 횟수</string>
<string name="pause_downloads_on_mobile">모바일 데이터로 전환시 일시정지</string>
<string name="pause_downloads_on_mobile_desc">일시정지 할 수 없는 다운로드의 경우에는 다시 시작됩니다</string>
<string name="conferences">컨퍼런스</string>
</resources>

View File

@ -120,8 +120,6 @@
<string name="video">Vaizdas</string>
<string name="audio">Muzika</string>
<string name="retry">Bandyti iš naujo</string>
<string name="use_old_player_title">Naudoti seną grotuvą</string>
<string name="use_old_player_summary">Senas įtaisytas media grotuvas</string>
<plurals name="subscribers">
<item quantity="one">%s prenumeratorius</item>

View File

@ -202,8 +202,6 @@
<string name="audio">Звук</string>
<string name="retry">Пробај повторно</string>
<string name="storage_permission_denied">Нема привилегии за пристап</string>
<string name="use_old_player_title">Користи го стариот плеер</string>
<string name="use_old_player_summary">Користи го стариот Mediaframework плеер</string>
<string name="short_thousand">K</string>
<string name="short_million">M</string>

View File

@ -432,7 +432,6 @@
<string name="app_update_notification_content_title">Kemas kini NewPipe Tersedia!</string>
<string name="app_update_notification_content_text">Ketik untuk muat turun</string>
<string name="missions_header_finished">Selesai</string>
<string name="missions_header_pending">Dalam barisan</string>
<string name="paused">dijeda</string>
<string name="queued">telah beratur</string>
<string name="post_processing">pemprosesan-pasca</string>
@ -443,12 +442,12 @@
<string name="download_finished_more">%s muat turun selesai</string>
<string name="generate_unique_name">Menjana nama yang unik</string>
<string name="overwrite">Timpa</string>
<string name="overwrite_warning">Fail yang dimuat turun dengan nama ini sudah wujud</string>
<string name="overwrite_finished_warning">Fail yang dimuat turun dengan nama ini sudah wujud</string>
<string name="download_already_running">Terdapat muat turun yang sedang berjalan dengan nama ini</string>
<string name="show_error">Tunjukkan kesilapan</string>
<string name="label_code">Kod</string>
<string name="error_path_creation">Fail tidak boleh dibuat</string>
<string name="error_file_creation">Folder destinasi tidak boleh dibuat</string>
<string name="error_file_creation">Fail tidak boleh dibuat</string>
<string name="error_path_creation">Folder destinasi tidak boleh dibuat</string>
<string name="error_permission_denied">Kebenaran ditolak oleh sistem</string>
<string name="error_ssl_exception">Sambungan selamat gagal</string>
<string name="error_unknown_host">Tidak dapat mencari server</string>
@ -465,4 +464,5 @@
<string name="max_retry_desc">Jumlah percubaan maksimum sebelum membatalkan muat turun</string>
<string name="pause_downloads_on_mobile">Jeda semasa beralih ke data mudah alih</string>
<string name="pause_downloads_on_mobile_desc">Muat turun yang tidak dapat dihentikan akan dimulakan semula</string>
<string name="missions_header_pending">Menunggu</string>
</resources>

View File

@ -141,8 +141,6 @@
<string name="later">Senere</string>
<string name="disabled">Avskrudd</string>
<string name="use_old_player_title">Bruk gammel avspiller</string>
<string name="short_thousand">K</string>
<string name="short_million">M</string>
@ -153,8 +151,7 @@
<string name="recaptcha_request_toast">reCAPTCHA-oppgave forespurt</string>
<string name="use_old_player_summary">Gammel innebygd Mediaframework-avspiller</string>
<string name="use_external_video_player_summary">Fjerner lyd ved NOEN oppløsninger</string>
<string name="use_external_video_player_summary">Fjerner lyd ved NOEN oppløsninger</string>
<string name="subscribe_button_title">Abonner</string>
<string name="subscribed_button_title">Abonnert</string>
<string name="channel_unsubscribed">Kanalabonnent oppsagt</string>
@ -315,8 +312,7 @@
<string name="video_player">Videoavspiller</string>
<string name="background_player">Bakgrunnsavspiller</string>
<string name="popup_player">Oppsprettsavspiller</string>
<string name="always_ask_player">Spør alltid</string>
<string name="preferred_player_fetcher_notification_title">Henter informasjon…</string>
<string name="preferred_player_fetcher_notification_message">Laster forespurt innhold</string>
<string name="import_data_title">Importer database</string>
@ -519,7 +515,6 @@
<string name="app_update_notification_content_title">Ny NewPipe-versjon tilgjengelig.</string>
<string name="app_update_notification_content_text">Trykk for å laste ned</string>
<string name="missions_header_finished">Fullført</string>
<string name="missions_header_pending">I kø</string>
<string name="paused">pauset</string>
<string name="queued">i kø</string>
<string name="post_processing">etterbehandling</string>
@ -530,12 +525,12 @@
<string name="download_finished_more">%s nedlastinger fullført</string>
<string name="generate_unique_name">Generer unikt navn</string>
<string name="overwrite">Overskriv</string>
<string name="overwrite_warning">Nedlastet fil ved dette navnet finnes allerede</string>
<string name="overwrite_finished_warning">Nedlastet fil ved dette navnet finnes allerede</string>
<string name="download_already_running">Nedlasting med dette navnet underveis allerede</string>
<string name="show_error">Vis feil</string>
<string name="label_code">Kode</string>
<string name="error_path_creation">Filen kan ikke opprettes</string>
<string name="error_file_creation">Målmappen kan ikke opprettes</string>
<string name="error_file_creation">Filen kan ikke opprettes</string>
<string name="error_path_creation">Målmappen kan ikke opprettes</string>
<string name="error_permission_denied">Tilgang nektet av systemet</string>
<string name="error_ssl_exception">Sikker tilkobling mislyktes</string>
<string name="error_unknown_host">Fant ikke tjeneren</string>

View File

@ -189,8 +189,6 @@
<string name="audio">Geluid</string>
<string name="retry">Opnieuw proberen</string>
<string name="storage_permission_denied">Toegang tot opslag geweigerd</string>
<string name="use_old_player_title">Gebruik oude speler</string>
<string name="use_old_player_summary">Verouderden ingebouwde Mediaframework-speler</string>
<string name="short_thousand">K</string>
<string name="short_million">M</string>
<string name="short_billion">B</string>
@ -292,7 +290,7 @@
<string name="could_not_import_all_files">Opgelet: kon niet alle bestanden importeren.</string>
<string name="override_current_data">Dit zal uw huidige configuratie overschrijven.</string>
<string name="kiosk">Kiosk</string>
<string name="trending">Trending</string>
<string name="trending">Populair</string>
<string name="top_50">Top 50</string>
<string name="new_and_hot">Nieuw en populair</string>
<string name="title_activity_background_player">Achtergrondspeler</string>
@ -436,7 +434,6 @@
<string name="app_update_notification_content_title">NewPipe-update beschikbaar!</string>
<string name="app_update_notification_content_text">Tikt voor te downloaden</string>
<string name="missions_header_finished">Voltooid</string>
<string name="missions_header_pending">In wachtrij</string>
<string name="paused">gepauzeerd</string>
<string name="queued">toegevoegd aan wachtrij</string>
<string name="post_processing">nabewerking</string>
@ -447,12 +444,12 @@
<string name="download_finished_more">%s downloads voltooid</string>
<string name="generate_unique_name">Unieke naam genereren</string>
<string name="overwrite">Overschrijven</string>
<string name="overwrite_warning">Der bestaat al een gedownload bestand met deze naam</string>
<string name="overwrite_finished_warning">Der bestaat al een gedownload bestand met deze naam</string>
<string name="download_already_running">Der is al een download met deze naam bezig</string>
<string name="show_error">Foutmelding weergeven</string>
<string name="label_code">Code</string>
<string name="error_path_creation">Het bestand kan niet aangemaakt worden</string>
<string name="error_file_creation">De doelmap kan niet aangemaakt worden</string>
<string name="error_file_creation">Het bestand kan niet aangemaakt worden</string>
<string name="error_path_creation">De doelmap kan niet aangemaakt worden</string>
<string name="error_permission_denied">Toelating geweigerd door het systeem</string>
<string name="error_ssl_exception">Beveiligde verbinding is mislukt</string>
<string name="error_unknown_host">Kon de server niet vinden</string>

View File

@ -123,8 +123,6 @@
\nopenen in pop-upmodus</string>
<string name="popup_mode_share_menu_title">NewPipe-pop-upmodus</string>
<string name="popup_playing_toast">Speelt af in pop-upmodus</string>
<string name="use_old_player_title">Oude speler gebruiken</string>
<string name="use_old_player_summary">Verouderde ingebouwde Mediaframework-speler</string>
<string name="default_video_format_title">Standaard videoformaat</string>
<string name="disabled">Uitgeschakeld</string>
<string name="default_popup_resolution_title">Standaardresolutie van pop-up</string>
@ -155,7 +153,7 @@
<string name="tab_about">Over</string>
<string name="tab_contributors">Bijdragers</string>
<string name="tab_licenses">Licenties</string>
<string name="app_description">Vrij en lichtgewicht streamen op Android.</string>
<string name="app_description">Vrij en licht streamen voor Android.</string>
<string name="view_on_github">Bekijken op GitHub</string>
<string name="app_license_title">Licentie van NewPipe</string>
<string name="contribution_encouragement">Hulp is altijd welkom. Of je nu nieuwe ideeën hebt, vertalingen kan aanleveren, wijzigingen in het ontwerp kan verrichten, code kan opschonen of van grote wijzigingen voorzien. Hoe meer hulp, hoe beter het wordt!</string>
@ -270,7 +268,6 @@
<string name="video_player">Videospeler</string>
<string name="background_player">Achtergrondspeler</string>
<string name="popup_player">Pop-upspeler</string>
<string name="always_ask_player">Altijd vragen</string>
<string name="preferred_player_fetcher_notification_title">Bezig met ophalen van informatie…</string>
<string name="preferred_player_fetcher_notification_message">Bezig met laden van gevraagde inhoud</string>
<string name="import_data_title">Databank importeren</string>
@ -441,7 +438,7 @@
<string name="app_update_notification_content_title">NewPipe-update beschikbaar!</string>
<string name="app_update_notification_content_text">Tik om te downloaden</string>
<string name="missions_header_finished">Voltooid</string>
<string name="missions_header_pending">In de wachtrij</string>
<string name="missions_header_pending">In afwachting van</string>
<string name="paused">gepauzeerd</string>
<string name="queued">aan de wachtrij toegevoegd</string>
<string name="post_processing">nabewerking</string>
@ -452,12 +449,12 @@
<string name="download_finished_more">%s downloads voltooid</string>
<string name="generate_unique_name">Genereer een unieke naam</string>
<string name="overwrite">Overschrijven</string>
<string name="overwrite_warning">Er bestaat al een gedownload bestand met deze naam</string>
<string name="overwrite_finished_warning">Er bestaat al een gedownload bestand met deze naam</string>
<string name="download_already_running">Er is een download aan de gang met deze naam</string>
<string name="show_error">Toon foutmelding</string>
<string name="label_code">Code</string>
<string name="error_path_creation">Het bestand kan niet worden gemaakt</string>
<string name="error_file_creation">De doelmap kan niet worden gemaakt</string>
<string name="error_file_creation">Het bestand kan niet worden gemaakt</string>
<string name="error_path_creation">De doelmap kan niet worden gemaakt</string>
<string name="error_permission_denied">Toestemming door het systeem geweigerd</string>
<string name="error_ssl_exception">Beveiligde connectie is mislukt</string>
<string name="error_unknown_host">Kon de server niet vinden</string>
@ -476,4 +473,5 @@
<string name="pause_downloads_on_mobile_desc">Downloads die niet kunnen worden gepauzeerd zullen worden herstart</string>
<string name="events">Gebeurtenissen</string>
<string name="conferences">Conferenties</string>
<string name="error_timeout">Time-out van verbinding</string>
</resources>

View File

@ -47,7 +47,7 @@
<string name="play_btn_text">Odtwórz</string>
<string name="content">Zawartość</string>
<string name="show_age_restricted_content_title">Treści z ograniczeniem wiekowym</string>
<string name="video_is_age_restricted">Pokaż wideo z ograniczeniem wiekowym. Zezwalanie na takie materiały jest możliwe w Ustawieniach.</string>
<string name="video_is_age_restricted">Pokaż wideo z ograniczeniami wiekowymi. Dopuszczenie takiego materiału jest możliwe z poziomu Ustawienia.</string>
<string name="duration_live">Na żywo</string>
<string name="downloads">Pobrane</string>
<string name="downloads_title">Pobrane</string>
@ -208,7 +208,7 @@
<plurals name="subscribers">
<item quantity="one">%s subskrybent</item>
<item quantity="few">%s subskrybentów</item>
<item quantity="many">%s subskrybentów</item>
<item quantity="many">%s subskrybenci</item>
</plurals>
<plurals name="views">
<item quantity="one">%s odtworzenie</item>
@ -356,7 +356,7 @@
\n
\nCzy chcesz kontynuować?</string>
<string name="playback_speed_control">Kontrola prędkości odtwarzania</string>
<string name="playback_tempo">Tempo</string>
<string name="playback_tempo">Czas</string>
<string name="playback_pitch">Wysokość dźwięku</string>
<string name="import_soundcloud_instructions_hint">twojeID, soundcloud.com/yourid</string>
<string name="unhook_checkbox">Odłącz (może powodować zniekształcenia)</string>
@ -435,7 +435,6 @@
<string name="app_update_notification_content_title">Dostępna jest aktualizacja NewPipe!</string>
<string name="app_update_notification_content_text">Stuknij, aby pobrać</string>
<string name="missions_header_finished">Gotowe</string>
<string name="missions_header_pending">W kolejce</string>
<string name="paused">wstrzymane</string>
<string name="queued">w kolejce</string>
<string name="post_processing">przetwarzanie końcowe</string>
@ -446,28 +445,29 @@
<string name="download_finished_more">%s pobieranie zostało zakończone</string>
<string name="generate_unique_name">Wygeneruj unikalną nazwę</string>
<string name="overwrite">Zastąp</string>
<string name="overwrite_warning">Pobrany plik o tej nazwie już istnieje</string>
<string name="overwrite_finished_warning">Pobrany plik o tej nazwie już istnieje</string>
<string name="download_already_running">Trwa pobieranie z tą nazwą</string>
<string name="show_error">Pokaż błąd</string>
<string name="label_code">Kod</string>
<string name="error_path_creation">Nie można utworzyć pliku</string>
<string name="error_file_creation">Nie można utworzyć folderu docelowego</string>
<string name="error_file_creation">Nie można utworzyć pliku</string>
<string name="error_path_creation">Nie można utworzyć folderu docelowego</string>
<string name="error_permission_denied">Odmowa dostępu do systemu</string>
<string name="error_ssl_exception">Bezpieczne połączenie nie powiodło się</string>
<string name="error_unknown_host">Nie można znaleźć serwera</string>
<string name="error_connect_host">Nie można połączyć się z serwerem</string>
<string name="error_http_no_content">Serwer nie wysyła danych</string>
<string name="error_http_unsupported_range">Serwer nie akceptuje pobierania wielowątkowego, spróbuj ponownie za pomocą @string/msg_threads = 1</string>
<string name="error_http_requested_range_not_satisfiable">Żądany zakres jest niewłaściwy</string>
<string name="error_http_requested_range_not_satisfiable">Niewłaściwy zakres</string>
<string name="error_http_not_found">Nie znaleziono</string>
<string name="error_postprocessing_failed">Przetwarzanie końcowe nie powiodło się</string>
<string name="clear_finished_download">Wyczyść ukończone pobieranie</string>
<string name="msg_pending_downloads">Kontynuuj %s oczekujące transfery z plików do pobrania</string>
<string name="stop">Zatrzymaj</string>
<string name="max_retry_msg">Maksymalna liczba prób</string>
<string name="max_retry_msg">Maksymalna liczba powtórzeń</string>
<string name="max_retry_desc">Maksymalna liczba prób przed anulowaniem pobierania</string>
<string name="pause_downloads_on_mobile">Przerwij przełączanie na dane mobilne</string>
<string name="pause_downloads_on_mobile_desc">Pobierane pliki, których nie można wstrzymać, zostaną ponownie uruchomione</string>
<string name="pause_downloads_on_mobile_desc">Pobierane pliki, których nie można wstrzymać, zostaną zrestartowane</string>
<string name="events">Zdarzenia</string>
<string name="conferences">Konferencje</string>
<string name="missions_header_pending">Oczekuje</string>
</resources>

Some files were not shown because too many files have changed in this diff Show More