[YouTube] Fix regression introduced in the order of streams used when adding more parameters to InnerTube requests, using the iOS client for livestreams and more
This commit is contained in:
parent
5f8f3929bd
commit
9f9af35adb
2 changed files with 136 additions and 8 deletions
|
@ -60,6 +60,7 @@ import org.schabi.newpipe.extractor.stream.StreamType;
|
|||
import org.schabi.newpipe.extractor.stream.SubtitlesStream;
|
||||
import org.schabi.newpipe.extractor.stream.VideoStream;
|
||||
import org.schabi.newpipe.extractor.utils.JsonUtils;
|
||||
import org.schabi.newpipe.extractor.utils.Pair;
|
||||
import org.schabi.newpipe.extractor.utils.Parser;
|
||||
import org.schabi.newpipe.extractor.utils.Utils;
|
||||
|
||||
|
@ -71,7 +72,6 @@ import java.time.format.DateTimeFormatter;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
@ -1170,19 +1170,19 @@ public class YoutubeStreamExtractor extends StreamExtractor {
|
|||
return urlAndItags;
|
||||
}
|
||||
|
||||
final Map<String, JsonObject> streamingDataAndCpnLoopMap = new HashMap<>();
|
||||
final List<Pair<JsonObject, String>> streamingDataAndCpnLoopList = new ArrayList<>();
|
||||
// Use the androidStreamingData object first because there is no n param and no
|
||||
// signatureCiphers in streaming URLs of the Android client
|
||||
streamingDataAndCpnLoopMap.put(androidCpn, androidStreamingData);
|
||||
streamingDataAndCpnLoopMap.put(html5Cpn, html5StreamingData);
|
||||
streamingDataAndCpnLoopList.add(new Pair<>(androidStreamingData, androidCpn));
|
||||
streamingDataAndCpnLoopList.add(new Pair<>(html5StreamingData, html5Cpn));
|
||||
// Use the iosStreamingData object in the last position because most of the available
|
||||
// streams can be extracted with the Android and web clients and also because the iOS
|
||||
// client is only enabled by default on livestreams
|
||||
streamingDataAndCpnLoopMap.put(iosCpn, iosStreamingData);
|
||||
streamingDataAndCpnLoopList.add(new Pair<>(iosStreamingData, iosCpn));
|
||||
|
||||
for (final Map.Entry<String, JsonObject> entry : streamingDataAndCpnLoopMap.entrySet()) {
|
||||
urlAndItags.putAll(getStreamsFromStreamingDataKey(entry.getValue(), streamingDataKey,
|
||||
itagTypeWanted, entry.getKey()));
|
||||
for (final Pair<JsonObject, String> pair : streamingDataAndCpnLoopList) {
|
||||
urlAndItags.putAll(getStreamsFromStreamingDataKey(pair.getFirst(), streamingDataKey,
|
||||
itagTypeWanted, pair.getSecond()));
|
||||
}
|
||||
|
||||
return urlAndItags;
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
package org.schabi.newpipe.extractor.utils;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Serializable class to create a pair of objects.
|
||||
*
|
||||
* <p>
|
||||
* The two objects of the pair must be {@link Serializable serializable} and can be of the same
|
||||
* type.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Note that this class is not intended to be used as a general-purpose pair and should only be
|
||||
* used when interfacing with the extractor.
|
||||
* </p>
|
||||
*
|
||||
* @param <F> the type of the first object, which must be {@link Serializable}
|
||||
* @param <S> the type of the second object, which must be {@link Serializable}
|
||||
*/
|
||||
public class Pair<F extends Serializable, S extends Serializable> implements Serializable {
|
||||
|
||||
/**
|
||||
* The first object of the pair.
|
||||
*/
|
||||
private F firstObject;
|
||||
|
||||
/**
|
||||
* The second object of the pair.
|
||||
*/
|
||||
private S secondObject;
|
||||
|
||||
/**
|
||||
* Creates a new {@link Pair} object.
|
||||
*
|
||||
* @param first the first object of the pair
|
||||
* @param second the second object of the pair
|
||||
*/
|
||||
public Pair(final F first, final S second) {
|
||||
firstObject = first;
|
||||
secondObject = second;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the first object, which must be of the {@link F} type.
|
||||
*
|
||||
* @param first the new first object of the pair
|
||||
*/
|
||||
public void setFirst(final F first) {
|
||||
firstObject = first;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the first object, which must be of the {@link S} type.
|
||||
*
|
||||
* @param second the new first object of the pair
|
||||
*/
|
||||
public void setSecond(final S second) {
|
||||
secondObject = second;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the first object of the pair.
|
||||
*
|
||||
* @return the first object of the pair
|
||||
*/
|
||||
public F getFirst() {
|
||||
return firstObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the second object of the pair.
|
||||
*
|
||||
* @return the second object of the pair
|
||||
*/
|
||||
public S getSecond() {
|
||||
return this.secondObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of the current {@code Pair}.
|
||||
*
|
||||
* <p>
|
||||
* The string representation will look like this:
|
||||
* <code>
|
||||
* {<i>firstObject.toString()</i>, <i>secondObject.toString()</i>}
|
||||
* </code>
|
||||
* </p>
|
||||
*
|
||||
* @return a string representation of the current {@code Pair}
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "{" + firstObject + ", " + secondObject + "}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Reveals whether an object is equal to this {@code Pair} instance.
|
||||
*
|
||||
* @param obj the object to compare with this {@code Pair} instance
|
||||
* @return whether an object is equal to this {@code Pair} instance
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj == null || getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final Pair<?, ?> pair = (Pair<?, ?>) obj;
|
||||
return Objects.equals(firstObject, pair.firstObject) && Objects.equals(secondObject,
|
||||
pair.secondObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hash code of the current {@code Pair} by using the first and second object.
|
||||
*
|
||||
* @return a hash code of the current {@code Pair}
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(firstObject, secondObject);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue