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

Multiple images support #889

Merged
merged 35 commits into from
Aug 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
d854541
Add an Image class to the extractor
AudricV Aug 12, 2023
78ce657
Add an ImageSuffix class to the extractor
AudricV Aug 12, 2023
2f3ee8a
Replace avatar and thumbnail URLs attributes and methods to List<Imag…
AudricV Jul 20, 2022
ca1d4a6
Replace avatar and thumbnail URLs attributes and methods to List<Imag…
AudricV Jul 20, 2022
0f4a5a8
Replace avatar and thumbnail URLs attributes and methods to List<Imag…
AudricV Jul 20, 2022
9d80985
Replace avatar and thumbnail URLs attributes and methods to List<Imag…
AudricV Jul 20, 2022
d56b880
Replace avatar and thumbnail URLs attributes and methods to List<Imag…
AudricV Jul 22, 2022
adfad08
[YouTube] Add utility methods to get images from InfoItems and thumbn…
AudricV Jul 22, 2022
4cc99f9
[YouTube] Apply changes in InfoItemExtractors except YouTube Music ones
AudricV Jul 22, 2022
c1981ed
[YouTube] Apply changes in Extractors except YoutubeMusicSearchExtractor
AudricV Jul 22, 2022
266cd1f
[YouTube] Apply changes in YoutubeMusicSearchExtractor and split its …
AudricV Jul 24, 2022
7f81821
[SoundCloud] Add utility methods to get images from track JSON object…
AudricV Jul 25, 2022
a3a74cd
[SoundCloud] Apply changes in InfoItemExtractors and return track use…
AudricV Jul 25, 2022
31da5be
[SoundCloud] Apply changes in Extractors
AudricV Jul 25, 2022
81c0d80
[PeerTube] Add utility methods to get avatars and banners of accounts…
AudricV Jul 27, 2022
6f83315
[PeerTube] Add utility method to get thumbnails of playlists and videos
AudricV Feb 9, 2023
0a6011a
[PeerTube] Apply changes in InfoItemExtractors
AudricV Jul 27, 2022
4e6fb36
[PeerTube] Apply changes in Extractors and remove usages of default a…
AudricV Jul 29, 2022
4b80d73
[Bandcamp] Add utility methods to get multiple images
AudricV Jul 30, 2022
7e01eaa
[Bandcamp] Apply changes in InfoItemExtractors
AudricV Jul 30, 2022
71cda03
[Bandcamp] Apply changes in Extractors
AudricV Jul 30, 2022
2f40861
[MediaCCC] Add utility methods to get image lists from conference log…
AudricV Jul 30, 2022
306068a
[MediaCCC] Apply changes in InfoItemExtractors
AudricV Jul 30, 2022
e16d521
[MediaCCC] Apply changes in Extractors
AudricV Jul 30, 2022
70fb3aa
Update BaseExtractorTests image methods' name
AudricV Aug 1, 2022
5158472
Apply changes in DefaultTests and add utility method to test image lists
AudricV Aug 1, 2022
434e885
Add utility methods in ExtractorAsserts to check whether a collection…
AudricV Aug 3, 2022
d381f3b
Update avatar, banners and thumbnail methods' name and apply changes …
AudricV Aug 3, 2022
2c436d4
[YouTube] Add utility test method to test images in YoutubeTestsUtils
AudricV Aug 3, 2022
93a2103
[YouTube] Apply changes in extractor tests
AudricV Aug 3, 2022
1d72bac
[SoundCloud] Apply changes in extractor tests
AudricV Aug 3, 2022
ba5315c
[PeerTube] Apply changes in extractor tests
AudricV Aug 3, 2022
2578f22
[Bandcamp] Add utility test method to test images
AudricV Aug 3, 2022
0292c4f
[Bandcamp] Apply changes in extractor tests
AudricV Aug 3, 2022
e8bfd20
[MediaCCC] Apply changes in extractor tests
AudricV Aug 3, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
211 changes: 211 additions & 0 deletions extractor/src/main/java/org/schabi/newpipe/extractor/Image.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
package org.schabi.newpipe.extractor;

import javax.annotation.Nonnull;
import java.io.Serializable;
import java.util.Objects;

/**
* Class representing images in the extractor.
*
* <p>
* An image has four properties: its URL, its height, its width and its estimated quality level.
* </p>
*
* <p>
* Depending of the services, the height, the width or both properties may be not known.
* Implementations <b>must use</b> the relevant unknown constants in this case
* ({@link #HEIGHT_UNKNOWN} and {@link #WIDTH_UNKNOWN}), to ensure properly the lack of knowledge
* of one or both of these properties to extractor clients.
* </p>
*
* <p>
* They should also respect the ranges defined in the estimated image resolution levels as much as
* possible, to ensure consistency to extractor clients.
* </p>
*/
public final class Image implements Serializable {

/**
* Constant representing that the height of an {@link Image} is unknown.
*/
public static final int HEIGHT_UNKNOWN = -1;

/**
* Constant representing that the width of an {@link Image} is unknown.
*/
public static final int WIDTH_UNKNOWN = -1;

@Nonnull
private final String url;
AudricV marked this conversation as resolved.
Show resolved Hide resolved
private final int height;
private final int width;
@Nonnull
private final ResolutionLevel estimatedResolutionLevel;

/**
* Construct an {@link Image} instance.
*
* @param url the URL to the image, which should be not null or empty
* @param height the image's height
* @param width the image's width
* @param estimatedResolutionLevel the image's estimated resolution level, which must not be
* null
* @throws NullPointerException if {@code estimatedResolutionLevel} is null
*/
public Image(@Nonnull final String url,
final int height,
final int width,
@Nonnull final ResolutionLevel estimatedResolutionLevel)
throws NullPointerException {
this.url = url;
this.height = height;
this.width = width;
this.estimatedResolutionLevel = Objects.requireNonNull(
estimatedResolutionLevel, "estimatedResolutionLevel is null");
}

/**
* Get the URL of this {@link Image}.
*
* @return the {@link Image}'s URL.
*/
@Nonnull
public String getUrl() {
return url;
}

/**
* Get the height of this {@link Image}.
*
* <p>
* If it is unknown, {@link #HEIGHT_UNKNOWN} is returned instead.
* </p>
*
* @return the {@link Image}'s height or {@link #HEIGHT_UNKNOWN}
*/
public int getHeight() {
return height;
}

/**
* Get the width of this {@link Image}.
*
* <p>
* If it is unknown, {@link #WIDTH_UNKNOWN} is returned instead.
* </p>
*
* @return the {@link Image}'s width or {@link #WIDTH_UNKNOWN}
*/
public int getWidth() {
return width;
}

/**
* Get the estimated resolution level of this image.
*
* <p>
* If it is unknown, {@link ResolutionLevel#UNKNOWN} is returned instead.
* </p>
*
* @return the estimated resolution level, which is never {@code null}
* @see ResolutionLevel
*/
@Nonnull
public ResolutionLevel getEstimatedResolutionLevel() {
return estimatedResolutionLevel;
}

/**
* Get a string representation of this {@link Image} instance.
*
* <p>
* The representation will be in the following format, where {@code url}, {@code height},
* {@code width} and {@code estimatedResolutionLevel} represent the corresponding properties:
* <br>
* <br>
* {@code Image {url=url, height='height, width=width,
* estimatedResolutionLevel=estimatedResolutionLevel}'}
* </p>
*
* @return a string representation of this {@link Image} instance
*/
@Nonnull
@Override
public String toString() {
return "Image {" + "url=" + url + ", height=" + height + ", width=" + width
+ ", estimatedResolutionLevel=" + estimatedResolutionLevel + "}";
}

/**
* The estimated resolution level of an {@link Image}.
*
* <p>
* Some services don't return the size of their images, but we may know for a specific image
* type that a service returns, according to real data, an approximation of the resolution
* level.
* </p>
*/
public enum ResolutionLevel {

/**
* The high resolution level.
*
* <p>
* This level applies to images with a height greater than or equal to 720px.
* </p>
*/
HIGH,

/**
* The medium resolution level.
*
* <p>
* This level applies to images with a height between 175px inclusive and 720px exclusive.
* </p>
*/
MEDIUM,

/**
* The low resolution level.
*
* <p>
* This level applies to images with a height between 1px inclusive and 175px exclusive.
* </p>
*/
LOW,

/**
* The unknown resolution level.
*
* <p>
* This value is returned when the extractor doesn't know what resolution level an image
* could have, for example if the extractor loops in an array of images with different
* resolution levels without knowing the height.
* </p>
*/
UNKNOWN;

/**
* Get a {@link ResolutionLevel} based from the given height.
*
* @param heightPx the height from which returning the good {@link ResolutionLevel}
* @return the {@link ResolutionLevel} corresponding to the height provided. See the
* {@link ResolutionLevel} values for details about what value is returned.
*/
public static ResolutionLevel fromHeight(final int heightPx) {
if (heightPx <= 0) {
return UNKNOWN;
}

if (heightPx < 175) {
return LOW;
}

if (heightPx < 720) {
return MEDIUM;
}

return HIGH;
}
}
}
26 changes: 15 additions & 11 deletions extractor/src/main/java/org/schabi/newpipe/extractor/InfoItem.java
Original file line number Diff line number Diff line change
@@ -1,33 +1,36 @@
package org.schabi.newpipe.extractor;

/*
* Created by Christian Schabesberger on 11.02.17.
*
* Copyright (C) Christian Schabesberger 2017 <[email protected]>
* InfoItem.java is part of NewPipe.
* InfoItem.java is part of NewPipe Extractor.
*
* NewPipe is free software: you can redistribute it and/or modify
* NewPipe Extractor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* NewPipe is distributed in the hope that it will be useful,
* NewPipe Extractor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
* along with NewPipe Extractor. If not, see <https://www.gnu.org/licenses/>.
*/

package org.schabi.newpipe.extractor;

import javax.annotation.Nonnull;
import java.io.Serializable;
import java.util.List;

public abstract class InfoItem implements Serializable {
private final InfoType infoType;
private final int serviceId;
private final String url;
private final String name;
private String thumbnailUrl;
@Nonnull
private List<Image> thumbnails = List.of();

public InfoItem(final InfoType infoType,
final int serviceId,
Expand Down Expand Up @@ -55,12 +58,13 @@ public String getName() {
return name;
}

public void setThumbnailUrl(final String thumbnailUrl) {
this.thumbnailUrl = thumbnailUrl;
public void setThumbnails(@Nonnull final List<Image> thumbnails) {
this.thumbnails = thumbnails;
}

public String getThumbnailUrl() {
return thumbnailUrl;
@Nonnull
public List<Image> getThumbnails() {
return thumbnails;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@

import org.schabi.newpipe.extractor.exceptions.ParsingException;

import javax.annotation.Nonnull;
import java.util.List;

public interface InfoItemExtractor {
String getName() throws ParsingException;
String getUrl() throws ParsingException;
String getThumbnailUrl() throws ParsingException;
@Nonnull
List<Image> getThumbnails() throws ParsingException;
}
Original file line number Diff line number Diff line change
@@ -1,33 +1,34 @@
package org.schabi.newpipe.extractor.channel;

import org.schabi.newpipe.extractor.Extractor;
import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;

import javax.annotation.Nonnull;
import java.util.List;

/*
* Created by Christian Schabesberger on 25.07.16.
*
* Copyright (C) Christian Schabesberger 2016 <[email protected]>
* ChannelExtractor.java is part of NewPipe.
* ChannelExtractor.java is part of NewPipe Extractor.
*
* NewPipe is free software: you can redistribute it and/or modify
* NewPipe Extractor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* NewPipe is distributed in the hope that it will be useful,
* NewPipe Extractor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
* along with NewPipe Extractor. If not, see <https://www.gnu.org/licenses/>.
*/

package org.schabi.newpipe.extractor.channel;

import org.schabi.newpipe.extractor.Extractor;
import org.schabi.newpipe.extractor.Image;
import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;

import javax.annotation.Nonnull;
import java.util.List;

public abstract class ChannelExtractor extends Extractor {

public static final long UNKNOWN_SUBSCRIBER_COUNT = -1;
Expand All @@ -36,14 +37,17 @@ protected ChannelExtractor(final StreamingService service, final ListLinkHandler
super(service, linkHandler);
}

public abstract String getAvatarUrl() throws ParsingException;
public abstract String getBannerUrl() throws ParsingException;
@Nonnull
public abstract List<Image> getAvatars() throws ParsingException;
@Nonnull
public abstract List<Image> getBanners() throws ParsingException;
public abstract String getFeedUrl() throws ParsingException;
public abstract long getSubscriberCount() throws ParsingException;
public abstract String getDescription() throws ParsingException;
public abstract String getParentChannelName() throws ParsingException;
public abstract String getParentChannelUrl() throws ParsingException;
public abstract String getParentChannelAvatarUrl() throws ParsingException;
@Nonnull
public abstract List<Image> getParentChannelAvatars() throws ParsingException;
public abstract boolean isVerified() throws ParsingException;
@Nonnull
public abstract List<ListLinkHandler> getTabs() throws ParsingException;
Expand Down
Loading
Loading