Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adaptive Stream parsing #535

Merged
merged 15 commits into from
Feb 18, 2021
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

public class ItagItem {
/**
* List can be found here https://github.com/rg3/youtube-dl/blob/master/youtube_dl/extractor/youtube.py#L360
* List can be found here https://github.com/ytdl-org/youtube-dl/blob/9fc5eafb8e384453a49f7cfe73147be491f0b19d/youtube_dl/extractor/youtube.py#L1071
*/
private static final ItagItem[] ITAG_LIST = {
/////////////////////////////////////////////////////
Expand Down Expand Up @@ -155,4 +155,77 @@ public MediaFormat getMediaFormat() {
public String resolutionString;
public int fps = -1;

// Fields for Dash
private int bitrate;
private int width;
private int height;
private int initStart;
private int initEnd;
private int indexStart;
private int indexEnd;
private String codec;

public int getBitrate() {
return bitrate;
}

public void setBitrate(int bitrate) {
this.bitrate = bitrate;
}

public int getWidth() {
return width;
}

public void setWidth(int width) {
this.width = width;
}

public int getHeight() {
return height;
}

public void setHeight(int height) {
this.height = height;
}

public int getInitStart() {
return initStart;
}

public void setInitStart(int initStart) {
this.initStart = initStart;
}

public int getInitEnd() {
return initEnd;
}

public void setInitEnd(int initEnd) {
this.initEnd = initEnd;
}

public int getIndexStart() {
return indexStart;
}

public void setIndexStart(int indexStart) {
this.indexStart = indexStart;
}

public int getIndexEnd() {
return indexEnd;
}

public void setIndexEnd(int indexEnd) {
this.indexEnd = indexEnd;
}

public String getCodec() {
return codec;
}

public void setCodec(String codec) {
this.codec = codec;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,7 @@ public List<AudioStream> getAudioStreams() throws ExtractionException {
for (Map.Entry<String, ItagItem> entry : getItags(ADAPTIVE_FORMATS, ItagItem.ItagType.AUDIO).entrySet()) {
ItagItem itag = entry.getValue();

AudioStream audioStream = new AudioStream(entry.getKey(), itag.getMediaFormat(), itag.avgBitrate);
AudioStream audioStream = new AudioStream(entry.getKey(), itag);
if (!Stream.containSimilarStream(audioStream, audioStreams)) {
audioStreams.add(audioStream);
}
Expand All @@ -522,7 +522,7 @@ public List<VideoStream> getVideoStreams() throws ExtractionException {
for (Map.Entry<String, ItagItem> entry : getItags(FORMATS, ItagItem.ItagType.VIDEO).entrySet()) {
ItagItem itag = entry.getValue();

VideoStream videoStream = new VideoStream(entry.getKey(), itag.getMediaFormat(), itag.resolutionString);
VideoStream videoStream = new VideoStream(entry.getKey(), false, itag);
if (!Stream.containSimilarStream(videoStream, videoStreams)) {
videoStreams.add(videoStream);
}
Expand All @@ -542,7 +542,7 @@ public List<VideoStream> getVideoOnlyStreams() throws ExtractionException {
for (Map.Entry<String, ItagItem> entry : getItags(ADAPTIVE_FORMATS, ItagItem.ItagType.VIDEO_ONLY).entrySet()) {
ItagItem itag = entry.getValue();

VideoStream videoStream = new VideoStream(entry.getKey(), itag.getMediaFormat(), itag.resolutionString, true);
VideoStream videoStream = new VideoStream(entry.getKey(), true, itag);
if (!Stream.containSimilarStream(videoStream, videoOnlyStreams)) {
videoOnlyStreams.add(videoStream);
}
Expand Down Expand Up @@ -949,6 +949,21 @@ private Map<String, ItagItem> getItags(final String streamingDataKey,
+ deobfuscateSignature(cipher.get("s"));
}

JsonObject initRange = formatData.getObject("initRange");
JsonObject indexRange = formatData.getObject("indexRange");
String mimeType = formatData.getString("mimeType", EMPTY_STRING);
String codec = mimeType.contains("codecs") ? mimeType.split("\"")[1] : EMPTY_STRING;

itagItem.setBitrate(formatData.getInt("bitrate"));
itagItem.setWidth(formatData.getInt("width"));
itagItem.setHeight(formatData.getInt("height"));
itagItem.setInitStart(Integer.parseInt(initRange.getString("start", "-1")));
itagItem.setInitEnd(Integer.parseInt(initRange.getString("end", "-1")));
itagItem.setIndexStart(Integer.parseInt(indexRange.getString("start", "-1")));
itagItem.setIndexEnd(Integer.parseInt(indexRange.getString("end", "-1")));
itagItem.fps = formatData.getInt("fps");
itagItem.setCodec(codec);

urlAndItags.put(streamUrl, itagItem);
}
} catch (UnsupportedEncodingException ignored) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,19 @@
*/

import org.schabi.newpipe.extractor.MediaFormat;
import org.schabi.newpipe.extractor.services.youtube.ItagItem;

public class AudioStream extends Stream {
public int average_bitrate = -1;

// Fields for Dash
private int bitrate;
private int initStart;
private int initEnd;
private int indexStart;
private int indexEnd;
private String codec;

/**
* Create a new audio stream
* @param url the url
Expand All @@ -36,6 +45,21 @@ public AudioStream(String url, MediaFormat format, int averageBitrate) {
this.average_bitrate = averageBitrate;
}

/**
* Create a new audio stream
* @param url the url
* @param itag the ItagItem of the Stream
*/
public AudioStream(String url, ItagItem itag) {
this(url, itag.getMediaFormat(), itag.avgBitrate);
this.bitrate = itag.getBitrate();
this.initStart = itag.getInitStart();
this.initEnd = itag.getInitEnd();
this.indexStart = itag.getIndexStart();
this.indexEnd = itag.getIndexEnd();
this.codec = itag.getCodec();
}

@Override
public boolean equalStats(Stream cmp) {
return super.equalStats(cmp) && cmp instanceof AudioStream &&
Expand All @@ -49,4 +73,28 @@ public boolean equalStats(Stream cmp) {
public int getAverageBitrate() {
return average_bitrate;
}

public int getBitrate() {
return bitrate;
}

public int getInitStart() {
return initStart;
}

public int getInitEnd() {
return initEnd;
}

public int getIndexStart() {
return indexStart;
}

public int getIndexEnd() {
return indexEnd;
}

public String getCodec() {
return codec;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,42 @@
*/

import org.schabi.newpipe.extractor.MediaFormat;
import org.schabi.newpipe.extractor.services.youtube.ItagItem;

public class VideoStream extends Stream {
public final String resolution;
public final boolean isVideoOnly;

// Fields for Dash
FireMasterK marked this conversation as resolved.
Show resolved Hide resolved
private int bitrate;
private int initStart;
private int initEnd;
private int indexStart;
private int indexEnd;
private int width;
private int height;
private int fps;
private String codec;

public VideoStream(String url, MediaFormat format, String resolution) {
this(url, format, resolution, false);
}

public VideoStream(String url, MediaFormat format, String resolution, boolean isVideoOnly) {
super(url, format);
this.resolution = resolution;
this.isVideoOnly = isVideoOnly;
this(url, null, format, resolution, isVideoOnly);
}

public VideoStream(String url, boolean isVideoOnly, ItagItem itag) {
this(url, itag.getMediaFormat(), itag.resolutionString, isVideoOnly);
this.bitrate = itag.getBitrate();
this.initStart = itag.getInitStart();
this.initEnd = itag.getInitEnd();
this.indexStart = itag.getIndexStart();
this.indexEnd = itag.getIndexEnd();
this.codec = itag.getCodec();
this.height = itag.getHeight();
this.width = itag.getWidth();
this.fps = itag.fps;
}

public VideoStream(String url, String torrentUrl, MediaFormat format, String resolution) {
Expand Down Expand Up @@ -73,4 +95,40 @@ public String getResolution() {
public boolean isVideoOnly() {
return isVideoOnly;
}

public int getBitrate() {
return bitrate;
}

public int getInitStart() {
return initStart;
}

public int getInitEnd() {
return initEnd;
}

public int getIndexStart() {
return indexStart;
}

public int getIndexEnd() {
return indexEnd;
}

public int getWidth() {
return width;
}

public int getHeight() {
return height;
}

public int getFps() {
return fps;
}

public String getCodec() {
return codec;
}
}