Created new basic stream architecture
This commit is contained in:
parent
6a858368c8
commit
c2b9537b66
|
@ -0,0 +1,5 @@
|
|||
package org.schabi.newpipe.extractor.streamdata.delivery;
|
||||
|
||||
public interface DASHDeliveryData extends DeliveryData {
|
||||
// Just a marker interface
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package org.schabi.newpipe.extractor.streamdata.delivery;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public interface DASHManifestDeliveryData extends DASHDeliveryData {
|
||||
/**
|
||||
* Returns the base url for the DashManifest.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
// TODO: Check removal
|
||||
@Nonnull
|
||||
default String getBaseUrl() {
|
||||
return "";
|
||||
}
|
||||
|
||||
String getManifestAsString();
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package org.schabi.newpipe.extractor.streamdata.delivery;
|
||||
|
||||
public interface DASHUrlDeliveryData extends UrlBasedDeliveryData, DASHDeliveryData {
|
||||
// Nothing to implement additionally
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package org.schabi.newpipe.extractor.streamdata.delivery;
|
||||
|
||||
public interface DeliveryData {
|
||||
// Only a marker so far
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package org.schabi.newpipe.extractor.streamdata.delivery;
|
||||
|
||||
public interface HLSDeliveryData extends UrlBasedDeliveryData {
|
||||
// Nothing to implement additionally
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package org.schabi.newpipe.extractor.streamdata.delivery;
|
||||
|
||||
public interface ProgressiveHTTPDeliveryData extends DeliveryData {
|
||||
// Nothing to implement additionally
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package org.schabi.newpipe.extractor.streamdata.delivery;
|
||||
|
||||
public interface TorrentDeliveryData extends UrlBasedDeliveryData {
|
||||
// Nothing to implement additionally
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package org.schabi.newpipe.extractor.streamdata.delivery;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public interface UrlBasedDeliveryData extends DeliveryData {
|
||||
@Nonnull
|
||||
String url();
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package org.schabi.newpipe.extractor.streamdata.delivery.simpleimpl;
|
||||
|
||||
import org.schabi.newpipe.extractor.streamdata.delivery.DeliveryData;
|
||||
|
||||
public abstract class AbstractDeliveryDataImpl implements DeliveryData {
|
||||
// Nothing to implement so far
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package org.schabi.newpipe.extractor.streamdata.delivery.simpleimpl;
|
||||
|
||||
import org.schabi.newpipe.extractor.streamdata.delivery.UrlBasedDeliveryData;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public abstract class AbstractUrlBasedDeliveryDataImpl extends AbstractDeliveryDataImpl
|
||||
implements UrlBasedDeliveryData {
|
||||
|
||||
@Nonnull
|
||||
private final String url;
|
||||
|
||||
protected AbstractUrlBasedDeliveryDataImpl(@Nonnull final String url) {
|
||||
this.url = Objects.requireNonNull(url);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public String url() {
|
||||
return url;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package org.schabi.newpipe.extractor.streamdata.delivery.simpleimpl;
|
||||
|
||||
import org.schabi.newpipe.extractor.streamdata.delivery.DASHManifestDeliveryData;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* Note we build the manifests for YT ourself because the provided ones (according to TiA4f8R)
|
||||
* <ul>
|
||||
* <li>aren't working https://github.com/google/ExoPlayer/issues/2422#issuecomment-283080031</li>
|
||||
* <li>causes memory problems; TransactionTooLargeException: data parcel size 3174340</li>
|
||||
* <li>are not always returned, only for videos with OTF streams, or on (ended or not)
|
||||
* livestreams</li>
|
||||
* <li>Instead of downloading a 10MB manifest when you can generate one which is 1 or 2MB large</li>
|
||||
* <li>Also, this manifest isn't used at all by modern YouTube clients.</li>
|
||||
* </ul>
|
||||
*/
|
||||
public class SimpleDASHManifestDeliveryDataImpl extends AbstractDeliveryDataImpl
|
||||
implements DASHManifestDeliveryData {
|
||||
@Nonnull
|
||||
private final Supplier<String> dashManifestBuilder;
|
||||
|
||||
public SimpleDASHManifestDeliveryDataImpl(@Nonnull final Supplier<String> dashManifestBuilder) {
|
||||
this.dashManifestBuilder = Objects.requireNonNull(dashManifestBuilder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getManifestAsString() {
|
||||
return dashManifestBuilder.get();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package org.schabi.newpipe.extractor.streamdata.delivery.simpleimpl;
|
||||
|
||||
import org.schabi.newpipe.extractor.streamdata.delivery.DASHUrlDeliveryData;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class SimpleDASHUrlDeliveryDataImpl extends AbstractUrlBasedDeliveryDataImpl
|
||||
implements DASHUrlDeliveryData {
|
||||
public SimpleDASHUrlDeliveryDataImpl(@Nonnull final String url) {
|
||||
super(url);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package org.schabi.newpipe.extractor.streamdata.delivery.simpleimpl;
|
||||
|
||||
import org.schabi.newpipe.extractor.streamdata.delivery.HLSDeliveryData;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class SimpleHLSDeliveryDataImpl extends AbstractUrlBasedDeliveryDataImpl
|
||||
implements HLSDeliveryData {
|
||||
public SimpleHLSDeliveryDataImpl(@Nonnull final String url) {
|
||||
super(url);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package org.schabi.newpipe.extractor.streamdata.delivery.simpleimpl;
|
||||
|
||||
import org.schabi.newpipe.extractor.streamdata.delivery.ProgressiveHTTPDeliveryData;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class SimpleProgressiveHTTPDeliveryDataImpl extends AbstractUrlBasedDeliveryDataImpl
|
||||
implements ProgressiveHTTPDeliveryData {
|
||||
public SimpleProgressiveHTTPDeliveryDataImpl(@Nonnull final String url) {
|
||||
super(url);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package org.schabi.newpipe.extractor.streamdata.delivery.simpleimpl;
|
||||
|
||||
import org.schabi.newpipe.extractor.streamdata.delivery.TorrentDeliveryData;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class SimpleTorrentDeliveryDataImpl extends AbstractUrlBasedDeliveryDataImpl
|
||||
implements TorrentDeliveryData {
|
||||
public SimpleTorrentDeliveryDataImpl(@Nonnull final String url) {
|
||||
super(url);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package org.schabi.newpipe.extractor.streamdata.format;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public abstract class AbstractMediaFormat {
|
||||
private final int id;
|
||||
private final String name;
|
||||
private final String suffix;
|
||||
private final String mimeType;
|
||||
|
||||
protected AbstractMediaFormat(
|
||||
final int id,
|
||||
final String name,
|
||||
final String suffix,
|
||||
final String mimeType
|
||||
) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.suffix = suffix;
|
||||
this.mimeType = mimeType;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getSuffix() {
|
||||
return suffix;
|
||||
}
|
||||
|
||||
public String getMimeType() {
|
||||
return mimeType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof AbstractMediaFormat)) return false;
|
||||
final AbstractMediaFormat that = (AbstractMediaFormat) o;
|
||||
return getId() == that.getId() && Objects.equals(getName(), that.getName()) && Objects.equals(getSuffix(), that.getSuffix()) && Objects.equals(getMimeType(), that.getMimeType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(getId(), getName(), getSuffix(), getMimeType());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package org.schabi.newpipe.extractor.streamdata.format;
|
||||
|
||||
public class AudioMediaFormat extends AbstractMediaFormat {
|
||||
public AudioMediaFormat(
|
||||
final int id,
|
||||
final String name,
|
||||
final String suffix,
|
||||
final String mimeType
|
||||
) {
|
||||
super(id, name, suffix, mimeType);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package org.schabi.newpipe.extractor.streamdata.format;
|
||||
|
||||
public class SubtitleMediaFormat extends AbstractMediaFormat {
|
||||
public SubtitleMediaFormat(
|
||||
final int id,
|
||||
final String name,
|
||||
final String suffix,
|
||||
final String mimeType
|
||||
) {
|
||||
super(id, name, suffix, mimeType);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package org.schabi.newpipe.extractor.streamdata.format;
|
||||
|
||||
public class VideoAudioMediaFormat extends AbstractMediaFormat {
|
||||
public VideoAudioMediaFormat(
|
||||
final int id,
|
||||
final String name,
|
||||
final String suffix,
|
||||
final String mimeType
|
||||
) {
|
||||
super(id, name, suffix, mimeType);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package org.schabi.newpipe.extractor.streamdata.format.registry;
|
||||
|
||||
import org.schabi.newpipe.extractor.streamdata.format.AudioMediaFormat;
|
||||
|
||||
public class AudioFormatRegistry extends MediaFormatRegistry<AudioMediaFormat> {
|
||||
|
||||
public static final AudioMediaFormat M4A =
|
||||
new AudioMediaFormat(0x100, "m4a", "m4a", "audio/mp4");
|
||||
public static final AudioMediaFormat WEBMA =
|
||||
new AudioMediaFormat(0x200, "WebM", "webm", "audio/webm");
|
||||
public static final AudioMediaFormat MP3 =
|
||||
new AudioMediaFormat(0x300, "MP3", "mp3", "audio/mpeg");
|
||||
public static final AudioMediaFormat OPUS =
|
||||
new AudioMediaFormat(0x400, "opus", "opus", "audio/opus");
|
||||
public static final AudioMediaFormat OGG =
|
||||
new AudioMediaFormat(0x500, "ogg", "ogg", "audio/ogg");
|
||||
public static final AudioMediaFormat WEBMA_OPUS =
|
||||
new AudioMediaFormat(0x200, "WebM Opus", "webm", "audio/webm");
|
||||
|
||||
public AudioFormatRegistry() {
|
||||
super(new AudioMediaFormat[]{M4A, WEBMA, MP3, OPUS, OGG, WEBMA_OPUS});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
package org.schabi.newpipe.extractor.streamdata.format.registry;
|
||||
|
||||
import org.schabi.newpipe.extractor.streamdata.format.AbstractMediaFormat;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.function.Function;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public abstract class MediaFormatRegistry<F extends AbstractMediaFormat> {
|
||||
|
||||
protected final F[] values;
|
||||
|
||||
protected MediaFormatRegistry(final F[] values) {
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
public F[] values() {
|
||||
return values;
|
||||
}
|
||||
|
||||
public <T> T getById(final int id,
|
||||
final Function<F, T> field,
|
||||
final T orElse) {
|
||||
return Arrays.stream(values())
|
||||
.filter(mediaFormat -> mediaFormat.getId() == id)
|
||||
.map(field)
|
||||
.findFirst()
|
||||
.orElse(orElse);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the friendly name of the media format with the supplied id
|
||||
*
|
||||
* @param id the id of the media format. Currently an arbitrary, NewPipe-specific number.
|
||||
* @return the friendly name of the MediaFormat associated with this ids,
|
||||
* or an empty String if none match it.
|
||||
*/
|
||||
@Nonnull
|
||||
public String getNameById(final int id) {
|
||||
return getById(id, AbstractMediaFormat::getName, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the MIME type of the media format with the supplied id
|
||||
*
|
||||
* @param id the id of the media format. Currently an arbitrary, NewPipe-specific number.
|
||||
* @return the MIME type of the MediaFormat associated with this ids,
|
||||
* or an empty String if none match it.
|
||||
*/
|
||||
@Nullable
|
||||
public String getMimeById(final int id) {
|
||||
return getById(id, AbstractMediaFormat::getMimeType, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the MediaFormat with the supplied mime type
|
||||
*
|
||||
* @return MediaFormat associated with this mime type,
|
||||
* or null if none match it.
|
||||
*/
|
||||
@Nullable
|
||||
public F getFromMimeType(final String mimeType) {
|
||||
return Arrays.stream(values())
|
||||
.filter(mediaFormat -> mediaFormat.getMimeType().equals(mimeType))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public F getFromSuffix(final String suffix) {
|
||||
return Arrays.stream(values())
|
||||
.filter(mediaFormat -> mediaFormat.getSuffix().equals(suffix))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package org.schabi.newpipe.extractor.streamdata.format.registry;
|
||||
|
||||
import org.schabi.newpipe.extractor.streamdata.format.SubtitleMediaFormat;
|
||||
|
||||
public class SubtitleFormatRegistry extends MediaFormatRegistry<SubtitleMediaFormat> {
|
||||
|
||||
public static final SubtitleMediaFormat VTT =
|
||||
new SubtitleMediaFormat(0x1000, "WebVTT", "vtt", "text/vtt");
|
||||
public static final SubtitleMediaFormat TTML =
|
||||
new SubtitleMediaFormat(0x2000, "Timed Text Markup Language", "ttml",
|
||||
"application/ttml+xml");
|
||||
public static final SubtitleMediaFormat TRANSCRIPT1 =
|
||||
new SubtitleMediaFormat(0x3000, "TranScript v1", "srv1", "text/xml");
|
||||
public static final SubtitleMediaFormat TRANSCRIPT2 =
|
||||
new SubtitleMediaFormat(0x4000, "TranScript v2", "srv2", "text/xml");
|
||||
public static final SubtitleMediaFormat TRANSCRIPT3 =
|
||||
new SubtitleMediaFormat(0x5000, "TranScript v3", "srv3", "text/xml");
|
||||
public static final SubtitleMediaFormat SRT =
|
||||
new SubtitleMediaFormat(0x6000, "SubRip file format", "srt", "text/srt");
|
||||
|
||||
|
||||
public SubtitleFormatRegistry() {
|
||||
super(new SubtitleMediaFormat[]{VTT, TTML, TRANSCRIPT1, TRANSCRIPT2, TRANSCRIPT3, SRT});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package org.schabi.newpipe.extractor.streamdata.format.registry;
|
||||
|
||||
import org.schabi.newpipe.extractor.streamdata.format.VideoAudioMediaFormat;
|
||||
|
||||
public class VideoAudioFormatRegistry extends MediaFormatRegistry<VideoAudioMediaFormat> {
|
||||
|
||||
public static final VideoAudioMediaFormat MPEG_4 =
|
||||
new VideoAudioMediaFormat(0x0, "MPEG-4", "mp4", "video/mp4");
|
||||
public static final VideoAudioMediaFormat V3GPP =
|
||||
new VideoAudioMediaFormat(0x10, "3GPP", "3gp", "video/3gpp");
|
||||
public static final VideoAudioMediaFormat WEBM =
|
||||
new VideoAudioMediaFormat(0x20, "WebM", "webm", "video/webm");
|
||||
|
||||
public VideoAudioFormatRegistry() {
|
||||
super(new VideoAudioMediaFormat[]{MPEG_4, V3GPP, WEBM});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package org.schabi.newpipe.extractor.streamdata.stream;
|
||||
|
||||
import org.schabi.newpipe.extractor.streamdata.format.AudioMediaFormat;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Represents a audio (only) stream.
|
||||
*/
|
||||
public interface AudioStream extends Stream {
|
||||
int UNKNOWN_BITRATE = -1;
|
||||
|
||||
// TODO: Check if this can be non-null
|
||||
@Nullable
|
||||
default AudioMediaFormat audioMediaFormat() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the average bitrate of the stream.
|
||||
*
|
||||
* @return the average bitrate or <code>-1</code> if unknown
|
||||
*/
|
||||
default int averageBitrate() {
|
||||
return UNKNOWN_BITRATE;
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean equalsStream(@Nullable final Stream other) {
|
||||
if (!(other instanceof AudioStream)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final AudioStream otherAudioStream = (AudioStream) other;
|
||||
return Objects.equals(audioMediaFormat(), otherAudioStream.audioMediaFormat())
|
||||
&& averageBitrate() == otherAudioStream.averageBitrate();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package org.schabi.newpipe.extractor.streamdata.stream;
|
||||
|
||||
import org.schabi.newpipe.extractor.streamdata.delivery.DeliveryData;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public interface Stream {
|
||||
@Nonnull
|
||||
DeliveryData deliveryData();
|
||||
|
||||
|
||||
// TODO: May also have to check deliverydata
|
||||
boolean equalsStream(@Nullable final Stream other);
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
package org.schabi.newpipe.extractor.streamdata.stream;
|
||||
|
||||
import org.schabi.newpipe.extractor.streamdata.format.SubtitleMediaFormat;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Represents a subtitle (only) stream.
|
||||
*/
|
||||
public interface SubtitleStream extends Stream {
|
||||
@Nonnull
|
||||
SubtitleMediaFormat subtitleMediaFormat();
|
||||
|
||||
/**
|
||||
* Return whether if the subtitles are auto-generated.
|
||||
* <p>
|
||||
* Some streaming services can generate subtitles for their contents, like YouTube.
|
||||
* </p>
|
||||
*
|
||||
* @return {@code true} if the subtitles are auto-generated, {@code false} otherwise
|
||||
*/
|
||||
default boolean autoGenerated() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the language code of the subtitles.
|
||||
*
|
||||
* @return the language code of the subtitles
|
||||
*/
|
||||
@Nonnull
|
||||
String languageCode();
|
||||
|
||||
/**
|
||||
* Get the {@link Locale locale} of the subtitles.
|
||||
*
|
||||
* <p>
|
||||
* Note: The locale is directly derived from the language-code.
|
||||
* </p>
|
||||
*
|
||||
* @return the {@link Locale locale} of the subtitles
|
||||
*/
|
||||
Locale locale();
|
||||
|
||||
@Override
|
||||
default boolean equalsStream(@Nullable final Stream other) {
|
||||
if (!(other instanceof SubtitleStream)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final SubtitleStream otherSubtitleStream = (SubtitleStream) other;
|
||||
return Objects.equals(subtitleMediaFormat(), otherSubtitleStream.subtitleMediaFormat())
|
||||
&& autoGenerated() == otherSubtitleStream.autoGenerated()
|
||||
&& Objects.equals(languageCode(), otherSubtitleStream.languageCode());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package org.schabi.newpipe.extractor.streamdata.stream;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Represents a combined video+audio stream.
|
||||
*/
|
||||
public interface VideoAudioStream extends VideoStream, AudioStream {
|
||||
@Override
|
||||
default boolean equalsStream(@Nullable final Stream other) {
|
||||
if (!(other instanceof VideoAudioStream)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return VideoStream.super.equalsStream(other) && AudioStream.super.equalsStream(other);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package org.schabi.newpipe.extractor.streamdata.stream;
|
||||
|
||||
import org.schabi.newpipe.extractor.streamdata.format.VideoAudioMediaFormat;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Represents a video (only) stream.
|
||||
*/
|
||||
public interface VideoStream extends Stream {
|
||||
String UNKNOWN_RESOLUTION = "";
|
||||
|
||||
// TODO: Check if this can be non-null
|
||||
@Nullable
|
||||
default VideoAudioMediaFormat videoMediaFormat() {
|
||||
return null;
|
||||
}
|
||||
|
||||
// TODO: This should be a separate entity (containing e.g. height x width + fps)
|
||||
@Nonnull
|
||||
default String resolution() {
|
||||
return UNKNOWN_RESOLUTION;
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean equalsStream(@Nullable final Stream other) {
|
||||
if (!(other instanceof VideoStream)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final VideoStream otherVideoStream = (VideoStream) other;
|
||||
return Objects.equals(videoMediaFormat(), otherVideoStream.videoMediaFormat())
|
||||
&& Objects.equals(resolution(), otherVideoStream.resolution());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package org.schabi.newpipe.extractor.streamdata.stream.simpleimpl;
|
||||
|
||||
import org.schabi.newpipe.extractor.streamdata.delivery.DeliveryData;
|
||||
import org.schabi.newpipe.extractor.streamdata.stream.Stream;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public abstract class AbstractStreamImpl implements Stream {
|
||||
@Nonnull
|
||||
private final DeliveryData deliveryData;
|
||||
|
||||
protected AbstractStreamImpl(@Nonnull final DeliveryData deliveryData) {
|
||||
this.deliveryData = Objects.requireNonNull(deliveryData);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public DeliveryData deliveryData() {
|
||||
return deliveryData;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package org.schabi.newpipe.extractor.streamdata.stream.simpleimpl;
|
||||
|
||||
import org.schabi.newpipe.extractor.streamdata.delivery.DeliveryData;
|
||||
import org.schabi.newpipe.extractor.streamdata.format.AudioMediaFormat;
|
||||
import org.schabi.newpipe.extractor.streamdata.stream.AudioStream;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class SimpleAudioStreamImpl extends AbstractStreamImpl implements AudioStream {
|
||||
@Nullable
|
||||
private final AudioMediaFormat audioMediaFormat;
|
||||
private final int averageBitrate;
|
||||
|
||||
public SimpleAudioStreamImpl(
|
||||
@Nonnull final DeliveryData deliveryData,
|
||||
@Nullable final AudioMediaFormat audioMediaFormat,
|
||||
final int averageBitrate
|
||||
) {
|
||||
super(deliveryData);
|
||||
this.audioMediaFormat = audioMediaFormat;
|
||||
this.averageBitrate = averageBitrate;
|
||||
}
|
||||
|
||||
public SimpleAudioStreamImpl(
|
||||
@Nonnull final DeliveryData deliveryData,
|
||||
@Nullable final AudioMediaFormat audioMediaFormat
|
||||
) {
|
||||
this(deliveryData, audioMediaFormat, UNKNOWN_BITRATE);
|
||||
}
|
||||
|
||||
public SimpleAudioStreamImpl(
|
||||
@Nonnull final DeliveryData deliveryData,
|
||||
final int averageBitrate
|
||||
) {
|
||||
this(deliveryData, null, averageBitrate);
|
||||
}
|
||||
|
||||
public SimpleAudioStreamImpl(@Nonnull final DeliveryData deliveryData) {
|
||||
this(deliveryData, null);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public AudioMediaFormat audioMediaFormat() {
|
||||
return audioMediaFormat;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int averageBitrate() {
|
||||
return averageBitrate;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
package org.schabi.newpipe.extractor.streamdata.stream.simpleimpl;
|
||||
|
||||
import org.schabi.newpipe.extractor.streamdata.delivery.DeliveryData;
|
||||
import org.schabi.newpipe.extractor.streamdata.format.SubtitleMediaFormat;
|
||||
import org.schabi.newpipe.extractor.streamdata.stream.SubtitleStream;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class SimpleSubtitleStreamImpl extends AbstractStreamImpl implements SubtitleStream {
|
||||
@Nonnull
|
||||
private final SubtitleMediaFormat subtitleMediaFormat;
|
||||
private final boolean autogenerated;
|
||||
@Nonnull
|
||||
private final String languageCode;
|
||||
private final Locale locale;
|
||||
|
||||
public SimpleSubtitleStreamImpl(
|
||||
@Nonnull final DeliveryData deliveryData,
|
||||
final SubtitleMediaFormat subtitleMediaFormat,
|
||||
final boolean autogenerated,
|
||||
@Nonnull final String languageCode
|
||||
) {
|
||||
super(deliveryData);
|
||||
this.subtitleMediaFormat = Objects.requireNonNull(subtitleMediaFormat);
|
||||
this.autogenerated = autogenerated;
|
||||
this.languageCode = Objects.requireNonNull(languageCode);
|
||||
/*
|
||||
* Locale.forLanguageTag only for Android API >= 21
|
||||
* Locale.Builder only for Android API >= 21
|
||||
* Country codes doesn't work well without
|
||||
*/
|
||||
final String[] splits = languageCode.split("-");
|
||||
switch (splits.length) {
|
||||
case 2:
|
||||
this.locale = new Locale(splits[0], splits[1]);
|
||||
break;
|
||||
case 3:
|
||||
// Complex variants don't work!
|
||||
this.locale = new Locale(splits[0], splits[1], splits[2]);
|
||||
break;
|
||||
default:
|
||||
this.locale = new Locale(splits[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public SubtitleMediaFormat subtitleMediaFormat() {
|
||||
return subtitleMediaFormat;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean autoGenerated() {
|
||||
return autogenerated;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public String languageCode() {
|
||||
return languageCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locale locale() {
|
||||
return locale;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
package org.schabi.newpipe.extractor.streamdata.stream.simpleimpl;
|
||||
|
||||
import org.schabi.newpipe.extractor.streamdata.delivery.DeliveryData;
|
||||
import org.schabi.newpipe.extractor.streamdata.format.AudioMediaFormat;
|
||||
import org.schabi.newpipe.extractor.streamdata.format.VideoAudioMediaFormat;
|
||||
import org.schabi.newpipe.extractor.streamdata.stream.VideoAudioStream;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class SimpleVideoAudioStreamImpl extends AbstractStreamImpl implements VideoAudioStream {
|
||||
@Nullable
|
||||
private final AudioMediaFormat audioMediaFormat;
|
||||
private final int averageBitrate;
|
||||
|
||||
@Nullable
|
||||
private final VideoAudioMediaFormat videoAudioMediaFormat;
|
||||
@Nonnull
|
||||
private final String resolution;
|
||||
|
||||
public SimpleVideoAudioStreamImpl(
|
||||
@Nonnull final DeliveryData deliveryData,
|
||||
@Nullable final AudioMediaFormat audioMediaFormat,
|
||||
final int averageBitrate,
|
||||
@Nullable final VideoAudioMediaFormat videoAudioMediaFormat,
|
||||
@Nonnull final String resolution
|
||||
) {
|
||||
super(deliveryData);
|
||||
this.audioMediaFormat = audioMediaFormat;
|
||||
this.averageBitrate = averageBitrate;
|
||||
this.videoAudioMediaFormat = videoAudioMediaFormat;
|
||||
this.resolution = Objects.requireNonNull(resolution);
|
||||
}
|
||||
|
||||
public SimpleVideoAudioStreamImpl(
|
||||
@Nonnull final DeliveryData deliveryData,
|
||||
@Nullable final VideoAudioMediaFormat videoAudioMediaFormat,
|
||||
@Nonnull final String resolution
|
||||
) {
|
||||
this(deliveryData, null, UNKNOWN_BITRATE, videoAudioMediaFormat, resolution);
|
||||
}
|
||||
|
||||
public SimpleVideoAudioStreamImpl(
|
||||
@Nonnull final DeliveryData deliveryData,
|
||||
@Nullable final VideoAudioMediaFormat videoAudioMediaFormat
|
||||
) {
|
||||
this(deliveryData, videoAudioMediaFormat, UNKNOWN_RESOLUTION);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public AudioMediaFormat audioMediaFormat() {
|
||||
return audioMediaFormat;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int averageBitrate() {
|
||||
return averageBitrate;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public VideoAudioMediaFormat videoMediaFormat() {
|
||||
return videoAudioMediaFormat;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public String resolution() {
|
||||
return resolution;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package org.schabi.newpipe.extractor.streamdata.stream.simpleimpl;
|
||||
|
||||
import org.schabi.newpipe.extractor.streamdata.delivery.DeliveryData;
|
||||
import org.schabi.newpipe.extractor.streamdata.format.VideoAudioMediaFormat;
|
||||
import org.schabi.newpipe.extractor.streamdata.stream.VideoStream;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class SimpleVideoStreamImpl extends AbstractStreamImpl implements VideoStream {
|
||||
@Nullable
|
||||
private final VideoAudioMediaFormat videoAudioMediaFormat;
|
||||
@Nonnull
|
||||
private final String resolution;
|
||||
|
||||
public SimpleVideoStreamImpl(
|
||||
@Nonnull final DeliveryData deliveryData,
|
||||
@Nullable final VideoAudioMediaFormat videoAudioMediaFormat,
|
||||
@Nonnull final String resolution
|
||||
) {
|
||||
super(deliveryData);
|
||||
this.videoAudioMediaFormat = videoAudioMediaFormat;
|
||||
this.resolution = Objects.requireNonNull(resolution);
|
||||
}
|
||||
|
||||
public SimpleVideoStreamImpl(
|
||||
@Nonnull final DeliveryData deliveryData,
|
||||
@Nonnull final String resolution
|
||||
) {
|
||||
this(deliveryData, null, resolution);
|
||||
}
|
||||
|
||||
public SimpleVideoStreamImpl(@Nonnull final DeliveryData deliveryData) {
|
||||
this(deliveryData, null, UNKNOWN_RESOLUTION);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public VideoAudioMediaFormat videoMediaFormat() {
|
||||
return videoAudioMediaFormat;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public String resolution() {
|
||||
return resolution;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue