331 lines
12 KiB
Java
331 lines
12 KiB
Java
package org.schabi.newpipe.extractor.stream;
|
|
|
|
import org.schabi.newpipe.extractor.MediaFormat;
|
|
import org.schabi.newpipe.extractor.services.youtube.ItagItem;
|
|
|
|
import javax.annotation.Nonnull;
|
|
import javax.annotation.Nullable;
|
|
|
|
import java.util.Locale;
|
|
|
|
import static org.schabi.newpipe.extractor.utils.Utils.EMPTY_STRING;
|
|
|
|
public final class SubtitlesStream extends Stream {
|
|
private final MediaFormat format;
|
|
private final Locale locale;
|
|
private final boolean autoGenerated;
|
|
private final String code;
|
|
|
|
/**
|
|
* Class to build {@link SubtitlesStream} objects.
|
|
*/
|
|
@SuppressWarnings("checkstyle:HiddenField")
|
|
public static final class Builder {
|
|
private String id;
|
|
private String content;
|
|
private boolean isUrl;
|
|
private DeliveryMethod deliveryMethod = DeliveryMethod.PROGRESSIVE_HTTP;
|
|
@Nullable
|
|
private MediaFormat mediaFormat;
|
|
@Nullable
|
|
private String manifestUrl;
|
|
private String languageCode;
|
|
// Use of the Boolean class instead of the primitive type needed for setter call check
|
|
private Boolean autoGenerated;
|
|
|
|
/**
|
|
* Create a new {@link Builder} instance with default values.
|
|
*/
|
|
public Builder() {
|
|
}
|
|
|
|
/**
|
|
* Set the identifier of the {@link SubtitlesStream}.
|
|
*
|
|
* @param id the identifier of the {@link SubtitlesStream}, which should not be null
|
|
* (otherwise the fallback to create the identifier will be used when building
|
|
* the builder)
|
|
* @return this {@link Builder} instance
|
|
*/
|
|
public Builder setId(@Nonnull final String id) {
|
|
this.id = id;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set the content of the {@link SubtitlesStream}.
|
|
*
|
|
* <p>
|
|
* It must not be null, and should be non empty.
|
|
* </p>
|
|
*
|
|
* @param content the content of the {@link SubtitlesStream}, which must not be null
|
|
* @param isUrl whether the content is a URL
|
|
* @return this {@link Builder} instance
|
|
*/
|
|
public Builder setContent(@Nonnull final String content,
|
|
final boolean isUrl) {
|
|
this.content = content;
|
|
this.isUrl = isUrl;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set the {@link MediaFormat} used by the {@link SubtitlesStream}.
|
|
*
|
|
* <p>
|
|
* It should be one of the subtitles {@link MediaFormat}s ({@link MediaFormat#SRT SRT},
|
|
* {@link MediaFormat#TRANSCRIPT1 TRANSCRIPT1}, {@link MediaFormat#TRANSCRIPT2
|
|
* TRANSCRIPT2}, {@link MediaFormat#TRANSCRIPT3 TRANSCRIPT3}, {@link MediaFormat#TTML
|
|
* TTML}, or {@link MediaFormat#VTT VTT}) but can be {@code null} if the media format could
|
|
* not be determined.
|
|
* </p>
|
|
*
|
|
* <p>
|
|
* The default value is {@code null}.
|
|
* </p>
|
|
*
|
|
* @param mediaFormat the {@link MediaFormat} of the {@link SubtitlesStream}, which can be
|
|
* null
|
|
* @return this {@link Builder} instance
|
|
*/
|
|
public Builder setMediaFormat(@Nullable final MediaFormat mediaFormat) {
|
|
this.mediaFormat = mediaFormat;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set the {@link DeliveryMethod} of the {@link SubtitlesStream}.
|
|
*
|
|
* <p>
|
|
* It must not be null.
|
|
* </p>
|
|
*
|
|
* <p>
|
|
* The default delivery method is {@link DeliveryMethod#PROGRESSIVE_HTTP}.
|
|
* </p>
|
|
*
|
|
* @param deliveryMethod the {@link DeliveryMethod} of the {@link SubtitlesStream}, which
|
|
* must not be null
|
|
* @return this {@link Builder} instance
|
|
*/
|
|
public Builder setDeliveryMethod(@Nonnull final DeliveryMethod deliveryMethod) {
|
|
this.deliveryMethod = deliveryMethod;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Sets the URL of the manifest this stream comes from (if applicable, otherwise null).
|
|
*
|
|
* @param manifestUrl the URL of the manifest this stream comes from or {@code null}
|
|
* @return this {@link Builder} instance
|
|
*/
|
|
public Builder setManifestUrl(@Nullable final String manifestUrl) {
|
|
this.manifestUrl = manifestUrl;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set the language code of the {@link SubtitlesStream}.
|
|
*
|
|
* <p>
|
|
* It <b>must not be null</b> and should not be an empty string.
|
|
* </p>
|
|
*
|
|
* @param languageCode the language code of the {@link SubtitlesStream}
|
|
* @return this {@link Builder} instance
|
|
*/
|
|
public Builder setLanguageCode(@Nonnull final String languageCode) {
|
|
this.languageCode = languageCode;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set whether the subtitles have been auto-generated by the streaming service.
|
|
*
|
|
* @param autoGenerated whether the subtitles have been generated by the streaming
|
|
* service
|
|
* @return this {@link Builder} instance
|
|
*/
|
|
public Builder setAutoGenerated(final boolean autoGenerated) {
|
|
this.autoGenerated = autoGenerated;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Build a {@link SubtitlesStream} using the builder's current values.
|
|
*
|
|
* <p>
|
|
* The content (and so the {@code isUrl} boolean), the language code and the {@code
|
|
* isAutoGenerated} properties must have been set.
|
|
* </p>
|
|
*
|
|
* <p>
|
|
* If no identifier has been set, an identifier will be generated using the language code
|
|
* and the media format suffix, if the media format is known.
|
|
* </p>
|
|
*
|
|
* @return a new {@link SubtitlesStream} using the builder's current values
|
|
* @throws IllegalStateException if {@code id}, {@code content} (and so {@code isUrl}),
|
|
* {@code deliveryMethod}, {@code languageCode} or the {@code isAutogenerated} have been
|
|
* not set, or have been set as {@code null}
|
|
*/
|
|
@Nonnull
|
|
public SubtitlesStream build() {
|
|
if (content == null) {
|
|
throw new IllegalStateException("No valid content was specified. Please specify a "
|
|
+ "valid one with setContent.");
|
|
}
|
|
|
|
if (deliveryMethod == null) {
|
|
throw new IllegalStateException(
|
|
"The delivery method of the subtitles stream has been set as null, which "
|
|
+ "is not allowed. Pass a valid one instead with"
|
|
+ "setDeliveryMethod.");
|
|
}
|
|
|
|
if (languageCode == null) {
|
|
throw new IllegalStateException("The language code of the subtitles stream has "
|
|
+ "been not set or is null. Make sure you specified an non null language "
|
|
+ "code with setLanguageCode.");
|
|
}
|
|
|
|
if (autoGenerated == null) {
|
|
throw new IllegalStateException("The subtitles stream has been not set as an "
|
|
+ "autogenerated subtitles stream or not. Please specify this information "
|
|
+ "with setIsAutoGenerated.");
|
|
}
|
|
|
|
if (id == null) {
|
|
id = languageCode + (mediaFormat != null ? "." + mediaFormat.suffix
|
|
: EMPTY_STRING);
|
|
}
|
|
|
|
return new SubtitlesStream(id, content, isUrl, mediaFormat, deliveryMethod,
|
|
languageCode, autoGenerated, manifestUrl);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Create a new subtitles stream.
|
|
*
|
|
* @param id the identifier which uniquely identifies the stream, e.g. for YouTube
|
|
* this would be the itag
|
|
* @param content the content or the URL of the stream, depending on whether isUrl is
|
|
* true
|
|
* @param isUrl whether content is the URL or the actual content of e.g. a DASH
|
|
* manifest
|
|
* @param mediaFormat the {@link MediaFormat} used by the stream
|
|
* @param deliveryMethod the {@link DeliveryMethod} of the stream
|
|
* @param languageCode the language code of the stream
|
|
* @param autoGenerated whether the subtitles are auto-generated by the streaming service
|
|
* @param manifestUrl the URL of the manifest this stream comes from (if applicable,
|
|
* otherwise null)
|
|
*/
|
|
@SuppressWarnings("checkstyle:ParameterNumber")
|
|
private SubtitlesStream(@Nonnull final String id,
|
|
@Nonnull final String content,
|
|
final boolean isUrl,
|
|
@Nullable final MediaFormat mediaFormat,
|
|
@Nonnull final DeliveryMethod deliveryMethod,
|
|
@Nonnull final String languageCode,
|
|
final boolean autoGenerated,
|
|
@Nullable final String manifestUrl) {
|
|
super(id, content, isUrl, mediaFormat, deliveryMethod, manifestUrl);
|
|
|
|
/*
|
|
* 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;
|
|
}
|
|
|
|
this.code = languageCode;
|
|
this.format = mediaFormat;
|
|
this.autoGenerated = autoGenerated;
|
|
}
|
|
|
|
/**
|
|
* Get the extension of the subtitles.
|
|
*
|
|
* @return the extension of the subtitles
|
|
*/
|
|
public String getExtension() {
|
|
return format.suffix;
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
*/
|
|
public boolean isAutoGenerated() {
|
|
return autoGenerated;
|
|
}
|
|
|
|
/**
|
|
* {@inheritDoc}
|
|
*/
|
|
@Override
|
|
public boolean equalStats(final Stream cmp) {
|
|
return super.equalStats(cmp)
|
|
&& cmp instanceof SubtitlesStream
|
|
&& code.equals(((SubtitlesStream) cmp).code)
|
|
&& autoGenerated == ((SubtitlesStream) cmp).autoGenerated;
|
|
}
|
|
|
|
/**
|
|
* Get the display language name of the subtitles.
|
|
*
|
|
* @return the display language name of the subtitles
|
|
*/
|
|
public String getDisplayLanguageName() {
|
|
return locale.getDisplayName(locale);
|
|
}
|
|
|
|
/**
|
|
* Get the language tag of the subtitles.
|
|
*
|
|
* @return the language tag of the subtitles
|
|
*/
|
|
public String getLanguageTag() {
|
|
return code;
|
|
}
|
|
|
|
/**
|
|
* Get the {@link Locale locale} of the subtitles.
|
|
*
|
|
* @return the {@link Locale locale} of the subtitles
|
|
*/
|
|
public Locale getLocale() {
|
|
return locale;
|
|
}
|
|
|
|
/**
|
|
* No subtitles which are currently extracted use an {@link ItagItem}, so {@code null} is
|
|
* returned by this method.
|
|
*
|
|
* @return {@code null}
|
|
*/
|
|
@Nullable
|
|
@Override
|
|
public ItagItem getItagItem() {
|
|
return null;
|
|
}
|
|
}
|