package org.schabi.newpipe.extractor.stream; /* * Created by Christian Schabesberger on 04.03.16. * * Copyright (C) Christian Schabesberger 2016 * AudioStream.java is part of NewPipe Extractor. * * NewPipe Extractor is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NewPipe Extractor is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NewPipe Extractor. If not, see . */ 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.Objects; public final class AudioStream extends Stream { public static final int UNKNOWN_BITRATE = -1; private final int averageBitrate; // Fields for DASH private int itag = ITAG_NOT_AVAILABLE_OR_NOT_APPLICABLE; private int bitrate; private int initStart; private int initEnd; private int indexStart; private int indexEnd; private String quality; private String codec; // Fields about the audio track id/name private String audioTrackId; private String audioTrackName; @Nullable private ItagItem itagItem; /** * Class to build {@link AudioStream} 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 int averageBitrate = UNKNOWN_BITRATE; @Nullable private String audioTrackId; @Nullable private String audioTrackName; @Nullable private ItagItem itagItem; /** * Create a new {@link Builder} instance with its default values. */ public Builder() { } /** * Set the identifier of the {@link AudioStream}. * *

* It must not be null and should be non empty. *

* *

* If you are not able to get an identifier, use the static constant {@link * Stream#ID_UNKNOWN ID_UNKNOWN} of the {@link Stream} class. *

* * @param id the identifier of the {@link AudioStream}, which must not be null * @return this {@link Builder} instance */ public Builder setId(@Nonnull final String id) { this.id = id; return this; } /** * Set the content of the {@link AudioStream}. * *

* It must not be null, and should be non empty. *

* * @param content the content of the {@link AudioStream} * @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 AudioStream}. * *

* It should be one of the audio {@link MediaFormat}s ({@link MediaFormat#M4A M4A}, * {@link MediaFormat#WEBMA WEBMA}, {@link MediaFormat#MP3 MP3}, {@link MediaFormat#OPUS * OPUS}, {@link MediaFormat#OGG OGG}, or {@link MediaFormat#WEBMA_OPUS WEBMA_OPUS}) but * can be {@code null} if the media format could not be determined. *

* *

* The default value is {@code null}. *

* * @param mediaFormat the {@link MediaFormat} of the {@link AudioStream}, 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 AudioStream}. * *

* It must not be null. *

* *

* The default delivery method is {@link DeliveryMethod#PROGRESSIVE_HTTP}. *

* * @param deliveryMethod the {@link DeliveryMethod} of the {@link AudioStream}, 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 average bitrate of the {@link AudioStream}. * *

* The default value is {@link #UNKNOWN_BITRATE}. *

* * @param averageBitrate the average bitrate of the {@link AudioStream}, which should * positive * @return this {@link Builder} instance */ public Builder setAverageBitrate(final int averageBitrate) { this.averageBitrate = averageBitrate; return this; } /** * Set the audio track id of the {@link AudioStream}. * * @param audioTrackId the audio track id of the {@link AudioStream} * @return this {@link Builder} instance */ public Builder setAudioTrackId(@Nullable final String audioTrackId) { this.audioTrackId = audioTrackId; return this; } /** * Set the audio track name of the {@link AudioStream}. * * @param audioTrackName the audio track name of the {@link AudioStream} * @return this {@link Builder} instance */ public Builder setAudioTrackName(@Nullable final String audioTrackName) { this.audioTrackName = audioTrackName; return this; } /** * Set the {@link ItagItem} corresponding to the {@link AudioStream}. * *

* {@link ItagItem}s are YouTube specific objects, so they are only known for this service * and can be null. *

* *

* The default value is {@code null}. *

* * @param itagItem the {@link ItagItem} of the {@link AudioStream}, which can be null * @return this {@link Builder} instance */ public Builder setItagItem(@Nullable final ItagItem itagItem) { this.itagItem = itagItem; return this; } /** * Build an {@link AudioStream} using the builder's current values. * *

* The identifier and the content (and so the {@code isUrl} boolean) properties must have * been set. *

* * @return a new {@link AudioStream} using the builder's current values * @throws IllegalStateException if {@code id}, {@code content} (and so {@code isUrl}) or * {@code deliveryMethod} have been not set, or have been set as {@code null} */ @Nonnull public AudioStream build() { if (id == null) { throw new IllegalStateException( "The identifier of the audio stream has been not set or is null. If you " + "are not able to get an identifier, use the static constant " + "ID_UNKNOWN of the Stream class."); } if (content == null) { throw new IllegalStateException("The content of the audio stream has been not set " + "or is null. Please specify a non-null one with setContent."); } if (deliveryMethod == null) { throw new IllegalStateException( "The delivery method of the audio stream has been set as null, which is " + "not allowed. Pass a valid one instead with setDeliveryMethod."); } return new AudioStream(id, content, isUrl, mediaFormat, deliveryMethod, averageBitrate, manifestUrl, audioTrackId, audioTrackName, itagItem); } } /** * Create a new audio 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 format the {@link MediaFormat} used by the stream, which can be null * @param deliveryMethod the {@link DeliveryMethod} of the stream * @param averageBitrate the average bitrate of the stream (which can be unknown, see * {@link #UNKNOWN_BITRATE}) * @param audioTrackId the id of the audio track * @param audioTrackName the name of the audio track * @param itagItem the {@link ItagItem} corresponding to the stream, which cannot be null * @param manifestUrl the URL of the manifest this stream comes from (if applicable, * otherwise null) */ @SuppressWarnings("checkstyle:ParameterNumber") private AudioStream(@Nonnull final String id, @Nonnull final String content, final boolean isUrl, @Nullable final MediaFormat format, @Nonnull final DeliveryMethod deliveryMethod, final int averageBitrate, @Nullable final String manifestUrl, @Nullable final String audioTrackId, @Nullable final String audioTrackName, @Nullable final ItagItem itagItem) { super(id, content, isUrl, format, deliveryMethod, manifestUrl); if (itagItem != null) { this.itagItem = itagItem; this.itag = itagItem.id; this.quality = itagItem.getQuality(); this.bitrate = itagItem.getBitrate(); this.initStart = itagItem.getInitStart(); this.initEnd = itagItem.getInitEnd(); this.indexStart = itagItem.getIndexStart(); this.indexEnd = itagItem.getIndexEnd(); this.codec = itagItem.getCodec(); } this.averageBitrate = averageBitrate; this.audioTrackId = audioTrackId; this.audioTrackName = audioTrackName; } /** * {@inheritDoc} */ @Override public boolean equalStats(final Stream cmp) { return super.equalStats(cmp) && cmp instanceof AudioStream && averageBitrate == ((AudioStream) cmp).averageBitrate && Objects.equals(audioTrackId, ((AudioStream) cmp).audioTrackId); } /** * Get the average bitrate of the stream. * * @return the average bitrate or {@link #UNKNOWN_BITRATE} if it is unknown */ public int getAverageBitrate() { return averageBitrate; } /** * Get the itag identifier of the stream. * *

* Always equals to {@link #ITAG_NOT_AVAILABLE_OR_NOT_APPLICABLE} for other streams than the * ones of the YouTube service. *

* * @return the number of the {@link ItagItem} passed in the constructor of the audio stream. */ public int getItag() { return itag; } /** * Get the bitrate of the stream. * * @return the bitrate set from the {@link ItagItem} passed in the constructor of the stream. */ public int getBitrate() { return bitrate; } /** * Get the initialization start of the stream. * * @return the initialization start value set from the {@link ItagItem} passed in the * constructor of the stream. */ public int getInitStart() { return initStart; } /** * Get the initialization end of the stream. * * @return the initialization end value set from the {@link ItagItem} passed in the constructor * of the stream. */ public int getInitEnd() { return initEnd; } /** * Get the index start of the stream. * * @return the index start value set from the {@link ItagItem} passed in the constructor of the * stream. */ public int getIndexStart() { return indexStart; } /** * Get the index end of the stream. * * @return the index end value set from the {@link ItagItem} passed in the constructor of the * stream. */ public int getIndexEnd() { return indexEnd; } /** * Get the quality of the stream. * * @return the quality label set from the {@link ItagItem} passed in the constructor of the * stream. */ public String getQuality() { return quality; } /** * Get the codec of the stream. * * @return the codec set from the {@link ItagItem} passed in the constructor of the stream. */ public String getCodec() { return codec; } /** * Get the id of the audio track. * * @return the id of the audio track */ @Nullable public String getAudioTrackId() { return audioTrackId; } /** * Get the name of the audio track. * * @return the name of the audio track */ @Nullable public String getAudioTrackName() { return audioTrackName; } /** * {@inheritDoc} */ @Override @Nullable public ItagItem getItagItem() { return itagItem; } }