55import org .schabi .newpipe .extractor .Image ;
66import org .schabi .newpipe .extractor .exceptions .ParsingException ;
77import org .schabi .newpipe .extractor .playlist .PlaylistInfoItemExtractor ;
8- import org .schabi .newpipe .extractor .utils .Utils ;
98
109import javax .annotation .Nonnull ;
1110import javax .annotation .Nullable ;
1211import java .util .List ;
1312
14- import static org .schabi .newpipe .extractor .ListExtractor .ITEM_COUNT_MORE_THAN_100 ;
1513import static org .schabi .newpipe .extractor .ListExtractor .ITEM_COUNT_UNKNOWN ;
1614import static org .schabi .newpipe .extractor .services .youtube .YoutubeParsingHelper .getTextFromObject ;
1715import static org .schabi .newpipe .extractor .services .youtube .YoutubeParsingHelper .getImagesFromThumbnailsArray ;
1816import static org .schabi .newpipe .extractor .services .youtube .YoutubeParsingHelper .getUrlFromNavigationEndpoint ;
1917import static org .schabi .newpipe .extractor .services .youtube .linkHandler .YoutubeSearchQueryHandlerFactory .MUSIC_ALBUMS ;
20- import static org .schabi .newpipe .extractor .services .youtube .linkHandler .YoutubeSearchQueryHandlerFactory .MUSIC_PLAYLISTS ;
2118import static org .schabi .newpipe .extractor .utils .Utils .isNullOrEmpty ;
2219
2320public class YoutubeMusicAlbumOrPlaylistInfoItemExtractor implements PlaylistInfoItemExtractor {
2421 private final JsonObject albumOrPlaylistInfoItem ;
25- private final JsonArray descriptionElements ;
26- private final String searchType ;
22+ private final JsonObject descriptionElementUploader ;
2723
2824 public YoutubeMusicAlbumOrPlaylistInfoItemExtractor (final JsonObject albumOrPlaylistInfoItem ,
2925 final JsonArray descriptionElements ,
3026 final String searchType ) {
3127 this .albumOrPlaylistInfoItem = albumOrPlaylistInfoItem ;
32- this .descriptionElements = descriptionElements ;
33- this .searchType = searchType ;
28+
29+ this .descriptionElementUploader = descriptionElements .getObject (
30+ // For albums: "Album/Single/EP", " • ", uploader, " • ", year -> uploader is at 2
31+ // For playlists: uploader, " • ", view count -> uploader is at 0
32+ MUSIC_ALBUMS .equals (searchType ) ? 2 : 0
33+ );
3434 }
3535
3636 @ Nonnull
@@ -92,12 +92,7 @@ public String getUrl() throws ParsingException {
9292
9393 @ Override
9494 public String getUploaderName () throws ParsingException {
95- final String name ;
96- if (searchType .equals (MUSIC_ALBUMS )) {
97- name = descriptionElements .getObject (2 ).getString ("text" );
98- } else {
99- name = descriptionElements .getObject (0 ).getString ("text" );
100- }
95+ final String name = descriptionElementUploader .getString ("text" );
10196
10297 if (!isNullOrEmpty (name )) {
10398 return name ;
@@ -109,10 +104,7 @@ public String getUploaderName() throws ParsingException {
109104 @ Nullable
110105 @ Override
111106 public String getUploaderUrl () throws ParsingException {
112- if (searchType .equals (MUSIC_PLAYLISTS )) {
113- return null ;
114- }
115-
107+ // first try obtaining the uploader from the menu (will not work for MUSIC_PLAYLISTS though)
116108 final JsonArray items = albumOrPlaylistInfoItem .getObject ("menu" )
117109 .getObject ("menuRenderer" )
118110 .getArray ("items" );
@@ -127,7 +119,14 @@ public String getUploaderUrl() throws ParsingException {
127119 }
128120 }
129121
130- throw new ParsingException ("Could not get uploader URL" );
122+ // then try obtaining it from the uploader description element
123+ if (!descriptionElementUploader .has ("navigationEndpoint" )) {
124+ // if there is no navigationEndpoint for the uploader
125+ // then this playlist/album is likely autogenerated
126+ return null ;
127+ }
128+ return getUrlFromNavigationEndpoint (
129+ descriptionElementUploader .getObject ("navigationEndpoint" ));
131130 }
132131
133132 @ Override
@@ -137,21 +136,7 @@ public boolean isUploaderVerified() throws ParsingException {
137136
138137 @ Override
139138 public long getStreamCount () throws ParsingException {
140- if (searchType .equals (MUSIC_ALBUMS )) {
141- return ITEM_COUNT_UNKNOWN ;
142- }
143-
144- final String count = descriptionElements .getObject (2 )
145- .getString ("text" );
146-
147- if (!isNullOrEmpty (count )) {
148- if (count .contains ("100+" )) {
149- return ITEM_COUNT_MORE_THAN_100 ;
150- } else {
151- return Long .parseLong (Utils .removeNonDigitCharacters (count ));
152- }
153- }
154-
155- throw new ParsingException ("Could not get stream count" );
139+ // YouTube Music album and playlist info items don't expose the stream count anywhere...
140+ return ITEM_COUNT_UNKNOWN ;
156141 }
157142}
0 commit comments