NewPipe/app/src/main/java/org/schabi/newpipe/util/StreamItemAdapter.java

320 lines
12 KiB
Java
Raw Normal View History

2018-04-08 13:08:19 +02:00
package org.schabi.newpipe.util;
import android.content.Context;
import android.util.SparseArray;
2018-04-08 13:08:19 +02:00
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;
Add support of other delivery methods than progressive HTTP (in the player only) Detailed changes: - External players: - Add a message instruction about stream selection; - Add a message when there is no stream available for external players; - Return now HLS, DASH and SmoothStreaming URL contents, in addition to progressive HTTP ones. - Player: - Support DASH, HLS and SmoothStreaming streams for videos, whether they are content URLs or the manifests themselves, in addition to progressive HTTP ones; - Use a custom HttpDataSource to play YouTube contents, based of ExoPlayer's default one, which allows better spoofing of official clients (custom user-agent and headers (depending of the client used), use of range and rn (set dynamically by the DataSource) parameters); - Fetch YouTube progressive contents as DASH streams, like official clients, support fully playback of livestreams which have ended recently and OTF streams; - Use ExoPlayer's default retries count for contents on non-fatal errors (instead of Integer.MAX_VALUE for non-live contents and 5 for live contents). - Download dialog: - Add message about support of progressive HTTP streams only for downloading; - Remove several duplicated code and update relevant usages; - Support downloading of contents with an unknown media format. - ListHelper: - Catch NumberFormatException when trying to compare two video streams between them. - Tests: - Update ListHelperTest and StreamItemAdapterTest to fix breaking changes in the extractor. - Other places: - Fixes deprecation of changes made in the extractor; - Improve some code related to the files changed. - Issues fixed and/or improved with the changes: - Seeking of PeerTube HLS streams (the duration shown was the one from the stream duration and not the one parsed, incomplete because HLS streams are fragmented MP4s with multiple sidx boxes, for which seeking is not supported by ExoPlayer) (the app now uses the HLS manifest returned for each quality, in the master playlist (not fetched and computed by the extractor)); - Crash when loading PeerTube streams with a separated audio; - Lack of some streams on some YouTube videos (OTF streams); - Loading times of YouTube streams, after a quality change or a playback start; - View count of YouTube ended livestreams interpreted as watching count (this type of streams is not interpreted anymore as livestreams); - Watchable time of YouTube ended livestreams; - Playback of SoundCloud HLS-only tracks (which cannot be downloaded anymore because the workaround which was used is being removed by SoundCloud, so it has been removed from the extractor).
2022-06-16 11:13:19 +02:00
import androidx.annotation.NonNull;
import org.schabi.newpipe.DownloaderImpl;
2018-04-08 13:08:19 +02:00
import org.schabi.newpipe.R;
import org.schabi.newpipe.extractor.MediaFormat;
2018-04-08 13:08:19 +02:00
import org.schabi.newpipe.extractor.stream.AudioStream;
import org.schabi.newpipe.extractor.stream.Stream;
import org.schabi.newpipe.extractor.stream.SubtitlesStream;
2018-04-08 13:08:19 +02:00
import org.schabi.newpipe.extractor.stream.VideoStream;
import java.io.Serializable;
import java.util.Arrays;
2018-04-08 13:08:19 +02:00
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Callable;
2020-10-31 21:55:45 +01:00
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Single;
import io.reactivex.rxjava3.schedulers.Schedulers;
2018-04-08 13:08:19 +02:00
import us.shandian.giga.util.Utility;
/**
* A list adapter for a list of {@link Stream streams}.
* It currently supports {@link VideoStream}, {@link AudioStream} and {@link SubtitlesStream}.
*
* @param <T> the primary stream type's class extending {@link Stream}
* @param <U> the secondary stream type's class extending {@link Stream}
2018-04-08 13:08:19 +02:00
*/
public class StreamItemAdapter<T extends Stream, U extends Stream> extends BaseAdapter {
2018-04-08 13:08:19 +02:00
private final Context context;
private final StreamSizeWrapper<T> streamsWrapper;
private final SparseArray<SecondaryStreamHelper<U>> secondaryStreams;
2018-04-08 13:08:19 +02:00
/**
* Indicates that at least one of the primary streams is an instance of {@link VideoStream},
* has no audio ({@link VideoStream#isVideoOnly()} returns true) and has no secondary stream
* associated with it.
*/
2022-04-02 15:44:06 +02:00
private final boolean hasAnyVideoOnlyStreamWithNoSecondaryStream;
public StreamItemAdapter(final Context context, final StreamSizeWrapper<T> streamsWrapper,
final SparseArray<SecondaryStreamHelper<U>> secondaryStreams) {
2018-04-08 13:08:19 +02:00
this.context = context;
this.streamsWrapper = streamsWrapper;
this.secondaryStreams = secondaryStreams;
2022-04-02 15:44:06 +02:00
this.hasAnyVideoOnlyStreamWithNoSecondaryStream =
checkHasAnyVideoOnlyStreamWithNoSecondaryStream();
2018-04-08 13:08:19 +02:00
}
public StreamItemAdapter(final Context context, final StreamSizeWrapper<T> streamsWrapper) {
this(context, streamsWrapper, null);
2018-04-08 13:08:19 +02:00
}
public List<T> getAll() {
return streamsWrapper.getStreamsList();
}
public SparseArray<SecondaryStreamHelper<U>> getAllSecondary() {
return secondaryStreams;
}
2018-04-08 13:08:19 +02:00
@Override
public int getCount() {
return streamsWrapper.getStreamsList().size();
}
@Override
public T getItem(final int position) {
2018-04-08 13:08:19 +02:00
return streamsWrapper.getStreamsList().get(position);
}
@Override
public long getItemId(final int position) {
2018-04-08 13:08:19 +02:00
return position;
}
@Override
Add support of other delivery methods than progressive HTTP (in the player only) Detailed changes: - External players: - Add a message instruction about stream selection; - Add a message when there is no stream available for external players; - Return now HLS, DASH and SmoothStreaming URL contents, in addition to progressive HTTP ones. - Player: - Support DASH, HLS and SmoothStreaming streams for videos, whether they are content URLs or the manifests themselves, in addition to progressive HTTP ones; - Use a custom HttpDataSource to play YouTube contents, based of ExoPlayer's default one, which allows better spoofing of official clients (custom user-agent and headers (depending of the client used), use of range and rn (set dynamically by the DataSource) parameters); - Fetch YouTube progressive contents as DASH streams, like official clients, support fully playback of livestreams which have ended recently and OTF streams; - Use ExoPlayer's default retries count for contents on non-fatal errors (instead of Integer.MAX_VALUE for non-live contents and 5 for live contents). - Download dialog: - Add message about support of progressive HTTP streams only for downloading; - Remove several duplicated code and update relevant usages; - Support downloading of contents with an unknown media format. - ListHelper: - Catch NumberFormatException when trying to compare two video streams between them. - Tests: - Update ListHelperTest and StreamItemAdapterTest to fix breaking changes in the extractor. - Other places: - Fixes deprecation of changes made in the extractor; - Improve some code related to the files changed. - Issues fixed and/or improved with the changes: - Seeking of PeerTube HLS streams (the duration shown was the one from the stream duration and not the one parsed, incomplete because HLS streams are fragmented MP4s with multiple sidx boxes, for which seeking is not supported by ExoPlayer) (the app now uses the HLS manifest returned for each quality, in the master playlist (not fetched and computed by the extractor)); - Crash when loading PeerTube streams with a separated audio; - Lack of some streams on some YouTube videos (OTF streams); - Loading times of YouTube streams, after a quality change or a playback start; - View count of YouTube ended livestreams interpreted as watching count (this type of streams is not interpreted anymore as livestreams); - Watchable time of YouTube ended livestreams; - Playback of SoundCloud HLS-only tracks (which cannot be downloaded anymore because the workaround which was used is being removed by SoundCloud, so it has been removed from the extractor).
2022-06-16 11:13:19 +02:00
public View getDropDownView(final int position,
final View convertView,
final ViewGroup parent) {
2018-04-08 13:08:19 +02:00
return getCustomView(position, convertView, parent, true);
}
@Override
public View getView(final int position, final View convertView, final ViewGroup parent) {
return getCustomView(((Spinner) parent).getSelectedItemPosition(),
convertView, parent, false);
2018-04-08 13:08:19 +02:00
}
Add support of other delivery methods than progressive HTTP (in the player only) Detailed changes: - External players: - Add a message instruction about stream selection; - Add a message when there is no stream available for external players; - Return now HLS, DASH and SmoothStreaming URL contents, in addition to progressive HTTP ones. - Player: - Support DASH, HLS and SmoothStreaming streams for videos, whether they are content URLs or the manifests themselves, in addition to progressive HTTP ones; - Use a custom HttpDataSource to play YouTube contents, based of ExoPlayer's default one, which allows better spoofing of official clients (custom user-agent and headers (depending of the client used), use of range and rn (set dynamically by the DataSource) parameters); - Fetch YouTube progressive contents as DASH streams, like official clients, support fully playback of livestreams which have ended recently and OTF streams; - Use ExoPlayer's default retries count for contents on non-fatal errors (instead of Integer.MAX_VALUE for non-live contents and 5 for live contents). - Download dialog: - Add message about support of progressive HTTP streams only for downloading; - Remove several duplicated code and update relevant usages; - Support downloading of contents with an unknown media format. - ListHelper: - Catch NumberFormatException when trying to compare two video streams between them. - Tests: - Update ListHelperTest and StreamItemAdapterTest to fix breaking changes in the extractor. - Other places: - Fixes deprecation of changes made in the extractor; - Improve some code related to the files changed. - Issues fixed and/or improved with the changes: - Seeking of PeerTube HLS streams (the duration shown was the one from the stream duration and not the one parsed, incomplete because HLS streams are fragmented MP4s with multiple sidx boxes, for which seeking is not supported by ExoPlayer) (the app now uses the HLS manifest returned for each quality, in the master playlist (not fetched and computed by the extractor)); - Crash when loading PeerTube streams with a separated audio; - Lack of some streams on some YouTube videos (OTF streams); - Loading times of YouTube streams, after a quality change or a playback start; - View count of YouTube ended livestreams interpreted as watching count (this type of streams is not interpreted anymore as livestreams); - Watchable time of YouTube ended livestreams; - Playback of SoundCloud HLS-only tracks (which cannot be downloaded anymore because the workaround which was used is being removed by SoundCloud, so it has been removed from the extractor).
2022-06-16 11:13:19 +02:00
@NonNull
private View getCustomView(final int position,
final View view,
final ViewGroup parent,
final boolean isDropdownItem) {
View convertView = view;
2018-04-08 13:08:19 +02:00
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(
R.layout.stream_quality_item, parent, false);
2018-04-08 13:08:19 +02:00
}
final ImageView woSoundIconView = convertView.findViewById(R.id.wo_sound_icon);
final TextView formatNameView = convertView.findViewById(R.id.stream_format_name);
final TextView qualityView = convertView.findViewById(R.id.stream_quality);
final TextView sizeView = convertView.findViewById(R.id.stream_size);
final T stream = getItem(position);
Add support of other delivery methods than progressive HTTP (in the player only) Detailed changes: - External players: - Add a message instruction about stream selection; - Add a message when there is no stream available for external players; - Return now HLS, DASH and SmoothStreaming URL contents, in addition to progressive HTTP ones. - Player: - Support DASH, HLS and SmoothStreaming streams for videos, whether they are content URLs or the manifests themselves, in addition to progressive HTTP ones; - Use a custom HttpDataSource to play YouTube contents, based of ExoPlayer's default one, which allows better spoofing of official clients (custom user-agent and headers (depending of the client used), use of range and rn (set dynamically by the DataSource) parameters); - Fetch YouTube progressive contents as DASH streams, like official clients, support fully playback of livestreams which have ended recently and OTF streams; - Use ExoPlayer's default retries count for contents on non-fatal errors (instead of Integer.MAX_VALUE for non-live contents and 5 for live contents). - Download dialog: - Add message about support of progressive HTTP streams only for downloading; - Remove several duplicated code and update relevant usages; - Support downloading of contents with an unknown media format. - ListHelper: - Catch NumberFormatException when trying to compare two video streams between them. - Tests: - Update ListHelperTest and StreamItemAdapterTest to fix breaking changes in the extractor. - Other places: - Fixes deprecation of changes made in the extractor; - Improve some code related to the files changed. - Issues fixed and/or improved with the changes: - Seeking of PeerTube HLS streams (the duration shown was the one from the stream duration and not the one parsed, incomplete because HLS streams are fragmented MP4s with multiple sidx boxes, for which seeking is not supported by ExoPlayer) (the app now uses the HLS manifest returned for each quality, in the master playlist (not fetched and computed by the extractor)); - Crash when loading PeerTube streams with a separated audio; - Lack of some streams on some YouTube videos (OTF streams); - Loading times of YouTube streams, after a quality change or a playback start; - View count of YouTube ended livestreams interpreted as watching count (this type of streams is not interpreted anymore as livestreams); - Watchable time of YouTube ended livestreams; - Playback of SoundCloud HLS-only tracks (which cannot be downloaded anymore because the workaround which was used is being removed by SoundCloud, so it has been removed from the extractor).
2022-06-16 11:13:19 +02:00
final MediaFormat mediaFormat = stream.getFormat();
2018-04-08 13:08:19 +02:00
int woSoundIconVisibility = View.GONE;
String qualityString;
if (stream instanceof VideoStream) {
2020-08-16 10:24:58 +02:00
final VideoStream videoStream = ((VideoStream) stream);
qualityString = videoStream.getResolution();
2022-04-02 15:44:06 +02:00
if (hasAnyVideoOnlyStreamWithNoSecondaryStream) {
if (videoStream.isVideoOnly()) {
woSoundIconVisibility = hasSecondaryStream(position)
// It has a secondary stream associated with it, so check if it's a
// dropdown view so it doesn't look out of place (missing margin)
// compared to those that don't.
? (isDropdownItem ? View.INVISIBLE : View.GONE)
// It doesn't have a secondary stream, icon is visible no matter what.
: View.VISIBLE;
} else if (isDropdownItem) {
woSoundIconVisibility = View.INVISIBLE;
}
2018-04-08 13:08:19 +02:00
}
} else if (stream instanceof AudioStream) {
2020-08-16 10:24:58 +02:00
final AudioStream audioStream = ((AudioStream) stream);
Add support of other delivery methods than progressive HTTP (in the player only) Detailed changes: - External players: - Add a message instruction about stream selection; - Add a message when there is no stream available for external players; - Return now HLS, DASH and SmoothStreaming URL contents, in addition to progressive HTTP ones. - Player: - Support DASH, HLS and SmoothStreaming streams for videos, whether they are content URLs or the manifests themselves, in addition to progressive HTTP ones; - Use a custom HttpDataSource to play YouTube contents, based of ExoPlayer's default one, which allows better spoofing of official clients (custom user-agent and headers (depending of the client used), use of range and rn (set dynamically by the DataSource) parameters); - Fetch YouTube progressive contents as DASH streams, like official clients, support fully playback of livestreams which have ended recently and OTF streams; - Use ExoPlayer's default retries count for contents on non-fatal errors (instead of Integer.MAX_VALUE for non-live contents and 5 for live contents). - Download dialog: - Add message about support of progressive HTTP streams only for downloading; - Remove several duplicated code and update relevant usages; - Support downloading of contents with an unknown media format. - ListHelper: - Catch NumberFormatException when trying to compare two video streams between them. - Tests: - Update ListHelperTest and StreamItemAdapterTest to fix breaking changes in the extractor. - Other places: - Fixes deprecation of changes made in the extractor; - Improve some code related to the files changed. - Issues fixed and/or improved with the changes: - Seeking of PeerTube HLS streams (the duration shown was the one from the stream duration and not the one parsed, incomplete because HLS streams are fragmented MP4s with multiple sidx boxes, for which seeking is not supported by ExoPlayer) (the app now uses the HLS manifest returned for each quality, in the master playlist (not fetched and computed by the extractor)); - Crash when loading PeerTube streams with a separated audio; - Lack of some streams on some YouTube videos (OTF streams); - Loading times of YouTube streams, after a quality change or a playback start; - View count of YouTube ended livestreams interpreted as watching count (this type of streams is not interpreted anymore as livestreams); - Watchable time of YouTube ended livestreams; - Playback of SoundCloud HLS-only tracks (which cannot be downloaded anymore because the workaround which was used is being removed by SoundCloud, so it has been removed from the extractor).
2022-06-16 11:13:19 +02:00
if (audioStream.getAverageBitrate() > 0) {
qualityString = audioStream.getAverageBitrate() + "kbps";
} else if (mediaFormat != null) {
qualityString = mediaFormat.getName();
} else {
qualityString = context.getString(R.string.unknown_quality);
}
} else if (stream instanceof SubtitlesStream) {
qualityString = ((SubtitlesStream) stream).getDisplayLanguageName();
if (((SubtitlesStream) stream).isAutoGenerated()) {
qualityString += " (" + context.getString(R.string.caption_auto_generated) + ")";
}
2018-04-08 13:08:19 +02:00
} else {
2022-05-21 12:02:57 +02:00
if (mediaFormat == null) {
Add support of other delivery methods than progressive HTTP (in the player only) Detailed changes: - External players: - Add a message instruction about stream selection; - Add a message when there is no stream available for external players; - Return now HLS, DASH and SmoothStreaming URL contents, in addition to progressive HTTP ones. - Player: - Support DASH, HLS and SmoothStreaming streams for videos, whether they are content URLs or the manifests themselves, in addition to progressive HTTP ones; - Use a custom HttpDataSource to play YouTube contents, based of ExoPlayer's default one, which allows better spoofing of official clients (custom user-agent and headers (depending of the client used), use of range and rn (set dynamically by the DataSource) parameters); - Fetch YouTube progressive contents as DASH streams, like official clients, support fully playback of livestreams which have ended recently and OTF streams; - Use ExoPlayer's default retries count for contents on non-fatal errors (instead of Integer.MAX_VALUE for non-live contents and 5 for live contents). - Download dialog: - Add message about support of progressive HTTP streams only for downloading; - Remove several duplicated code and update relevant usages; - Support downloading of contents with an unknown media format. - ListHelper: - Catch NumberFormatException when trying to compare two video streams between them. - Tests: - Update ListHelperTest and StreamItemAdapterTest to fix breaking changes in the extractor. - Other places: - Fixes deprecation of changes made in the extractor; - Improve some code related to the files changed. - Issues fixed and/or improved with the changes: - Seeking of PeerTube HLS streams (the duration shown was the one from the stream duration and not the one parsed, incomplete because HLS streams are fragmented MP4s with multiple sidx boxes, for which seeking is not supported by ExoPlayer) (the app now uses the HLS manifest returned for each quality, in the master playlist (not fetched and computed by the extractor)); - Crash when loading PeerTube streams with a separated audio; - Lack of some streams on some YouTube videos (OTF streams); - Loading times of YouTube streams, after a quality change or a playback start; - View count of YouTube ended livestreams interpreted as watching count (this type of streams is not interpreted anymore as livestreams); - Watchable time of YouTube ended livestreams; - Playback of SoundCloud HLS-only tracks (which cannot be downloaded anymore because the workaround which was used is being removed by SoundCloud, so it has been removed from the extractor).
2022-06-16 11:13:19 +02:00
qualityString = context.getString(R.string.unknown_quality);
2022-05-21 12:02:57 +02:00
} else {
qualityString = mediaFormat.getSuffix();
Add support of other delivery methods than progressive HTTP (in the player only) Detailed changes: - External players: - Add a message instruction about stream selection; - Add a message when there is no stream available for external players; - Return now HLS, DASH and SmoothStreaming URL contents, in addition to progressive HTTP ones. - Player: - Support DASH, HLS and SmoothStreaming streams for videos, whether they are content URLs or the manifests themselves, in addition to progressive HTTP ones; - Use a custom HttpDataSource to play YouTube contents, based of ExoPlayer's default one, which allows better spoofing of official clients (custom user-agent and headers (depending of the client used), use of range and rn (set dynamically by the DataSource) parameters); - Fetch YouTube progressive contents as DASH streams, like official clients, support fully playback of livestreams which have ended recently and OTF streams; - Use ExoPlayer's default retries count for contents on non-fatal errors (instead of Integer.MAX_VALUE for non-live contents and 5 for live contents). - Download dialog: - Add message about support of progressive HTTP streams only for downloading; - Remove several duplicated code and update relevant usages; - Support downloading of contents with an unknown media format. - ListHelper: - Catch NumberFormatException when trying to compare two video streams between them. - Tests: - Update ListHelperTest and StreamItemAdapterTest to fix breaking changes in the extractor. - Other places: - Fixes deprecation of changes made in the extractor; - Improve some code related to the files changed. - Issues fixed and/or improved with the changes: - Seeking of PeerTube HLS streams (the duration shown was the one from the stream duration and not the one parsed, incomplete because HLS streams are fragmented MP4s with multiple sidx boxes, for which seeking is not supported by ExoPlayer) (the app now uses the HLS manifest returned for each quality, in the master playlist (not fetched and computed by the extractor)); - Crash when loading PeerTube streams with a separated audio; - Lack of some streams on some YouTube videos (OTF streams); - Loading times of YouTube streams, after a quality change or a playback start; - View count of YouTube ended livestreams interpreted as watching count (this type of streams is not interpreted anymore as livestreams); - Watchable time of YouTube ended livestreams; - Playback of SoundCloud HLS-only tracks (which cannot be downloaded anymore because the workaround which was used is being removed by SoundCloud, so it has been removed from the extractor).
2022-06-16 11:13:19 +02:00
}
2018-04-08 13:08:19 +02:00
}
if (streamsWrapper.getSizeInBytes(position) > 0) {
final SecondaryStreamHelper<U> secondary = secondaryStreams == null ? null
: secondaryStreams.get(position);
if (secondary != null) {
Add support of other delivery methods than progressive HTTP (in the player only) Detailed changes: - External players: - Add a message instruction about stream selection; - Add a message when there is no stream available for external players; - Return now HLS, DASH and SmoothStreaming URL contents, in addition to progressive HTTP ones. - Player: - Support DASH, HLS and SmoothStreaming streams for videos, whether they are content URLs or the manifests themselves, in addition to progressive HTTP ones; - Use a custom HttpDataSource to play YouTube contents, based of ExoPlayer's default one, which allows better spoofing of official clients (custom user-agent and headers (depending of the client used), use of range and rn (set dynamically by the DataSource) parameters); - Fetch YouTube progressive contents as DASH streams, like official clients, support fully playback of livestreams which have ended recently and OTF streams; - Use ExoPlayer's default retries count for contents on non-fatal errors (instead of Integer.MAX_VALUE for non-live contents and 5 for live contents). - Download dialog: - Add message about support of progressive HTTP streams only for downloading; - Remove several duplicated code and update relevant usages; - Support downloading of contents with an unknown media format. - ListHelper: - Catch NumberFormatException when trying to compare two video streams between them. - Tests: - Update ListHelperTest and StreamItemAdapterTest to fix breaking changes in the extractor. - Other places: - Fixes deprecation of changes made in the extractor; - Improve some code related to the files changed. - Issues fixed and/or improved with the changes: - Seeking of PeerTube HLS streams (the duration shown was the one from the stream duration and not the one parsed, incomplete because HLS streams are fragmented MP4s with multiple sidx boxes, for which seeking is not supported by ExoPlayer) (the app now uses the HLS manifest returned for each quality, in the master playlist (not fetched and computed by the extractor)); - Crash when loading PeerTube streams with a separated audio; - Lack of some streams on some YouTube videos (OTF streams); - Loading times of YouTube streams, after a quality change or a playback start; - View count of YouTube ended livestreams interpreted as watching count (this type of streams is not interpreted anymore as livestreams); - Watchable time of YouTube ended livestreams; - Playback of SoundCloud HLS-only tracks (which cannot be downloaded anymore because the workaround which was used is being removed by SoundCloud, so it has been removed from the extractor).
2022-06-16 11:13:19 +02:00
final long size = secondary.getSizeInBytes()
+ streamsWrapper.getSizeInBytes(position);
sizeView.setText(Utility.formatBytes(size));
} else {
sizeView.setText(streamsWrapper.getFormattedSize(position));
}
2018-04-08 13:08:19 +02:00
sizeView.setVisibility(View.VISIBLE);
} else {
sizeView.setVisibility(View.GONE);
}
if (stream instanceof SubtitlesStream) {
formatNameView.setText(((SubtitlesStream) stream).getLanguageTag());
} else {
Add support of other delivery methods than progressive HTTP (in the player only) Detailed changes: - External players: - Add a message instruction about stream selection; - Add a message when there is no stream available for external players; - Return now HLS, DASH and SmoothStreaming URL contents, in addition to progressive HTTP ones. - Player: - Support DASH, HLS and SmoothStreaming streams for videos, whether they are content URLs or the manifests themselves, in addition to progressive HTTP ones; - Use a custom HttpDataSource to play YouTube contents, based of ExoPlayer's default one, which allows better spoofing of official clients (custom user-agent and headers (depending of the client used), use of range and rn (set dynamically by the DataSource) parameters); - Fetch YouTube progressive contents as DASH streams, like official clients, support fully playback of livestreams which have ended recently and OTF streams; - Use ExoPlayer's default retries count for contents on non-fatal errors (instead of Integer.MAX_VALUE for non-live contents and 5 for live contents). - Download dialog: - Add message about support of progressive HTTP streams only for downloading; - Remove several duplicated code and update relevant usages; - Support downloading of contents with an unknown media format. - ListHelper: - Catch NumberFormatException when trying to compare two video streams between them. - Tests: - Update ListHelperTest and StreamItemAdapterTest to fix breaking changes in the extractor. - Other places: - Fixes deprecation of changes made in the extractor; - Improve some code related to the files changed. - Issues fixed and/or improved with the changes: - Seeking of PeerTube HLS streams (the duration shown was the one from the stream duration and not the one parsed, incomplete because HLS streams are fragmented MP4s with multiple sidx boxes, for which seeking is not supported by ExoPlayer) (the app now uses the HLS manifest returned for each quality, in the master playlist (not fetched and computed by the extractor)); - Crash when loading PeerTube streams with a separated audio; - Lack of some streams on some YouTube videos (OTF streams); - Loading times of YouTube streams, after a quality change or a playback start; - View count of YouTube ended livestreams interpreted as watching count (this type of streams is not interpreted anymore as livestreams); - Watchable time of YouTube ended livestreams; - Playback of SoundCloud HLS-only tracks (which cannot be downloaded anymore because the workaround which was used is being removed by SoundCloud, so it has been removed from the extractor).
2022-06-16 11:13:19 +02:00
if (mediaFormat == null) {
formatNameView.setText(context.getString(R.string.unknown_format));
} else if (mediaFormat == MediaFormat.WEBMA_OPUS) {
// noinspection AndroidLintSetTextI18n
formatNameView.setText("opus");
} else {
formatNameView.setText(mediaFormat.getName());
}
}
2018-04-08 13:08:19 +02:00
qualityView.setText(qualityString);
woSoundIconView.setVisibility(woSoundIconVisibility);
return convertView;
}
/**
* @param position which primary stream to check.
* @return whether the primary stream at position has a secondary stream associated with it.
*/
private boolean hasSecondaryStream(final int position) {
return secondaryStreams != null && secondaryStreams.get(position) != null;
}
/**
* @return if there are any video-only streams with no secondary stream associated with them.
2022-04-02 15:44:06 +02:00
* @see #hasAnyVideoOnlyStreamWithNoSecondaryStream
*/
2022-04-02 15:44:06 +02:00
private boolean checkHasAnyVideoOnlyStreamWithNoSecondaryStream() {
for (int i = 0; i < streamsWrapper.getStreamsList().size(); i++) {
final T stream = streamsWrapper.getStreamsList().get(i);
if (stream instanceof VideoStream) {
final boolean videoOnly = ((VideoStream) stream).isVideoOnly();
if (videoOnly && !hasSecondaryStream(i)) {
return true;
}
}
}
return false;
}
2018-04-08 13:08:19 +02:00
/**
* A wrapper class that includes a way of storing the stream sizes.
*
* @param <T> the stream type's class extending {@link Stream}
2018-04-08 13:08:19 +02:00
*/
public static class StreamSizeWrapper<T extends Stream> implements Serializable {
private static final StreamSizeWrapper<Stream> EMPTY = new StreamSizeWrapper<>(
Collections.emptyList(), null);
2018-04-08 13:08:19 +02:00
private final List<T> streamsList;
2018-11-08 23:03:30 +01:00
private final long[] streamSizes;
private final String unknownSize;
2018-04-08 13:08:19 +02:00
public StreamSizeWrapper(final List<T> sL, final Context context) {
this.streamsList = sL != null
? sL
: Collections.emptyList();
2018-04-08 13:08:19 +02:00
this.streamSizes = new long[streamsList.size()];
this.unknownSize = context == null
? "--.-" : context.getString(R.string.unknown_content);
2018-04-08 13:08:19 +02:00
Arrays.fill(streamSizes, -2);
2018-04-08 13:08:19 +02:00
}
/**
* Helper method to fetch the sizes of all the streams in a wrapper.
*
* @param <X> the stream type's class extending {@link Stream}
2018-04-08 13:08:19 +02:00
* @param streamsWrapper the wrapper
* @return a {@link Single} that returns a boolean indicating if any elements were changed
*/
Add support of other delivery methods than progressive HTTP (in the player only) Detailed changes: - External players: - Add a message instruction about stream selection; - Add a message when there is no stream available for external players; - Return now HLS, DASH and SmoothStreaming URL contents, in addition to progressive HTTP ones. - Player: - Support DASH, HLS and SmoothStreaming streams for videos, whether they are content URLs or the manifests themselves, in addition to progressive HTTP ones; - Use a custom HttpDataSource to play YouTube contents, based of ExoPlayer's default one, which allows better spoofing of official clients (custom user-agent and headers (depending of the client used), use of range and rn (set dynamically by the DataSource) parameters); - Fetch YouTube progressive contents as DASH streams, like official clients, support fully playback of livestreams which have ended recently and OTF streams; - Use ExoPlayer's default retries count for contents on non-fatal errors (instead of Integer.MAX_VALUE for non-live contents and 5 for live contents). - Download dialog: - Add message about support of progressive HTTP streams only for downloading; - Remove several duplicated code and update relevant usages; - Support downloading of contents with an unknown media format. - ListHelper: - Catch NumberFormatException when trying to compare two video streams between them. - Tests: - Update ListHelperTest and StreamItemAdapterTest to fix breaking changes in the extractor. - Other places: - Fixes deprecation of changes made in the extractor; - Improve some code related to the files changed. - Issues fixed and/or improved with the changes: - Seeking of PeerTube HLS streams (the duration shown was the one from the stream duration and not the one parsed, incomplete because HLS streams are fragmented MP4s with multiple sidx boxes, for which seeking is not supported by ExoPlayer) (the app now uses the HLS manifest returned for each quality, in the master playlist (not fetched and computed by the extractor)); - Crash when loading PeerTube streams with a separated audio; - Lack of some streams on some YouTube videos (OTF streams); - Loading times of YouTube streams, after a quality change or a playback start; - View count of YouTube ended livestreams interpreted as watching count (this type of streams is not interpreted anymore as livestreams); - Watchable time of YouTube ended livestreams; - Playback of SoundCloud HLS-only tracks (which cannot be downloaded anymore because the workaround which was used is being removed by SoundCloud, so it has been removed from the extractor).
2022-06-16 11:13:19 +02:00
@NonNull
public static <X extends Stream> Single<Boolean> fetchSizeForWrapper(
final StreamSizeWrapper<X> streamsWrapper) {
2018-04-08 13:08:19 +02:00
final Callable<Boolean> fetchAndSet = () -> {
boolean hasChanged = false;
2020-08-16 10:24:58 +02:00
for (final X stream : streamsWrapper.getStreamsList()) {
if (streamsWrapper.getSizeInBytes(stream) > -2) {
2018-04-08 13:08:19 +02:00
continue;
}
final long contentLength = DownloaderImpl.getInstance().getContentLength(
Add support of other delivery methods than progressive HTTP (in the player only) Detailed changes: - External players: - Add a message instruction about stream selection; - Add a message when there is no stream available for external players; - Return now HLS, DASH and SmoothStreaming URL contents, in addition to progressive HTTP ones. - Player: - Support DASH, HLS and SmoothStreaming streams for videos, whether they are content URLs or the manifests themselves, in addition to progressive HTTP ones; - Use a custom HttpDataSource to play YouTube contents, based of ExoPlayer's default one, which allows better spoofing of official clients (custom user-agent and headers (depending of the client used), use of range and rn (set dynamically by the DataSource) parameters); - Fetch YouTube progressive contents as DASH streams, like official clients, support fully playback of livestreams which have ended recently and OTF streams; - Use ExoPlayer's default retries count for contents on non-fatal errors (instead of Integer.MAX_VALUE for non-live contents and 5 for live contents). - Download dialog: - Add message about support of progressive HTTP streams only for downloading; - Remove several duplicated code and update relevant usages; - Support downloading of contents with an unknown media format. - ListHelper: - Catch NumberFormatException when trying to compare two video streams between them. - Tests: - Update ListHelperTest and StreamItemAdapterTest to fix breaking changes in the extractor. - Other places: - Fixes deprecation of changes made in the extractor; - Improve some code related to the files changed. - Issues fixed and/or improved with the changes: - Seeking of PeerTube HLS streams (the duration shown was the one from the stream duration and not the one parsed, incomplete because HLS streams are fragmented MP4s with multiple sidx boxes, for which seeking is not supported by ExoPlayer) (the app now uses the HLS manifest returned for each quality, in the master playlist (not fetched and computed by the extractor)); - Crash when loading PeerTube streams with a separated audio; - Lack of some streams on some YouTube videos (OTF streams); - Loading times of YouTube streams, after a quality change or a playback start; - View count of YouTube ended livestreams interpreted as watching count (this type of streams is not interpreted anymore as livestreams); - Watchable time of YouTube ended livestreams; - Playback of SoundCloud HLS-only tracks (which cannot be downloaded anymore because the workaround which was used is being removed by SoundCloud, so it has been removed from the extractor).
2022-06-16 11:13:19 +02:00
stream.getContent());
2018-04-08 13:08:19 +02:00
streamsWrapper.setSize(stream, contentLength);
hasChanged = true;
}
return hasChanged;
};
return Single.fromCallable(fetchAndSet)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.onErrorReturnItem(true);
}
public static <X extends Stream> StreamSizeWrapper<X> empty() {
//noinspection unchecked
return (StreamSizeWrapper<X>) EMPTY;
}
2018-04-08 13:08:19 +02:00
public List<T> getStreamsList() {
return streamsList;
}
public long getSizeInBytes(final int streamIndex) {
2018-04-08 13:08:19 +02:00
return streamSizes[streamIndex];
}
public long getSizeInBytes(final T stream) {
2018-04-08 13:08:19 +02:00
return streamSizes[streamsList.indexOf(stream)];
}
public String getFormattedSize(final int streamIndex) {
return formatSize(getSizeInBytes(streamIndex));
2018-04-08 13:08:19 +02:00
}
public String getFormattedSize(final T stream) {
return formatSize(getSizeInBytes(stream));
}
private String formatSize(final long size) {
if (size > -1) {
return Utility.formatBytes(size);
}
return unknownSize;
2018-04-08 13:08:19 +02:00
}
public void setSize(final int streamIndex, final long sizeInBytes) {
2018-04-08 13:08:19 +02:00
streamSizes[streamIndex] = sizeInBytes;
}
public void setSize(final T stream, final long sizeInBytes) {
2018-04-08 13:08:19 +02:00
streamSizes[streamsList.indexOf(stream)] = sizeInBytes;
}
}
2018-11-08 23:03:30 +01:00
}