Created new basic stream architecture

This commit is contained in:
litetex 2022-05-28 23:09:02 +02:00
parent 6a858368c8
commit c2b9537b66
33 changed files with 844 additions and 0 deletions

View File

@ -0,0 +1,5 @@
package org.schabi.newpipe.extractor.streamdata.delivery;
public interface DASHDeliveryData extends DeliveryData {
// Just a marker interface
}

View File

@ -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();
}

View File

@ -0,0 +1,5 @@
package org.schabi.newpipe.extractor.streamdata.delivery;
public interface DASHUrlDeliveryData extends UrlBasedDeliveryData, DASHDeliveryData {
// Nothing to implement additionally
}

View File

@ -0,0 +1,5 @@
package org.schabi.newpipe.extractor.streamdata.delivery;
public interface DeliveryData {
// Only a marker so far
}

View File

@ -0,0 +1,5 @@
package org.schabi.newpipe.extractor.streamdata.delivery;
public interface HLSDeliveryData extends UrlBasedDeliveryData {
// Nothing to implement additionally
}

View File

@ -0,0 +1,5 @@
package org.schabi.newpipe.extractor.streamdata.delivery;
public interface ProgressiveHTTPDeliveryData extends DeliveryData {
// Nothing to implement additionally
}

View File

@ -0,0 +1,5 @@
package org.schabi.newpipe.extractor.streamdata.delivery;
public interface TorrentDeliveryData extends UrlBasedDeliveryData {
// Nothing to implement additionally
}

View File

@ -0,0 +1,8 @@
package org.schabi.newpipe.extractor.streamdata.delivery;
import javax.annotation.Nonnull;
public interface UrlBasedDeliveryData extends DeliveryData {
@Nonnull
String url();
}

View File

@ -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
}

View File

@ -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;
}
}

View File

@ -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();
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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());
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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});
}
}

View File

@ -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);
}
}

View File

@ -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});
}
}

View File

@ -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});
}
}

View File

@ -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();
}
}

View File

@ -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);
}

View File

@ -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());
}
}

View File

@ -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);
}
}

View File

@ -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());
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}