mirror of
https://github.com/TeamNewPipe/NewPipeExtractor
synced 2025-08-28 21:07:57 +00:00
Handle situations where there are multiple uploaders
This commit is contained in:
parent
ef6a53ebb3
commit
182df6eebe
@ -44,6 +44,7 @@ public class YoutubeStreamInfoItemLockupExtractor implements StreamInfoItemExtra
|
|||||||
private String cachedName;
|
private String cachedName;
|
||||||
private Optional<String> cachedTextualUploadDate;
|
private Optional<String> cachedTextualUploadDate;
|
||||||
|
|
||||||
|
private ChannelImageViewModel cachedChannelImageViewModel;
|
||||||
private JsonArray cachedMetadataRows;
|
private JsonArray cachedMetadataRows;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -165,10 +166,15 @@ public class YoutubeStreamInfoItemLockupExtractor implements StreamInfoItemExtra
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getUploaderUrl() throws ParsingException {
|
public String getUploaderUrl() throws ParsingException {
|
||||||
final String channelId = JsonUtils.getString(lockupViewModel,
|
final String channelId = channelImageViewModel()
|
||||||
"metadata.lockupMetadataViewModel.image.decoratedAvatarViewModel"
|
.forUploaderUrlExtraction()
|
||||||
+ ".rendererContext.commandContext.onTap"
|
.getObject("rendererContext")
|
||||||
+ ".innertubeCommand.browseEndpoint.browseId");
|
.getObject("commandContext")
|
||||||
|
.getObject("onTap")
|
||||||
|
.getObject("innertubeCommand")
|
||||||
|
.getObject("browseEndpoint")
|
||||||
|
.getString("browseId");
|
||||||
|
|
||||||
if (isNullOrEmpty(channelId)) {
|
if (isNullOrEmpty(channelId)) {
|
||||||
throw new ParsingException("Could not get uploader url");
|
throw new ParsingException("Could not get uploader url");
|
||||||
}
|
}
|
||||||
@ -179,9 +185,9 @@ public class YoutubeStreamInfoItemLockupExtractor implements StreamInfoItemExtra
|
|||||||
@Override
|
@Override
|
||||||
public List<Image> getUploaderAvatars() throws ParsingException {
|
public List<Image> getUploaderAvatars() throws ParsingException {
|
||||||
return YoutubeParsingHelper.getImagesFromThumbnailsArray(
|
return YoutubeParsingHelper.getImagesFromThumbnailsArray(
|
||||||
JsonUtils.getArray(lockupViewModel,
|
JsonUtils.getArray(
|
||||||
"metadata.lockupMetadataViewModel.image.decoratedAvatarViewModel"
|
channelImageViewModel().forAvatarExtraction(),
|
||||||
+ ".avatar.avatarViewModel.image.sources"));
|
"avatarViewModel.image.sources"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -253,6 +259,34 @@ public class YoutubeStreamInfoItemLockupExtractor implements StreamInfoItemExtra
|
|||||||
"contentImage.thumbnailViewModel.image.sources"));
|
"contentImage.thumbnailViewModel.image.sources"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ChannelImageViewModel channelImageViewModel() throws ParsingException {
|
||||||
|
if (cachedChannelImageViewModel == null) {
|
||||||
|
cachedChannelImageViewModel = determineChannelImageViewModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
return cachedChannelImageViewModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ChannelImageViewModel determineChannelImageViewModel() throws ParsingException {
|
||||||
|
final JsonObject image = lockupViewModel
|
||||||
|
.getObject("metadata")
|
||||||
|
.getObject("lockupMetadataViewModel")
|
||||||
|
.getObject("image");
|
||||||
|
|
||||||
|
final JsonObject single = image
|
||||||
|
.getObject("decoratedAvatarViewModel", null);
|
||||||
|
if (single != null) {
|
||||||
|
return new SingleChannelImageViewModel(single);
|
||||||
|
}
|
||||||
|
|
||||||
|
final JsonObject multi = image.getObject("avatarStackViewModel", null);
|
||||||
|
if (multi != null) {
|
||||||
|
return new MultiChannelImageViewModel(multi);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new ParsingException("Failed to determine channel image view model");
|
||||||
|
}
|
||||||
|
|
||||||
private Optional<JsonObject> metadataPart(final int rowIndex, final int partIndex)
|
private Optional<JsonObject> metadataPart(final int rowIndex, final int partIndex)
|
||||||
throws ParsingException {
|
throws ParsingException {
|
||||||
if (cachedMetadataRows == null) {
|
if (cachedMetadataRows == null) {
|
||||||
@ -274,4 +308,64 @@ public class YoutubeStreamInfoItemLockupExtractor implements StreamInfoItemExtra
|
|||||||
private String getTextContentFromMetadataPart(final JsonObject metadataPart) {
|
private String getTextContentFromMetadataPart(final JsonObject metadataPart) {
|
||||||
return metadataPart.getObject("text").getString("content");
|
return metadataPart.getObject("text").getString("content");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract static class ChannelImageViewModel {
|
||||||
|
protected JsonObject viewModel;
|
||||||
|
|
||||||
|
protected ChannelImageViewModel(final JsonObject viewModel) {
|
||||||
|
this.viewModel = viewModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract JsonObject forUploaderUrlExtraction();
|
||||||
|
|
||||||
|
public abstract JsonObject forAvatarExtraction();
|
||||||
|
}
|
||||||
|
|
||||||
|
static class SingleChannelImageViewModel extends ChannelImageViewModel {
|
||||||
|
SingleChannelImageViewModel(final JsonObject viewModel) {
|
||||||
|
super(viewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonObject forUploaderUrlExtraction() {
|
||||||
|
return viewModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonObject forAvatarExtraction() {
|
||||||
|
return viewModel.getObject("avatar");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class MultiChannelImageViewModel extends ChannelImageViewModel {
|
||||||
|
MultiChannelImageViewModel(final JsonObject viewModel) {
|
||||||
|
super(viewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonObject forUploaderUrlExtraction() {
|
||||||
|
return viewModel
|
||||||
|
.getObject("rendererContext")
|
||||||
|
.getObject("commandContext")
|
||||||
|
.getObject("onTap")
|
||||||
|
.getObject("innertubeCommand")
|
||||||
|
.getObject("showDialogCommand")
|
||||||
|
.getObject("panelLoadingStrategy")
|
||||||
|
.getObject("inlineContent")
|
||||||
|
.getObject("dialogViewModel")
|
||||||
|
.getObject("customContent")
|
||||||
|
.getObject("listViewModel")
|
||||||
|
.getArray("listItems")
|
||||||
|
.streamAsJsonObjects()
|
||||||
|
.map(item -> item.getObject("listItemViewModel"))
|
||||||
|
.findFirst()
|
||||||
|
.orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonObject forAvatarExtraction() {
|
||||||
|
return viewModel.getArray("avatars")
|
||||||
|
.getObject(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user