diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/downloader/Downloader.java b/extractor/src/main/java/org/schabi/newpipe/extractor/downloader/Downloader.java
index 75d0bbf80..18017ded2 100644
--- a/extractor/src/main/java/org/schabi/newpipe/extractor/downloader/Downloader.java
+++ b/extractor/src/main/java/org/schabi/newpipe/extractor/downloader/Downloader.java
@@ -4,12 +4,13 @@ import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.exceptions.ReCaptchaException;
import org.schabi.newpipe.extractor.localization.Localization;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
import java.io.IOException;
import java.util.List;
import java.util.Map;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
/**
* A base for downloader implementations that NewPipe will use
* to download needed resources during extraction.
@@ -148,8 +149,27 @@ public abstract class Downloader {
/**
* Do a request using the specified {@link Request} object.
*
+ * @param request The request to process
* @return the result of the request
*/
public abstract Response execute(@Nonnull Request request)
throws IOException, ReCaptchaException;
+
+ /**
+ * Get the size of the content that the url is pointing by firing a HEAD request.
+ *
+ * @param url an url pointing to the content
+ * @return the size of the content, in bytes or -1 if unknown
+ */
+ public long getContentLength(final String url) {
+ try {
+ final String contentLengthHeader = head(url).getHeader("Content-Length");
+ if (contentLengthHeader == null) {
+ return -1;
+ }
+ return Long.parseLong(contentLengthHeader);
+ } catch (final Exception e) {
+ return -1;
+ }
+ }
}
diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/dashmanifestcreator/AbstractYoutubeDashManifestCreator.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/dashmanifestcreator/AbstractYoutubeDashManifestCreator.java
index f8c2cc9a2..2b55e2e87 100644
--- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/dashmanifestcreator/AbstractYoutubeDashManifestCreator.java
+++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/dashmanifestcreator/AbstractYoutubeDashManifestCreator.java
@@ -102,6 +102,11 @@ public abstract class AbstractYoutubeDashManifestCreator implements DashManifest
this.durationSecondsFallback = durationSecondsFallback;
}
+ @Override
+ public long getExpectedContentLength(final Downloader downloader) {
+ return downloader.getContentLength(itagInfo.getStreamUrl());
+ }
+
protected boolean isLiveDelivery() {
return false;
}
diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/stream/StreamInfoItem.java b/extractor/src/main/java/org/schabi/newpipe/extractor/stream/StreamInfoItem.java
index b88a27506..f3b45b6e6 100644
--- a/extractor/src/main/java/org/schabi/newpipe/extractor/stream/StreamInfoItem.java
+++ b/extractor/src/main/java/org/schabi/newpipe/extractor/stream/StreamInfoItem.java
@@ -29,8 +29,8 @@ import javax.annotation.Nullable;
* Info object for previews of unopened videos, eg search results, related videos
*/
public class StreamInfoItem extends InfoItem {
- private final boolean audioOnly;
private final boolean live;
+ private final boolean audioOnly;
private String uploaderName;
private String shortDescription;
@@ -47,11 +47,11 @@ public class StreamInfoItem extends InfoItem {
public StreamInfoItem(final int serviceId,
final String url,
final String name,
- final boolean audioOnly,
- final boolean live) {
+ final boolean live,
+ final boolean audioOnly) {
super(InfoType.STREAM, serviceId, url, name);
- this.audioOnly = audioOnly;
this.live = live;
+ this.audioOnly = audioOnly;
}
public boolean isAudioOnly() {
diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/stream/StreamInfoItemsCollector.java b/extractor/src/main/java/org/schabi/newpipe/extractor/stream/StreamInfoItemsCollector.java
index d2d1b527a..c294e18b7 100644
--- a/extractor/src/main/java/org/schabi/newpipe/extractor/stream/StreamInfoItemsCollector.java
+++ b/extractor/src/main/java/org/schabi/newpipe/extractor/stream/StreamInfoItemsCollector.java
@@ -48,8 +48,8 @@ public class StreamInfoItemsCollector
getServiceId(),
extractor.getUrl(),
extractor.getName(),
- extractor.isAudioOnly(),
- extractor.isLive());
+ extractor.isLive(),
+ extractor.isAudioOnly());
// optional information
try {
diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/streamdata/delivery/DASHManifestDeliveryData.java b/extractor/src/main/java/org/schabi/newpipe/extractor/streamdata/delivery/DASHManifestDeliveryData.java
index 412a51276..56acf8e98 100644
--- a/extractor/src/main/java/org/schabi/newpipe/extractor/streamdata/delivery/DASHManifestDeliveryData.java
+++ b/extractor/src/main/java/org/schabi/newpipe/extractor/streamdata/delivery/DASHManifestDeliveryData.java
@@ -1,5 +1,6 @@
package org.schabi.newpipe.extractor.streamdata.delivery;
+import org.schabi.newpipe.extractor.downloader.Downloader;
import org.schabi.newpipe.extractor.streamdata.delivery.dashmanifestcreator.DashManifestCreator;
import javax.annotation.Nonnull;
@@ -9,4 +10,9 @@ public interface DASHManifestDeliveryData extends DASHDeliveryData {
DashManifestCreator dashManifestCreator();
String getCachedDashManifestAsString();
+
+ @Override
+ default long getExpectedContentLength(final Downloader downloader) {
+ return dashManifestCreator().getExpectedContentLength(downloader);
+ }
}
diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/streamdata/delivery/DeliveryData.java b/extractor/src/main/java/org/schabi/newpipe/extractor/streamdata/delivery/DeliveryData.java
index 9149d7794..1c861a6d8 100644
--- a/extractor/src/main/java/org/schabi/newpipe/extractor/streamdata/delivery/DeliveryData.java
+++ b/extractor/src/main/java/org/schabi/newpipe/extractor/streamdata/delivery/DeliveryData.java
@@ -1,5 +1,13 @@
package org.schabi.newpipe.extractor.streamdata.delivery;
+import org.schabi.newpipe.extractor.downloader.Downloader;
+
public interface DeliveryData {
- // Only a marker so far
+ /**
+ * Returns the expected content length/size of the data.
+ *
+ * @param downloader The downloader that may be used for fetching (HTTP HEAD).
+ * @return the expected size/content length or -1
if unknown
+ */
+ long getExpectedContentLength(Downloader downloader);
}
diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/streamdata/delivery/UrlBasedDeliveryData.java b/extractor/src/main/java/org/schabi/newpipe/extractor/streamdata/delivery/UrlBasedDeliveryData.java
index a0df54f91..1b7e56ecd 100644
--- a/extractor/src/main/java/org/schabi/newpipe/extractor/streamdata/delivery/UrlBasedDeliveryData.java
+++ b/extractor/src/main/java/org/schabi/newpipe/extractor/streamdata/delivery/UrlBasedDeliveryData.java
@@ -1,8 +1,15 @@
package org.schabi.newpipe.extractor.streamdata.delivery;
+import org.schabi.newpipe.extractor.downloader.Downloader;
+
import javax.annotation.Nonnull;
public interface UrlBasedDeliveryData extends DeliveryData {
@Nonnull
String url();
+
+ @Override
+ default long getExpectedContentLength(final Downloader downloader) {
+ return downloader.getContentLength(url());
+ }
}
diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/streamdata/delivery/dashmanifestcreator/DashManifestCreator.java b/extractor/src/main/java/org/schabi/newpipe/extractor/streamdata/delivery/dashmanifestcreator/DashManifestCreator.java
index 66cd2d860..0195f25ce 100644
--- a/extractor/src/main/java/org/schabi/newpipe/extractor/streamdata/delivery/dashmanifestcreator/DashManifestCreator.java
+++ b/extractor/src/main/java/org/schabi/newpipe/extractor/streamdata/delivery/dashmanifestcreator/DashManifestCreator.java
@@ -1,14 +1,23 @@
package org.schabi.newpipe.extractor.streamdata.delivery.dashmanifestcreator;
+import org.schabi.newpipe.extractor.downloader.Downloader;
+
import javax.annotation.Nonnull;
public interface DashManifestCreator {
/**
* Generates the DASH manifest.
+ *
* @return The dash manifest as string.
* @throws DashManifestCreationException May throw a CreationException
*/
@Nonnull
String generateManifest();
+
+ /**
+ * See
+ * {@link org.schabi.newpipe.extractor.streamdata.delivery.DeliveryData#getExpectedContentLength(Downloader)}
+ */
+ long getExpectedContentLength(Downloader downloader);
}
diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/streamdata/stream/SubtitleStream.java b/extractor/src/main/java/org/schabi/newpipe/extractor/streamdata/stream/SubtitleStream.java
index 98ceb9287..47aedce7d 100644
--- a/extractor/src/main/java/org/schabi/newpipe/extractor/streamdata/stream/SubtitleStream.java
+++ b/extractor/src/main/java/org/schabi/newpipe/extractor/streamdata/stream/SubtitleStream.java
@@ -39,5 +39,10 @@ public interface SubtitleStream extends Stream {
*
* @return the {@link Locale locale} of the subtitles
*/
+ @Nonnull
Locale locale();
+
+ default String getDisplayLanguageName() {
+ return locale().getDisplayName(locale());
+ }
}
diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/streamdata/stream/VideoStream.java b/extractor/src/main/java/org/schabi/newpipe/extractor/streamdata/stream/VideoStream.java
index a5c32d249..115d4bbd1 100644
--- a/extractor/src/main/java/org/schabi/newpipe/extractor/streamdata/stream/VideoStream.java
+++ b/extractor/src/main/java/org/schabi/newpipe/extractor/streamdata/stream/VideoStream.java
@@ -10,5 +10,5 @@ import javax.annotation.Nonnull;
*/
public interface VideoStream extends Stream {
@Nonnull
- VideoQualityData videoQualityData();
+ VideoQualityData qualityData();
}
diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/streamdata/stream/simpleimpl/SimpleVideoAudioStreamImpl.java b/extractor/src/main/java/org/schabi/newpipe/extractor/streamdata/stream/simpleimpl/SimpleVideoAudioStreamImpl.java
index 68d03a090..7dd0e266d 100644
--- a/extractor/src/main/java/org/schabi/newpipe/extractor/streamdata/stream/simpleimpl/SimpleVideoAudioStreamImpl.java
+++ b/extractor/src/main/java/org/schabi/newpipe/extractor/streamdata/stream/simpleimpl/SimpleVideoAudioStreamImpl.java
@@ -38,7 +38,7 @@ public class SimpleVideoAudioStreamImpl extends AbstractStreamImpl