SponsorBlock: Merge branch 'dev' into sponsorblock
# Conflicts: # app/src/main/res/values/strings.xml
This commit is contained in:
commit
8e7238cd54
64 changed files with 1809 additions and 1283 deletions
|
@ -13,8 +13,8 @@ android {
|
|||
resValue "string", "app_name", "NewPipe"
|
||||
minSdkVersion 19
|
||||
targetSdkVersion 29
|
||||
versionCode 959
|
||||
versionName "0.20.5"
|
||||
versionCode 960
|
||||
versionName "0.20.6"
|
||||
|
||||
multiDexEnabled true
|
||||
|
||||
|
@ -175,7 +175,7 @@ dependencies {
|
|||
|
||||
// NewPipe dependencies
|
||||
// You can use a local version by uncommenting a few lines in settings.gradle
|
||||
implementation 'com.github.TeamNewPipe:NewPipeExtractor:175df679e05b24b6094570d719cc11f8dfc17c68'
|
||||
implementation 'com.github.TeamNewPipe:NewPipeExtractor:b3835bd616ab28b861c83dcefd56e1754c6d20be'
|
||||
implementation "com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751"
|
||||
|
||||
implementation "org.jsoup:jsoup:1.13.1"
|
||||
|
|
|
@ -51,10 +51,10 @@ public final class CheckForNewAppVersion {
|
|||
private static final String NEWPIPE_API_URL = "https://newpipe.schabi.org/api/data.json";
|
||||
|
||||
/**
|
||||
* Method to get the apk's SHA1 key. See https://stackoverflow.com/questions/9293019/#22506133.
|
||||
* Method to get the APK's SHA1 key. See https://stackoverflow.com/questions/9293019/#22506133.
|
||||
*
|
||||
* @param application The application
|
||||
* @return String with the apk's SHA1 fingeprint in hexadecimal
|
||||
* @return String with the APK's SHA1 fingerprint in hexadecimal
|
||||
*/
|
||||
@NonNull
|
||||
private static String getCertificateSHA1Fingerprint(@NonNull final Application application) {
|
||||
|
|
|
@ -1,10 +1,29 @@
|
|||
package org.schabi.newpipe.ktx
|
||||
|
||||
import java.time.OffsetDateTime
|
||||
import java.time.ZoneId
|
||||
import java.time.ZoneOffset
|
||||
import java.time.temporal.ChronoField
|
||||
import java.util.Calendar
|
||||
import java.util.Date
|
||||
import java.util.GregorianCalendar
|
||||
import java.util.TimeZone
|
||||
|
||||
fun OffsetDateTime.toCalendar(zoneId: ZoneId = ZoneId.systemDefault()): Calendar {
|
||||
return GregorianCalendar.from(if (zoneId != offset) atZoneSameInstant(zoneId) else toZonedDateTime())
|
||||
// This method is a modified version of GregorianCalendar.from(ZonedDateTime).
|
||||
// Math.addExact() and Math.multiplyExact() are desugared even though lint displays a warning.
|
||||
@SuppressWarnings("NewApi")
|
||||
fun OffsetDateTime.toCalendar(): Calendar {
|
||||
val cal = GregorianCalendar(TimeZone.getTimeZone("UTC"))
|
||||
val offsetDateTimeUTC = withOffsetSameInstant(ZoneOffset.UTC)
|
||||
cal.gregorianChange = Date(Long.MIN_VALUE)
|
||||
cal.firstDayOfWeek = Calendar.MONDAY
|
||||
cal.minimalDaysInFirstWeek = 4
|
||||
try {
|
||||
cal.timeInMillis = Math.addExact(
|
||||
Math.multiplyExact(offsetDateTimeUTC.toEpochSecond(), 1000),
|
||||
offsetDateTimeUTC[ChronoField.MILLI_OF_SECOND].toLong()
|
||||
)
|
||||
} catch (ex: ArithmeticException) {
|
||||
throw IllegalArgumentException(ex)
|
||||
}
|
||||
return cal
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ public interface ImportExportEventListener {
|
|||
void onSizeReceived(int size);
|
||||
|
||||
/**
|
||||
* Called everytime an item has been parsed/resolved.
|
||||
* Called every time an item has been parsed/resolved.
|
||||
*
|
||||
* @param itemName the name of the subscription item
|
||||
*/
|
||||
|
|
|
@ -698,7 +698,7 @@ public abstract class BasePlayer implements
|
|||
|
||||
public void onMuteUnmuteButtonClicked() {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onMuteUnmuteButtonClicled() called");
|
||||
Log.d(TAG, "onMuteUnmuteButtonClicked() called");
|
||||
}
|
||||
simpleExoPlayer.setVolume(isMuted() ? 1 : 0);
|
||||
}
|
||||
|
|
|
@ -618,7 +618,7 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
|
|||
progressLiveSync.setClickable(!player.isLiveEdge());
|
||||
}
|
||||
|
||||
// this will make shure progressCurrentTime has the same width as progressEndTime
|
||||
// this will make sure progressCurrentTime has the same width as progressEndTime
|
||||
final ViewGroup.LayoutParams endTimeParams = progressEndTime.getLayoutParams();
|
||||
final ViewGroup.LayoutParams currentTimeParams = progressCurrentTime.getLayoutParams();
|
||||
currentTimeParams.width = progressEndTime.getWidth();
|
||||
|
|
|
@ -26,12 +26,12 @@ public class LoadController implements LoadControl {
|
|||
}
|
||||
|
||||
private LoadController(final int initialPlaybackBufferMs,
|
||||
final int minimumPlaybackbufferMs,
|
||||
final int minimumPlaybackBufferMs,
|
||||
final int optimalPlaybackBufferMs) {
|
||||
this.initialPlaybackBufferUs = initialPlaybackBufferMs * 1000;
|
||||
|
||||
final DefaultLoadControl.Builder builder = new DefaultLoadControl.Builder();
|
||||
builder.setBufferDurationsMs(minimumPlaybackbufferMs, optimalPlaybackBufferMs,
|
||||
builder.setBufferDurationsMs(minimumPlaybackBufferMs, optimalPlaybackBufferMs,
|
||||
initialPlaybackBufferMs, initialPlaybackBufferMs);
|
||||
internalLoadControl = builder.createDefaultLoadControl();
|
||||
}
|
||||
|
|
|
@ -128,9 +128,9 @@ abstract class AbstractInfoPlayQueue<T extends ListInfo, U extends InfoItem> ext
|
|||
fetchReactor = null;
|
||||
}
|
||||
|
||||
private static List<PlayQueueItem> extractListItems(final List<StreamInfoItem> infos) {
|
||||
private static List<PlayQueueItem> extractListItems(final List<StreamInfoItem> infoItems) {
|
||||
final List<PlayQueueItem> result = new ArrayList<>();
|
||||
for (final InfoItem stream : infos) {
|
||||
for (final InfoItem stream : infoItems) {
|
||||
if (stream instanceof StreamInfoItem) {
|
||||
result.add(new PlayQueueItem((StreamInfoItem) stream));
|
||||
}
|
||||
|
|
|
@ -1,416 +1,416 @@
|
|||
package org.schabi.newpipe.streams;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
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.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
/**
|
||||
* @author kapodamy
|
||||
*/
|
||||
public class OggFromWebMWriter implements Closeable {
|
||||
private static final byte FLAG_UNSET = 0x00;
|
||||
//private static final byte FLAG_CONTINUED = 0x01;
|
||||
private static final byte FLAG_FIRST = 0x02;
|
||||
private static final byte FLAG_LAST = 0x04;
|
||||
|
||||
private static final byte HEADER_CHECKSUM_OFFSET = 22;
|
||||
private static final byte HEADER_SIZE = 27;
|
||||
|
||||
private static final int TIME_SCALE_NS = 1000000000;
|
||||
|
||||
private boolean done = false;
|
||||
private boolean parsed = false;
|
||||
|
||||
private final SharpStream source;
|
||||
private final SharpStream output;
|
||||
|
||||
private int sequenceCount = 0;
|
||||
private final int streamId;
|
||||
private byte packetFlag = FLAG_FIRST;
|
||||
|
||||
private WebMReader webm = null;
|
||||
private WebMTrack webmTrack = null;
|
||||
private Segment webmSegment = null;
|
||||
private Cluster webmCluster = null;
|
||||
private SimpleBlock webmBlock = null;
|
||||
|
||||
private long webmBlockLastTimecode = 0;
|
||||
private long webmBlockNearDuration = 0;
|
||||
|
||||
private short segmentTableSize = 0;
|
||||
private final byte[] segmentTable = new byte[255];
|
||||
private long segmentTableNextTimestamp = TIME_SCALE_NS;
|
||||
|
||||
private final int[] crc32Table = new int[256];
|
||||
|
||||
public OggFromWebMWriter(@NonNull final SharpStream source, @NonNull final SharpStream target) {
|
||||
if (!source.canRead() || !source.canRewind()) {
|
||||
throw new IllegalArgumentException("source stream must be readable and allows seeking");
|
||||
}
|
||||
if (!target.canWrite() || !target.canRewind()) {
|
||||
throw new IllegalArgumentException("output stream must be writable and allows seeking");
|
||||
}
|
||||
|
||||
this.source = source;
|
||||
this.output = target;
|
||||
|
||||
this.streamId = (int) System.currentTimeMillis();
|
||||
|
||||
populateCrc32Table();
|
||||
}
|
||||
|
||||
public boolean isDone() {
|
||||
return done;
|
||||
}
|
||||
|
||||
public boolean isParsed() {
|
||||
return parsed;
|
||||
}
|
||||
|
||||
public WebMTrack[] getTracksFromSource() throws IllegalStateException {
|
||||
if (!parsed) {
|
||||
throw new IllegalStateException("source must be parsed first");
|
||||
}
|
||||
|
||||
return webm.getAvailableTracks();
|
||||
}
|
||||
|
||||
public void parseSource() throws IOException, IllegalStateException {
|
||||
if (done) {
|
||||
throw new IllegalStateException("already done");
|
||||
}
|
||||
if (parsed) {
|
||||
throw new IllegalStateException("already parsed");
|
||||
}
|
||||
|
||||
try {
|
||||
webm = new WebMReader(source);
|
||||
webm.parse();
|
||||
webmSegment = webm.getNextSegment();
|
||||
} finally {
|
||||
parsed = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void selectTrack(final int trackIndex) throws IOException {
|
||||
if (!parsed) {
|
||||
throw new IllegalStateException("source must be parsed first");
|
||||
}
|
||||
if (done) {
|
||||
throw new IOException("already done");
|
||||
}
|
||||
if (webmTrack != null) {
|
||||
throw new IOException("tracks already selected");
|
||||
}
|
||||
|
||||
switch (webm.getAvailableTracks()[trackIndex].kind) {
|
||||
case Audio:
|
||||
case Video:
|
||||
break;
|
||||
default:
|
||||
throw new UnsupportedOperationException("the track must an audio or video stream");
|
||||
}
|
||||
|
||||
try {
|
||||
webmTrack = webm.selectTrack(trackIndex);
|
||||
} finally {
|
||||
parsed = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
done = true;
|
||||
parsed = true;
|
||||
|
||||
webmTrack = null;
|
||||
webm = null;
|
||||
|
||||
if (!output.isClosed()) {
|
||||
output.flush();
|
||||
}
|
||||
|
||||
source.close();
|
||||
output.close();
|
||||
}
|
||||
|
||||
public void build() throws IOException {
|
||||
final float resolution;
|
||||
SimpleBlock bloq;
|
||||
final ByteBuffer header = ByteBuffer.allocate(27 + (255 * 255));
|
||||
final ByteBuffer page = ByteBuffer.allocate(64 * 1024);
|
||||
|
||||
header.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
/* step 1: get the amount of frames per seconds */
|
||||
switch (webmTrack.kind) {
|
||||
case Audio:
|
||||
resolution = getSampleFrequencyFromTrack(webmTrack.bMetadata);
|
||||
if (resolution == 0f) {
|
||||
throw new RuntimeException("cannot get the audio sample rate");
|
||||
}
|
||||
break;
|
||||
case Video:
|
||||
// WARNING: untested
|
||||
if (webmTrack.defaultDuration == 0) {
|
||||
throw new RuntimeException("missing default frame time");
|
||||
}
|
||||
resolution = 1000f / ((float) webmTrack.defaultDuration
|
||||
/ webmSegment.info.timecodeScale);
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("not implemented");
|
||||
}
|
||||
|
||||
/* step 2: create packet with code init data */
|
||||
if (webmTrack.codecPrivate != null) {
|
||||
addPacketSegment(webmTrack.codecPrivate.length);
|
||||
makePacketheader(0x00, header, webmTrack.codecPrivate);
|
||||
write(header);
|
||||
output.write(webmTrack.codecPrivate);
|
||||
}
|
||||
|
||||
/* step 3: create packet with metadata */
|
||||
final byte[] buffer = makeMetadata();
|
||||
if (buffer != null) {
|
||||
addPacketSegment(buffer.length);
|
||||
makePacketheader(0x00, header, buffer);
|
||||
write(header);
|
||||
output.write(buffer);
|
||||
}
|
||||
|
||||
/* step 4: calculate amount of packets */
|
||||
while (webmSegment != null) {
|
||||
bloq = getNextBlock();
|
||||
|
||||
if (bloq != null && addPacketSegment(bloq)) {
|
||||
final int pos = page.position();
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
bloq.data.read(page.array(), pos, bloq.dataSize);
|
||||
page.position(pos + bloq.dataSize);
|
||||
continue;
|
||||
}
|
||||
|
||||
// calculate the current packet duration using the next block
|
||||
double elapsedNs = webmTrack.codecDelay;
|
||||
|
||||
if (bloq == null) {
|
||||
packetFlag = FLAG_LAST; // note: if the flag is FLAG_CONTINUED, is changed
|
||||
elapsedNs += webmBlockLastTimecode;
|
||||
|
||||
if (webmTrack.defaultDuration > 0) {
|
||||
elapsedNs += webmTrack.defaultDuration;
|
||||
} else {
|
||||
// hardcoded way, guess the sample duration
|
||||
elapsedNs += webmBlockNearDuration;
|
||||
}
|
||||
} else {
|
||||
elapsedNs += bloq.absoluteTimeCodeNs;
|
||||
}
|
||||
|
||||
// get the sample count in the page
|
||||
elapsedNs = elapsedNs / TIME_SCALE_NS;
|
||||
elapsedNs = Math.ceil(elapsedNs * resolution);
|
||||
|
||||
// create header and calculate page checksum
|
||||
int checksum = makePacketheader((long) elapsedNs, header, null);
|
||||
checksum = calcCrc32(checksum, page.array(), page.position());
|
||||
|
||||
header.putInt(HEADER_CHECKSUM_OFFSET, checksum);
|
||||
|
||||
// dump data
|
||||
write(header);
|
||||
write(page);
|
||||
|
||||
webmBlock = bloq;
|
||||
}
|
||||
}
|
||||
|
||||
private int makePacketheader(final long granPos, @NonNull final ByteBuffer buffer,
|
||||
final byte[] immediatePage) {
|
||||
short length = HEADER_SIZE;
|
||||
|
||||
buffer.putInt(0x5367674f); // "OggS" binary string in little-endian
|
||||
buffer.put((byte) 0x00); // version
|
||||
buffer.put(packetFlag); // type
|
||||
|
||||
buffer.putLong(granPos); // granulate position
|
||||
|
||||
buffer.putInt(streamId); // bitstream serial number
|
||||
buffer.putInt(sequenceCount++); // page sequence number
|
||||
|
||||
buffer.putInt(0x00); // page checksum
|
||||
|
||||
buffer.put((byte) segmentTableSize); // segment table
|
||||
buffer.put(segmentTable, 0, segmentTableSize); // segment size
|
||||
|
||||
length += segmentTableSize;
|
||||
|
||||
clearSegmentTable(); // clear segment table for next header
|
||||
|
||||
int checksumCrc32 = calcCrc32(0x00, buffer.array(), length);
|
||||
|
||||
if (immediatePage != null) {
|
||||
checksumCrc32 = calcCrc32(checksumCrc32, immediatePage, immediatePage.length);
|
||||
buffer.putInt(HEADER_CHECKSUM_OFFSET, checksumCrc32);
|
||||
segmentTableNextTimestamp -= TIME_SCALE_NS;
|
||||
}
|
||||
|
||||
return checksumCrc32;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private byte[] makeMetadata() {
|
||||
if ("A_OPUS".equals(webmTrack.codecId)) {
|
||||
return new byte[]{
|
||||
0x4F, 0x70, 0x75, 0x73, 0x54, 0x61, 0x67, 0x73, // "OpusTags" binary string
|
||||
0x00, 0x00, 0x00, 0x00, // writing application string size (not present)
|
||||
0x00, 0x00, 0x00, 0x00 // additional tags count (zero means no tags)
|
||||
};
|
||||
} else if ("A_VORBIS".equals(webmTrack.codecId)) {
|
||||
return new byte[]{
|
||||
0x03, // ¿¿¿???
|
||||
0x76, 0x6f, 0x72, 0x62, 0x69, 0x73, // "vorbis" binary string
|
||||
0x00, 0x00, 0x00, 0x00, // writing application string size (not present)
|
||||
0x00, 0x00, 0x00, 0x00 // additional tags count (zero means no tags)
|
||||
};
|
||||
}
|
||||
|
||||
// not implemented for the desired codec
|
||||
return null;
|
||||
}
|
||||
|
||||
private void write(final ByteBuffer buffer) throws IOException {
|
||||
output.write(buffer.array(), 0, buffer.position());
|
||||
buffer.position(0);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private SimpleBlock getNextBlock() throws IOException {
|
||||
SimpleBlock res;
|
||||
|
||||
if (webmBlock != null) {
|
||||
res = webmBlock;
|
||||
webmBlock = null;
|
||||
return res;
|
||||
}
|
||||
|
||||
if (webmSegment == null) {
|
||||
webmSegment = webm.getNextSegment();
|
||||
if (webmSegment == null) {
|
||||
return null; // no more blocks in the selected track
|
||||
}
|
||||
}
|
||||
|
||||
if (webmCluster == null) {
|
||||
webmCluster = webmSegment.getNextCluster();
|
||||
if (webmCluster == null) {
|
||||
webmSegment = null;
|
||||
return getNextBlock();
|
||||
}
|
||||
}
|
||||
|
||||
res = webmCluster.getNextSimpleBlock();
|
||||
if (res == null) {
|
||||
webmCluster = null;
|
||||
return getNextBlock();
|
||||
}
|
||||
|
||||
webmBlockNearDuration = res.absoluteTimeCodeNs - webmBlockLastTimecode;
|
||||
webmBlockLastTimecode = res.absoluteTimeCodeNs;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
private float getSampleFrequencyFromTrack(final byte[] bMetadata) {
|
||||
// hardcoded way
|
||||
final ByteBuffer buffer = ByteBuffer.wrap(bMetadata);
|
||||
|
||||
while (buffer.remaining() >= 6) {
|
||||
final int id = buffer.getShort() & 0xFFFF;
|
||||
if (id == 0x0000B584) {
|
||||
return buffer.getFloat();
|
||||
}
|
||||
}
|
||||
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
private void clearSegmentTable() {
|
||||
segmentTableNextTimestamp += TIME_SCALE_NS;
|
||||
packetFlag = FLAG_UNSET;
|
||||
segmentTableSize = 0;
|
||||
}
|
||||
|
||||
private boolean addPacketSegment(final SimpleBlock block) {
|
||||
final long timestamp = block.absoluteTimeCodeNs + webmTrack.codecDelay;
|
||||
|
||||
if (timestamp >= segmentTableNextTimestamp) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return addPacketSegment(block.dataSize);
|
||||
}
|
||||
|
||||
private boolean addPacketSegment(final int size) {
|
||||
if (size > 65025) {
|
||||
throw new UnsupportedOperationException("page size cannot be larger than 65025");
|
||||
}
|
||||
|
||||
int available = (segmentTable.length - segmentTableSize) * 255;
|
||||
final boolean extra = (size % 255) == 0;
|
||||
|
||||
if (extra) {
|
||||
// add a zero byte entry in the table
|
||||
// required to indicate the sample size is multiple of 255
|
||||
available -= 255;
|
||||
}
|
||||
|
||||
// check if possible add the segment, without overflow the table
|
||||
if (available < size) {
|
||||
return false; // not enough space on the page
|
||||
}
|
||||
|
||||
for (int seg = size; seg > 0; seg -= 255) {
|
||||
segmentTable[segmentTableSize++] = (byte) Math.min(seg, 255);
|
||||
}
|
||||
|
||||
if (extra) {
|
||||
segmentTable[segmentTableSize++] = 0x00;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void populateCrc32Table() {
|
||||
for (int i = 0; i < 0x100; i++) {
|
||||
int crc = i << 24;
|
||||
for (int j = 0; j < 8; j++) {
|
||||
final long b = crc >>> 31;
|
||||
crc <<= 1;
|
||||
crc ^= (int) (0x100000000L - b) & 0x04c11db7;
|
||||
}
|
||||
crc32Table[i] = crc;
|
||||
}
|
||||
}
|
||||
|
||||
private int calcCrc32(final int initialCrc, final byte[] buffer, final int size) {
|
||||
int crc = initialCrc;
|
||||
for (int i = 0; i < size; i++) {
|
||||
final int reg = (crc >>> 24) & 0xff;
|
||||
crc = (crc << 8) ^ crc32Table[reg ^ (buffer[i] & 0xff)];
|
||||
}
|
||||
|
||||
return crc;
|
||||
}
|
||||
}
|
||||
package org.schabi.newpipe.streams;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
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.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
/**
|
||||
* @author kapodamy
|
||||
*/
|
||||
public class OggFromWebMWriter implements Closeable {
|
||||
private static final byte FLAG_UNSET = 0x00;
|
||||
//private static final byte FLAG_CONTINUED = 0x01;
|
||||
private static final byte FLAG_FIRST = 0x02;
|
||||
private static final byte FLAG_LAST = 0x04;
|
||||
|
||||
private static final byte HEADER_CHECKSUM_OFFSET = 22;
|
||||
private static final byte HEADER_SIZE = 27;
|
||||
|
||||
private static final int TIME_SCALE_NS = 1000000000;
|
||||
|
||||
private boolean done = false;
|
||||
private boolean parsed = false;
|
||||
|
||||
private final SharpStream source;
|
||||
private final SharpStream output;
|
||||
|
||||
private int sequenceCount = 0;
|
||||
private final int streamId;
|
||||
private byte packetFlag = FLAG_FIRST;
|
||||
|
||||
private WebMReader webm = null;
|
||||
private WebMTrack webmTrack = null;
|
||||
private Segment webmSegment = null;
|
||||
private Cluster webmCluster = null;
|
||||
private SimpleBlock webmBlock = null;
|
||||
|
||||
private long webmBlockLastTimecode = 0;
|
||||
private long webmBlockNearDuration = 0;
|
||||
|
||||
private short segmentTableSize = 0;
|
||||
private final byte[] segmentTable = new byte[255];
|
||||
private long segmentTableNextTimestamp = TIME_SCALE_NS;
|
||||
|
||||
private final int[] crc32Table = new int[256];
|
||||
|
||||
public OggFromWebMWriter(@NonNull final SharpStream source, @NonNull final SharpStream target) {
|
||||
if (!source.canRead() || !source.canRewind()) {
|
||||
throw new IllegalArgumentException("source stream must be readable and allows seeking");
|
||||
}
|
||||
if (!target.canWrite() || !target.canRewind()) {
|
||||
throw new IllegalArgumentException("output stream must be writable and allows seeking");
|
||||
}
|
||||
|
||||
this.source = source;
|
||||
this.output = target;
|
||||
|
||||
this.streamId = (int) System.currentTimeMillis();
|
||||
|
||||
populateCrc32Table();
|
||||
}
|
||||
|
||||
public boolean isDone() {
|
||||
return done;
|
||||
}
|
||||
|
||||
public boolean isParsed() {
|
||||
return parsed;
|
||||
}
|
||||
|
||||
public WebMTrack[] getTracksFromSource() throws IllegalStateException {
|
||||
if (!parsed) {
|
||||
throw new IllegalStateException("source must be parsed first");
|
||||
}
|
||||
|
||||
return webm.getAvailableTracks();
|
||||
}
|
||||
|
||||
public void parseSource() throws IOException, IllegalStateException {
|
||||
if (done) {
|
||||
throw new IllegalStateException("already done");
|
||||
}
|
||||
if (parsed) {
|
||||
throw new IllegalStateException("already parsed");
|
||||
}
|
||||
|
||||
try {
|
||||
webm = new WebMReader(source);
|
||||
webm.parse();
|
||||
webmSegment = webm.getNextSegment();
|
||||
} finally {
|
||||
parsed = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void selectTrack(final int trackIndex) throws IOException {
|
||||
if (!parsed) {
|
||||
throw new IllegalStateException("source must be parsed first");
|
||||
}
|
||||
if (done) {
|
||||
throw new IOException("already done");
|
||||
}
|
||||
if (webmTrack != null) {
|
||||
throw new IOException("tracks already selected");
|
||||
}
|
||||
|
||||
switch (webm.getAvailableTracks()[trackIndex].kind) {
|
||||
case Audio:
|
||||
case Video:
|
||||
break;
|
||||
default:
|
||||
throw new UnsupportedOperationException("the track must an audio or video stream");
|
||||
}
|
||||
|
||||
try {
|
||||
webmTrack = webm.selectTrack(trackIndex);
|
||||
} finally {
|
||||
parsed = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
done = true;
|
||||
parsed = true;
|
||||
|
||||
webmTrack = null;
|
||||
webm = null;
|
||||
|
||||
if (!output.isClosed()) {
|
||||
output.flush();
|
||||
}
|
||||
|
||||
source.close();
|
||||
output.close();
|
||||
}
|
||||
|
||||
public void build() throws IOException {
|
||||
final float resolution;
|
||||
SimpleBlock bloq;
|
||||
final ByteBuffer header = ByteBuffer.allocate(27 + (255 * 255));
|
||||
final ByteBuffer page = ByteBuffer.allocate(64 * 1024);
|
||||
|
||||
header.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
/* step 1: get the amount of frames per seconds */
|
||||
switch (webmTrack.kind) {
|
||||
case Audio:
|
||||
resolution = getSampleFrequencyFromTrack(webmTrack.bMetadata);
|
||||
if (resolution == 0f) {
|
||||
throw new RuntimeException("cannot get the audio sample rate");
|
||||
}
|
||||
break;
|
||||
case Video:
|
||||
// WARNING: untested
|
||||
if (webmTrack.defaultDuration == 0) {
|
||||
throw new RuntimeException("missing default frame time");
|
||||
}
|
||||
resolution = 1000f / ((float) webmTrack.defaultDuration
|
||||
/ webmSegment.info.timecodeScale);
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("not implemented");
|
||||
}
|
||||
|
||||
/* step 2: create packet with code init data */
|
||||
if (webmTrack.codecPrivate != null) {
|
||||
addPacketSegment(webmTrack.codecPrivate.length);
|
||||
makePacketheader(0x00, header, webmTrack.codecPrivate);
|
||||
write(header);
|
||||
output.write(webmTrack.codecPrivate);
|
||||
}
|
||||
|
||||
/* step 3: create packet with metadata */
|
||||
final byte[] buffer = makeMetadata();
|
||||
if (buffer != null) {
|
||||
addPacketSegment(buffer.length);
|
||||
makePacketheader(0x00, header, buffer);
|
||||
write(header);
|
||||
output.write(buffer);
|
||||
}
|
||||
|
||||
/* step 4: calculate amount of packets */
|
||||
while (webmSegment != null) {
|
||||
bloq = getNextBlock();
|
||||
|
||||
if (bloq != null && addPacketSegment(bloq)) {
|
||||
final int pos = page.position();
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
bloq.data.read(page.array(), pos, bloq.dataSize);
|
||||
page.position(pos + bloq.dataSize);
|
||||
continue;
|
||||
}
|
||||
|
||||
// calculate the current packet duration using the next block
|
||||
double elapsedNs = webmTrack.codecDelay;
|
||||
|
||||
if (bloq == null) {
|
||||
packetFlag = FLAG_LAST; // note: if the flag is FLAG_CONTINUED, is changed
|
||||
elapsedNs += webmBlockLastTimecode;
|
||||
|
||||
if (webmTrack.defaultDuration > 0) {
|
||||
elapsedNs += webmTrack.defaultDuration;
|
||||
} else {
|
||||
// hardcoded way, guess the sample duration
|
||||
elapsedNs += webmBlockNearDuration;
|
||||
}
|
||||
} else {
|
||||
elapsedNs += bloq.absoluteTimeCodeNs;
|
||||
}
|
||||
|
||||
// get the sample count in the page
|
||||
elapsedNs = elapsedNs / TIME_SCALE_NS;
|
||||
elapsedNs = Math.ceil(elapsedNs * resolution);
|
||||
|
||||
// create header and calculate page checksum
|
||||
int checksum = makePacketheader((long) elapsedNs, header, null);
|
||||
checksum = calcCrc32(checksum, page.array(), page.position());
|
||||
|
||||
header.putInt(HEADER_CHECKSUM_OFFSET, checksum);
|
||||
|
||||
// dump data
|
||||
write(header);
|
||||
write(page);
|
||||
|
||||
webmBlock = bloq;
|
||||
}
|
||||
}
|
||||
|
||||
private int makePacketheader(final long granPos, @NonNull final ByteBuffer buffer,
|
||||
final byte[] immediatePage) {
|
||||
short length = HEADER_SIZE;
|
||||
|
||||
buffer.putInt(0x5367674f); // "OggS" binary string in little-endian
|
||||
buffer.put((byte) 0x00); // version
|
||||
buffer.put(packetFlag); // type
|
||||
|
||||
buffer.putLong(granPos); // granulate position
|
||||
|
||||
buffer.putInt(streamId); // bitstream serial number
|
||||
buffer.putInt(sequenceCount++); // page sequence number
|
||||
|
||||
buffer.putInt(0x00); // page checksum
|
||||
|
||||
buffer.put((byte) segmentTableSize); // segment table
|
||||
buffer.put(segmentTable, 0, segmentTableSize); // segment size
|
||||
|
||||
length += segmentTableSize;
|
||||
|
||||
clearSegmentTable(); // clear segment table for next header
|
||||
|
||||
int checksumCrc32 = calcCrc32(0x00, buffer.array(), length);
|
||||
|
||||
if (immediatePage != null) {
|
||||
checksumCrc32 = calcCrc32(checksumCrc32, immediatePage, immediatePage.length);
|
||||
buffer.putInt(HEADER_CHECKSUM_OFFSET, checksumCrc32);
|
||||
segmentTableNextTimestamp -= TIME_SCALE_NS;
|
||||
}
|
||||
|
||||
return checksumCrc32;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private byte[] makeMetadata() {
|
||||
if ("A_OPUS".equals(webmTrack.codecId)) {
|
||||
return new byte[]{
|
||||
0x4F, 0x70, 0x75, 0x73, 0x54, 0x61, 0x67, 0x73, // "OpusTags" binary string
|
||||
0x00, 0x00, 0x00, 0x00, // writing application string size (not present)
|
||||
0x00, 0x00, 0x00, 0x00 // additional tags count (zero means no tags)
|
||||
};
|
||||
} else if ("A_VORBIS".equals(webmTrack.codecId)) {
|
||||
return new byte[]{
|
||||
0x03, // ¿¿¿???
|
||||
0x76, 0x6f, 0x72, 0x62, 0x69, 0x73, // "vorbis" binary string
|
||||
0x00, 0x00, 0x00, 0x00, // writing application string size (not present)
|
||||
0x00, 0x00, 0x00, 0x00 // additional tags count (zero means no tags)
|
||||
};
|
||||
}
|
||||
|
||||
// not implemented for the desired codec
|
||||
return null;
|
||||
}
|
||||
|
||||
private void write(final ByteBuffer buffer) throws IOException {
|
||||
output.write(buffer.array(), 0, buffer.position());
|
||||
buffer.position(0);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private SimpleBlock getNextBlock() throws IOException {
|
||||
SimpleBlock res;
|
||||
|
||||
if (webmBlock != null) {
|
||||
res = webmBlock;
|
||||
webmBlock = null;
|
||||
return res;
|
||||
}
|
||||
|
||||
if (webmSegment == null) {
|
||||
webmSegment = webm.getNextSegment();
|
||||
if (webmSegment == null) {
|
||||
return null; // no more blocks in the selected track
|
||||
}
|
||||
}
|
||||
|
||||
if (webmCluster == null) {
|
||||
webmCluster = webmSegment.getNextCluster();
|
||||
if (webmCluster == null) {
|
||||
webmSegment = null;
|
||||
return getNextBlock();
|
||||
}
|
||||
}
|
||||
|
||||
res = webmCluster.getNextSimpleBlock();
|
||||
if (res == null) {
|
||||
webmCluster = null;
|
||||
return getNextBlock();
|
||||
}
|
||||
|
||||
webmBlockNearDuration = res.absoluteTimeCodeNs - webmBlockLastTimecode;
|
||||
webmBlockLastTimecode = res.absoluteTimeCodeNs;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
private float getSampleFrequencyFromTrack(final byte[] bMetadata) {
|
||||
// hardcoded way
|
||||
final ByteBuffer buffer = ByteBuffer.wrap(bMetadata);
|
||||
|
||||
while (buffer.remaining() >= 6) {
|
||||
final int id = buffer.getShort() & 0xFFFF;
|
||||
if (id == 0x0000B584) {
|
||||
return buffer.getFloat();
|
||||
}
|
||||
}
|
||||
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
private void clearSegmentTable() {
|
||||
segmentTableNextTimestamp += TIME_SCALE_NS;
|
||||
packetFlag = FLAG_UNSET;
|
||||
segmentTableSize = 0;
|
||||
}
|
||||
|
||||
private boolean addPacketSegment(final SimpleBlock block) {
|
||||
final long timestamp = block.absoluteTimeCodeNs + webmTrack.codecDelay;
|
||||
|
||||
if (timestamp >= segmentTableNextTimestamp) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return addPacketSegment(block.dataSize);
|
||||
}
|
||||
|
||||
private boolean addPacketSegment(final int size) {
|
||||
if (size > 65025) {
|
||||
throw new UnsupportedOperationException("page size cannot be larger than 65025");
|
||||
}
|
||||
|
||||
int available = (segmentTable.length - segmentTableSize) * 255;
|
||||
final boolean extra = (size % 255) == 0;
|
||||
|
||||
if (extra) {
|
||||
// add a zero byte entry in the table
|
||||
// required to indicate the sample size is multiple of 255
|
||||
available -= 255;
|
||||
}
|
||||
|
||||
// check if possible add the segment, without overflow the table
|
||||
if (available < size) {
|
||||
return false; // not enough space on the page
|
||||
}
|
||||
|
||||
for (int seg = size; seg > 0; seg -= 255) {
|
||||
segmentTable[segmentTableSize++] = (byte) Math.min(seg, 255);
|
||||
}
|
||||
|
||||
if (extra) {
|
||||
segmentTable[segmentTableSize++] = 0x00;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void populateCrc32Table() {
|
||||
for (int i = 0; i < 0x100; i++) {
|
||||
int crc = i << 24;
|
||||
for (int j = 0; j < 8; j++) {
|
||||
final long b = crc >>> 31;
|
||||
crc <<= 1;
|
||||
crc ^= (int) (0x100000000L - b) & 0x04c11db7;
|
||||
}
|
||||
crc32Table[i] = crc;
|
||||
}
|
||||
}
|
||||
|
||||
private int calcCrc32(final int initialCrc, final byte[] buffer, final int size) {
|
||||
int crc = initialCrc;
|
||||
for (int i = 0; i < size; i++) {
|
||||
final int reg = (crc >>> 24) & 0xff;
|
||||
crc = (crc << 8) ^ crc32Table[reg ^ (buffer[i] & 0xff)];
|
||||
}
|
||||
|
||||
return crc;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import android.content.Context;
|
|||
import org.schabi.newpipe.R;
|
||||
|
||||
/**
|
||||
* Created by Chrsitian Schabesberger on 28.09.17.
|
||||
* Created by Christian Schabesberger on 28.09.17.
|
||||
* KioskTranslator.java is part of NewPipe.
|
||||
* <p>
|
||||
* NewPipe is free software: you can redistribute it and/or modify
|
||||
|
|
|
@ -141,7 +141,7 @@ public final class ListHelper {
|
|||
final SharedPreferences preferences
|
||||
= PreferenceManager.getDefaultSharedPreferences(context);
|
||||
|
||||
// Load the prefered resolution otherwise the best available
|
||||
// Load the preferred resolution otherwise the best available
|
||||
String resolution = preferences != null
|
||||
? preferences.getString(context.getString(key), context.getString(value))
|
||||
: context.getString(R.string.best_resolution_key);
|
||||
|
@ -161,7 +161,7 @@ public final class ListHelper {
|
|||
*
|
||||
* @param defaultResolution the default resolution to look for
|
||||
* @param bestResolutionKey key of the best resolution
|
||||
* @param defaultFormat the default fomat to look for
|
||||
* @param defaultFormat the default format to look for
|
||||
* @param videoStreams list of the video streams to check
|
||||
* @return index of the default resolution&format
|
||||
*/
|
||||
|
@ -351,7 +351,7 @@ public final class ListHelper {
|
|||
* @param targetResolution the resolution to look for
|
||||
* @param targetFormat the format to look for
|
||||
* @param videoStreams the available video streams
|
||||
* @return the index of the prefered video stream
|
||||
* @return the index of the preferred video stream
|
||||
*/
|
||||
static int getVideoStreamIndex(final String targetResolution, final MediaFormat targetFormat,
|
||||
final List<VideoStream> videoStreams) {
|
||||
|
@ -413,7 +413,7 @@ public final class ListHelper {
|
|||
* @param context Android app context
|
||||
* @param defaultResolution the default resolution
|
||||
* @param videoStreams the list of video streams to check
|
||||
* @return the index of the prefered video stream
|
||||
* @return the index of the preferred video stream
|
||||
*/
|
||||
private static int getDefaultResolutionWithDefaultFormat(final Context context,
|
||||
final String defaultResolution,
|
||||
|
|
|
@ -20,6 +20,7 @@ import org.ocpsoft.prettytime.units.Decade;
|
|||
import org.schabi.newpipe.R;
|
||||
import org.schabi.newpipe.extractor.ListExtractor;
|
||||
import org.schabi.newpipe.extractor.localization.ContentCountry;
|
||||
import org.schabi.newpipe.ktx.OffsetDateTimeKt;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
|
@ -30,7 +31,6 @@ import java.time.format.DateTimeFormatter;
|
|||
import java.time.format.FormatStyle;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
|
@ -314,7 +314,7 @@ public final class Localization {
|
|||
}
|
||||
|
||||
public static String relativeTime(final OffsetDateTime offsetDateTime) {
|
||||
return relativeTime(GregorianCalendar.from(offsetDateTime.toZonedDateTime()));
|
||||
return relativeTime(OffsetDateTimeKt.toCalendar(offsetDateTime));
|
||||
}
|
||||
|
||||
public static String relativeTime(final Calendar calendarTime) {
|
||||
|
|
|
@ -1,313 +1,313 @@
|
|||
package us.shandian.giga.get;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import org.schabi.newpipe.extractor.NewPipe;
|
||||
import org.schabi.newpipe.extractor.StreamingService;
|
||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
import org.schabi.newpipe.extractor.stream.AudioStream;
|
||||
import org.schabi.newpipe.extractor.stream.StreamExtractor;
|
||||
import org.schabi.newpipe.extractor.stream.SubtitlesStream;
|
||||
import org.schabi.newpipe.extractor.stream.VideoStream;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.nio.channels.ClosedByInterruptException;
|
||||
import java.util.List;
|
||||
|
||||
import us.shandian.giga.get.DownloadMission.HttpError;
|
||||
|
||||
import static us.shandian.giga.get.DownloadMission.ERROR_RESOURCE_GONE;
|
||||
|
||||
public class DownloadMissionRecover extends Thread {
|
||||
private static final String TAG = "DownloadMissionRecover";
|
||||
static final int mID = -3;
|
||||
|
||||
private final DownloadMission mMission;
|
||||
private final boolean mNotInitialized;
|
||||
|
||||
private final int mErrCode;
|
||||
|
||||
private HttpURLConnection mConn;
|
||||
private MissionRecoveryInfo mRecovery;
|
||||
private StreamExtractor mExtractor;
|
||||
|
||||
DownloadMissionRecover(DownloadMission mission, int errCode) {
|
||||
mMission = mission;
|
||||
mNotInitialized = mission.blocks == null && mission.current == 0;
|
||||
mErrCode = errCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (mMission.source == null) {
|
||||
mMission.notifyError(mErrCode, null);
|
||||
return;
|
||||
}
|
||||
|
||||
Exception err = null;
|
||||
int attempt = 0;
|
||||
|
||||
while (attempt++ < mMission.maxRetry) {
|
||||
try {
|
||||
tryRecover();
|
||||
return;
|
||||
} catch (InterruptedIOException | ClosedByInterruptException e) {
|
||||
return;
|
||||
} catch (Exception e) {
|
||||
if (!mMission.running || super.isInterrupted()) return;
|
||||
err = e;
|
||||
}
|
||||
}
|
||||
|
||||
// give up
|
||||
mMission.notifyError(mErrCode, err);
|
||||
}
|
||||
|
||||
private void tryRecover() throws ExtractionException, IOException, HttpError {
|
||||
if (mExtractor == null) {
|
||||
try {
|
||||
StreamingService svr = NewPipe.getServiceByUrl(mMission.source);
|
||||
mExtractor = svr.getStreamExtractor(mMission.source);
|
||||
mExtractor.fetchPage();
|
||||
} catch (ExtractionException e) {
|
||||
mExtractor = null;
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
// maybe the following check is redundant
|
||||
if (!mMission.running || super.isInterrupted()) return;
|
||||
|
||||
if (!mNotInitialized) {
|
||||
// set the current download url to null in case if the recovery
|
||||
// process is canceled. Next time start() method is called the
|
||||
// recovery will be executed, saving time
|
||||
mMission.urls[mMission.current] = null;
|
||||
|
||||
mRecovery = mMission.recoveryInfo[mMission.current];
|
||||
resolveStream();
|
||||
return;
|
||||
}
|
||||
|
||||
Log.w(TAG, "mission is not fully initialized, this will take a while");
|
||||
|
||||
try {
|
||||
for (; mMission.current < mMission.urls.length; mMission.current++) {
|
||||
mRecovery = mMission.recoveryInfo[mMission.current];
|
||||
|
||||
if (test()) continue;
|
||||
if (!mMission.running) return;
|
||||
|
||||
resolveStream();
|
||||
if (!mMission.running) return;
|
||||
|
||||
// before continue, check if the current stream was resolved
|
||||
if (mMission.urls[mMission.current] == null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
mMission.current = 0;
|
||||
}
|
||||
|
||||
mMission.writeThisToFile();
|
||||
|
||||
if (!mMission.running || super.isInterrupted()) return;
|
||||
|
||||
mMission.running = false;
|
||||
mMission.start();
|
||||
}
|
||||
|
||||
private void resolveStream() throws IOException, ExtractionException, HttpError {
|
||||
// FIXME: this getErrorMessage() always returns "video is unavailable"
|
||||
/*if (mExtractor.getErrorMessage() != null) {
|
||||
mMission.notifyError(mErrCode, new ExtractionException(mExtractor.getErrorMessage()));
|
||||
return;
|
||||
}*/
|
||||
|
||||
String url = null;
|
||||
|
||||
switch (mRecovery.getKind()) {
|
||||
case 'a':
|
||||
for (AudioStream audio : mExtractor.getAudioStreams()) {
|
||||
if (audio.average_bitrate == mRecovery.getDesiredBitrate() && audio.getFormat() == mRecovery.getFormat()) {
|
||||
url = audio.getUrl();
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'v':
|
||||
List<VideoStream> videoStreams;
|
||||
if (mRecovery.isDesired2())
|
||||
videoStreams = mExtractor.getVideoOnlyStreams();
|
||||
else
|
||||
videoStreams = mExtractor.getVideoStreams();
|
||||
for (VideoStream video : videoStreams) {
|
||||
if (video.resolution.equals(mRecovery.getDesired()) && video.getFormat() == mRecovery.getFormat()) {
|
||||
url = video.getUrl();
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
for (SubtitlesStream subtitles : mExtractor.getSubtitles(mRecovery.getFormat())) {
|
||||
String tag = subtitles.getLanguageTag();
|
||||
if (tag.equals(mRecovery.getDesired()) && subtitles.isAutoGenerated() == mRecovery.isDesired2()) {
|
||||
url = subtitles.getUrl();
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("Unknown stream type");
|
||||
}
|
||||
|
||||
resolve(url);
|
||||
}
|
||||
|
||||
private void resolve(String url) throws IOException, HttpError {
|
||||
if (mRecovery.getValidateCondition() == null) {
|
||||
Log.w(TAG, "validation condition not defined, the resource can be stale");
|
||||
}
|
||||
|
||||
if (mMission.unknownLength || mRecovery.getValidateCondition() == null) {
|
||||
recover(url, false);
|
||||
return;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
////// Validate the http resource doing a range request
|
||||
/////////////////////
|
||||
try {
|
||||
mConn = mMission.openConnection(url, true, mMission.length - 10, mMission.length);
|
||||
mConn.setRequestProperty("If-Range", mRecovery.getValidateCondition());
|
||||
mMission.establishConnection(mID, mConn);
|
||||
|
||||
int code = mConn.getResponseCode();
|
||||
|
||||
switch (code) {
|
||||
case 200:
|
||||
case 413:
|
||||
// stale
|
||||
recover(url, true);
|
||||
return;
|
||||
case 206:
|
||||
// in case of validation using the Last-Modified date, check the resource length
|
||||
long[] contentRange = parseContentRange(mConn.getHeaderField("Content-Range"));
|
||||
boolean lengthMismatch = contentRange[2] != -1 && contentRange[2] != mMission.length;
|
||||
|
||||
recover(url, lengthMismatch);
|
||||
return;
|
||||
}
|
||||
|
||||
throw new HttpError(code);
|
||||
} finally {
|
||||
disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
private void recover(String url, boolean stale) {
|
||||
Log.i(TAG,
|
||||
String.format("recover() name=%s isStale=%s url=%s", mMission.storage.getName(), stale, url)
|
||||
);
|
||||
|
||||
mMission.urls[mMission.current] = url;
|
||||
|
||||
if (url == null) {
|
||||
mMission.urls = new String[0];
|
||||
mMission.notifyError(ERROR_RESOURCE_GONE, null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mNotInitialized) return;
|
||||
|
||||
if (stale) {
|
||||
mMission.resetState(false, false, DownloadMission.ERROR_NOTHING);
|
||||
}
|
||||
|
||||
mMission.writeThisToFile();
|
||||
|
||||
if (!mMission.running || super.isInterrupted()) return;
|
||||
|
||||
mMission.running = false;
|
||||
mMission.start();
|
||||
}
|
||||
|
||||
private long[] parseContentRange(String value) {
|
||||
long[] range = new long[3];
|
||||
|
||||
if (value == null) {
|
||||
// this never should happen
|
||||
return range;
|
||||
}
|
||||
|
||||
try {
|
||||
value = value.trim();
|
||||
|
||||
if (!value.startsWith("bytes")) {
|
||||
return range;// unknown range type
|
||||
}
|
||||
|
||||
int space = value.lastIndexOf(' ') + 1;
|
||||
int dash = value.indexOf('-', space) + 1;
|
||||
int bar = value.indexOf('/', dash);
|
||||
|
||||
// start
|
||||
range[0] = Long.parseLong(value.substring(space, dash - 1));
|
||||
|
||||
// end
|
||||
range[1] = Long.parseLong(value.substring(dash, bar));
|
||||
|
||||
// resource length
|
||||
value = value.substring(bar + 1);
|
||||
if (value.equals("*")) {
|
||||
range[2] = -1;// unknown length received from the server but should be valid
|
||||
} else {
|
||||
range[2] = Long.parseLong(value);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
return range;
|
||||
}
|
||||
|
||||
private boolean test() {
|
||||
if (mMission.urls[mMission.current] == null) return false;
|
||||
|
||||
try {
|
||||
mConn = mMission.openConnection(mMission.urls[mMission.current], true, -1, -1);
|
||||
mMission.establishConnection(mID, mConn);
|
||||
|
||||
if (mConn.getResponseCode() == 200) return true;
|
||||
} catch (Exception e) {
|
||||
// nothing to do
|
||||
} finally {
|
||||
disconnect();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void disconnect() {
|
||||
try {
|
||||
try {
|
||||
mConn.getInputStream().close();
|
||||
} finally {
|
||||
mConn.disconnect();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// nothing to do
|
||||
} finally {
|
||||
mConn = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void interrupt() {
|
||||
super.interrupt();
|
||||
if (mConn != null) disconnect();
|
||||
}
|
||||
}
|
||||
package us.shandian.giga.get;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import org.schabi.newpipe.extractor.NewPipe;
|
||||
import org.schabi.newpipe.extractor.StreamingService;
|
||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
import org.schabi.newpipe.extractor.stream.AudioStream;
|
||||
import org.schabi.newpipe.extractor.stream.StreamExtractor;
|
||||
import org.schabi.newpipe.extractor.stream.SubtitlesStream;
|
||||
import org.schabi.newpipe.extractor.stream.VideoStream;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.nio.channels.ClosedByInterruptException;
|
||||
import java.util.List;
|
||||
|
||||
import us.shandian.giga.get.DownloadMission.HttpError;
|
||||
|
||||
import static us.shandian.giga.get.DownloadMission.ERROR_RESOURCE_GONE;
|
||||
|
||||
public class DownloadMissionRecover extends Thread {
|
||||
private static final String TAG = "DownloadMissionRecover";
|
||||
static final int mID = -3;
|
||||
|
||||
private final DownloadMission mMission;
|
||||
private final boolean mNotInitialized;
|
||||
|
||||
private final int mErrCode;
|
||||
|
||||
private HttpURLConnection mConn;
|
||||
private MissionRecoveryInfo mRecovery;
|
||||
private StreamExtractor mExtractor;
|
||||
|
||||
DownloadMissionRecover(DownloadMission mission, int errCode) {
|
||||
mMission = mission;
|
||||
mNotInitialized = mission.blocks == null && mission.current == 0;
|
||||
mErrCode = errCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (mMission.source == null) {
|
||||
mMission.notifyError(mErrCode, null);
|
||||
return;
|
||||
}
|
||||
|
||||
Exception err = null;
|
||||
int attempt = 0;
|
||||
|
||||
while (attempt++ < mMission.maxRetry) {
|
||||
try {
|
||||
tryRecover();
|
||||
return;
|
||||
} catch (InterruptedIOException | ClosedByInterruptException e) {
|
||||
return;
|
||||
} catch (Exception e) {
|
||||
if (!mMission.running || super.isInterrupted()) return;
|
||||
err = e;
|
||||
}
|
||||
}
|
||||
|
||||
// give up
|
||||
mMission.notifyError(mErrCode, err);
|
||||
}
|
||||
|
||||
private void tryRecover() throws ExtractionException, IOException, HttpError {
|
||||
if (mExtractor == null) {
|
||||
try {
|
||||
StreamingService svr = NewPipe.getServiceByUrl(mMission.source);
|
||||
mExtractor = svr.getStreamExtractor(mMission.source);
|
||||
mExtractor.fetchPage();
|
||||
} catch (ExtractionException e) {
|
||||
mExtractor = null;
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
// maybe the following check is redundant
|
||||
if (!mMission.running || super.isInterrupted()) return;
|
||||
|
||||
if (!mNotInitialized) {
|
||||
// set the current download url to null in case if the recovery
|
||||
// process is canceled. Next time start() method is called the
|
||||
// recovery will be executed, saving time
|
||||
mMission.urls[mMission.current] = null;
|
||||
|
||||
mRecovery = mMission.recoveryInfo[mMission.current];
|
||||
resolveStream();
|
||||
return;
|
||||
}
|
||||
|
||||
Log.w(TAG, "mission is not fully initialized, this will take a while");
|
||||
|
||||
try {
|
||||
for (; mMission.current < mMission.urls.length; mMission.current++) {
|
||||
mRecovery = mMission.recoveryInfo[mMission.current];
|
||||
|
||||
if (test()) continue;
|
||||
if (!mMission.running) return;
|
||||
|
||||
resolveStream();
|
||||
if (!mMission.running) return;
|
||||
|
||||
// before continue, check if the current stream was resolved
|
||||
if (mMission.urls[mMission.current] == null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
mMission.current = 0;
|
||||
}
|
||||
|
||||
mMission.writeThisToFile();
|
||||
|
||||
if (!mMission.running || super.isInterrupted()) return;
|
||||
|
||||
mMission.running = false;
|
||||
mMission.start();
|
||||
}
|
||||
|
||||
private void resolveStream() throws IOException, ExtractionException, HttpError {
|
||||
// FIXME: this getErrorMessage() always returns "video is unavailable"
|
||||
/*if (mExtractor.getErrorMessage() != null) {
|
||||
mMission.notifyError(mErrCode, new ExtractionException(mExtractor.getErrorMessage()));
|
||||
return;
|
||||
}*/
|
||||
|
||||
String url = null;
|
||||
|
||||
switch (mRecovery.getKind()) {
|
||||
case 'a':
|
||||
for (AudioStream audio : mExtractor.getAudioStreams()) {
|
||||
if (audio.average_bitrate == mRecovery.getDesiredBitrate() && audio.getFormat() == mRecovery.getFormat()) {
|
||||
url = audio.getUrl();
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'v':
|
||||
List<VideoStream> videoStreams;
|
||||
if (mRecovery.isDesired2())
|
||||
videoStreams = mExtractor.getVideoOnlyStreams();
|
||||
else
|
||||
videoStreams = mExtractor.getVideoStreams();
|
||||
for (VideoStream video : videoStreams) {
|
||||
if (video.resolution.equals(mRecovery.getDesired()) && video.getFormat() == mRecovery.getFormat()) {
|
||||
url = video.getUrl();
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
for (SubtitlesStream subtitles : mExtractor.getSubtitles(mRecovery.getFormat())) {
|
||||
String tag = subtitles.getLanguageTag();
|
||||
if (tag.equals(mRecovery.getDesired()) && subtitles.isAutoGenerated() == mRecovery.isDesired2()) {
|
||||
url = subtitles.getUrl();
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("Unknown stream type");
|
||||
}
|
||||
|
||||
resolve(url);
|
||||
}
|
||||
|
||||
private void resolve(String url) throws IOException, HttpError {
|
||||
if (mRecovery.getValidateCondition() == null) {
|
||||
Log.w(TAG, "validation condition not defined, the resource can be stale");
|
||||
}
|
||||
|
||||
if (mMission.unknownLength || mRecovery.getValidateCondition() == null) {
|
||||
recover(url, false);
|
||||
return;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
////// Validate the http resource doing a range request
|
||||
/////////////////////
|
||||
try {
|
||||
mConn = mMission.openConnection(url, true, mMission.length - 10, mMission.length);
|
||||
mConn.setRequestProperty("If-Range", mRecovery.getValidateCondition());
|
||||
mMission.establishConnection(mID, mConn);
|
||||
|
||||
int code = mConn.getResponseCode();
|
||||
|
||||
switch (code) {
|
||||
case 200:
|
||||
case 413:
|
||||
// stale
|
||||
recover(url, true);
|
||||
return;
|
||||
case 206:
|
||||
// in case of validation using the Last-Modified date, check the resource length
|
||||
long[] contentRange = parseContentRange(mConn.getHeaderField("Content-Range"));
|
||||
boolean lengthMismatch = contentRange[2] != -1 && contentRange[2] != mMission.length;
|
||||
|
||||
recover(url, lengthMismatch);
|
||||
return;
|
||||
}
|
||||
|
||||
throw new HttpError(code);
|
||||
} finally {
|
||||
disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
private void recover(String url, boolean stale) {
|
||||
Log.i(TAG,
|
||||
String.format("recover() name=%s isStale=%s url=%s", mMission.storage.getName(), stale, url)
|
||||
);
|
||||
|
||||
mMission.urls[mMission.current] = url;
|
||||
|
||||
if (url == null) {
|
||||
mMission.urls = new String[0];
|
||||
mMission.notifyError(ERROR_RESOURCE_GONE, null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mNotInitialized) return;
|
||||
|
||||
if (stale) {
|
||||
mMission.resetState(false, false, DownloadMission.ERROR_NOTHING);
|
||||
}
|
||||
|
||||
mMission.writeThisToFile();
|
||||
|
||||
if (!mMission.running || super.isInterrupted()) return;
|
||||
|
||||
mMission.running = false;
|
||||
mMission.start();
|
||||
}
|
||||
|
||||
private long[] parseContentRange(String value) {
|
||||
long[] range = new long[3];
|
||||
|
||||
if (value == null) {
|
||||
// this never should happen
|
||||
return range;
|
||||
}
|
||||
|
||||
try {
|
||||
value = value.trim();
|
||||
|
||||
if (!value.startsWith("bytes")) {
|
||||
return range;// unknown range type
|
||||
}
|
||||
|
||||
int space = value.lastIndexOf(' ') + 1;
|
||||
int dash = value.indexOf('-', space) + 1;
|
||||
int bar = value.indexOf('/', dash);
|
||||
|
||||
// start
|
||||
range[0] = Long.parseLong(value.substring(space, dash - 1));
|
||||
|
||||
// end
|
||||
range[1] = Long.parseLong(value.substring(dash, bar));
|
||||
|
||||
// resource length
|
||||
value = value.substring(bar + 1);
|
||||
if (value.equals("*")) {
|
||||
range[2] = -1;// unknown length received from the server but should be valid
|
||||
} else {
|
||||
range[2] = Long.parseLong(value);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
return range;
|
||||
}
|
||||
|
||||
private boolean test() {
|
||||
if (mMission.urls[mMission.current] == null) return false;
|
||||
|
||||
try {
|
||||
mConn = mMission.openConnection(mMission.urls[mMission.current], true, -1, -1);
|
||||
mMission.establishConnection(mID, mConn);
|
||||
|
||||
if (mConn.getResponseCode() == 200) return true;
|
||||
} catch (Exception e) {
|
||||
// nothing to do
|
||||
} finally {
|
||||
disconnect();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void disconnect() {
|
||||
try {
|
||||
try {
|
||||
mConn.getInputStream().close();
|
||||
} finally {
|
||||
mConn.disconnect();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// nothing to do
|
||||
} finally {
|
||||
mConn = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void interrupt() {
|
||||
super.interrupt();
|
||||
if (mConn != null) disconnect();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ import static us.shandian.giga.get.DownloadMission.ERROR_HTTP_FORBIDDEN;
|
|||
* Single-threaded fallback mode
|
||||
*/
|
||||
public class DownloadRunnableFallback extends Thread {
|
||||
private static final String TAG = "DownloadRunnableFallbac";
|
||||
private static final String TAG = "DownloadRunnableFallback";
|
||||
|
||||
private final DownloadMission mMission;
|
||||
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
package us.shandian.giga.get;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
public class FinishedMission extends Mission {
|
||||
|
||||
public FinishedMission() {
|
||||
}
|
||||
|
||||
public FinishedMission(@NonNull DownloadMission mission) {
|
||||
source = mission.source;
|
||||
length = mission.length;
|
||||
timestamp = mission.timestamp;
|
||||
kind = mission.kind;
|
||||
storage = mission.storage;
|
||||
}
|
||||
|
||||
}
|
||||
package us.shandian.giga.get;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
public class FinishedMission extends Mission {
|
||||
|
||||
public FinishedMission() {
|
||||
}
|
||||
|
||||
public FinishedMission(@NonNull DownloadMission mission) {
|
||||
source = mission.source;
|
||||
length = mission.length;
|
||||
timestamp = mission.timestamp;
|
||||
kind = mission.kind;
|
||||
storage = mission.storage;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,64 +1,64 @@
|
|||
package us.shandian.giga.get;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Calendar;
|
||||
|
||||
import us.shandian.giga.io.StoredFileHelper;
|
||||
|
||||
public abstract class Mission implements Serializable {
|
||||
private static final long serialVersionUID = 1L;// last bump: 27 march 2019
|
||||
|
||||
/**
|
||||
* Source url of the resource
|
||||
*/
|
||||
public String source;
|
||||
|
||||
/**
|
||||
* Length of the current resource
|
||||
*/
|
||||
public long length;
|
||||
|
||||
/**
|
||||
* creation timestamp (and maybe unique identifier)
|
||||
*/
|
||||
public long timestamp;
|
||||
|
||||
/**
|
||||
* pre-defined content type
|
||||
*/
|
||||
public char kind;
|
||||
|
||||
/**
|
||||
* The downloaded file
|
||||
*/
|
||||
public StoredFileHelper storage;
|
||||
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the downloaded file
|
||||
*
|
||||
* @return {@code true] if and only if the file is successfully deleted, otherwise, {@code false}
|
||||
*/
|
||||
public boolean delete() {
|
||||
if (storage != null) return storage.delete();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate if this mission is deleted whatever is stored
|
||||
*/
|
||||
public transient boolean deleted = false;
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTimeInMillis(timestamp);
|
||||
return "[" + calendar.getTime().toString() + "] " + (storage.isInvalid() ? storage.getName() : storage.getUri());
|
||||
}
|
||||
}
|
||||
package us.shandian.giga.get;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Calendar;
|
||||
|
||||
import us.shandian.giga.io.StoredFileHelper;
|
||||
|
||||
public abstract class Mission implements Serializable {
|
||||
private static final long serialVersionUID = 1L;// last bump: 27 march 2019
|
||||
|
||||
/**
|
||||
* Source url of the resource
|
||||
*/
|
||||
public String source;
|
||||
|
||||
/**
|
||||
* Length of the current resource
|
||||
*/
|
||||
public long length;
|
||||
|
||||
/**
|
||||
* creation timestamp (and maybe unique identifier)
|
||||
*/
|
||||
public long timestamp;
|
||||
|
||||
/**
|
||||
* pre-defined content type
|
||||
*/
|
||||
public char kind;
|
||||
|
||||
/**
|
||||
* The downloaded file
|
||||
*/
|
||||
public StoredFileHelper storage;
|
||||
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the downloaded file
|
||||
*
|
||||
* @return {@code true] if and only if the file is successfully deleted, otherwise, {@code false}
|
||||
*/
|
||||
public boolean delete() {
|
||||
if (storage != null) return storage.delete();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate if this mission is deleted whatever is stored
|
||||
*/
|
||||
public transient boolean deleted = false;
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTimeInMillis(timestamp);
|
||||
return "[" + calendar.getTime().toString() + "] " + (storage.isInvalid() ? storage.getName() : storage.getUri());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
package us.shandian.giga.io;
|
||||
|
||||
public interface ProgressReport {
|
||||
|
||||
/**
|
||||
* Report the size of the new file
|
||||
*
|
||||
* @param progress the new size
|
||||
*/
|
||||
void report(long progress);
|
||||
package us.shandian.giga.io;
|
||||
|
||||
public interface ProgressReport {
|
||||
|
||||
/**
|
||||
* Report the size of the new file
|
||||
*
|
||||
* @param progress the new size
|
||||
*/
|
||||
void report(long progress);
|
||||
}
|
|
@ -1,44 +1,44 @@
|
|||
package us.shandian.giga.postprocessing;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.schabi.newpipe.streams.OggFromWebMWriter;
|
||||
import org.schabi.newpipe.streams.io.SharpStream;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
class OggFromWebmDemuxer extends Postprocessing {
|
||||
|
||||
OggFromWebmDemuxer() {
|
||||
super(true, true, ALGORITHM_OGG_FROM_WEBM_DEMUXER);
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean test(SharpStream... sources) throws IOException {
|
||||
ByteBuffer buffer = ByteBuffer.allocate(4);
|
||||
sources[0].read(buffer.array());
|
||||
|
||||
// youtube uses WebM as container, but the file extension (format suffix) is "*.opus"
|
||||
// check if the file is a webm/mkv file before proceed
|
||||
|
||||
switch (buffer.getInt()) {
|
||||
case 0x1a45dfa3:
|
||||
return true;// webm/mkv
|
||||
case 0x4F676753:
|
||||
return false;// ogg
|
||||
}
|
||||
|
||||
throw new UnsupportedOperationException("file not recognized, failed to demux the audio stream");
|
||||
}
|
||||
|
||||
@Override
|
||||
int process(SharpStream out, @NonNull SharpStream... sources) throws IOException {
|
||||
OggFromWebMWriter demuxer = new OggFromWebMWriter(sources[0], out);
|
||||
demuxer.parseSource();
|
||||
demuxer.selectTrack(0);
|
||||
demuxer.build();
|
||||
|
||||
return OK_RESULT;
|
||||
}
|
||||
}
|
||||
package us.shandian.giga.postprocessing;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.schabi.newpipe.streams.OggFromWebMWriter;
|
||||
import org.schabi.newpipe.streams.io.SharpStream;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
class OggFromWebmDemuxer extends Postprocessing {
|
||||
|
||||
OggFromWebmDemuxer() {
|
||||
super(true, true, ALGORITHM_OGG_FROM_WEBM_DEMUXER);
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean test(SharpStream... sources) throws IOException {
|
||||
ByteBuffer buffer = ByteBuffer.allocate(4);
|
||||
sources[0].read(buffer.array());
|
||||
|
||||
// youtube uses WebM as container, but the file extension (format suffix) is "*.opus"
|
||||
// check if the file is a webm/mkv file before proceed
|
||||
|
||||
switch (buffer.getInt()) {
|
||||
case 0x1a45dfa3:
|
||||
return true;// webm/mkv
|
||||
case 0x4F676753:
|
||||
return false;// ogg
|
||||
}
|
||||
|
||||
throw new UnsupportedOperationException("file not recognized, failed to demux the audio stream");
|
||||
}
|
||||
|
||||
@Override
|
||||
int process(SharpStream out, @NonNull SharpStream... sources) throws IOException {
|
||||
OggFromWebMWriter demuxer = new OggFromWebMWriter(sources[0], out);
|
||||
demuxer.parseSource();
|
||||
demuxer.selectTrack(0);
|
||||
demuxer.build();
|
||||
|
||||
return OK_RESULT;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,138 +1,138 @@
|
|||
package us.shandian.giga.ui.common;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.os.Handler;
|
||||
import android.view.View;
|
||||
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
|
||||
import org.schabi.newpipe.R;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import us.shandian.giga.get.FinishedMission;
|
||||
import us.shandian.giga.get.Mission;
|
||||
import us.shandian.giga.service.DownloadManager;
|
||||
import us.shandian.giga.service.DownloadManager.MissionIterator;
|
||||
import us.shandian.giga.ui.adapter.MissionAdapter;
|
||||
|
||||
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 Snackbar snackbar;
|
||||
private ArrayList<Mission> items;
|
||||
private boolean running = true;
|
||||
|
||||
private final Context mContext;
|
||||
private final MissionAdapter mAdapter;
|
||||
private final DownloadManager mDownloadManager;
|
||||
private final MissionIterator mIterator;
|
||||
private final Handler mHandler;
|
||||
private final View mView;
|
||||
|
||||
private final Runnable rShow;
|
||||
private final Runnable rNext;
|
||||
private final Runnable rCommit;
|
||||
|
||||
public Deleter(View v, Context c, MissionAdapter a, DownloadManager d, MissionIterator i, Handler h) {
|
||||
mView = v;
|
||||
mContext = c;
|
||||
mAdapter = a;
|
||||
mDownloadManager = d;
|
||||
mIterator = i;
|
||||
mHandler = h;
|
||||
|
||||
// use variables to know the reference of the lambdas
|
||||
rShow = this::show;
|
||||
rNext = this::next;
|
||||
rCommit = this::commit;
|
||||
|
||||
items = new ArrayList<>(2);
|
||||
}
|
||||
|
||||
public void append(Mission item) {
|
||||
mIterator.hide(item);
|
||||
items.add(0, item);
|
||||
|
||||
show();
|
||||
}
|
||||
|
||||
private void forget() {
|
||||
mIterator.unHide(items.remove(0));
|
||||
mAdapter.applyChanges();
|
||||
|
||||
show();
|
||||
}
|
||||
|
||||
private void show() {
|
||||
if (items.size() < 1) return;
|
||||
|
||||
pause();
|
||||
running = true;
|
||||
|
||||
mHandler.postDelayed(rNext, DELAY);
|
||||
}
|
||||
|
||||
private void next() {
|
||||
if (items.size() < 1) return;
|
||||
|
||||
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());
|
||||
snackbar.setActionTextColor(Color.YELLOW);
|
||||
snackbar.show();
|
||||
|
||||
mHandler.postDelayed(rCommit, TIMEOUT);
|
||||
}
|
||||
|
||||
private void commit() {
|
||||
if (items.size() < 1) return;
|
||||
|
||||
while (items.size() > 0) {
|
||||
Mission mission = items.remove(0);
|
||||
if (mission.deleted) continue;
|
||||
|
||||
mIterator.unHide(mission);
|
||||
mDownloadManager.deleteMission(mission);
|
||||
|
||||
if (mission instanceof FinishedMission) {
|
||||
mContext.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, mission.storage.getUri()));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (items.size() < 1) {
|
||||
pause();
|
||||
return;
|
||||
}
|
||||
|
||||
show();
|
||||
}
|
||||
|
||||
public void pause() {
|
||||
running = false;
|
||||
mHandler.removeCallbacks(rNext);
|
||||
mHandler.removeCallbacks(rShow);
|
||||
mHandler.removeCallbacks(rCommit);
|
||||
if (snackbar != null) snackbar.dismiss();
|
||||
}
|
||||
|
||||
public void resume() {
|
||||
if (running) return;
|
||||
mHandler.postDelayed(rShow, DELAY_RESUME);
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
if (items.size() < 1) return;
|
||||
|
||||
pause();
|
||||
|
||||
for (Mission mission : items) mDownloadManager.deleteMission(mission);
|
||||
items = null;
|
||||
}
|
||||
}
|
||||
package us.shandian.giga.ui.common;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.os.Handler;
|
||||
import android.view.View;
|
||||
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
|
||||
import org.schabi.newpipe.R;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import us.shandian.giga.get.FinishedMission;
|
||||
import us.shandian.giga.get.Mission;
|
||||
import us.shandian.giga.service.DownloadManager;
|
||||
import us.shandian.giga.service.DownloadManager.MissionIterator;
|
||||
import us.shandian.giga.ui.adapter.MissionAdapter;
|
||||
|
||||
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 Snackbar snackbar;
|
||||
private ArrayList<Mission> items;
|
||||
private boolean running = true;
|
||||
|
||||
private final Context mContext;
|
||||
private final MissionAdapter mAdapter;
|
||||
private final DownloadManager mDownloadManager;
|
||||
private final MissionIterator mIterator;
|
||||
private final Handler mHandler;
|
||||
private final View mView;
|
||||
|
||||
private final Runnable rShow;
|
||||
private final Runnable rNext;
|
||||
private final Runnable rCommit;
|
||||
|
||||
public Deleter(View v, Context c, MissionAdapter a, DownloadManager d, MissionIterator i, Handler h) {
|
||||
mView = v;
|
||||
mContext = c;
|
||||
mAdapter = a;
|
||||
mDownloadManager = d;
|
||||
mIterator = i;
|
||||
mHandler = h;
|
||||
|
||||
// use variables to know the reference of the lambdas
|
||||
rShow = this::show;
|
||||
rNext = this::next;
|
||||
rCommit = this::commit;
|
||||
|
||||
items = new ArrayList<>(2);
|
||||
}
|
||||
|
||||
public void append(Mission item) {
|
||||
mIterator.hide(item);
|
||||
items.add(0, item);
|
||||
|
||||
show();
|
||||
}
|
||||
|
||||
private void forget() {
|
||||
mIterator.unHide(items.remove(0));
|
||||
mAdapter.applyChanges();
|
||||
|
||||
show();
|
||||
}
|
||||
|
||||
private void show() {
|
||||
if (items.size() < 1) return;
|
||||
|
||||
pause();
|
||||
running = true;
|
||||
|
||||
mHandler.postDelayed(rNext, DELAY);
|
||||
}
|
||||
|
||||
private void next() {
|
||||
if (items.size() < 1) return;
|
||||
|
||||
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());
|
||||
snackbar.setActionTextColor(Color.YELLOW);
|
||||
snackbar.show();
|
||||
|
||||
mHandler.postDelayed(rCommit, TIMEOUT);
|
||||
}
|
||||
|
||||
private void commit() {
|
||||
if (items.size() < 1) return;
|
||||
|
||||
while (items.size() > 0) {
|
||||
Mission mission = items.remove(0);
|
||||
if (mission.deleted) continue;
|
||||
|
||||
mIterator.unHide(mission);
|
||||
mDownloadManager.deleteMission(mission);
|
||||
|
||||
if (mission instanceof FinishedMission) {
|
||||
mContext.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, mission.storage.getUri()));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (items.size() < 1) {
|
||||
pause();
|
||||
return;
|
||||
}
|
||||
|
||||
show();
|
||||
}
|
||||
|
||||
public void pause() {
|
||||
running = false;
|
||||
mHandler.removeCallbacks(rNext);
|
||||
mHandler.removeCallbacks(rShow);
|
||||
mHandler.removeCallbacks(rCommit);
|
||||
if (snackbar != null) snackbar.dismiss();
|
||||
}
|
||||
|
||||
public void resume() {
|
||||
if (running) return;
|
||||
mHandler.postDelayed(rShow, DELAY_RESUME);
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
if (items.size() < 1) return;
|
||||
|
||||
pause();
|
||||
|
||||
for (Mission mission : items) mDownloadManager.deleteMission(mission);
|
||||
items = null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,29 +1,29 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="30dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/item_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:text="relative header"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="2dp"
|
||||
android:background="@color/black_settings_accent_color" />
|
||||
|
||||
</LinearLayout>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="30dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/item_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:text="relative header"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="2dp"
|
||||
android:background="@color/black_settings_accent_color" />
|
||||
|
||||
</LinearLayout>
|
||||
|
|
|
@ -268,8 +268,8 @@
|
|||
<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="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>
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="view_count_text">%1$s visualizaciones</string>
|
||||
<string name="view_count_text">%1$s vistes</string>
|
||||
<string name="upload_date_text">Espublizóse\'l %1$s</string>
|
||||
<string name="cancel">Encaboxar</string>
|
||||
<string name="open_in_browser">Abrir nun restolador web</string>
|
||||
<string name="open_in_browser">Abrir nun restolador</string>
|
||||
<string name="share">Compartir</string>
|
||||
<string name="settings">Axustes</string>
|
||||
<string name="did_you_mean">¿Quixesti dicir «%1$s»\?</string>
|
||||
<string name="did_you_mean">¿Quxesti dicir «%1$s»\?</string>
|
||||
<string name="use_external_video_player_title">Usar un reproductor esternu de videu</string>
|
||||
<string name="use_external_audio_player_title">Usar un reproductor esternu d\'audiu</string>
|
||||
<string name="default_resolution_title">Resolución predeterminada</string>
|
||||
<string name="play_with_kodi_title">Reproducir en Kodi</string>
|
||||
<string name="show_play_with_kodi_title">Amosar la opción «Reproducir en Kodi»</string>
|
||||
<string name="show_play_with_kodi_summary">Amuesa una opción pa reproducir un videu pel centru multimedia Kodi</string>
|
||||
<string name="show_play_with_kodi_summary">Amuesa una opción pa reproducir vídeos pel centru multimedia Kodi</string>
|
||||
<string name="play_audio">Audiu</string>
|
||||
<string name="default_audio_format_title">Formatu predetermináu d\'audiu</string>
|
||||
<string name="default_audio_format_title">Formatu d\'audiu predetermináu</string>
|
||||
<string name="theme_title">Estilu</string>
|
||||
<string name="dark_theme_title">Escuridá</string>
|
||||
<string name="light_theme_title">Claridá</string>
|
||||
|
@ -26,16 +26,16 @@
|
|||
<string name="duration_live">En direuto</string>
|
||||
<string name="general_error">Fallu</string>
|
||||
<string name="could_not_load_thumbnails">Nun pudieron cargase toles miniatures</string>
|
||||
<string name="youtube_signature_deobfuscation_error">Nun pudo descifrase la robla de la URL del videu</string>
|
||||
<string name="youtube_signature_deobfuscation_error">Nun pudo sabese la robla de la URL del videu</string>
|
||||
<string name="parsing_error">Nun pudo analizase\'l sitiu web</string>
|
||||
<string name="live_streams_not_supported">Entá nun se sofiten los fluxos en direuto</string>
|
||||
<string name="could_not_get_stream">Nun pudo consiguise dengún fluxu</string>
|
||||
<string name="sorry_string">Perdona pero eso nun debió asoceder.</string>
|
||||
<string name="live_streams_not_supported">Los fluxos en direuto entá nun se sofiten</string>
|
||||
<string name="could_not_get_stream">Nun pudo consiguise nengún fluxu</string>
|
||||
<string name="sorry_string">Buff... Esto nun debió asoceder.</string>
|
||||
<string name="error_snackbar_message">Perdona mas asocedió daqué malo.</string>
|
||||
<string name="what_device_headline">Información:</string>
|
||||
<string name="error_details_headline">Detalles:</string>
|
||||
<string name="detail_likes_img_view_description">Préstames</string>
|
||||
<string name="use_tor_title">Usar TOR</string>
|
||||
<string name="use_tor_title">Usar Tor</string>
|
||||
<string name="info_dir_created">Creóse\'l direutoriu de descarga «%1$s»</string>
|
||||
<string name="video">Videu</string>
|
||||
<string name="audio">Audiu</string>
|
||||
|
@ -48,73 +48,73 @@
|
|||
<string name="msg_wait">Espera…</string>
|
||||
<string name="msg_copied">Copióse al cartafueyu</string>
|
||||
<string name="detail_dislikes_img_view_description">Tarrezmes</string>
|
||||
<string name="default_video_format_title">Formatu predetermináu de videu</string>
|
||||
<string name="default_video_format_title">Formatu de videu predetermináu</string>
|
||||
<string name="black_theme_title">Prietu</string>
|
||||
<string name="channel">Canal</string>
|
||||
<string name="yes">Sí</string>
|
||||
<string name="short_thousand">Mil</string>
|
||||
<string name="short_million">Mill.</string>
|
||||
<string name="short_billion">Mil mill.</string>
|
||||
<string name="msg_popup_permission">Precísase esti permisu
|
||||
\np\'abrir nel mou ventanu</string>
|
||||
<string name="short_thousand">mil</string>
|
||||
<string name="short_million">mill.</string>
|
||||
<string name="short_billion">mil mill.</string>
|
||||
<string name="msg_popup_permission">Precísase esti permisu p\'abrir
|
||||
\nnel mou ventanu</string>
|
||||
<string name="title_activity_recaptcha">Retu de reCAPTCHA</string>
|
||||
<string name="recaptcha_request_toast">Solicitóse\'l retu de reCAPTCHA</string>
|
||||
<string name="recaptcha_request_toast">Solicitóse un retu de reCAPTCHA</string>
|
||||
<string name="controls_background_title">En segundu planu</string>
|
||||
<string name="controls_popup_title">Ventanu</string>
|
||||
<string name="default_popup_resolution_title">Resolución predeterminada del ventanu</string>
|
||||
<string name="show_higher_resolutions_title">Amosar resoluciones más altes</string>
|
||||
<string name="show_higher_resolutions_summary">Namái dalgunos preseos puen reproducir vídeos en 2K/4K</string>
|
||||
<string name="show_higher_resolutions_summary">Namás dalgunos preseos puen reproducir videos en 2K/4K</string>
|
||||
<string name="clear">Llimpiar</string>
|
||||
<string name="use_external_video_player_summary">Quita l\'audiu en dalgunes resoluciones</string>
|
||||
<string name="player_gesture_controls_summary">Usa xestos pa controlar el brilléu y volume del reproductor</string>
|
||||
<string name="show_search_suggestions_title">Guetar suxerencies</string>
|
||||
<string name="show_search_suggestions_summary">Amuesa suxerencies al guetar</string>
|
||||
<string name="player_gesture_controls_summary">Usa xestos pa controlar el volume y brillu del reproductor</string>
|
||||
<string name="show_search_suggestions_title">Suxerencies de busca</string>
|
||||
<string name="show_search_suggestions_summary">Amosar suxerencies al buscar</string>
|
||||
<string name="subscribe_button_title">Soscribise</string>
|
||||
<string name="subscription_update_failed">Nun pudo anovase la soscripción</string>
|
||||
<string name="tab_subscriptions">Soscripciones</string>
|
||||
<string name="fragment_feed_title">Novedaes</string>
|
||||
<string name="enable_search_history_title">Historial de gueta</string>
|
||||
<string name="resume_on_audio_focus_gain_title"/>
|
||||
<string name="resume_on_audio_focus_gain_summary">Sigue cola reproducción dempués de les interrupciones (llamaes telefóniques, por exemplu)</string>
|
||||
<string name="enable_search_history_title">Historial de busques</string>
|
||||
<string name="resume_on_audio_focus_gain_title">Siguir cola reproducción</string>
|
||||
<string name="resume_on_audio_focus_gain_summary">Sigue cola reproducción dempués de les interrupciones (por exemplu, llamaes)</string>
|
||||
<string name="settings_category_player_title">Reproductor</string>
|
||||
<string name="settings_category_player_behavior_title">Comportamientu</string>
|
||||
<string name="settings_category_history_title">Historial y caché</string>
|
||||
<string name="best_resolution">La meyor resolución</string>
|
||||
<string name="notification_channel_name">Avisu de NewPipe</string>
|
||||
<string name="notification_channel_name">Avisu permanente de NewPipe</string>
|
||||
<string name="search_no_results">Nun hai resultaos</string>
|
||||
<string name="empty_subscription_feed_subtitle">Equí nun hai más que grillos</string>
|
||||
<plurals name="subscribers">
|
||||
<item quantity="one">%s soscriptor</item>
|
||||
<item quantity="other">%s soscriptores</item>
|
||||
</plurals>
|
||||
<string name="no_views">Nun hai visualizaciones</string>
|
||||
<string name="no_views">Nun hai vistes</string>
|
||||
<plurals name="views">
|
||||
<item quantity="one">%s visualización</item>
|
||||
<item quantity="other">%s visualizaciones</item>
|
||||
<item quantity="one">%s vista</item>
|
||||
<item quantity="other">%s vistes</item>
|
||||
</plurals>
|
||||
<string name="settings_category_downloads_title">Descarga</string>
|
||||
<string name="settings_file_charset_title">Caráuteres almitíos nos nomes de ficheros</string>
|
||||
<string name="settings_file_charset_title">Caráuteres permitíos nos nomes de los ficheros</string>
|
||||
<string name="charset_letters_and_digits">Lletres y díxitos</string>
|
||||
<string name="charset_most_special_characters">La mayoría de caráuteres especiales</string>
|
||||
<string name="title_activity_about">Tocante a NewPipe</string>
|
||||
<string name="action_settings">Axustes</string>
|
||||
<string name="action_about">Tocante a</string>
|
||||
<string name="title_licenses">Llicencies de terceros</string>
|
||||
<string name="copyright" formatted="true">© %1$s por %2$s so %3$s</string>
|
||||
<string name="copyright" formatted="true">© %1$s por %2$s baxo %3$s</string>
|
||||
<string name="error_unable_to_load_license">Nun pudo cargase la llicencia</string>
|
||||
<string name="tab_about">Tocante a</string>
|
||||
<string name="tab_contributors">Collaboradores</string>
|
||||
<string name="tab_licenses">Llicencies</string>
|
||||
<string name="view_on_github">Ver en GitHub</string>
|
||||
<string name="app_license_title">Llicencia de NewPipe</string>
|
||||
<string name="contribution_encouragement">Si sabes traducir, quies encuriosar el códigu, amestar carauteríques o proponer cambeos nel diseñu, vamos agradecételo siempres. ¡Cuánto más, meyor!</string>
|
||||
<string name="read_full_license">Lleer la llicencia</string>
|
||||
<string name="contribution_encouragement">Si tienes idees, quies traducir, facer dalgún cambéu nel diseñu, acuriosar poco o muncho\'l códigu... Agradecemos l\'ayuda. ¡Cuanto más se faiga, meyor!</string>
|
||||
<string name="read_full_license">Lleer</string>
|
||||
<string name="contribution_title">Collaboración</string>
|
||||
<string name="title_activity_history">Historial</string>
|
||||
<string name="title_history_view">Vióse</string>
|
||||
<string name="action_history">Historial</string>
|
||||
<string name="history_empty">L\'historial ta baleru</string>
|
||||
<string name="delete_item_search_history">¿Quies desaniciar esti elementu del historial de gueta\?</string>
|
||||
<string name="delete_item_search_history">¿Quies desaniciar esti elementu del historial de busques\?</string>
|
||||
<string name="play_all">Reproducir too</string>
|
||||
<string name="player_stream_failure">Nun pudo reproducise esti fluxu</string>
|
||||
<string name="player_unrecoverable_failure">Asocedió un fallu irrecuperable del reproductor</string>
|
||||
|
@ -123,14 +123,14 @@
|
|||
<string name="select_a_kiosk">Esbilla d\'un quioscu</string>
|
||||
<string name="kiosk">Quioscu</string>
|
||||
<string name="trending">Tendencies</string>
|
||||
<string name="top_50">Destácase</string>
|
||||
<string name="top_50">Los 50 destacaos</string>
|
||||
<string name="play_queue_stream_detail">Detalles</string>
|
||||
<string name="new_and_hot">Novedaes</string>
|
||||
<string name="new_and_hot">Novedaes destacaes</string>
|
||||
<string name="unknown_content">[Desconozse]</string>
|
||||
<string name="start_here_on_background">Reproducir en segundu planu</string>
|
||||
<string name="start_here_on_popup"/>
|
||||
<string name="start_here_on_popup">Reproducir nun ventanu</string>
|
||||
<string name="donation_title">Donación</string>
|
||||
<string name="donation_encouragement"/>
|
||||
<string name="donation_encouragement">NewPipe ta desendolcáu por xente voluntario que pasa\'l tiempu llibre ufriéndote la meyor esperiencia d\'usuariu. Devolvi\'l favor p\'ayudar a los desendolcadores p\'ameyorar NewPipe tovía más mentanto esfruten d\'una taza de café.</string>
|
||||
<string name="give_back">Donar</string>
|
||||
<string name="website_title">Sitiu web</string>
|
||||
<string name="website_encouragement">Visita\'l sitiu web de NewPipe pa más información y noticies.</string>
|
||||
|
@ -138,43 +138,43 @@
|
|||
<string name="always">Siempres</string>
|
||||
<string name="import_data_title">Importar una base de datos</string>
|
||||
<string name="export_data_title">Esportar la base de datos</string>
|
||||
<string name="import_data_summary">Anula l\'historial y les soscripciones actuales</string>
|
||||
<string name="export_data_summary">Esporta l\'historial, les soscripciones y llistes de reproducción.</string>
|
||||
<string name="invalid_url_toast">URL nun ye válida</string>
|
||||
<string name="import_data_summary">Anula l\'historial, les soscripciones, les llistes de reproducción y (opcionalmente) los axustes actuales</string>
|
||||
<string name="export_data_summary">Esporta l\'historial, les soscripciones, les llistes de reproducción y los axustes</string>
|
||||
<string name="invalid_url_toast">La URL nun ye válida</string>
|
||||
<string name="override_current_data">Esto va anular la configuración actual.</string>
|
||||
<string name="show_info">Amosar la información</string>
|
||||
<string name="tab_bookmarks">Llistes de reproducción</string>
|
||||
<string name="tab_bookmarks">Llistes en marcadores</string>
|
||||
<string name="create">Crear</string>
|
||||
<string name="dismiss">Escartar</string>
|
||||
<string name="delete_all_history_prompt">¿De xuru que quies desaniciar tolos elementos del historial\?</string>
|
||||
<string name="drawer_header_action_paceholder_text">Equí va apaecer dalgo ceo ;D</string>
|
||||
<string name="create_playlist">Llista nueva de repoducción</string>
|
||||
<string name="drawer_header_action_paceholder_text">Equí va apaecer daqué pronto ;D</string>
|
||||
<string name="create_playlist">Llista de reproducción nueva</string>
|
||||
<string name="name">Nome</string>
|
||||
<string name="append_playlist">Amestar a una llista de repoducción</string>
|
||||
<string name="delete_playlist_prompt">¿Desaniciar esta llista de reproducción\?</string>
|
||||
<string name="append_playlist">Amestar a una llista de reproducción</string>
|
||||
<string name="delete_playlist_prompt">¿Desanicair esta llista de reproducción\?</string>
|
||||
<string name="playlist_delete_failure">Nun pudo desaniciase la llista de reproducción.</string>
|
||||
<string name="caption_none">Ensin sotítulos</string>
|
||||
<string name="resize_fit">Axustar</string>
|
||||
<string name="resize_fill">Rellenar</string>
|
||||
<string name="resize_zoom">Zoom</string>
|
||||
<string name="file">Ficheru</string>
|
||||
<string name="invalid_file">El ficheru nun esiste o falta\'l permisu d\'escritura o llectura</string>
|
||||
<string name="file">FIcheru</string>
|
||||
<string name="invalid_file">El ficheru nun esiste o a l\'aplicación fálta-y el permisu de llectura/escritura</string>
|
||||
<string name="error_occurred_detail">Asocedió un fallu: %1$s</string>
|
||||
<string name="import_export_title">Importación/Esportación</string>
|
||||
<string name="import_ongoing">Importando…</string>
|
||||
<string name="export_ongoing">Esportando…</string>
|
||||
<string name="subscriptions_export_unsuccessful">Nun pudieron esportase les soscripciones</string>
|
||||
<string name="preferred_open_action_settings_title">Aición preferida d\'apertura</string>
|
||||
<string name="import_settings">¿Quies importar los axustes tamién\?</string>
|
||||
<string name="read_privacy_policy">Lleer la política de privacidá</string>
|
||||
<string name="preferred_open_action_settings_title">Aición d\'apertura preferida</string>
|
||||
<string name="import_settings">¿Quies tamién importar los axustes\?</string>
|
||||
<string name="read_privacy_policy">Lleer</string>
|
||||
<string name="channels">Canales</string>
|
||||
<string name="playlists">Llistes de reproducción</string>
|
||||
<string name="tracks">Pistes</string>
|
||||
<string name="users">Usuarios</string>
|
||||
<string name="tab_new">Llingüeta nueva</string>
|
||||
<string name="volume_gesture_control_summary">Usa xestos pa controlar el volume del reproductor</string>
|
||||
<string name="brightness_gesture_control_summary">Usa xestos pa controlar el brilléu del reproductor</string>
|
||||
<string name="restore_defaults">Reafitar</string>
|
||||
<string name="brightness_gesture_control_summary">Usa xestos pa controlar el brillu del reproductor</string>
|
||||
<string name="restore_defaults">Reafitamientu de valores</string>
|
||||
<string name="subscribers_count_not_available">El númberu de soscriptores nun ta disponible</string>
|
||||
<string name="selection">Esbilla</string>
|
||||
<string name="updates_setting_title">Anovamientos</string>
|
||||
|
@ -184,10 +184,10 @@
|
|||
<string name="missions_header_finished">Finó</string>
|
||||
<string name="download_failed">Falló la descarga</string>
|
||||
<string name="download_already_running">Hai una descarga en cursu con esti nome</string>
|
||||
<string name="error_path_creation">Nun pue crease la carpeta de destín</string>
|
||||
<string name="error_path_creation">La carpeta de destín nun pue crease</string>
|
||||
<string name="error_ssl_exception">Nun pudo afitase una conexón segura</string>
|
||||
<string name="error_connect_host">Nun pue coneutase col sirvidor</string>
|
||||
<string name="max_retry_msg">Reintentos máximos</string>
|
||||
<string name="error_connect_host">Nun pues coneutate al sirvidor</string>
|
||||
<string name="max_retry_msg">Intentos máximos</string>
|
||||
<string name="events">Eventos</string>
|
||||
<string name="conferences">Conferencies</string>
|
||||
<string name="autoplay_title">Reproducción automática</string>
|
||||
|
@ -195,50 +195,52 @@
|
|||
<string name="missing_file">El ficheru movióse o desanicióse</string>
|
||||
<string name="overwrite_unrelated_warning">Yá esiste un ficheru con esti nome</string>
|
||||
<string name="overwrite_finished_warning">Yá esiste un ficheru baxáu con esti nome</string>
|
||||
<string name="overwrite_failed">nun pue sobrescribise\'l ficheru</string>
|
||||
<string name="overwrite_failed">nun pue sobrecribise\'l ficheru</string>
|
||||
<string name="download_already_pending">Hai una descarga pendiente con esti nome</string>
|
||||
<string name="error_insufficient_storage">Escosó l\'espaciu del preséu</string>
|
||||
<string name="error_insufficient_storage">Nun queda espaciu nel preséu</string>
|
||||
<string name="error_timeout">Escosó\'l tiempu d\'espera de la conexón</string>
|
||||
<string name="subscriptions_import_unsuccessful">Nun pudieron importase les soscripciones</string>
|
||||
<string name="caption_setting_title">Sotítulos</string>
|
||||
<string name="accept">Aceutar</string>
|
||||
<string name="restore_defaults_confirmation">¿Quies reafitar los valores\?</string>
|
||||
<string name="error_unknown_host"/>
|
||||
<string name="error_http_unsupported_range">El sirvidor nun aceuta descargues multifilu, volvi probar con @string/msg_threads = 1</string>
|
||||
<string name="error_unknown_host">Nun pudo atopase\'l sirvidor</string>
|
||||
<string name="error_http_unsupported_range">El sirvidor nun aceuta descargues multifilu, volvi tentalo con @string/msg_threads = 1</string>
|
||||
<string name="no_comments">Nun hai comentarios</string>
|
||||
<string name="settings_category_clear_data_title">Llimpieza de datos</string>
|
||||
<string name="show_comments_title">Amosar comentarios</string>
|
||||
<string name="show_comments_title">Amosar los comentarios</string>
|
||||
<string name="show_comments_summary">Desactiva esta opción p\'anubrir los comentarios</string>
|
||||
<string name="start_accept_privacy_policy">Pa cumplir cola GDPR (Regulación Xeneral de Proteición de Datos) europea, pidímoste que revises la política de privacidá de NewPipe. Lléila con procuru.
|
||||
\nHas aceutala unviándonos un informe de fallos.
|
||||
</string>
|
||||
<string name="minimize_on_exit_summary">Aición al cambiar a otra aplicación dende\'l reproductor de vídeos principal — %s</string>
|
||||
<string name="max_retry_desc">El númberu máximu d\'intentos enantes d\'encaboxar la descarga</string>
|
||||
<string name="start_accept_privacy_policy">Pa cumplir cola Regulación Xeneral de Proteición de Datos (RGPD), pidímoste que mires la política de privacidá de NewPipe. Lleila con procuru.
|
||||
\nHas aceutala pa unvianos informes de fallos.</string>
|
||||
<string name="minimize_on_exit_summary">L\'aición al cambiar a otra aplicación dende\'l reproductor de videu princpial — %s</string>
|
||||
<string name="max_retry_desc">El númberu máximu d\'intentos pa encaboxar la descarga</string>
|
||||
<string name="confirm_prompt">¿Quies llimpiar l\'historial de descargues o desaniciar tolos ficheros baxaos\?</string>
|
||||
<string name="previous_export">Esportación anterior</string>
|
||||
<string name="import_file_title">Importar el ficheru</string>
|
||||
<string name="import_youtube_instructions">Importa les soscripciones de YouTube baxando\'l ficheru d\'esportación:
|
||||
\n
|
||||
\n1.- Vete a esta URL: %1$s
|
||||
\n2.- Anicia sesión cuando se te pida
|
||||
\n3.- Debería aniciase una descarga (que ye\'l ficheru d\'esportación)</string>
|
||||
<string name="import_soundcloud_instructions">Importa un perfil de SoundCloud teclexando la URL o la ID de to:
|
||||
\n1.- Activa\'l mou escritoriu nun restolador web (el sitiu nun ta disponible pa móviles)
|
||||
<string name="import_file_title">Importación d\'un ficheru</string>
|
||||
<string name="import_youtube_instructions">Importa les soscripciones de YouTube dende Google Takeout:
|
||||
\n
|
||||
\n3.- Anicia sesión cuando se te pida
|
||||
\n2.- Vete a esta URL: %1$s
|
||||
\n4.- Copia la URL del perfil al que se te redirixa.</string>
|
||||
<string name="import_soundcloud_instructions_hint">LaToID, soundcloud.com/latoid</string>
|
||||
<string name="download_thumbnail_title">Cargar miniatures</string>
|
||||
<string name="download_thumbnail_summary">Desactiva esta opción pa evitar la carga de miniatures y aforrar datos y usu de la memoria. Los cambeos van llimpiar la memoria y la caché d\'imáxenes.</string>
|
||||
<string name="minimize_on_exit_title">Minimizar al cambiar a otra aplicación</string>
|
||||
\n1. Vete a esta URL: %1$s
|
||||
\n2. Anicia sesión cuando se te pida
|
||||
\n3. Calca en «Tolos datos incluyíos», darréu en «Deseleicionar too», dempués esbilla namás «soscripciones» y calca «Aceutar»
|
||||
\n4. Calca en «Pasu siguiente» y darréu en «Crear una esportación»
|
||||
\n5. Calca nel botón «Baxar» dempués de qu\'apaeza y
|
||||
\n6. A partir del ficheru baxáu, estrái\'l ficheru .json (polo xeneral baxo «YouTube and YouTube Music/subscriptions/subscriptions.json») ya impórtalu equí.</string>
|
||||
<string name="import_soundcloud_instructions">Importa un perfil de SoundCloud teclexando la URL o la to ID:
|
||||
\n
|
||||
\n1. Activa\'l «mou d\'escritoriu» nun restolador web (el sitiu nun ta disponible pa móviles)
|
||||
\n2. Vete a esta URL: %1$s
|
||||
\n3. Anicia sesión cuando se te pida
|
||||
\n4. Copia la URL del perfil al que te redirixeron.</string>
|
||||
<string name="import_soundcloud_instructions_hint">soundcloud.com/LaToID</string>
|
||||
<string name="download_thumbnail_title">Cargar les miniatures</string>
|
||||
<string name="download_thumbnail_summary">Desactiva esta opción pa eviar la carga de miniatures y aforrar datos y usu de memoria. Los cambeos llimpien la caché d\'imáxenes temporal y permanente.</string>
|
||||
<string name="minimize_on_exit_title">Minimizar al cambiar d\'aplicación</string>
|
||||
<string name="minimize_on_exit_background_description">Minimizar al reproductor en segundu planu</string>
|
||||
<string name="minimize_on_exit_popup_description">Minimizar al reproductor en ventanu</string>
|
||||
<string name="unsubscribe">Desoscribise</string>
|
||||
<string name="tab_choose">Escoyeta d\'una llingüeta</string>
|
||||
<string name="unsubscribe">Esborrase</string>
|
||||
<string name="tab_choose">Esbilla d\'una llingüeta</string>
|
||||
<string name="enable_playback_resume_title">Siguir cola reproducción</string>
|
||||
<string name="main_page_content_summary">Les llingüetes que s\'amuesen na páxina principal</string>
|
||||
<string name="downloads_storage_ask_title">Entrugar ánde baxar</string>
|
||||
<string name="downloads_storage_ask_title">Entrugar ónde baxar</string>
|
||||
<string name="downloads">Descargues</string>
|
||||
<string name="downloads_title">Descargues</string>
|
||||
<plurals name="videos">
|
||||
|
@ -247,26 +249,26 @@
|
|||
</plurals>
|
||||
<string name="player_gesture_controls_title">Control per xestos del reproductor</string>
|
||||
<string name="preferred_player_fetcher_notification_message">Cargando\'l conteníu solicitáu</string>
|
||||
<string name="privacy_policy_title">Política de Privacidá de NewPipe</string>
|
||||
<string name="privacy_policy_title">Política de privacidá de NewPipe</string>
|
||||
<string name="volume_gesture_control_title">Control per xestos del volume</string>
|
||||
<string name="brightness_gesture_control_title">Control per xestos del brilléu</string>
|
||||
<string name="brightness_gesture_control_title">Control per xestos del brillu</string>
|
||||
<string name="error_file_creation">El ficheru nun pue crease</string>
|
||||
<string name="error_http_no_content">El sirvidor nun unvia datos</string>
|
||||
<string name="localization_changes_requires_app_restart">La llingua va camudar namái que se reanicie l\'aplicación.</string>
|
||||
<string name="search">Guetar</string>
|
||||
<string name="localization_changes_requires_app_restart">La llingua va camudar namás que se reanicie l\'aplicación.</string>
|
||||
<string name="search">Buscar</string>
|
||||
<string name="share_dialog_title">Compartir con</string>
|
||||
<string name="msg_exists">El ficheru yá esiste</string>
|
||||
<string name="msg_exists">Yá esiste\'l ficheru</string>
|
||||
<string name="subscribed_button_title">Soscribiéstite</string>
|
||||
<string name="history_disabled">L\'historial ta desactiváu</string>
|
||||
<string name="no_videos">Nun hai vídeos</string>
|
||||
<string name="delete_search_history_alert">¿Desaniciar tol historial de guetes\?</string>
|
||||
<string name="app_update_notification_content_title">¡Hai un anovamientu disponible pa NewPipe!</string>
|
||||
<string name="app_update_notification_content_text">Toca pa baxar la versión</string>
|
||||
<string name="delete_search_history_alert">¿Desaniciar tol historial de busques\?</string>
|
||||
<string name="app_update_notification_content_title">¡Hai un anovamientu pa NewPipe!</string>
|
||||
<string name="app_update_notification_content_text">Toca pa baxalu</string>
|
||||
<string name="error_progress_lost">Perdióse\'l progresu porque se desanició\'l ficheru</string>
|
||||
<string name="peertube_instance_url_title">Instancies de PeerTube</string>
|
||||
<string name="peertube_instance_add_exists">La instancia yá esiste</string>
|
||||
<string name="app_language_title">Llingua de l\'aplicación</string>
|
||||
<string name="systems_language">La predeterminada del sistema</string>
|
||||
<string name="systems_language">Lo predeterminao del sistema</string>
|
||||
<string name="videos_string">Vídeos</string>
|
||||
<plurals name="seconds">
|
||||
<item quantity="one">%d segundu</item>
|
||||
|
@ -275,14 +277,14 @@
|
|||
<string name="playback_tempo">Tempu</string>
|
||||
<string name="playback_pitch">Tonu</string>
|
||||
<string name="decline">Refugar</string>
|
||||
<string name="unsupported_url">La URL nun se sofita</string>
|
||||
<string name="unsupported_url">La URL nun ta sofitada</string>
|
||||
<string name="background_player_playing_toast">Reproduciendo en segundu planu</string>
|
||||
<string name="popup_playing_toast">Reproduciendo nel mou ventanu</string>
|
||||
<string name="enable_search_history_summary">Atroxa llocalmente les consultes de gueta</string>
|
||||
<string name="external_player_unsupported_link_type">Los reproductores esternos nun so</string>
|
||||
<string name="enable_search_history_summary">Atroxa llocalmente les consultes de busca</string>
|
||||
<string name="external_player_unsupported_link_type">Los reproductores esternos nun sofiten esti tipu d\'enllaces</string>
|
||||
<string name="export_complete_toast">Esportóse</string>
|
||||
<string name="import_complete_toast">Importóse</string>
|
||||
<string name="could_not_import_all_files">Alvertencia: Nun pudieron importase tolos ficheros.</string>
|
||||
<string name="could_not_import_all_files">Alvertencia: nun pudieron importase tolos ficheros.</string>
|
||||
<string name="settings_category_updates_title">Anovamientos</string>
|
||||
<string name="download_finished">Finó la descarga</string>
|
||||
<string name="peertube_instance_add_fail">Nun pudo validase la instancia</string>
|
||||
|
@ -299,10 +301,352 @@
|
|||
<item quantity="other">%d díes</item>
|
||||
</plurals>
|
||||
<string name="feed_group_dialog_delete_message">¿Quies desaniciar esti grupu\?</string>
|
||||
<string name="metadata_cache_wipe_complete_notice">Llipióse la caché de metadatos</string>
|
||||
<string name="metadata_cache_wipe_summary">Desanicia los datos de les páxines web na caché</string>
|
||||
<string name="metadata_cache_wipe_complete_notice">Llimpióse la caché de metadatos</string>
|
||||
<string name="metadata_cache_wipe_summary">Desanicia tolos datos na caché de les páxines web</string>
|
||||
<string name="metadata_cache_wipe_title">Llimpiar los metadatos de la caché</string>
|
||||
<string name="thumbnail_cache_wipe_complete_notice">Llimpióse la caché d\'imáxenes</string>
|
||||
<string name="kore_not_found">¿Instalar l\'aplicación Kore\?</string>
|
||||
<string name="autoplay_by_calling_app_summary">Reproduz un videu cuando s\'invoca a NewPipe dende otra aplicación</string>
|
||||
<string name="kore_not_found">¿Instalar Kore\?</string>
|
||||
<string name="autoplay_by_calling_app_summary">Reproduz un videu al llamar a NewPipe dende otra aplicación</string>
|
||||
<string name="info_labels">Qué asocedió:\\nSolicitú:\\nLlingua del conteníu:\\nPaís del conteníu:\\nLlingua de l\'aplicación:\\nServiciu:\\nHora en GMT:\\nPaquete:\\nVersión de l\'aplicación:\\nVersión del SO:</string>
|
||||
<string name="no_player_found_toast">Nun s\'atopó nengún reproductor de fluxos (pues instalar VLC pa reproducilos).</string>
|
||||
<string name="show_thumbnail_summary">Amuesa una miniatura nel fondu de la pantalla de bloquéu y dientro de los avisos</string>
|
||||
<string name="show_thumbnail_title">Amosar una miniatura</string>
|
||||
<string name="playlist_page_summary">Páxina d\'una llista de reproducción</string>
|
||||
<string name="video_detail_by">Por %s</string>
|
||||
<string name="channel_created_by">Canal creada por %s</string>
|
||||
<string name="detail_sub_channel_thumbnail_view_description">Avatar de la canal</string>
|
||||
<string name="content_not_supported">Esti conteníu entá nun ta sofitáu por NewPipe.
|
||||
\n
|
||||
\nQuiciabes nel futuru sí.</string>
|
||||
<string name="feed_use_dedicated_fetch_method_help_text">¿Cuides que la carga del feed ye perlenta\? Si ye asina, activa la carga rápida (pues camudalo nos axustes o primiendo\'l botón d\'embaxo).
|
||||
\n
|
||||
\nNewPipe ufre dos estratexes de descarga de feeds:
|
||||
\n• Dir en cata de tola canal de soscripciones, lo cual ye lento pero completo.
|
||||
\n• Usar un serviciu final dedicáu, lo cual ye rápido mas xeneralmente incompleto.
|
||||
\n
|
||||
\nLa diferencia ente los dos ye qu\'al más rápidu, polo xeneral, fálta-y dalguna información como\'l tipu (nun pue estremar ente vídeos en direuto o normales) o la duración de los elementos (que devuelve menos).
|
||||
\n
|
||||
\nYouTube ye l\'exemplu d\'un serviciu qu\'ufre esti métodu rápidu col so feed RSS.
|
||||
\n
|
||||
\nPolo que tu escueyes según lo que prefieras, si velocidá o información precisa.</string>
|
||||
<string name="feed_use_dedicated_fetch_method_disable_button">Desactivar el mou rápidu</string>
|
||||
<string name="feed_use_dedicated_fetch_method_enable_button">Activar el mou rápidu</string>
|
||||
<string name="feed_use_dedicated_fetch_method_summary">Disponible en dalgunos preseos, suel ser muncho más rápido mas podría devolver un númberu llendáu d\'elementos y davezu información completa (por exemplu, falta de la duración, el tipu d\'elementu o l\'estáu de la tresmisión).</string>
|
||||
<string name="feed_use_dedicated_fetch_method_title">Dir en cata de feeds dedicaos cuando seya posible</string>
|
||||
<string name="feed_update_threshold_option_always_update">Anovar siempres</string>
|
||||
<string name="feed_update_threshold_summary">Tiempu que tarda (dende l\'últimu anovamientu) en considerase una soscripción ensin anovar — %s</string>
|
||||
<string name="feed_update_threshold_title">Llende del anovamientu del feed</string>
|
||||
<string name="settings_category_feed_title">Feed</string>
|
||||
<string name="feed_group_show_only_ungrouped_subscriptions">Amosar namás les soscripciones ensin agrupar</string>
|
||||
<string name="feed_create_new_group_button_title">Nuevu</string>
|
||||
<string name="feed_group_dialog_empty_name">El nome del grupu ta baleru</string>
|
||||
<plurals name="feed_group_dialog_selection_count">
|
||||
<item quantity="one">%d na esbilla</item>
|
||||
<item quantity="other">%d na esbilla</item>
|
||||
</plurals>
|
||||
<string name="feed_group_dialog_empty_selection">Nun s\'esbilló nenguna soscripción</string>
|
||||
<string name="feed_group_dialog_select_subscriptions">Esbillar soscripciones</string>
|
||||
<string name="feed_processing_message">Procesando\'l feed…</string>
|
||||
<string name="feed_notification_loading">Cargando\'l feed…</string>
|
||||
<string name="feed_subscription_not_loaded_count">Númberu d\'elementos que nun cargaron: %d</string>
|
||||
<string name="feed_oldest_subscription_update">Últimu anovamientu del feed: %s</string>
|
||||
<string name="feed_groups_header_title">Grupos de canales</string>
|
||||
<string name="new_seek_duration_toast">Pola mor de les torgues d\'ExoPlayer la duración afitóse en %d segundos</string>
|
||||
<string name="remove_watched_popup_yes_and_partially_watched_videos">Sí, y tamién los vistos parcialmente</string>
|
||||
<string name="remove_watched_popup_warning">Van desaniciase los vídeos que se vieren enantes y dempués d\'amestase a la llista de reproducción.
|
||||
\n¿De xuru\? ¡Esto nun pue desfacese!</string>
|
||||
<string name="remove_watched_popup_title">¿Desaniciar los vídeos vistos\?</string>
|
||||
<string name="remove_watched">Desaniciar lo visto</string>
|
||||
<string name="choose_instance_prompt">Escoyeta d\'una instancia</string>
|
||||
<string name="downloads_storage_use_saf_summary">El «Storage Access Framework» permite les descargues nuna tarxeta SD esterna.
|
||||
\nDalgunos preseos son incompatibles</string>
|
||||
<string name="downloads_storage_use_saf_title">Usar SAF</string>
|
||||
<string name="downloads_storage_ask_summary_kitkat">Va pidísete l\'allugamientu onde guardar les descargues con cauna.
|
||||
\nEscueyi SAF si quies guardar les descargues na tarxeta SD esterna</string>
|
||||
<string name="downloads_storage_ask_summary">Va pidísete l\'allugamientu onde guardar les descargues con cauna</string>
|
||||
<string name="pause_downloads">Posar les descargues</string>
|
||||
<string name="start_downloads">Aniciar les descargues</string>
|
||||
<string name="enable_queue_limit_desc">Namás va executase una descarga al empar</string>
|
||||
<string name="enable_queue_limit">Llendar la cola de descarga</string>
|
||||
<string name="close">Zarrar</string>
|
||||
<string name="pause_downloads_on_mobile_desc">Útil al cambiar a los datos móviles, magar que dalgunes descargues nun puedan suspendese</string>
|
||||
<string name="pause_downloads_on_mobile">Torgar nes redes midíes</string>
|
||||
<string name="stop">Parar</string>
|
||||
<string name="deleted_downloads">Desaniciáronse %1$d descargues</string>
|
||||
<string name="delete_downloaded_files">Desaniciar lo baxao</string>
|
||||
<string name="clear_download_history">Llimpiar l\'historial de descargues</string>
|
||||
<string name="error_download_resource_gone">Esta descarga nun pue recuperase</string>
|
||||
<string name="error_postprocessing_stopped">NewPipe zarróse mentanto trabayaba nel ficheru</string>
|
||||
<string name="error_postprocessing_failed">Falló\'l posprocesamientu</string>
|
||||
<string name="error_http_not_found">Nun s\'atopó</string>
|
||||
<string name="error_permission_denied">El sistema negó\'l permisu</string>
|
||||
<string name="label_code">Códigu</string>
|
||||
<string name="show_error">Amosar el fallu</string>
|
||||
<string name="overwrite">Sobrescribir</string>
|
||||
<string name="generate_unique_name">Xenerar un nome únicu</string>
|
||||
<string name="download_finished_more">Finaron %s descargues</string>
|
||||
<string name="permission_denied">El sistema negó l\'aición</string>
|
||||
<string name="enqueue">Amestar a la cola</string>
|
||||
<string name="recovering">recuperando</string>
|
||||
<string name="post_processing">posprocesando</string>
|
||||
<string name="queued">na cola</string>
|
||||
<string name="paused">posóse</string>
|
||||
<string name="missions_header_pending">Pendiente</string>
|
||||
<string name="switch_view">Cambiar la vista</string>
|
||||
<string name="auto">Auto</string>
|
||||
<string name="list_view_mode">Mou de la vista de les llistes</string>
|
||||
<string name="never">Enxamás</string>
|
||||
<string name="wifi_only">Namás na Wi-Fi</string>
|
||||
<string name="autoplay_summary">Anicia automáticamente la reproducción — %s</string>
|
||||
<string name="minimize_on_exit_none_description">Nada</string>
|
||||
<string name="limit_mobile_data_usage_title">Llendar la resolución al usar los datos móviles</string>
|
||||
<string name="limit_data_usage_none_description">Ensin llende</string>
|
||||
<string name="playback_reset">Reafitar</string>
|
||||
<string name="playback_step">Pasu</string>
|
||||
<string name="skip_silence_checkbox">Avance rápidu nos silencios</string>
|
||||
<string name="unhook_checkbox">Separtar (pue causar distorsión)</string>
|
||||
<string name="playback_speed_control">Controles de la velocidá de reproducción</string>
|
||||
<string name="import_network_expensive_warning">Ten en cuenta qu\'esta operación pue ser esixente cola rede.
|
||||
\n
|
||||
\n¿Quies siguir\?</string>
|
||||
<string name="export_to">Esportar a</string>
|
||||
<string name="import_from">Importar dende</string>
|
||||
<string name="import_title">Importar</string>
|
||||
<string name="show_original_time_ago_summary">Los testos orxinales de los servicios van amosase nos elementos de les tresmisiones</string>
|
||||
<string name="show_original_time_ago_title">Amosar les marques de tiempu orixinales</string>
|
||||
<string name="enable_disposed_exceptions_summary">Forcia l\'informe d\'esceiciones Rx que nun se puen entregar fuera del ciclu de vida d\'un fragmentu o actividá dempués de desanicialos</string>
|
||||
<string name="enable_disposed_exceptions_title">Informar de fallos fuera de ciclu</string>
|
||||
<string name="show_memory_leaks">Amosar los escapes de memoria</string>
|
||||
<string name="enable_leak_canary_summary">La supervisión de los escapes de memoria pue facer que l\'aplicación nun respuenda al volquiar la pila</string>
|
||||
<string name="caption_setting_description">Modifica\'l testu de los sotítulos y el so fondu. Rique\'l reaniciu de l\'aplicación pa que faiga efeutu.</string>
|
||||
<string name="caption_auto_generated">Xeneróse automáticamente</string>
|
||||
<string name="playlist_no_uploader">Xeneróse automáticamente (nun s\'atopó\'l xubidor)</string>
|
||||
<string name="playlist_thumbnail_change_success">Camudóse la miniatura de la llista de reproducción.</string>
|
||||
<string name="playlist_add_stream_success">Metióse nuna llista de reproducción</string>
|
||||
<string name="playlist_creation_success">Creóse la llista de reproducción</string>
|
||||
<string name="unbookmark_playlist">Desaniciar el marcador</string>
|
||||
<string name="bookmark_playlist">Amestar la llista a marcadores</string>
|
||||
<string name="set_as_playlist_thumbnail">Afitar como la miniatura de la llista</string>
|
||||
<string name="unmute">Desactivar el soníu</string>
|
||||
<string name="mute">Activar el soníu</string>
|
||||
<string name="rename_playlist">Renomar</string>
|
||||
<string name="delete_playlist">Desaniciar</string>
|
||||
<string name="preferred_player_fetcher_notification_title">Consiguiendo la información…</string>
|
||||
<string name="always_ask_open_action">Entrugar siempres</string>
|
||||
<string name="popup_player">Reproductor en ventanu</string>
|
||||
<string name="background_player">Reproductor en segundu planu</string>
|
||||
<string name="video_player">Reproductor de videu</string>
|
||||
<string name="preferred_open_action_settings_summary">L\'aición predeterminada al abrir conteníu — %s</string>
|
||||
<string name="drawer_close">Zarrar el caxón</string>
|
||||
<string name="drawer_open">Abrir el caxón</string>
|
||||
<string name="start_here_on_main">Reproducir equí</string>
|
||||
<string name="enqueued">Amestóse a la cola</string>
|
||||
<string name="enqueue_stream">Amestar a la cola</string>
|
||||
<string name="hold_to_append">Ten primío p\'amestar a la cola</string>
|
||||
<string name="play_queue_audio_settings">Axustes del audiu</string>
|
||||
<string name="play_queue_remove">Desaniciar</string>
|
||||
<string name="title_activity_play_queue">Cola de reproducción</string>
|
||||
<string name="most_liked">Lo que más prestó</string>
|
||||
<string name="recently_added">Amestóse apocayá</string>
|
||||
<string name="local">Llocal</string>
|
||||
<string name="no_valid_zip_file">El ficheru ZIP nun ye válidu</string>
|
||||
<string name="no_playlist_bookmarked_yet">Entá nun hai llistes en marcadores</string>
|
||||
<string name="select_a_playlist">Esbilla d\'una llista de reproducción</string>
|
||||
<string name="no_channel_subscribed_yet">Entá nun hai soscripciones a canales</string>
|
||||
<string name="select_a_channel">Esbilla d\'una canal</string>
|
||||
<string name="channel_page_summary">Páxina d\'una canal</string>
|
||||
<string name="feed_page_summary">Páxina del feed</string>
|
||||
<string name="subscription_page_summary">Páxina de soscripciones</string>
|
||||
<string name="default_kiosk_page_summary">Quioscu predetermináu</string>
|
||||
<string name="kiosk_page_summary">Páxina de quioscu</string>
|
||||
<string name="title_most_played">Lo más reproducío</string>
|
||||
<string name="title_last_played">Lo último reproducío</string>
|
||||
<string name="delete_stream_history_prompt">¿Quies desaniciar esti elementu del historial de vídeos vistos\?</string>
|
||||
<string name="item_deleted">Desanicióse l\'elementu</string>
|
||||
<string name="history_cleared">Llimpióse l\'historial</string>
|
||||
<string name="title_history_search">Buscóse</string>
|
||||
<string name="app_license">NewPipe ye software copyleft: pues usalu, estudialu, compartilu y ameyoralu como quieras. N\'especial, pues redistribuyilu y/o modificalu baxo los términos de la GNU General Public License según espublizó la Free Software Foundation, quier la versión 3 de la llicencia quier (na to opinión) cualesquier versión posterior.</string>
|
||||
<string name="privacy_policy_encouragement">El proyeutu de NewPipe toma mui en serio la privacidá. Poro, l\'aplicación nun recueye nengún datu ensin el to consentimientu.
|
||||
\nLa política de privacidá de NewPipe desplica en detalle los datos que s\'unvien y atroxen cuando unvies un informe de casque.</string>
|
||||
<string name="app_description">Un aplicación llibre pa ver/sentir plataformes de tresmisión n\'Android.</string>
|
||||
<string name="action_open_website">Abrir el sitiu web</string>
|
||||
<string name="toast_no_player">Nun hai nenguna aplicación pa reproducir esti ficheru</string>
|
||||
<string name="settings_file_replacement_character_title">Caráuteres de troquéu</string>
|
||||
<string name="settings_file_replacement_character_summary">Los caráuteres que nun son válidos van trocase por esti valor</string>
|
||||
<string name="recaptcha_done_button">Fecho</string>
|
||||
<string name="subtitle_activity_recaptcha">Primi «Fecho» al resolvelu</string>
|
||||
<string name="one_item_deleted">Desanicióse 1 elementu.</string>
|
||||
<string name="no_available_dir">Defini una capeta de descargues dempués, nos axustes de l\'aplicación</string>
|
||||
<string name="msg_running_detail">Toca pa los detalles</string>
|
||||
<string name="msg_running">Descarga de NewPipe</string>
|
||||
<string name="msg_url_malform">La URL ta mal formada o internet nun ta disponible</string>
|
||||
<string name="msg_server_unsupported">El sirvidor nun ta sofitáu</string>
|
||||
<string name="msg_name">Nome del ficheru</string>
|
||||
<string name="rename">Renomar</string>
|
||||
<string name="delete_all">Desaniciar too</string>
|
||||
<string name="delete_one">Desaniciar un elementu</string>
|
||||
<string name="view">Reproducir</string>
|
||||
<string name="pause">Posar</string>
|
||||
<string name="start">Aniciar</string>
|
||||
<string name="infinite_videos">Vídeos ∞</string>
|
||||
<string name="more_than_100_videos">+100 vídeos</string>
|
||||
<plurals name="listening">
|
||||
<item quantity="one">%s oyente</item>
|
||||
<item quantity="other">%s oyentes</item>
|
||||
</plurals>
|
||||
<string name="no_one_listening">Naide nun ta sintiendo</string>
|
||||
<plurals name="watching">
|
||||
<item quantity="one">%s espectador</item>
|
||||
<item quantity="other">%s espectadores</item>
|
||||
</plurals>
|
||||
<string name="no_one_watching">Nun hai espectadores</string>
|
||||
<string name="no_subscribers">Nun hai soscriptores</string>
|
||||
<string name="drawer_header_description">Alternar el serviciu, esbillóse:</string>
|
||||
<string name="storage_permission_denied">Concedi l\'accesu al almacenamientu primero</string>
|
||||
<string name="retry">Retentar</string>
|
||||
<string name="err_dir_create">Nun pue crease\'l direutoriu de descarga «%1$s»</string>
|
||||
<string name="detail_drag_description">Arrastra pa reordenar</string>
|
||||
<string name="user_report">Informe d\'usuariu</string>
|
||||
<string name="report_error">Informar del fallu</string>
|
||||
<string name="use_tor_summary">(Esperimental) Forcia\'l tráficu de les descargues pente Tor pa más privacidá (la reproducción de vídeos entá nun se sofita).</string>
|
||||
<string name="detail_uploader_thumbnail_view_description">Avatar del xubidor</string>
|
||||
<string name="detail_thumbnail_view_description">Reproducción d\'un videu, duración:</string>
|
||||
<string name="list_thumbnail_view_description">Miniatura del videu</string>
|
||||
<string name="your_comment">Un comentariu (n\'inglés):</string>
|
||||
<string name="what_happened_headline">Qué pasó:</string>
|
||||
<string name="error_snackbar_action">Informar</string>
|
||||
<string name="error_report_open_github_notice">Comprueba si yá esiste un problema qu\'alderique esti casque, por favor. Al crear informes duplicaos faes que perdamos el tiempu que podríemos dedicar a iguar el fallu.</string>
|
||||
<string name="error_report_open_issue_button_text">Informar en GitHub</string>
|
||||
<string name="copy_for_github">Copiar l\'informe con formatu</string>
|
||||
<string name="error_report_button_text">Informar d\'esti fallu per corréu</string>
|
||||
<string name="permission_display_over_apps">Da\'l permisu p\'amosar NewPipe penriba d\'otres aplicaciones</string>
|
||||
<string name="saved_tabs_invalid_json">Nun pudieron lleese les llingüetes guardaes polo que van usase les predeterminaes</string>
|
||||
<string name="no_streams_available_download">Nun hai fluxos disponibles pa baxar</string>
|
||||
<string name="file_name_empty_error">El nome del ficheru nun pue tar baleru</string>
|
||||
<string name="invalid_source">El ficheru/orixe del conteníu nun esiste</string>
|
||||
<string name="invalid_directory">La carpeta nun esiste</string>
|
||||
<string name="audio_streams_empty">Nun s\'atoparon fluxos d\'audiu</string>
|
||||
<string name="video_streams_empty">Nun s\'atoparon fluxos de videu</string>
|
||||
<string name="player_recoverable_failure">L\'aplicación ta recuperándose d\'un fallu del reproductor</string>
|
||||
<string name="app_ui_crash">L\'aplicación/IU cascó</string>
|
||||
<string name="could_not_load_image">Nun pudo cargase la imaxe</string>
|
||||
<string name="could_not_setup_download_menu">Nun pudo configurase\'l menú de descarga</string>
|
||||
<string name="content_not_available">El conteníu nun ta disponible</string>
|
||||
<string name="light_parsing_error">Nun pudo analizase dafechu\'l sitiu web</string>
|
||||
<string name="network_error">Fallu de la rede</string>
|
||||
<string name="download_to_sdcard_error_message">La descarga a la tarxeta SD nun ye posible. ¿Reafitar l\'allugamientu de la carpeta de descarga\?</string>
|
||||
<string name="download_to_sdcard_error_title">L\'almacenamientu esternu nun ta disponible</string>
|
||||
<string name="help">Ayuda</string>
|
||||
<string name="search_history_deleted">Desanicióse l\'historial de busques.</string>
|
||||
<string name="clear_search_history_summary">Desanicia l\'historial de les pallabres clave de busca</string>
|
||||
<string name="clear_search_history_title">Llimpiar l\'historial de busca</string>
|
||||
<string name="watch_history_states_deleted">Desaniciáronse los puntos de reproducción.</string>
|
||||
<string name="delete_playback_states_alert">¿Desaniciar tolos puntos de reproducción\?</string>
|
||||
<string name="clear_playback_states_summary">Desanicia tolos puntos de reproducción</string>
|
||||
<string name="clear_playback_states_title">Desaniciar los puntos de reproducción</string>
|
||||
<string name="watch_history_deleted">Desanicióse l\'historial de vídeos vistos.</string>
|
||||
<string name="delete_view_history_alert">¿Desaniciar tol historial de vídeos vistos\?</string>
|
||||
<string name="clear_views_history_summary">Desanicia l\'historial de fluxos reproducíos y el de puntos de reproducción</string>
|
||||
<string name="clear_views_history_title">Llimpiar l\'historial de los vídeos vistos</string>
|
||||
<string name="clear_cookie_summary">Llimpia les cookies que NewPipe atrroxa cuando soluciones un reCAPTCHA</string>
|
||||
<string name="recaptcha_cookies_cleared">Llimpiáronse les cookies de reCAPTCHA</string>
|
||||
<string name="clear_cookie_title">Llimpiar les cookies de reCAPTCHA</string>
|
||||
<string name="switch_to_main">Cambiar al reproductor principal</string>
|
||||
<string name="switch_to_popup">Cambiar al reproductor en ventanu</string>
|
||||
<string name="switch_to_background">Cambiar al reproductor en segundu planu</string>
|
||||
<string name="toggle_orientation">Alternar la orientación</string>
|
||||
<string name="app_update_notification_channel_description">Anovamientos pa NewPipe</string>
|
||||
<string name="app_update_notification_channel_name">Avisos d\'anovamientos</string>
|
||||
<string name="notification_channel_description">Avisos de los reproductores en segundu planu y en ventanu de NewPipe</string>
|
||||
<string name="just_once">Namás una vegada</string>
|
||||
<string name="file_deleted">Desanicióse\'l ficheru</string>
|
||||
<string name="undo">Desfacer</string>
|
||||
<string name="popup_resizing_indicator_title">Redimensionáu</string>
|
||||
<string name="refresh">Refrescar</string>
|
||||
<string name="filter">Peñerar</string>
|
||||
<string name="disabled">Desactivóse</string>
|
||||
<string name="later">Dempués</string>
|
||||
<string name="artists">Artistes</string>
|
||||
<string name="albums">Álbumes</string>
|
||||
<string name="songs">Canciones</string>
|
||||
<string name="playlist">Llista de reproducción</string>
|
||||
<string name="all">Too</string>
|
||||
<string name="error_report_title">Informe d\'un fallu</string>
|
||||
<string name="restricted_video">Tien una torga por edá.
|
||||
\n
|
||||
\nActiva «%1$s» nos axustes de l\'aplicación si quies velu.</string>
|
||||
<string name="youtube_restricted_mode_enabled_summary">YouTube forne\'l «Mou torgáu» qu\'anubre conteníu\'l que seya potencialmente p\'adultos</string>
|
||||
<string name="youtube_restricted_mode_enabled_title">Activar el «Mou torgáu» de YouTube</string>
|
||||
<string name="show_age_restricted_content_summary">Amuesa\'l conteníu que quiciabes nun seya afayadizu pa guaḥes porque tien una llende d\'edá (como +18)</string>
|
||||
<string name="popup_playing_append">Amestóse a la cola del reproductor en ventanu</string>
|
||||
<string name="background_player_append">Amestóse a la cola del reproductor en segundu planu</string>
|
||||
<string name="settings_category_notification_title">Avisu permanente</string>
|
||||
<string name="settings_category_debug_title">Depuración</string>
|
||||
<string name="settings_category_other_title">Miscelánea</string>
|
||||
<string name="settings_category_popup_title">Ventanu</string>
|
||||
<string name="peertube_instance_add_https_only">Namás se sofiten URLs HTTPS</string>
|
||||
<string name="peertube_instance_add_help">Introduz la URL d\'una instancia</string>
|
||||
<string name="peertube_instance_add_title">Amiestu d\'una instancia</string>
|
||||
<string name="peertube_instance_url_help">Atopa les instancies que te presten en %s</string>
|
||||
<string name="peertube_instance_url_summary">Esbilla les instancies de PeerTube que prefieras</string>
|
||||
<string name="service_title">Serviciu</string>
|
||||
<string name="unsupported_url_dialog_message">Nun pudo reconocese la URL. ¿Abrila con otra aplicación\?</string>
|
||||
<string name="show_hold_to_append_summary">Amuesa\'l mensaxe al primir el nel botón «En segundu planu» o «Ventanu» nel «Details:» de los vídeos</string>
|
||||
<string name="show_hold_to_append_title">Amosar el mensaxe «Ten primío p\'amestar a la cola»</string>
|
||||
<string name="show_next_and_similar_title">Amosar los vídeos siguientes y asemeyaos</string>
|
||||
<string name="download_dialog_title">Descarga</string>
|
||||
<string name="enable_watch_history_summary">Rexistra los vídeos vistos</string>
|
||||
<string name="enable_playback_state_lists_summary">Amuesa los indicadores de los puntos de reprodución nes llistes</string>
|
||||
<string name="enable_playback_state_lists_title">Puntos de reproducción nes llistes</string>
|
||||
<string name="enable_playback_resume_summary">Restaura l\'últimu puntu de reproducción</string>
|
||||
<string name="enable_watch_history_title">Historial de vídeos vistos</string>
|
||||
<string name="auto_queue_toggle">Cola automática</string>
|
||||
<string name="auto_queue_summary">Amiesta un videu rellacionáu a la cola cuando se repoduz l\'últimu videu a una cola ensin repitición</string>
|
||||
<string name="auto_queue_title">Meter les tresmisiones siguientes a cola automática</string>
|
||||
<string name="clear_queue_confirmation_description">Va trocase la cola del reproductor activu</string>
|
||||
<string name="clear_queue_confirmation_summary">Cambiar d\'un reproductor a otru pue trocar la cola</string>
|
||||
<string name="clear_queue_confirmation_title">Confirmar la llimpieza de les coles</string>
|
||||
<string name="seek_duration_title">Duración de la gueta del avance/rebobináu rápidu</string>
|
||||
<string name="use_inexact_seek_summary">La gueta imprecisa permite al reproductor que guete les posiciones más rápido con menos precisión. La gueta de 5, 15 ó 25 segundos nun funciona con esti axuste.</string>
|
||||
<string name="use_inexact_seek_title">Usar la gueta rápida imprecisa</string>
|
||||
<string name="popup_remember_size_pos_summary">Acuérdase del últimu tamañu y la última posición del ventanu</string>
|
||||
<string name="popup_remember_size_pos_title">Acordase de les propiedaes del ventanu</string>
|
||||
<string name="notification_colorize_summary">Fai qu\'Android personalice\'l color del avisu permanente según el color principal de les miniatures (decátate qu\'esto nun ta disponible en tolos preseos)</string>
|
||||
<string name="notification_colorize_title">Avisu con color</string>
|
||||
<string name="notification_action_nothing">Nada</string>
|
||||
<string name="notification_action_buffering">Atroxar nel búfer</string>
|
||||
<string name="notification_action_shuffle">Al debalu</string>
|
||||
<string name="notification_action_repeat">Repitir</string>
|
||||
<string name="notification_actions_at_most_three">¡Pues esbillar tres aiciones como máximu p\'amosar nel avisu permanente!</string>
|
||||
<string name="notification_actions_summary">Edita cada aición d\'embaxo tocando nelles. Esbilla hasta tres p\'amosales nel avisu compautu col usu de los caxellos de la derercha.</string>
|
||||
<string name="notification_action_4_title">Quintu botón d\'aición</string>
|
||||
<string name="notification_action_3_title">Cuartu botón d\'aición</string>
|
||||
<string name="notification_action_2_title">Tercer botón d\'aición</string>
|
||||
<string name="notification_action_1_title">Segundu botón d\'aición</string>
|
||||
<string name="notification_action_0_title">Primer botón d\'aición</string>
|
||||
<string name="notification_scale_to_square_image_summary">Escala les miniatures de los vídeos que s\'amuesen nel avisu permanente de los 16:9 al 1:1 (podría distorsionar les imáxenes)</string>
|
||||
<string name="notification_scale_to_square_image_title">Afitar la escala 1:1 a les miniatures</string>
|
||||
<string name="autoplay_by_calling_app_title">Reproducción automática</string>
|
||||
<string name="download_choose_new_path">Camuda les carpetes de descarga pa que faiga efeutu</string>
|
||||
<string name="download_path_audio_dialog_title">Escueyi la carpeta de descarga pa los ficheros d\'audiu</string>
|
||||
<string name="download_path_audio_summary">Los ficheros d\'audiu baxaos atróxense equí</string>
|
||||
<string name="download_path_audio_title">Carpeta de la descarga d\'audiu</string>
|
||||
<string name="download_path_dialog_title">Escueyi la carpeta de descarga pa los ficheros de videu</string>
|
||||
<string name="download_path_summary">Los ficheros de videu baxaos atróxense equí</string>
|
||||
<string name="download_path_title">Carpeta de la descarga de vídeos</string>
|
||||
<string name="controls_add_to_playlist_title">Meter nuna llista</string>
|
||||
<string name="tab_main">Principal</string>
|
||||
<string name="subscription_change_failed">Nun pudo camudar la soscripción</string>
|
||||
<string name="channel_unsubscribed">Esborriéstite de la canal</string>
|
||||
<string name="popup_mode_share_menu_title">Mou ventanu</string>
|
||||
<string name="screen_rotation">voltéu</string>
|
||||
<string name="choose_browser">Escoyer un restolador</string>
|
||||
<string name="search_showing_result_for">Amosando los resultaos de: %s</string>
|
||||
<string name="controls_download_desc">Baxar el ficheru de fluxos</string>
|
||||
<string name="download">Baxar</string>
|
||||
<string name="open_in_popup_mode">Abrir nel mou ventanu</string>
|
||||
<string name="install">Instalar</string>
|
||||
<string name="no_player_found">Nun s\'atopó nengún reproductor de fluxos. ¿Instalar VLC\?</string>
|
||||
<string name="main_bg_subtitle">Toca «Buscar» pa entamar
|
||||
\n</string>
|
||||
</resources>
|
|
@ -303,8 +303,8 @@
|
|||
<string name="preferred_player_fetcher_notification_message">正在加载请求的内容</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="import_data_summary">覆盖您的当前播放历史、订阅、播放列表和(可选)设置</string>
|
||||
<string name="export_data_summary">导出历史记录、订阅、播放列表和设置</string>
|
||||
<string name="export_complete_toast">导出成功</string>
|
||||
<string name="import_complete_toast">导入成功</string>
|
||||
<string name="no_valid_zip_file">没有有效的ZIP文件</string>
|
||||
|
|
|
@ -255,7 +255,7 @@
|
|||
<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="action_about">А прыладзе</string>
|
||||
<string name="title_licenses">Іншыя ліцэнзіі</string>
|
||||
<string name="copyright" formatted="true">© %1$s %2$s пад ліцэнзіяй %3$s</string>
|
||||
<string name="error_unable_to_load_license">Не атрымалася загрузіць ліцэнзію</string>
|
||||
|
@ -314,7 +314,7 @@
|
|||
<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="hold_to_append">Утрымлівайце, каб дадаць у чаргу</string>
|
||||
<string name="start_here_on_main">Пачаць адсюль у плэеры</string>
|
||||
<string name="start_here_on_background">Пачаць адсюль у фоне</string>
|
||||
<string name="start_here_on_popup">Пачаць адсюль у акне</string>
|
||||
|
@ -402,7 +402,7 @@
|
|||
<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="settings_category_updates_title">Абнаўленні</string>
|
||||
<string name="file_deleted">Файл выдалены</string>
|
||||
<string name="app_update_notification_channel_name">Апавяшчэнне аб абнаўленні</string>
|
||||
<string name="app_update_notification_channel_description">Апавяшчэння аб новай версіі NewPipe</string>
|
||||
|
@ -476,7 +476,7 @@
|
|||
<string name="error_insufficient_storage">Скончылася вольнае месца на прыладзе</string>
|
||||
<string name="error_progress_lost">Прагрэс страчаны, так як файл быў выдалены</string>
|
||||
<string name="error_timeout">Час злучэння выйшла</string>
|
||||
<string name="confirm_prompt">Вы ўпэўненыя\?</string>
|
||||
<string name="confirm_prompt">Вы ўпэўнены\?</string>
|
||||
<string name="enable_queue_limit">Абмежаваць чаргу загрузкі</string>
|
||||
<string name="enable_queue_limit_desc">Толькі адна адначасовая загрузка</string>
|
||||
<string name="start_downloads">Пачаць загрузку</string>
|
||||
|
@ -492,8 +492,8 @@
|
|||
<string name="clear_playback_states_summary">Выдаліць ўсе пазіцыі прайгравання</string>
|
||||
<string name="youtube_restricted_mode_enabled_title">Абмежаваны рэжым YouTube</string>
|
||||
<string name="peertube_instance_add_https_only">Падтрымліваюцца толькі адрасы URL HTTPS</string>
|
||||
<string name="peertube_instance_add_title">Дадаць інстанцыю</string>
|
||||
<string name="peertube_instance_url_title">Інстанцыі PeerTube</string>
|
||||
<string name="peertube_instance_add_title">Дадаць экзэмпляр</string>
|
||||
<string name="peertube_instance_url_title">Экзэмпляры PeerTube</string>
|
||||
<string name="download_choose_new_path">Змяніце папкі загрузкі, каб змены ўступілі ў сілу</string>
|
||||
<string name="search_showing_result_for">Вынікі для: %s</string>
|
||||
<string name="notification_scale_to_square_image_title">Мініяцюра відэа ў 1:1</string>
|
||||
|
@ -502,4 +502,58 @@
|
|||
<string name="notification_action_2_title">Кнопка трэцяга дзеяння</string>
|
||||
<string name="notification_action_1_title">Кнопка другога дзеяння</string>
|
||||
<string name="notification_action_0_title">Кнопка першага дзеяння</string>
|
||||
<string name="feed_groups_header_title">Групы каналаў</string>
|
||||
<string name="systems_language">Як у сістэме</string>
|
||||
<string name="app_language_title">Мова прылады</string>
|
||||
<string name="choose_instance_prompt">Выберыце экзэмпляр</string>
|
||||
<string name="deleted_downloads">Выдалена %1$d загрузак</string>
|
||||
<string name="delete_downloaded_files">Выдаліць загружаныя файлы</string>
|
||||
<string name="show_original_time_ago_summary">Арыгінальныя тэксты з сэрвісаў будуць бачны ў ленце элементаў</string>
|
||||
<string name="clear_cookie_summary">Ачысціце cookie, якія NewPipe захоўвае пры рашэнні reCAPTCHA</string>
|
||||
<string name="peertube_instance_add_exists">Экзэмпляр ужо існуе</string>
|
||||
<string name="peertube_instance_add_fail">Немагчыма праверыць экзэмпляр</string>
|
||||
<string name="peertube_instance_add_help">Увесці URL экзэмпляра</string>
|
||||
<string name="peertube_instance_url_summary">Абярыце любімыя экзэмпляры PeerTube</string>
|
||||
<string name="clear_queue_confirmation_description">Актыўны плэер быў зменены</string>
|
||||
<string name="clear_queue_confirmation_summary">Змена плэера можа замяніць вашу чаргу</string>
|
||||
<string name="clear_queue_confirmation_title">Запытаць, перш чым ачысціць чаргу</string>
|
||||
<string name="never">Ніколі</string>
|
||||
<string name="wifi_only">Толькі па Wi-Fi</string>
|
||||
<string name="show_original_time_ago_title">Паказаць арыгінальны час на элементах</string>
|
||||
<string name="unmute">Уключыць гук</string>
|
||||
<string name="mute">Цішына</string>
|
||||
<string name="enqueue_stream">Дадаць у чаргу</string>
|
||||
<string name="enqueued">Даданае у чаргу</string>
|
||||
<string name="title_activity_play_queue">Чарга прайгравання</string>
|
||||
<string name="most_liked">Найбольш папулярнае</string>
|
||||
<string name="local">Лакальнае</string>
|
||||
<string name="recently_added">Нядаўна дададзенае</string>
|
||||
<string name="no_playlist_bookmarked_yet">Няма закладак у плейлісце</string>
|
||||
<string name="select_a_playlist">Абярыце плэйліст</string>
|
||||
<string name="default_kiosk_page_summary">Кіёск па змаўчанні</string>
|
||||
<string name="recaptcha_done_button">Так</string>
|
||||
<string name="subtitle_activity_recaptcha">Націсніце \"Так\" калі вырашана</string>
|
||||
<string name="infinite_videos">∞ відэа</string>
|
||||
<string name="more_than_100_videos">100+ відэа</string>
|
||||
<string name="error_report_open_issue_button_text">Багрэпарт на GitHub</string>
|
||||
<string name="copy_for_github">Скапіруйце адфарматаваны багрэпарт</string>
|
||||
<string name="permission_display_over_apps">Дайце дазвол на адлюстраванне паверх іншых праграм</string>
|
||||
<string name="help">Дапамога</string>
|
||||
<string name="delete_playback_states_alert">Выдаліць усе пазіцыі прайгравання\?</string>
|
||||
<string name="clear_playback_states_title">Выдаліць пазіцыі прайгравання</string>
|
||||
<string name="clear_cookie_title">Ачысціць reCAPTCHA cookies</string>
|
||||
<string name="recaptcha_cookies_cleared">reCAPTCHA cookies былі ачышчаны</string>
|
||||
<string name="artists">Выканаўцы</string>
|
||||
<string name="albums">Альбомы</string>
|
||||
<string name="songs">Песні</string>
|
||||
<string name="videos_string">Відэа</string>
|
||||
<string name="auto_queue_toggle">Аўтаматычная чарга</string>
|
||||
<string name="seek_duration_title">Працягласць перамоткі ўперад/назад</string>
|
||||
<string name="notification_colorize_title">Каляровыя апавяшчэнні</string>
|
||||
<string name="notification_action_nothing">Нічога</string>
|
||||
<string name="notification_action_buffering">Буферызацыя</string>
|
||||
<string name="notification_action_shuffle">Ператасаваць</string>
|
||||
<string name="notification_action_repeat">Паўтор</string>
|
||||
<string name="notification_action_4_title">Кнопка пятага дзеяння</string>
|
||||
<string name="settings_category_notification_title">Паведамленні</string>
|
||||
</resources>
|
|
@ -258,8 +258,8 @@
|
|||
<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>
|
||||
<string name="export_data_summary">Exportuje historii, odběry a playlisty</string>
|
||||
<string name="import_data_summary">Přepíše Vaši dosavadní historii, odběry, playlisty a (volitelně) nastavení</string>
|
||||
<string name="export_data_summary">Exportuje historii, odběry, playlisty a nastavení</string>
|
||||
<string name="external_player_unsupported_link_type">Externí přehrávače nepodporují tyto druhy odkazů</string>
|
||||
<string name="invalid_url_toast">Neplatná URL</string>
|
||||
<string name="video_streams_empty">Nenalezeny žádné video streamy</string>
|
||||
|
|
|
@ -132,7 +132,7 @@
|
|||
<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="player_gesture_controls_summary">Gesten verwenden, um die Helligkeit und Lautstärke einzustellen</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>
|
||||
|
@ -266,8 +266,8 @@
|
|||
<string name="preferred_player_fetcher_notification_message">Gewünschten Inhalt laden</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="import_data_summary">Überschreibt deinen aktuellen Verlauf, Abonnements, Wiedergabelisten und (optionale) Einstellungen</string>
|
||||
<string name="export_data_summary">Export von Verlauf, Abonnements, Wiedergabelisten und Einstellungen</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>
|
||||
|
@ -402,9 +402,9 @@
|
|||
<string name="tab_new">Neuer Tab</string>
|
||||
<string name="tab_choose">Tab wählen</string>
|
||||
<string name="volume_gesture_control_title">Gestensteuerung für Lautstärke</string>
|
||||
<string name="volume_gesture_control_summary">Verwende Gesten um die Abspielerlautstärke einzustellen</string>
|
||||
<string name="volume_gesture_control_summary">Gesten verwenden, um die Lautstärke einzustellen</string>
|
||||
<string name="brightness_gesture_control_title">Gestensteuerung für Helligkeit</string>
|
||||
<string name="brightness_gesture_control_summary">Player-Helligkeit über Gesten steuern</string>
|
||||
<string name="brightness_gesture_control_summary">Gesten verwenden, um die Helligkeit einzustellen</string>
|
||||
<string name="settings_category_updates_title">Aktualisierungen</string>
|
||||
<string name="file_deleted">Datei gelöscht</string>
|
||||
<string name="app_update_notification_channel_name">App-Update-Benachrichtigung</string>
|
||||
|
@ -643,7 +643,7 @@
|
|||
<string name="clear_cookie_summary">Lösche Cookies, die NewPipe speichert, wenn du ein reCAPTCHA löst</string>
|
||||
<string name="recaptcha_cookies_cleared">reCAPTCHA-Cookies wurden gelöscht</string>
|
||||
<string name="clear_cookie_title">reCAPTCHA-Cookies löschen</string>
|
||||
<string name="show_age_restricted_content_summary">Zeige Inhalt, der möglicherweise unpassend für Kinder ist, da er eine Altersbeschränkung (wie z.B. 18+) hat</string>
|
||||
<string name="show_age_restricted_content_summary">Zeige altersbeschränkte Inhalte (bspw. 18+), welche möglicherweise unpassend für Kinder sein könnten</string>
|
||||
<string name="enqueue_stream">Wiedergabe einreihen</string>
|
||||
<string name="notification_colorize_summary">Android kann die Farbe der Benachrichtigung entsprechend der Hauptfarbe in der Miniaturansicht anpassen (beachte, dass dies nicht auf allen Geräten verfügbar ist)</string>
|
||||
<string name="notification_colorize_title">Benachrichtigung farblich anpassen</string>
|
||||
|
|
|
@ -265,8 +265,8 @@
|
|||
<string name="preferred_player_fetcher_notification_message">Cargando contenido solicitado</string>
|
||||
<string name="import_data_title">Importar base de datos</string>
|
||||
<string name="export_data_title">Exportar base de datos</string>
|
||||
<string name="import_data_summary">Anula su historial actual y suscripciones</string>
|
||||
<string name="export_data_summary">Exportar historial, suscripciones y listas de reproducción</string>
|
||||
<string name="import_data_summary">Anula su historial actual, suscripciones, listas de reproducción y (opcionalmente) ajustes</string>
|
||||
<string name="export_data_summary">Exportar historial, suscripciones, listas de reproducción y ajustes</string>
|
||||
<string name="export_complete_toast">Exportado</string>
|
||||
<string name="import_complete_toast">Importado</string>
|
||||
<string name="no_valid_zip_file">Archivo ZIP no válido</string>
|
||||
|
|
|
@ -263,8 +263,8 @@
|
|||
<string name="preferred_player_fetcher_notification_message">Chargement du contenu demandé</string>
|
||||
<string name="import_data_title">Importer la base de données</string>
|
||||
<string name="export_data_title">Exporter la base de données</string>
|
||||
<string name="import_data_summary">Remplace votre historique et vos abonnements actuels</string>
|
||||
<string name="export_data_summary">Exporte l’historique, les abonnements et les listes de lecture</string>
|
||||
<string name="import_data_summary">Remplace votre historique, vos abonnements, vos listes de lecture et (en option) vos paramètres</string>
|
||||
<string name="export_data_summary">Exporte l’historique, les abonnements, les listes de lecture et les paramètres</string>
|
||||
<string name="export_complete_toast">Exporté</string>
|
||||
<string name="import_complete_toast">Importé</string>
|
||||
<string name="no_valid_zip_file">Fichier ZIP non valide</string>
|
||||
|
|
|
@ -268,7 +268,7 @@
|
|||
<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>
|
||||
<string name="export_data_summary">ייצוא היסטוריה, מינויים, רשימות נגינה והגדרות</string>
|
||||
<string name="clear_views_history_title">מחיקת היסטוריית הצפייה</string>
|
||||
<string name="watch_history_deleted">היסטוריית הצפייה נמחקה.</string>
|
||||
<string name="clear_search_history_title">מחיקת היסטוריית החיפוש</string>
|
||||
|
@ -336,7 +336,7 @@
|
|||
<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="import_data_summary">משכתב את ההיסטוריה, המינויים ו(אולי גם) את ההגדרות הנוכחיים שלך</string>
|
||||
<string name="clear_views_history_summary">מחיקת היסטוריית התזרימים שהתנגנו ומיקומי הנגינה</string>
|
||||
<string name="channels">ערוצים</string>
|
||||
<string name="playlists">רשימות נגינה</string>
|
||||
|
|
|
@ -290,15 +290,15 @@
|
|||
<string name="switch_to_main">Prijeđi na glavni</string>
|
||||
<string name="import_data_title">Uvoz baze podataka</string>
|
||||
<string name="export_data_title">Izvoz baze podataka</string>
|
||||
<string name="import_data_summary">Poništava vašu trenutnu povijest i pretplate</string>
|
||||
<string name="export_data_summary">Izvezi povijest, pretplate i playliste</string>
|
||||
<string name="clear_views_history_title">Očisti povijest gledanja</string>
|
||||
<string name="import_data_summary">Poništava vašu trenutačnu povijest, pretplate, playliste i (opcionalno) postavke</string>
|
||||
<string name="export_data_summary">Izvezi povijest, pretplate, playliste i postavke</string>
|
||||
<string name="clear_views_history_title">Izbriši povijest gledanja</string>
|
||||
<string name="clear_views_history_summary">Briše povijest reproduciranih streamova i pozicije reprodukcije</string>
|
||||
<string name="delete_view_history_alert">Obriši cijelu povijest gledanja\?</string>
|
||||
<string name="watch_history_deleted">Povijest gledanja izbrisana.</string>
|
||||
<string name="clear_search_history_title">Obriši povijest pretraživanja</string>
|
||||
<string name="delete_search_history_alert">Obriši cijelu povijest pretraživanja\?</string>
|
||||
<string name="search_history_deleted">Povijest pretraživanja obrisana.</string>
|
||||
<string name="delete_view_history_alert">Izbrisati cijelu povijest gledanja\?</string>
|
||||
<string name="watch_history_deleted">Povijest gledanja je izbrisana.</string>
|
||||
<string name="clear_search_history_title">Izbriši povijest pretraživanja</string>
|
||||
<string name="delete_search_history_alert">Izbrisati cijelu povijest pretraživanja\?</string>
|
||||
<string name="search_history_deleted">Povijest pretraživanja je izbrisana.</string>
|
||||
<string name="invalid_url_toast">Neispravan URL</string>
|
||||
<string name="invalid_directory">Nema takve mape</string>
|
||||
<string name="file_name_empty_error">Naziv datoteke ne može biti prazan</string>
|
||||
|
@ -477,9 +477,9 @@
|
|||
<string name="start_downloads">Započni preuzimanja</string>
|
||||
<string name="pause_downloads">Zaustavi preuzimanja</string>
|
||||
<string name="downloads_storage_ask_title">Pitaj gdje preuzeti</string>
|
||||
<string name="clear_playback_states_title">Obriši poziciju reprodukcije</string>
|
||||
<string name="clear_playback_states_summary">Obriši sve pozicije reprodukcije</string>
|
||||
<string name="delete_playback_states_alert">Obriši sve pozicije reprodukcije\?</string>
|
||||
<string name="clear_playback_states_title">Izbriši poziciju reprodukcije</string>
|
||||
<string name="clear_playback_states_summary">Izbriši sve pozicije reprodukcije</string>
|
||||
<string name="delete_playback_states_alert">Izbrisati sve pozicije reprodukcije\?</string>
|
||||
<string name="no_one_watching">Nitko ne gleda</string>
|
||||
<string name="no_one_listening">Nitko ne sluša</string>
|
||||
<string name="localization_changes_requires_app_restart">Jezik će se promjeniti nakon ponovnog pokretanja aplikacije.</string>
|
||||
|
@ -641,4 +641,8 @@
|
|||
<string name="show_thumbnail_summary">Prikaži minijaturu kao pozadinu pri zaključanom ekranu i unutar obavijesti</string>
|
||||
<string name="show_thumbnail_title">Prikaži minijaturu</string>
|
||||
<string name="show_original_time_ago_title">Prikaži izvorno vrijeme elemenata</string>
|
||||
<string name="downloads_storage_use_saf_summary">„Okvir za pristup spremištu” omogućuje preuzimanje na SD karticu.
|
||||
\nNeki uređaji nisu kompatibilni</string>
|
||||
<string name="show_original_time_ago_summary">Izvorni tekstovi usluga bit će vidljivi u elementima prijenosa</string>
|
||||
<string name="feed_use_dedicated_fetch_method_summary">Dostupno je u nekim uslugama. Obično je puno brže, ali može vratiti ograničenu količinu predmeta i često nepotpune podatke (npr. bez trajanja, vrste predmeta, bez stanja uživo).</string>
|
||||
</resources>
|
|
@ -459,4 +459,8 @@
|
|||
<string name="clear_playback_states_title">Lejátszási pozíciók törlése</string>
|
||||
<string name="search_showing_result_for">Találatok a következőre: %s</string>
|
||||
<string name="notification_scale_to_square_image_title">Bélyegkép méretezése 1:1 arányra</string>
|
||||
<string name="notification_colorize_title">Értesítés színezése</string>
|
||||
<string name="notification_action_nothing">Semmi</string>
|
||||
<string name="notification_action_shuffle">Keverés</string>
|
||||
<string name="notification_action_repeat">Ismétlés</string>
|
||||
</resources>
|
|
@ -206,8 +206,8 @@
|
|||
<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 langganan anda saat ini</string>
|
||||
<string name="export_data_summary">Ekspor riwayat, langganan dan daftar putar</string>
|
||||
<string name="import_data_summary">Timpa riwayat, langganan, daftar putar dan (opsional) pengaturan anda saat ini</string>
|
||||
<string name="export_data_summary">Ekspor riwayat, langganan, daftar putar dan pengaturan</string>
|
||||
<string name="player_stream_failure">Tidak bisa memutar stream ini</string>
|
||||
<string name="player_unrecoverable_failure">Telah terjadi galat pemutar yang tidak bisa dipulihkan</string>
|
||||
<string name="player_recoverable_failure">Memulihkan dari galat pemutar</string>
|
||||
|
|
|
@ -5,25 +5,25 @@
|
|||
<string name="no_player_found">Nessun lettore multimediale trovato. Installare VLC\?</string>
|
||||
<string name="install">Installa</string>
|
||||
<string name="cancel">Annulla</string>
|
||||
<string name="open_in_browser">Apri nel Browser</string>
|
||||
<string name="open_in_browser">Apri nel browser</string>
|
||||
<string name="share">Condividi</string>
|
||||
<string name="download">Scarica</string>
|
||||
<string name="search">Cerca</string>
|
||||
<string name="settings">Impostazioni</string>
|
||||
<string name="did_you_mean">Forse cercavi \"%1$s\"\?</string>
|
||||
<string name="share_dialog_title">Condividi con</string>
|
||||
<string name="choose_browser">Scegli Browser</string>
|
||||
<string name="choose_browser">Scegli browser</string>
|
||||
<string name="screen_rotation">rotazione</string>
|
||||
<string name="download_path_title">Cartella Video Scaricati</string>
|
||||
<string name="download_path_title">Cartella video scaricati</string>
|
||||
<string name="download_path_summary">I video scaricati saranno salvati qui</string>
|
||||
<string name="download_path_dialog_title">Scegli la cartella per i video scaricati</string>
|
||||
<string name="default_resolution_title">Risoluzione Predefinita</string>
|
||||
<string name="default_resolution_title">Risoluzione predefinita</string>
|
||||
<string name="play_with_kodi_title">Riproduci con Kodi</string>
|
||||
<string name="kore_not_found">Installare l\'app Kore\?</string>
|
||||
<string name="show_play_with_kodi_title">Mostra \"Riproduci con Kodi\"</string>
|
||||
<string name="show_play_with_kodi_summary">Mostra l\'opzione per riprodurre video tramite Kodi</string>
|
||||
<string name="play_audio">Audio</string>
|
||||
<string name="default_audio_format_title">Formato Audio Predefinito</string>
|
||||
<string name="default_audio_format_title">Formato audio predefinito</string>
|
||||
<string name="download_dialog_title">Scarica</string>
|
||||
<string name="show_next_and_similar_title">Mostra video \"Prossimo\" e \"Simili\"</string>
|
||||
<string name="unsupported_url">URL non supportato</string>
|
||||
|
@ -36,9 +36,9 @@
|
|||
<string name="detail_likes_img_view_description">Mi piace</string>
|
||||
<string name="err_dir_create">Impossibile creare la cartella di download \'%1$s\'</string>
|
||||
<string name="info_dir_created">Creata la cartella per i download \'%1$s\'</string>
|
||||
<string name="use_external_video_player_title">Usa Lettore Video Esterno</string>
|
||||
<string name="use_external_audio_player_title">Usa Lettore Audio Esterno</string>
|
||||
<string name="download_path_audio_title">Cartella Audio Scaricati</string>
|
||||
<string name="use_external_video_player_title">Usa lettore video esterno</string>
|
||||
<string name="use_external_audio_player_title">Usa lettore audio esterno</string>
|
||||
<string name="download_path_audio_title">Cartella audio scaricati</string>
|
||||
<string name="download_path_audio_summary">Gli audio scaricati saranno salvati qui</string>
|
||||
<string name="download_path_audio_dialog_title">Scegli la cartella per gli audio scaricati</string>
|
||||
<string name="theme_title">Tema</string>
|
||||
|
@ -61,7 +61,7 @@
|
|||
<string name="show_age_restricted_content_title">Mostra contenuti con restrizioni di età</string>
|
||||
<string name="main_bg_subtitle">Tocca \"Cerca\" per iniziare
|
||||
\n</string>
|
||||
<string name="autoplay_by_calling_app_title">Riproduzione Automatica</string>
|
||||
<string name="autoplay_by_calling_app_title">Riproduzione automatica</string>
|
||||
<string name="autoplay_by_calling_app_summary">Riproduci i video quando NewPipe viene aperto da un\'altra app</string>
|
||||
<string name="duration_live">In diretta</string>
|
||||
<string name="light_parsing_error">Impossibile analizzare completamente il sito web</string>
|
||||
|
@ -114,22 +114,22 @@
|
|||
<string name="recaptcha_request_toast">È richiesta la risoluzione del reCAPTCHA</string>
|
||||
<string name="yes">Sì</string>
|
||||
<string name="later">Più tardi</string>
|
||||
<string name="open_in_popup_mode">Apri in Modalità Popup</string>
|
||||
<string name="popup_mode_share_menu_title">Modalità Popup</string>
|
||||
<string name="open_in_popup_mode">Apri in modalità popup</string>
|
||||
<string name="popup_mode_share_menu_title">Modalità popup</string>
|
||||
<string name="popup_playing_toast">Riproduzione in modalità popup</string>
|
||||
<string name="disabled">Disattivato</string>
|
||||
<string name="use_external_video_player_summary">Audio non disponibile per alcune risoluzioni</string>
|
||||
<string name="controls_background_title">In Sottofondo</string>
|
||||
<string name="controls_background_title">In sottofondo</string>
|
||||
<string name="controls_popup_title">Popup</string>
|
||||
<string name="default_popup_resolution_title">Risoluzione Predefinita Lettore Popup</string>
|
||||
<string name="show_higher_resolutions_title">Mostra Altre Risoluzioni</string>
|
||||
<string name="default_popup_resolution_title">Risoluzione predefinita lettore popup</string>
|
||||
<string name="show_higher_resolutions_title">Mostra altre risoluzioni</string>
|
||||
<string name="show_higher_resolutions_summary">Solo alcuni dispositivi possono riprodurre video 2K/4K</string>
|
||||
<string name="default_video_format_title">Formato Video Predefinito</string>
|
||||
<string name="default_video_format_title">Formato video predefinito</string>
|
||||
<string name="popup_remember_size_pos_title">Ricorda proprietà lettore popup</string>
|
||||
<string name="popup_remember_size_pos_summary">Ricorda dimensione e posizione della finestra Popup</string>
|
||||
<string name="player_gesture_controls_title">Controllo Gesti Lettore Multimediale</string>
|
||||
<string name="popup_remember_size_pos_summary">Ricorda dimensione e posizione del lettore popup</string>
|
||||
<string name="player_gesture_controls_title">Controllo gesti lettore multimediale</string>
|
||||
<string name="player_gesture_controls_summary">Usa i gesti per controllare luminosità e volume del lettore multimediale</string>
|
||||
<string name="show_search_suggestions_title">Suggerimenti di Ricerca</string>
|
||||
<string name="show_search_suggestions_title">Suggerimenti di ricerca</string>
|
||||
<string name="show_search_suggestions_summary">Mostra suggerimenti durante la ricerca</string>
|
||||
<string name="settings_category_popup_title">Popup</string>
|
||||
<string name="filter">Filtra i risultati</string>
|
||||
|
@ -264,16 +264,16 @@
|
|||
<string name="preferred_player_fetcher_notification_message">Caricamento del contenuto richiesto</string>
|
||||
<string name="import_data_title">Importa database</string>
|
||||
<string name="export_data_title">Esporta database</string>
|
||||
<string name="import_data_summary">Sovrascrive la cronologia e le iscrizioni attuali</string>
|
||||
<string name="export_data_summary">Esporta la cronologia, le iscrizioni e le playlist</string>
|
||||
<string name="import_data_summary">Sovrascrive la cronologia, le iscrizioni, le playlist e (facoltativamente) le impostazioni correnti</string>
|
||||
<string name="export_data_summary">Esporta cronologia, iscrizioni, playlist e impostazioni</string>
|
||||
<string name="export_complete_toast">Esportazione completa</string>
|
||||
<string name="import_complete_toast">Importazione completa</string>
|
||||
<string name="no_valid_zip_file">Nessun file ZIP valido</string>
|
||||
<string name="could_not_import_all_files">Attenzione: Impossibile importare tutti i file.</string>
|
||||
<string name="override_current_data">Questa operazione sostituirà le tue impostazioni attuali.</string>
|
||||
<string name="controls_download_desc">Scarica il video</string>
|
||||
<string name="show_info">Mostra Informazioni</string>
|
||||
<string name="tab_bookmarks">Playlist Salvate</string>
|
||||
<string name="show_info">Mostra informazioni</string>
|
||||
<string name="tab_bookmarks">Playlist salvate</string>
|
||||
<string name="controls_add_to_playlist_title">Aggiungi a</string>
|
||||
<string name="detail_drag_description">Trascina per riordinare</string>
|
||||
<string name="create">Crea</string>
|
||||
|
@ -309,7 +309,7 @@
|
|||
<string name="enable_leak_canary_summary">Il monitoraggio di memory leak potrebbe causare la mancata risposta dell\'applicazione durante il dumping dell\'heap</string>
|
||||
<string name="enable_disposed_exceptions_title">Segnala errori «fuori del ciclo di vita»</string>
|
||||
<string name="enable_disposed_exceptions_summary">Forza la segnalazione di eccezioni Rx non consegnabili al di fuori del ciclo di vita dell\'attività dopo la chiusura</string>
|
||||
<string name="use_inexact_seek_title">Usa Ricerca Rapida (Imprecisa)</string>
|
||||
<string name="use_inexact_seek_title">Usa ricerca rapida (imprecisa)</string>
|
||||
<string name="use_inexact_seek_summary">Consente al lettore multimediale di spostarsi più velocemente, ma con precisione ridotta. Spostamenti di 5, 15 o 25 secondi non funzionano con questo.</string>
|
||||
<string name="auto_queue_title">Accoda automaticamente l\'elemento successivo</string>
|
||||
<string name="auto_queue_summary">Accoda un contenuto consigliato al termine della riproduzione, in una coda non ripetitiva</string>
|
||||
|
@ -347,7 +347,7 @@
|
|||
<string name="import_network_expensive_warning">Tieni presente che questa operazione può consumare una grande quantità di traffico dati.
|
||||
\n
|
||||
\nVuoi continuare?</string>
|
||||
<string name="download_thumbnail_title">Carica Copertine</string>
|
||||
<string name="download_thumbnail_title">Carica copertine</string>
|
||||
<string name="download_thumbnail_summary">Disabilita per prevenire il caricamento delle copertine, risparmiando dati e memoria. La modifica di questa opzione cancellerà la cache delle immagini in memoria e sul disco.</string>
|
||||
<string name="thumbnail_cache_wipe_complete_notice">Cache immagini svuotata</string>
|
||||
<string name="metadata_cache_wipe_title">Pulisci Cache Metadati</string>
|
||||
|
@ -401,7 +401,7 @@
|
|||
<string name="tab_choose">Scegli scheda</string>
|
||||
<string name="volume_gesture_control_title">Gesti Controllo Volume</string>
|
||||
<string name="volume_gesture_control_summary">Utilizza i gesti per controllare il volume del lettore multimediale</string>
|
||||
<string name="brightness_gesture_control_title">Gesti Controllo Luminosità</string>
|
||||
<string name="brightness_gesture_control_title">Gesti controllo luminosità</string>
|
||||
<string name="brightness_gesture_control_summary">Utilizza i gesti per controllare la luminosità del lettore multimediale</string>
|
||||
<string name="settings_category_updates_title">Aggiornamenti</string>
|
||||
<string name="file_deleted">File eliminato</string>
|
||||
|
@ -458,7 +458,7 @@
|
|||
<string name="events">Eventi</string>
|
||||
<string name="conferences">Conferenze</string>
|
||||
<string name="error_timeout">Tempo per la connessione esaurito</string>
|
||||
<string name="show_comments_title">Mostra Commenti</string>
|
||||
<string name="show_comments_title">Mostra commenti</string>
|
||||
<string name="show_comments_summary">Disattiva per nascondere i commenti</string>
|
||||
<string name="autoplay_title">Riproduzione automatica</string>
|
||||
<string name="no_comments">Nessun commento</string>
|
||||
|
@ -506,7 +506,7 @@
|
|||
</plurals>
|
||||
<string name="localization_changes_requires_app_restart">La lingua verrà cambiata al riavvio dell\'applicazione.</string>
|
||||
<string name="default_kiosk_page_summary">Contenuti in evidenza predefiniti</string>
|
||||
<string name="seek_duration_title">Durata Avanzamento e Riavvolgimento Rapidi</string>
|
||||
<string name="seek_duration_title">Durata avanzamento e riavvolgimento rapidi</string>
|
||||
<string name="peertube_instance_url_title">Istanze PeerTube</string>
|
||||
<string name="peertube_instance_url_summary">Seleziona le istanze PeerTube preferite</string>
|
||||
<string name="peertube_instance_url_help">Trova altre istanze su %s</string>
|
||||
|
@ -619,7 +619,7 @@
|
|||
<string name="wifi_only">Solo Wi-Fi</string>
|
||||
<string name="autoplay_summary">Avvia la riproduzione automaticamente — %s</string>
|
||||
<string name="unsupported_url_dialog_message">URL non riconosciuto. Vuoi aprirlo con un\'altra app\?</string>
|
||||
<string name="auto_queue_toggle">Accoda Automaticamente</string>
|
||||
<string name="auto_queue_toggle">Accoda automaticamente</string>
|
||||
<string name="clear_queue_confirmation_description">La coda del lettore attivo sarà sostituita</string>
|
||||
<string name="clear_queue_confirmation_title">Chiedi prima di svuotare la coda</string>
|
||||
<string name="clear_queue_confirmation_summary">Cambiare tipo di riproduzione potrebbe sostituire gli elementi in coda</string>
|
||||
|
@ -635,7 +635,7 @@
|
|||
<string name="settings_category_notification_title">Notifica</string>
|
||||
<string name="notification_action_nothing">Niente</string>
|
||||
<string name="notification_action_repeat">Ripeti</string>
|
||||
<string name="notification_scale_to_square_image_title">Ridimensiona Copertina alla Proporzione 1:1</string>
|
||||
<string name="notification_scale_to_square_image_title">Ridimensiona copertina alla proporzione 1:1</string>
|
||||
<string name="notification_scale_to_square_image_summary">Modifica la proporzione della copertina del video mostrata nella notifica da 16:9 a 1:1 (può introdurre distorsioni)</string>
|
||||
<string name="show_memory_leaks">Mostra memory leak</string>
|
||||
<string name="enqueued">Aggiunto alla coda</string>
|
||||
|
@ -646,7 +646,7 @@
|
|||
<string name="youtube_restricted_mode_enabled_summary">Consente di usufruire della «Modalità con restrizioni» di YouTube, che esclude contenuti potenzialmente inappropriati per i minori</string>
|
||||
<string name="show_age_restricted_content_summary">Mostra contenuti che hanno un limite di età (es. 18+). Potrebbero essere inadatti ai bambini</string>
|
||||
<string name="notification_colorize_summary">Lascia che Android modifichi il colore della notifica, secondo il colore principale della copertina (funzione non disponibile per tutti i dispositivi)</string>
|
||||
<string name="notification_colorize_title">Colora Notifica</string>
|
||||
<string name="notification_colorize_title">Colora notifica</string>
|
||||
<string name="show_thumbnail_summary">Mostra le copertine come sfondo della schermata di blocco e all\'interno delle notifiche</string>
|
||||
<string name="show_thumbnail_title">Mostra copertina</string>
|
||||
</resources>
|
|
@ -93,7 +93,7 @@
|
|||
<string name="msg_server_unsupported">このサーバーには対応していません</string>
|
||||
<string name="msg_exists">ファイルが既に存在します</string>
|
||||
<string name="msg_url_malform">URL の形式が正しくないか、通信が利用できません</string>
|
||||
<string name="msg_running">NewPipeで保存中</string>
|
||||
<string name="msg_running">NewPipe ダウンロード中</string>
|
||||
<string name="msg_running_detail">タップして詳細を表示</string>
|
||||
<string name="msg_wait">お待ちください…</string>
|
||||
<string name="msg_copied">クリップボードにコピーしました</string>
|
||||
|
@ -176,7 +176,7 @@
|
|||
<string name="playlist">プレイリスト</string>
|
||||
<string name="undo">元に戻す</string>
|
||||
<string name="play_all">すべて再生</string>
|
||||
<string name="notification_channel_name">NewPipeの通知</string>
|
||||
<string name="notification_channel_name">NewPipe の通知</string>
|
||||
<string name="unknown_content">[不明]</string>
|
||||
<string name="player_stream_failure">動画の再生ができませんでした</string>
|
||||
<string name="player_unrecoverable_failure">回復不能な再生エラーが発生しました</string>
|
||||
|
@ -228,8 +228,8 @@
|
|||
<string name="just_once">一度だけ</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="import_data_summary">既存の再生履歴、登録チャンネル一覧、プレイリストおよび(任意の)設定は上書きされます</string>
|
||||
<string name="export_data_summary">再生履歴、登録チャンネル一覧、プレイリストおよび設定をエクスポートします</string>
|
||||
<string name="player_recoverable_failure">再生エラーからの回復中</string>
|
||||
<string name="external_player_unsupported_link_type">外部プレイヤーは、これらのタイプのリンクをサポートしていません</string>
|
||||
<string name="invalid_url_toast">無効なURL</string>
|
||||
|
@ -324,11 +324,11 @@
|
|||
<string name="delete_search_history_alert">すべての検索履歴を削除しますか?</string>
|
||||
<string name="invalid_source">このファイル/コンテンツはありません</string>
|
||||
<plurals name="subscribers">
|
||||
<item quantity="other">%s人が登録しています</item>
|
||||
<item quantity="other">チャンネル登録者数 %s人</item>
|
||||
</plurals>
|
||||
<string name="no_views">再生なし</string>
|
||||
<plurals name="views">
|
||||
<item quantity="other">再生回数 %s再生</item>
|
||||
<item quantity="other">再生回数 %s回</item>
|
||||
</plurals>
|
||||
<string name="one_item_deleted">1 つのアイテムが削除されました。</string>
|
||||
<string name="give_back">支援する</string>
|
||||
|
@ -341,7 +341,7 @@
|
|||
<string name="controls_add_to_playlist_title">プレイリスト</string>
|
||||
<string name="show_hold_to_append_title">「長押しして追加」のヒントを表示</string>
|
||||
<string name="tracks">トラック</string>
|
||||
<string name="notification_channel_description">NewPipeのバックグラウンドおよびポップアッププレイヤーの通知</string>
|
||||
<string name="notification_channel_description">NewPipe のバックグラウンドおよびポップアッププレイヤーの通知</string>
|
||||
<string name="new_and_hot">新着と人気</string>
|
||||
<string name="hold_to_append">長押ししてキューに追加</string>
|
||||
<string name="start_here_on_popup">ポップアップで連続再生を開始</string>
|
||||
|
|
|
@ -550,4 +550,32 @@
|
|||
<string name="search_showing_result_for">%s에 대한 검색 결과</string>
|
||||
<string name="notification_action_shuffle">셔플</string>
|
||||
<string name="notification_action_repeat">연속 재생</string>
|
||||
<string name="playlist_page_summary">재생목록 페이지</string>
|
||||
<string name="show_thumbnail_title">썸네일 보기</string>
|
||||
<string name="feed_group_dialog_empty_name">그룹 이름이 없음</string>
|
||||
<plurals name="days">
|
||||
<item quantity="other">%d 일</item>
|
||||
</plurals>
|
||||
<plurals name="hours">
|
||||
<item quantity="other">%d 시간</item>
|
||||
</plurals>
|
||||
<plurals name="minutes">
|
||||
<item quantity="other">%d 분</item>
|
||||
</plurals>
|
||||
<plurals name="seconds">
|
||||
<item quantity="other">%d 초</item>
|
||||
</plurals>
|
||||
<string name="remove_watched_popup_title">시청 기록을 지우겠습니까\?</string>
|
||||
<string name="remove_watched">시청 기록 지우기</string>
|
||||
<string name="title_activity_play_queue">재생목록 실행</string>
|
||||
<string name="settings_category_notification_title">알림</string>
|
||||
<string name="unsupported_url_dialog_message">URL을 인식할 수 없습니다. 다른 앱으로 여시겠습니까\?</string>
|
||||
<string name="clear_queue_confirmation_title">스트림을 비우기 전 확인을 요청합니다.</string>
|
||||
<string name="notification_colorize_summary">안드로이드에서 썸네일의 색상에 따라 알림 색상을 조절합니다. (지원되지 않는 기기가 있을 수 있습니다.)</string>
|
||||
<string name="notification_action_buffering">버퍼링</string>
|
||||
<string name="notification_action_4_title">다섯번째 버튼</string>
|
||||
<string name="notification_action_3_title">네번째 버튼</string>
|
||||
<string name="notification_action_2_title">세번째 버튼</string>
|
||||
<string name="notification_action_1_title">두번째 버튼</string>
|
||||
<string name="permission_display_over_apps">다른 앱 위에 표시되는 권한 부여</string>
|
||||
</resources>
|
|
@ -1,6 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="main_bg_subtitle">Tekan carian untuk bermula</string>
|
||||
<string name="main_bg_subtitle">Tekan \"Cari\" untuk bermula
|
||||
\n</string>
|
||||
<string name="view_count_text">%1$s tontonan</string>
|
||||
<string name="upload_date_text">Diterbitkan pada %1$s</string>
|
||||
<string name="no_player_found">Tiada pemain strim ditemui. Adakah anda mahu memasang VLC\?</string>
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
<string name="autoplay_by_calling_app_title">Automatisk avspilling</string>
|
||||
<string name="autoplay_by_calling_app_summary">Spiller en video når NewPipe blir forespurt av et annet program</string>
|
||||
<string name="content">Innhold</string>
|
||||
<string name="show_age_restricted_content_title">Aldersbegrenset innhold</string>
|
||||
<string name="show_age_restricted_content_title">Vis aldersbegrenset innhold</string>
|
||||
<string name="general_error">Feil</string>
|
||||
<string name="could_not_load_thumbnails">Kunne ikke laste inn alle miniatyrbilder</string>
|
||||
<string name="youtube_signature_deobfuscation_error">Kunne ikke dekryptere signaturen til videoens nettadresse</string>
|
||||
|
@ -225,7 +225,7 @@
|
|||
<string name="play_queue_audio_settings">Lydinnstillinger</string>
|
||||
<string name="hold_to_append">Hold for å legge i kø</string>
|
||||
<string name="show_hold_to_append_title">Vis \"Hold for å legge til\" -tips</string>
|
||||
<string name="show_hold_to_append_summary">Vis tips når bakgrunnen eller oppsprettsknappen i videoens «Detaljer:» trykkes</string>
|
||||
<string name="show_hold_to_append_summary">Vis tips når det trykkes på bakgrunnen eller oppsprettsknappen i videoens «Detaljer:»</string>
|
||||
<string name="background_player_append">Lagt i kø for bakgrunnsavspiller</string>
|
||||
<string name="popup_playing_append">Lagt i kø for oppsprettsspiller</string>
|
||||
<string name="unknown_content">[Ukjent]</string>
|
||||
|
@ -265,7 +265,7 @@
|
|||
<string name="import_data_title">Importer database</string>
|
||||
<string name="export_data_title">Eksporter database</string>
|
||||
<string name="import_data_summary">Overstyrer din nåværende historikk og abonnementsliste</string>
|
||||
<string name="export_data_summary">Eksporter historikk, abonnementer og spillelister</string>
|
||||
<string name="export_data_summary">Eksporter historikk, abonnementer, spillelister og innstillinger</string>
|
||||
<string name="export_complete_toast">Eksportert</string>
|
||||
<string name="import_complete_toast">Importert</string>
|
||||
<string name="no_valid_zip_file">Ingen gyldig ZIP-fil</string>
|
||||
|
@ -357,7 +357,10 @@
|
|||
\n
|
||||
\n1. Gå til denne nettadressen: %1$s
|
||||
\n2. Logg inn når forespurt
|
||||
\n3. En nedlasting av eksportfilen bør starte</string>
|
||||
\n3. En nedlasting av eksportfilen bør starte
|
||||
\n4. Klikk på «Neste steg» og så på «Opprett eksport»
|
||||
\n5. Klikk på «Last ned»-knappen etter den vises, og
|
||||
\n6. Fra nedlastet takeout.zip, pakk ut .json-filen (vanligvis under «YouTube og YouTube Music/subscriptions/subscriptions.json» og importer den her.</string>
|
||||
<string name="import_soundcloud_instructions">Importer en SoundCloud-profil ved å skrive enten nettadressen eller din ID:
|
||||
\n
|
||||
\n1. Skru på \"skrivebordsmodus\" i en nettleser ( siden er ikke tilgjengelig for mobile enheter)
|
||||
|
@ -644,4 +647,6 @@
|
|||
<string name="show_age_restricted_content_summary">Vis innhold som muligens er upassende for barn, siden det har aldersgrense (som 18+).</string>
|
||||
<string name="notification_colorize_summary">Få Android til å tilpasse merknadens farge i henhold til hovedfargen på miniatyrbildet (merk at dette ikke støttes på alle enheter)</string>
|
||||
<string name="notification_colorize_title">Fargelegg merknad</string>
|
||||
<string name="show_thumbnail_summary">Vis miniatyrbilde på låseskjerm som bakgrunn og i merknader</string>
|
||||
<string name="show_thumbnail_title">Vis miniatyrbilde</string>
|
||||
</resources>
|
|
@ -269,8 +269,8 @@
|
|||
<string name="switch_to_main">Odtwarzaj na pierwszym planie</string>
|
||||
<string name="import_data_title">Importuj dane</string>
|
||||
<string name="export_data_title">Eksportuj dane</string>
|
||||
<string name="import_data_summary">Zastępuje Twoją bieżącą historię i subskrypcje</string>
|
||||
<string name="export_data_summary">Eksportuje bieżącą historię, subskrypcje i playlisty</string>
|
||||
<string name="import_data_summary">Zastępuje Twoją bieżącą historię, subskrypcje, playlisty i (opcjonalnie) ustawienia</string>
|
||||
<string name="export_data_summary">Eksportuje bieżącą historię, subskrypcje, playlisty i ustawienia</string>
|
||||
<string name="detail_drag_description">Przeciągnij, aby zmienić kolejność</string>
|
||||
<string name="create">Utwórz</string>
|
||||
<string name="delete_one">Usuń bieżący</string>
|
||||
|
|
|
@ -262,8 +262,8 @@
|
|||
<string name="preferred_player_fetcher_notification_message">Carregando conteúdo solicitado</string>
|
||||
<string name="import_data_title">Importar base de dados</string>
|
||||
<string name="export_data_title">Exportar base de dados</string>
|
||||
<string name="import_data_summary">Substitui seu histórico e inscrições atuai</string>
|
||||
<string name="export_data_summary">Exporte histórico, inscrições e playlists</string>
|
||||
<string name="import_data_summary">Substitui seu histórico atual, inscrições, playlists e (opcionalmente) configurações</string>
|
||||
<string name="export_data_summary">Exporte histórico, inscrições, playlists e configurações</string>
|
||||
<string name="export_complete_toast">Exportado</string>
|
||||
<string name="import_complete_toast">Importado</string>
|
||||
<string name="no_valid_zip_file">Não há nenhum arquivo ZIP válido</string>
|
||||
|
@ -596,7 +596,7 @@
|
|||
\n
|
||||
\nAtive \"%1$s\" nas configurações se quiser vê-lo.</string>
|
||||
<string name="remove_watched_popup_yes_and_partially_watched_videos">Sim, e vídeos parcialmente vistos</string>
|
||||
<string name="remove_watched_popup_warning">Vídeos vistos antes e depois de adicionar à lista de reprodução serão removidos.
|
||||
<string name="remove_watched_popup_warning">Vídeos vistos antes e depois de adicionar à playlists serão removidos.
|
||||
\nTem certeza\? Isto não pode ser desfeito!</string>
|
||||
<string name="remove_watched_popup_title">Remover vídeos vistos\?</string>
|
||||
<string name="remove_watched">Remover vistos</string>
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
<string name="new_seek_duration_toast">Devido às restrições de ExoPlayer, a duração da pesquisa foi definida para %d segundos</string>
|
||||
<string name="overwrite">Sobrescrever</string>
|
||||
<string name="mute">Sem som</string>
|
||||
<string name="enable_watch_history_title">Ver histórico</string>
|
||||
<string name="enable_watch_history_title">Histórico de visualizações</string>
|
||||
<plurals name="views">
|
||||
<item quantity="one">%s visualização</item>
|
||||
<item quantity="other">%s visualizações</item>
|
||||
|
@ -108,7 +108,7 @@
|
|||
<string name="artists">Artistas</string>
|
||||
<string name="error_connect_host">Não foi possível ligar ao servidor</string>
|
||||
<string name="show_play_with_kodi_summary">Mostrar uma opção para reproduzir o vídeo no Kodi</string>
|
||||
<string name="list_view_mode">Modo de vista em lista</string>
|
||||
<string name="list_view_mode">Modo de exibição</string>
|
||||
<string name="use_inexact_seek_summary">A pesquisa inexata permite que esta seja mais rápida mas reduz a precisão. Procurar por 5, 15 ou 25 segundos não funciona corretamente.</string>
|
||||
<string name="permission_display_over_apps">Permitir sobreposição a outras aplicações</string>
|
||||
<string name="autoplay_by_calling_app_title">Reprodução automática</string>
|
||||
|
@ -121,7 +121,7 @@
|
|||
<string name="error_report_open_issue_button_text">Reportar no GitHub</string>
|
||||
<string name="detail_likes_img_view_description">Gosto</string>
|
||||
<string name="history_disabled">O histórico está desativado</string>
|
||||
<string name="download_path_title">Pasta para os vídeos</string>
|
||||
<string name="download_path_title">Pasta para os ficheiros de vídeo</string>
|
||||
<string name="subtitle_activity_recaptcha">Prima \"Feito\" ao resolver</string>
|
||||
<string name="feed_notification_loading">A carregar…</string>
|
||||
<string name="play_audio">Áudio</string>
|
||||
|
@ -398,7 +398,7 @@
|
|||
<string name="auto_queue_title">Colocar vídeo seguinte na fila</string>
|
||||
<string name="peertube_instance_url_summary">Defina as suas instâncias favoritas PeerTube</string>
|
||||
<string name="import_export_title">Importar/exportar</string>
|
||||
<string name="export_data_summary">Exportar histórico, subscrições e listas de reprodução</string>
|
||||
<string name="export_data_summary">Exportar histórico, subscrições, listas de reprodução e definições</string>
|
||||
<string name="best_resolution">Melhor resolução</string>
|
||||
<string name="select_a_channel">Selecione um canal</string>
|
||||
<string name="choose_browser">Escolher navegador</string>
|
||||
|
@ -453,7 +453,7 @@
|
|||
<string name="clear_search_history_title">Limpar histórico de pesquisas</string>
|
||||
<string name="msg_error">Erro</string>
|
||||
<string name="popup_remember_size_pos_title">Lembrar propriedades de popup</string>
|
||||
<string name="download_path_summary">Os ficheiros de vídeo descarregados serão armazenados aqui</string>
|
||||
<string name="download_path_summary">Os ficheiros de vídeo descarregados serão guardados aqui</string>
|
||||
<string name="switch_to_main">Mudar para principal</string>
|
||||
<string name="msg_popup_permission">Esta permissão é necessária
|
||||
\npara o modo popup</string>
|
||||
|
@ -471,7 +471,7 @@
|
|||
<string name="missions_header_pending">Pendente</string>
|
||||
<string name="import_complete_toast">Importado</string>
|
||||
<string name="auto">Automático</string>
|
||||
<string name="import_data_summary">Substitui o histórico e as subscrições atuais</string>
|
||||
<string name="import_data_summary">Substitui o seu histórico, subscrições, listas de reprodução e (opcionalmente) definições</string>
|
||||
<string name="settings_category_popup_title">Popup</string>
|
||||
<string name="short_thousand">k</string>
|
||||
<string name="err_dir_create">Não foi possível criar a pasta \'%1$s\'</string>
|
||||
|
@ -538,7 +538,7 @@
|
|||
<string name="settings_file_replacement_character_title">Carácter de substituição</string>
|
||||
<string name="video">Vídeo</string>
|
||||
<string name="no_streams_available_download">Não existem vídeos para descarregar</string>
|
||||
<string name="download_path_audio_summary">Os ficheiros de áudio descarregados serão armazenados aqui</string>
|
||||
<string name="download_path_audio_summary">Os ficheiros de áudio descarregados serão guardados aqui</string>
|
||||
<string name="videos_string">Vídeos</string>
|
||||
<string name="metadata_cache_wipe_complete_notice">Meta-dados em cache limpos</string>
|
||||
<string name="show_hold_to_append_summary">Mostrar dica ao premir em segundo plano ou no botão \"Detalhes:\" da janela popup</string>
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
<string name="screen_rotation">rotação</string>
|
||||
<string name="use_external_video_player_title">Utilizar reprodutor de vídeo externo</string>
|
||||
<string name="use_external_audio_player_title">Utilizar reprodutor de áudio externo</string>
|
||||
<string name="download_path_title">Pasta para os vídeos</string>
|
||||
<string name="download_path_summary">Os ficheiros de vídeo descarregados serão armazenados aqui</string>
|
||||
<string name="download_path_title">Pasta para os ficheiros de vídeo</string>
|
||||
<string name="download_path_summary">Os ficheiros de vídeo descarregados serão guardados aqui</string>
|
||||
<string name="download_path_dialog_title">Escolha a pasta para colocar os ficheiros de vídeo</string>
|
||||
<string name="default_resolution_title">Resolução padrão</string>
|
||||
<string name="play_with_kodi_title">Reproduzir no Kodi</string>
|
||||
|
@ -46,7 +46,7 @@
|
|||
<string name="use_tor_title">Utilizar Tor</string>
|
||||
<string name="use_tor_summary">(Experimental) Forçar tráfego via Tor para aumentar a privacidade (ainda não é suportada a emissão de vídeos).</string>
|
||||
<string name="download_path_audio_title">Pasta para ficheiros de áudio</string>
|
||||
<string name="download_path_audio_summary">Os ficheiros de áudio descarregados serão armazenados aqui</string>
|
||||
<string name="download_path_audio_summary">Os ficheiros de áudio descarregados serão guardados aqui</string>
|
||||
<string name="download_path_audio_dialog_title">Escolha a pasta para colocar os ficheiros de áudio</string>
|
||||
<string name="err_dir_create">Não foi possível criar a pasta \'%1$s\'</string>
|
||||
<string name="info_dir_created">Pasta \'%1$s\' criada com sucesso</string>
|
||||
|
@ -165,8 +165,8 @@
|
|||
<string name="fragment_feed_title">Novidades</string>
|
||||
<string name="enable_search_history_title">Histórico de pesquisa</string>
|
||||
<string name="enable_search_history_summary">Guardar termos de pesquisa localmente</string>
|
||||
<string name="enable_watch_history_title">Ver histórico</string>
|
||||
<string name="enable_watch_history_summary">Manter histórico dos vídeos vistos</string>
|
||||
<string name="enable_watch_history_title">Histórico de visualizações</string>
|
||||
<string name="enable_watch_history_summary">Manter histórico dos vídeos visualizados</string>
|
||||
<string name="resume_on_audio_focus_gain_title">Continuar reprodução</string>
|
||||
<string name="resume_on_audio_focus_gain_summary">Continuar reprodução após interrupções (ex. chamadas)</string>
|
||||
<string name="settings_category_player_title">Reprodutor</string>
|
||||
|
@ -237,8 +237,8 @@
|
|||
<string name="toggle_orientation">Alternar orientação</string>
|
||||
<string name="import_data_title">Importar base de dados</string>
|
||||
<string name="export_data_title">Exportar base de dados</string>
|
||||
<string name="import_data_summary">Substitui o histórico e as subscrições atuais</string>
|
||||
<string name="export_data_summary">Exportar histórico, subscrições e listas de reprodução</string>
|
||||
<string name="import_data_summary">Substitui o seu histórico, subscrições, listas de reprodução e (opcionalmente) definições</string>
|
||||
<string name="export_data_summary">Exportar histórico, subscrições, listas de reprodução e definições</string>
|
||||
<string name="background_player_append">Na fila do reprodutor em segundo plano</string>
|
||||
<string name="popup_playing_append">Na fila do reprodutor popup</string>
|
||||
<string name="switch_to_background">Mudar para segundo plano</string>
|
||||
|
@ -417,7 +417,7 @@
|
|||
<string name="selection">Seleção</string>
|
||||
<string name="updates_setting_title">Atualizações</string>
|
||||
<string name="updates_setting_description">Mostrar uma notificação para pedir a atualização da aplicação se existir uma nova versão</string>
|
||||
<string name="list_view_mode">Modo de vista em lista</string>
|
||||
<string name="list_view_mode">Modo de exibição</string>
|
||||
<string name="list">Lista</string>
|
||||
<string name="grid">Grelha</string>
|
||||
<string name="auto">Automático</string>
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
<string name="default_audio_format_title">Формат аудио по умолчанию</string>
|
||||
<string name="download_dialog_title">Скачать</string>
|
||||
<string name="unsupported_url">URL не поддерживается</string>
|
||||
<string name="show_next_and_similar_title">\"Следующее\" и похожие видео</string>
|
||||
<string name="show_next_and_similar_title">Показать похожие видео</string>
|
||||
<string name="content_language_title">Язык контента по умолчанию</string>
|
||||
<string name="settings_category_video_audio_title">Видео и аудио</string>
|
||||
<string name="settings_category_appearance_title">Внешний вид</string>
|
||||
|
@ -153,7 +153,7 @@
|
|||
<string name="app_description">Свободное и легковесное потоковое воспроизведение для Android.</string>
|
||||
<string name="view_on_github">Открыть на GitHub</string>
|
||||
<string name="contribution_encouragement">Приветствуется всё — идеи, перевод, изменения дизайна, чистка кода или огромные изменения в коде. Чем больше сделано, тем лучше!</string>
|
||||
<string name="copyright" formatted="true">© %1$s %2$s под лицензией %3$s</string>
|
||||
<string name="copyright" formatted="true">© %1$s • %2$s • %3$s</string>
|
||||
<string name="contribution_title">Помощь проекту</string>
|
||||
<string name="subscribe_button_title">Подписаться</string>
|
||||
<string name="subscription_change_failed">Не удалось изменить подписку</string>
|
||||
|
@ -162,7 +162,7 @@
|
|||
<string name="tab_subscriptions">Подписки</string>
|
||||
<string name="fragment_feed_title">Что нового</string>
|
||||
<string name="enable_search_history_title">История поиска</string>
|
||||
<string name="enable_search_history_summary">Хранить запросы поиска локально</string>
|
||||
<string name="enable_search_history_summary">Хранить запросы поиска (локально)</string>
|
||||
<string name="enable_watch_history_title">История просмотров</string>
|
||||
<string name="enable_playback_resume_title">Продолжать воспроизведение</string>
|
||||
<string name="enable_playback_resume_summary">Восстанавливать последнюю позицию</string>
|
||||
|
@ -282,8 +282,8 @@
|
|||
<string name="file">Файл</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="import_data_summary">Текущие подписки, плейлисты, история и (опционально) настройки будут заменены</string>
|
||||
<string name="export_data_summary">Экспорт подписок, плейлистов, истории и настроек</string>
|
||||
<string name="invalid_directory">Папка не существует</string>
|
||||
<string name="invalid_source">Папка или источник контента не существуют</string>
|
||||
<string name="invalid_file">Файл не существует или нет разрешения на его чтение или запись</string>
|
||||
|
@ -383,7 +383,7 @@
|
|||
<string name="preferred_open_action_settings_title">При открытии ссылки</string>
|
||||
<string name="import_settings">Хотите импортировать настройки?</string>
|
||||
<string name="privacy_policy_title">Конфиденциальность</string>
|
||||
<string name="privacy_policy_encouragement">Проект NewPipe очень серьёзно относится к вашей конфиденциальности. Поэтому приложение не собирает никаких данных без вашего согласия.
|
||||
<string name="privacy_policy_encouragement">Проект NewPipe очень серьёзно относится к вашей конфиденциальности. Приложение не собирает никаких данных без вашего согласия.
|
||||
\nПолитика конфиденциальности NewPipe подробно объясняет, какие данные отправляются и хранятся при отправке отчёта о сбоях.</string>
|
||||
<string name="read_privacy_policy">Прочитать политику</string>
|
||||
<string name="start_accept_privacy_policy">В соответствии с Общим регламентом по защите данных ЕС (GDPR), обращаем ваше внимание на политику конфиденциальности NewPipe. Пожалуйста, внимательно ознакомьтесь с ней.
|
||||
|
@ -580,19 +580,19 @@
|
|||
<string name="feed_update_threshold_option_always_update">Обновлять всегда</string>
|
||||
<string name="feed_group_dialog_empty_selection">Подписки не выбраны</string>
|
||||
<string name="feed_groups_header_title">Группы каналов</string>
|
||||
<string name="feed_use_dedicated_fetch_method_help_text">Если обновление подписок кажется вам слишком медленным, попробуйте быстрый режим (включите в настройках или кнопкой внизу).
|
||||
<string name="feed_use_dedicated_fetch_method_help_text">Если подписки обновляются слишком медленно, попробуйте быстрый режим (включите в настройках или кнопкой внизу).
|
||||
\n
|
||||
\nNewPipe позволяет обновлять подписки двумя способами:
|
||||
\n• получение канала целиком, медленное, но с полными сведениями;
|
||||
\n• обновление по RSS, быстрое, но с потерей сведений.
|
||||
\nNewPipe может обновлять подписки двумя способами:
|
||||
\n• получение канала целиком, медленное, с полными сведениями;
|
||||
\n• обновление по RSS, быстрое, с потерей сведений.
|
||||
\n
|
||||
\nПри быстром обновлении теряются длительность элемента и его тип (нельзя определить, трансляция это или обычное видео), могут быть получены не все элементы канала.
|
||||
\nПри быстром обновлении теряются длительность элемента и его тип (трансляция или обычное видео), могут быть получены не все элементы канала.
|
||||
\n
|
||||
\nYouTube является примером такого сервиса, допуская быстрое обновление по RSS.
|
||||
\nКак пример, YouTube поддерживает быстрое обновление.
|
||||
\n
|
||||
\nВыбор за вами: скорость или точность.</string>
|
||||
<string name="feed_use_dedicated_fetch_method_title">Обновление по RSS, если доступно</string>
|
||||
<string name="feed_use_dedicated_fetch_method_summary">Доступно для некоторых сервисов, быстрое, но может возвращать не всё содержимое канала и не содержать часть сведений (длительность, тип элемента, статус трансляции)</string>
|
||||
<string name="feed_use_dedicated_fetch_method_summary">Доступно для некоторых сервисов, быстрое, но может возвращать не всё содержимое канала и не содержать часть сведений (длительность, статус трансляции)</string>
|
||||
<string name="feed_update_threshold_summary">Период актуальности подписок после обновления — %s</string>
|
||||
<string name="restricted_video">Это видео имеет возрастное ограничение.
|
||||
\n
|
||||
|
@ -640,7 +640,7 @@
|
|||
<string name="notification_action_shuffle">Перемешать</string>
|
||||
<string name="notification_action_repeat">Повтор</string>
|
||||
<string name="notification_actions_at_most_three">В компактном уведомлении доступно не более трёх действий!</string>
|
||||
<string name="notification_actions_summary">Действия можно отредактировать, нажав на них. Отметьте не более трёх для отображения в компактном уведомлении</string>
|
||||
<string name="notification_actions_summary">Действия можно изменить, нажав на них. Отметьте не более трёх для отображения в компактном уведомлении</string>
|
||||
<string name="notification_action_4_title">Пятое действие</string>
|
||||
<string name="notification_action_3_title">Четвёртое действие</string>
|
||||
<string name="notification_action_2_title">Третье действие</string>
|
||||
|
|
|
@ -443,8 +443,8 @@
|
|||
<string name="delete_view_history_alert">Cheres iscantzellare totu sa cronologia de sos pompiados\?</string>
|
||||
<string name="clear_views_history_summary">Iscantzellat sa cronologia de sos cuntenutos riproduidos e sas positziones de riprodutzione</string>
|
||||
<string name="clear_views_history_title">Isbòida sa cronologia de sos pompiados</string>
|
||||
<string name="export_data_summary">Esporta sa cronologia, sos abbonamentos e sas iscalitas</string>
|
||||
<string name="import_data_summary">Subraiscriet sa cronologia e sos abbonamentos atuales tuos</string>
|
||||
<string name="export_data_summary">Esporta sa cronologia, sos abbonamentos, sas iscalitas e sas impostatziones</string>
|
||||
<string name="import_data_summary">Subraiscriet sa cronologia, sos abbonamentos, sas iscalita e (optzionalmente) sas impostatziones tuas atuales</string>
|
||||
<string name="export_data_title">Esporta sa base de datos</string>
|
||||
<string name="import_data_title">Importa sa base de datos</string>
|
||||
<string name="switch_to_main">Cola a sa modalidade printzipale</string>
|
||||
|
|
|
@ -231,8 +231,8 @@
|
|||
<string name="switch_to_main">Prepnúť na Video</string>
|
||||
<string name="import_data_title">Importovať databázu</string>
|
||||
<string name="export_data_title">Exportovať databázu</string>
|
||||
<string name="import_data_summary">Prepíše aktuálnu históriu pozretí a odberov</string>
|
||||
<string name="export_data_summary">Exportovať históriu, odbery a zoznamy skladieb</string>
|
||||
<string name="import_data_summary">Prepíše aktuálnu históriu, odbery, zoznamy skladieb a (voliteľne aj) nastavenia</string>
|
||||
<string name="export_data_summary">Exportovať históriu, odbery, zoznamy skladieb a nastavenia</string>
|
||||
<string name="player_stream_failure">Nepodarilo sa prehrať tento stream</string>
|
||||
<string name="player_unrecoverable_failure">Pri prehrávaní došlo k chybe a nemožno pokračovať</string>
|
||||
<string name="player_recoverable_failure">Zotavovanie po chybe v prehrávaní</string>
|
||||
|
|
|
@ -260,8 +260,8 @@
|
|||
<string name="preferred_player_fetcher_notification_message">İstenen içerik yükleniyor</string>
|
||||
<string name="import_data_title">Veri tabanını içe aktar</string>
|
||||
<string name="export_data_title">Veri tabanını dışa aktar</string>
|
||||
<string name="import_data_summary">Geçerli geçmişinizi ve aboneliklerinizi geçersiz kılar</string>
|
||||
<string name="export_data_summary">Geçmişi, abonelikleri ve oynatma listelerini dışa aktar</string>
|
||||
<string name="import_data_summary">Geçerli geçmişinizi, aboneliklerinizi, oynatma listelerinizi ve (isteğe bağlı olarak) ayarlarınızı geçersiz kılar</string>
|
||||
<string name="export_data_summary">Geçmişi, abonelikleri, oynatma listelerini ve ayarları dışa aktar</string>
|
||||
<string name="export_complete_toast">Dışa aktarıldı</string>
|
||||
<string name="import_complete_toast">İçe aktarıldı</string>
|
||||
<string name="no_valid_zip_file">Geçerli ZIP dosyası yok</string>
|
||||
|
|
|
@ -228,8 +228,8 @@
|
|||
<string name="website_title">網站</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="import_data_summary">覆蓋您目前的歷史記錄、訂閱與(可選的)設定</string>
|
||||
<string name="export_data_summary">匯出歷史記錄、訂閱、播放清單與設定</string>
|
||||
<string name="give_back">回饋</string>
|
||||
<string name="website_encouragement">如欲了解更多有關 NewPipe 的資訊和新聞,請造訪我們的網站。</string>
|
||||
<string name="main_page_content">首頁內容</string>
|
||||
|
|
|
@ -222,8 +222,8 @@
|
|||
<string name="export_data_title">Export database</string>
|
||||
<string name="clear_cookie_title">Clear reCAPTCHA cookies</string>
|
||||
<string name="recaptcha_cookies_cleared">reCAPTCHA cookies have been cleared</string>
|
||||
<string name="import_data_summary">Overrides your current history and subscriptions</string>
|
||||
<string name="export_data_summary">Export history, subscriptions and playlists</string>
|
||||
<string name="import_data_summary">Overrides your current history, subscriptions, playlists and (optionally) settings</string>
|
||||
<string name="export_data_summary">Export history, subscriptions, playlists and settings</string>
|
||||
<string name="clear_cookie_summary">Clear cookies that NewPipe stores when you solve a reCAPTCHA</string>
|
||||
<string name="clear_views_history_title">Clear watch history</string>
|
||||
<string name="clear_views_history_summary">Deletes the history of played streams and the playback positions</string>
|
||||
|
@ -734,4 +734,4 @@
|
|||
<string name="sponsor_block_whitelist_cleared_toast">Whitelist cleared</string>
|
||||
<string name="sponsor_block_uploader_added_to_whitelist_toast">Uploader added to whitelist</string>
|
||||
<string name="sponsor_block_uploader_removed_from_whitelist_toast">Uploader removed from whitelist</string>
|
||||
</resources>
|
||||
</resources>
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
package org.schabi.newpipe.ktx
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
import java.time.LocalDate
|
||||
import java.time.OffsetDateTime
|
||||
import java.time.ZoneId
|
||||
import java.time.ZoneOffset
|
||||
import java.util.Calendar
|
||||
import java.util.TimeZone
|
||||
|
||||
class OffsetDateTimeToCalendarTest {
|
||||
@Test
|
||||
fun testRelativeTimeWithCurrentOffsetDateTime() {
|
||||
val calendar = LocalDate.of(2020, 1, 1).atStartOfDay().atOffset(ZoneOffset.UTC)
|
||||
.toCalendar()
|
||||
|
||||
assertEquals(2020, calendar[Calendar.YEAR])
|
||||
assertEquals(0, calendar[Calendar.MONTH])
|
||||
assertEquals(1, calendar[Calendar.DAY_OF_MONTH])
|
||||
assertEquals(0, calendar[Calendar.HOUR])
|
||||
assertEquals(0, calendar[Calendar.MINUTE])
|
||||
assertEquals(0, calendar[Calendar.SECOND])
|
||||
assertEquals(TimeZone.getTimeZone("UTC"), calendar.timeZone)
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException::class)
|
||||
fun testRelativeTimeWithFarOffOffsetDateTime() {
|
||||
OffsetDateTime.MAX.minusYears(1).toCalendar()
|
||||
}
|
||||
}
|
|
@ -205,7 +205,7 @@ public class ListHelperTest {
|
|||
assertEquals(MediaFormat.M4A, stream.getFormat());
|
||||
|
||||
// Adding a new format and bitrate. Adding another stream will have no impact since
|
||||
// it's not a prefered format.
|
||||
// it's not a preferred format.
|
||||
testList.add(new AudioStream("", MediaFormat.WEBMA, /**/ 192));
|
||||
stream = testList.get(ListHelper.getHighestQualityAudioIndex(MediaFormat.MP3, testList));
|
||||
assertEquals(192, stream.average_bitrate);
|
||||
|
|
4
fastlane/metadata/android/en-US/changelogs/960.txt
Normal file
4
fastlane/metadata/android/en-US/changelogs/960.txt
Normal file
|
@ -0,0 +1,4 @@
|
|||
• Improved description of export database option in settings.
|
||||
• Fixed YouTube comments parsing.
|
||||
• Fixed display name of media.ccc.de service.
|
||||
• Updated translations.
|
|
@ -1,7 +1,7 @@
|
|||
Mejorado
|
||||
• Reproducción automática disponible para todos los servicios (no sólo para YouTube)
|
||||
|
||||
Reparado
|
||||
Arreglado
|
||||
• Streams relacionados, gracias al soporte de las nuevas continuaciones de YouTube
|
||||
• Videos con restricción de edad en YouTube
|
||||
• [Android TV] Foco retenido
|
||||
• [Android TV] Superposición de los destacados de foco persistente
|
||||
|
|
3
fastlane/metadata/android/es/changelogs/959.txt
Normal file
3
fastlane/metadata/android/es/changelogs/959.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
Arreglado un bucle interminable de caídas después de abrir el reportador de errores.
|
||||
Lista actualizada de instancias de PeerTube que pueden ser abiertas automáticamente por NewPipe.
|
||||
Traducciones actualizadas.
|
3
fastlane/metadata/android/eu/changelogs/959.txt
Normal file
3
fastlane/metadata/android/eu/changelogs/959.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
Akatsen txostena ireki ostean zeuden hutsegite amaigabeak konpondu dira.
|
||||
NewPipekin automatikoki ireki daitezkeen PeerTube instantziak eguneratu dira.
|
||||
Itzulpenak eguneratuta.
|
4
fastlane/metadata/android/it/changelogs/770.txt
Normal file
4
fastlane/metadata/android/it/changelogs/770.txt
Normal file
|
@ -0,0 +1,4 @@
|
|||
Modifiche su 0.17.2
|
||||
|
||||
Correzionw
|
||||
• Risolto il problema con nessun video disponibile
|
1
fastlane/metadata/android/it/changelogs/830.txt
Normal file
1
fastlane/metadata/android/it/changelogs/830.txt
Normal file
|
@ -0,0 +1 @@
|
|||
Aggiornato SoundCloud client_id per risolvere i problemi di SoundCloud.
|
1
fastlane/metadata/android/it/changelogs/850.txt
Normal file
1
fastlane/metadata/android/it/changelogs/850.txt
Normal file
|
@ -0,0 +1 @@
|
|||
In questa versione è stata aggiornata la versione del sito web di YouTube. La vecchia versione del sito web verrà interrotta a Marzo e quindi è necessario aggiornare NewPipe.
|
7
fastlane/metadata/android/it/changelogs/860.txt
Normal file
7
fastlane/metadata/android/it/changelogs/860.txt
Normal file
|
@ -0,0 +1,7 @@
|
|||
Migliorato
|
||||
• Salvare e ripristinare se intonazione e tempo sono sganciati o meno
|
||||
• Supporta il ritaglio del display nel lettore
|
||||
• Visualizzazione rotonda e numero di iscritti
|
||||
• YouTube ottimizzato per utilizzare meno dati
|
||||
|
||||
In questa versione sono stati corretti più di 15 errori relativi a YouTube.
|
2
fastlane/metadata/android/it/changelogs/870.txt
Normal file
2
fastlane/metadata/android/it/changelogs/870.txt
Normal file
|
@ -0,0 +1,2 @@
|
|||
Questa è una versione hotfix che aggiorna NewPipe per consentire nuovamente l'utilizzo di SoundCloud senza grossi problemi.
|
||||
L'API v2 di SoundCloud viene ora utilizzata nell'estrattore e il rilevamento di ID client non validi è stato migliorato.
|
1
fastlane/metadata/android/it/changelogs/910.txt
Normal file
1
fastlane/metadata/android/it/changelogs/910.txt
Normal file
|
@ -0,0 +1 @@
|
|||
Corretta la migrazione del database che in alcuni rari casi impediva l'avvio di NewPipe.
|
1
fastlane/metadata/android/it/changelogs/956.txt
Normal file
1
fastlane/metadata/android/it/changelogs/956.txt
Normal file
|
@ -0,0 +1 @@
|
|||
[YouTube] Risolto un arresto anomalo durante il caricamento di qualsiasi video
|
3
fastlane/metadata/android/nb-NO/changelogs/959.txt
Normal file
3
fastlane/metadata/android/nb-NO/changelogs/959.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
Fikset uendelig kræsjløkke ved åpning av feilrapportering.
|
||||
Oppdatert liste over PeerTube-isntanser som kan åpnes automatisk av NewPipe.
|
||||
Oppdaterte oversettelser.
|
3
fastlane/metadata/android/pl/changelogs/959.txt
Normal file
3
fastlane/metadata/android/pl/changelogs/959.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
Naprawiono niekończącą się pętlę awarii po otwarciu raportu o błędach.
|
||||
Zaktualizowana lista instancji PeerTube, które mogą być otwierane automatycznie przez NewPipe.
|
||||
Zaktualizowano tłumaczenia.
|
3
fastlane/metadata/android/pt_BR/changelogs/959.txt
Normal file
3
fastlane/metadata/android/pt_BR/changelogs/959.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
Corrigimos um loop interminável de crash depois de abrir o reportar erro.
|
||||
Atualizado lista de instâncias do PeerTube que podem ser abertas automaticamente pelo NewPipe.
|
||||
Traduções atualizadas.
|
|
@ -1 +1 @@
|
|||
NewPipe не использует библиотеки фреймворка Google или API YouTube, взаимодействуя только с сайтом сервиса для получения необходимых сведений. NewPipe может работать на устройствах без установленных Сервисов Google и не требует учётной записи YouTube. Это свободное программное обеспечение.
|
||||
NewPipe не использует библиотеки фреймворка Google или API YouTube, взаимодействуя только с сайтом сервиса для получения необходимых сведений. NewPipe может работать на устройствах без установленных Сервисов Google и не требует учётной записи YouTube, это свободное программное обеспечение.
|
||||
|
|
Loading…
Reference in a new issue