Skip to content

Commit

Permalink
Add dynamic itag support.
Browse files Browse the repository at this point in the history
  • Loading branch information
FireMasterK committed Aug 3, 2023
1 parent 5492343 commit b204560
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ public class ItagItem implements Serializable {
new ItagItem(400, VIDEO_ONLY, MPEG_4, "1440p"),
new ItagItem(266, VIDEO_ONLY, MPEG_4, "2160p"),
new ItagItem(401, VIDEO_ONLY, MPEG_4, "2160p"),
new ItagItem(402, VIDEO_ONLY, MPEG_4, "4320p"), // can be 4320p60 as well
new ItagItem(571, VIDEO_ONLY, MPEG_4, "4320p"),
// can be 4320p60 HDR as well (1La4QzGeaaQ)
new ItagItem(402, VIDEO_ONLY, MPEG_4, "4320p60", 60),

new ItagItem(278, VIDEO_ONLY, WEBM, "144p"),
new ItagItem(242, VIDEO_ONLY, WEBM, "240p"),
Expand All @@ -89,28 +93,19 @@ public class ItagItem implements Serializable {
new ItagItem(247, VIDEO_ONLY, WEBM, "720p"),
new ItagItem(248, VIDEO_ONLY, WEBM, "1080p"),
new ItagItem(271, VIDEO_ONLY, WEBM, "1440p"),
// #272 is either 3840x2160 (e.g. RtoitU2A-3E) or 7680x4320 (sLprVF6d7Ug)
new ItagItem(272, VIDEO_ONLY, WEBM, "2160p"),
new ItagItem(302, VIDEO_ONLY, WEBM, "720p60", 60),
new ItagItem(303, VIDEO_ONLY, WEBM, "1080p60", 60),
new ItagItem(308, VIDEO_ONLY, WEBM, "1440p60", 60),
new ItagItem(313, VIDEO_ONLY, WEBM, "2160p"),
new ItagItem(315, VIDEO_ONLY, WEBM, "2160p60", 60)
new ItagItem(315, VIDEO_ONLY, WEBM, "2160p60", 60),
new ItagItem(272, VIDEO_ONLY, WEBM, "4320p60", 60)
};

/*//////////////////////////////////////////////////////////////////////////
// Utils
//////////////////////////////////////////////////////////////////////////*/

public static boolean isSupported(final int itag) {
for (final ItagItem item : ITAG_LIST) {
if (itag == item.id) {
return true;
}
}
return false;
}

@Deprecated
@Nonnull
public static ItagItem getItag(final int itagId) throws ParsingException {
for (final ItagItem item : ITAG_LIST) {
Expand All @@ -121,6 +116,65 @@ public static ItagItem getItag(final int itagId) throws ParsingException {
throw new ParsingException("itag " + itagId + " is not supported");
}

public static ItagItem getItag(final int itagId, final int averageBitrate,
final int fps, final String qualityLabel, final String mimeType)
throws ParsingException {

final String[] split = mimeType.split(";")[0].split("/");
final String streamType = split[0];
final String fileType = split[1];
final String codec = mimeType.split("\"")[1];

MediaFormat format = null;
ItagType itagType = null;

if (codec.contains(",")) { // muxed streams have both an audio and video codec
itagType = VIDEO;
} else {
if (streamType.equals("video")) {
itagType = VIDEO_ONLY;
}
if (streamType.equals("audio")) {
itagType = AUDIO;
}
}

if (itagType == VIDEO) {
if (fileType.equals("mp4")) {
format = MPEG_4;
}
if (fileType.equals("3gpp")) {
format = v3GPP;
}
}

if (itagType == VIDEO_ONLY) {
if (fileType.equals("mp4")) {
format = MPEG_4;
}
if (fileType.equals("webm")) {
format = WEBM;
}
}

if (itagType == AUDIO) {
if (fileType.equals("mp4") && (codec.startsWith("m4a") || codec.startsWith("mp4a"))) {
format = M4A;
}
if (fileType.startsWith("webm") && codec.equals("opus")) {
format = WEBMA_OPUS;
}
}

if (itagType == null || format == null) {
throw new ParsingException("Unknown mimeType: " + mimeType);
}

return itagType == AUDIO
? new ItagItem(itagId, itagType, format, Math.round(averageBitrate / 1024f))
: new ItagItem(itagId, itagType, format, qualityLabel, fps);
}

/*//////////////////////////////////////////////////////////////////////////
// Static constants
//////////////////////////////////////////////////////////////////////////*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1412,9 +1412,18 @@ private java.util.stream.Stream<ItagInfo> getStreamsFromStreamingDataKey(
return streamingData.getArray(streamingDataKey).stream()
.filter(JsonObject.class::isInstance)
.map(JsonObject.class::cast)
.filter(formatData -> !formatData.getString("mimeType", "")
.startsWith("text"))
.map(formatData -> {
try {
final ItagItem itagItem = ItagItem.getItag(formatData.getInt("itag"));
final int itag = formatData.getInt("itag");
final int averageBitrate = formatData.getInt("averageBitrate");
final int fps = formatData.getInt("fps");
final String qualityLabel = formatData.getString("qualityLabel");
final String mimeType = formatData.getString("mimeType");

final ItagItem itagItem = ItagItem.
getItag(itag, averageBitrate, fps, qualityLabel, mimeType);
if (itagItem.itagType == itagTypeWanted) {
return buildAndAddItagInfoToList(videoId, formatData, itagItem,
itagItem.itagType, contentPlaybackNonce);
Expand Down

0 comments on commit b204560

Please sign in to comment.