导航菜单

页面标题

页面副标题

Kreate v1.5.0 - SoundcloudParsingHelper.java 源代码

正在查看: Kreate v1.5.0 应用的 SoundcloudParsingHelper.java JAVA 源代码文件

本页面展示 JAVA 反编译生成的源代码文件,支持语法高亮显示。 仅供安全研究与技术分析使用,严禁用于任何非法用途。请遵守相关法律法规。


package org.schabi.newpipe.extractor.services.soundcloud;

import androidx.core.graphics.TypefaceCompat$;
import com.grack.nanojson.JsonObject;
import com.grack.nanojson.JsonParser;
import com.grack.nanojson.JsonParserException;
import j$.time.OffsetDateTime;
import j$.time.format.DateTimeFormatter;
import j$.time.format.DateTimeParseException;
import j$.util.Collection;
import j$.util.function.Consumer;
import j$.util.function.Function;
import j$.util.stream.Collectors;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.regex.Pattern;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import kotlin.UByte$;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.mozilla.javascript.Context;
import org.schabi.newpipe.extractor.Image;
import org.schabi.newpipe.extractor.MultiInfoItemsCollector;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.ServiceList;
import org.schabi.newpipe.extractor.channel.ChannelInfoItemsCollector;
import org.schabi.newpipe.extractor.downloader.Downloader;
import org.schabi.newpipe.extractor.downloader.Response;
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.exceptions.ReCaptchaException;
import org.schabi.newpipe.extractor.services.bandcamp.extractors.BandcampCommentsExtractor$$ExternalSyntheticLambda0;
import org.schabi.newpipe.extractor.services.bandcamp.extractors.BandcampCommentsExtractor$$ExternalSyntheticLambda1;
import org.schabi.newpipe.extractor.services.soundcloud.extractors.SoundcloudChannelInfoItemExtractor;
import org.schabi.newpipe.extractor.services.soundcloud.extractors.SoundcloudPlaylistInfoItemExtractor;
import org.schabi.newpipe.extractor.services.soundcloud.extractors.SoundcloudStreamInfoItemExtractor;
import org.schabi.newpipe.extractor.stream.StreamInfoItemExtractor;
import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector;
import org.schabi.newpipe.extractor.utils.ImageSuffix;
import org.schabi.newpipe.extractor.utils.JsonUtils;
import org.schabi.newpipe.extractor.utils.Parser;
import org.schabi.newpipe.extractor.utils.Utils;

public final class SoundcloudParsingHelper {
    public static final String SOUNDCLOUD_API_V2_URL = "https://api-v2.soundcloud.com/";
    private static String clientId;
    private static final List<ImageSuffix> ALBUMS_AND_ARTWORKS_IMAGE_SUFFIXES = TypefaceCompat$.ExternalSyntheticBackport0.m(new ImageSuffix[]{new ImageSuffix("mini", 16, 16, Image.ResolutionLevel.LOW), new ImageSuffix("t20x20", 20, 20, Image.ResolutionLevel.LOW), new ImageSuffix("small", 32, 32, Image.ResolutionLevel.LOW), new ImageSuffix("badge", 47, 47, Image.ResolutionLevel.LOW), new ImageSuffix("t50x50", 50, 50, Image.ResolutionLevel.LOW), new ImageSuffix("t60x60", 60, 60, Image.ResolutionLevel.LOW), new ImageSuffix("t67x67", 67, 67, Image.ResolutionLevel.LOW), new ImageSuffix("t80x80", 80, 80, Image.ResolutionLevel.LOW), new ImageSuffix("large", 100, 100, Image.ResolutionLevel.LOW), new ImageSuffix("t120x120", 120, 120, Image.ResolutionLevel.LOW), new ImageSuffix("t200x200", 200, 200, Image.ResolutionLevel.MEDIUM), new ImageSuffix("t240x240", 240, 240, Image.ResolutionLevel.MEDIUM), new ImageSuffix("t250x250", Context.VERSION_ECMASCRIPT, Context.VERSION_ECMASCRIPT, Image.ResolutionLevel.MEDIUM), new ImageSuffix("t300x300", 300, 300, Image.ResolutionLevel.MEDIUM), new ImageSuffix("t500x500", 500, 500, Image.ResolutionLevel.MEDIUM)});
    private static final List<ImageSuffix> VISUALS_IMAGE_SUFFIXES = TypefaceCompat$.ExternalSyntheticBackport0.m(new ImageSuffix("t1240x260", 1240, 260, Image.ResolutionLevel.MEDIUM), new ImageSuffix("t2480x520", 2480, 520, Image.ResolutionLevel.MEDIUM));
    private static final Pattern ON_URL_PATTERN = Pattern.compile("^https?://on.soundcloud.com/[0-9a-zA-Z]+$");

    private SoundcloudParsingHelper() {
    }

    public static synchronized String clientId() throws ExtractionException, IOException {
        synchronized (SoundcloudParsingHelper.class) {
            if (!Utils.isNullOrEmpty(clientId)) {
                return clientId;
            }
            Downloader downloader = NewPipe.getDownloader();
            Elements select = Jsoup.parse(downloader.get("https://soundcloud.com").responseBody()).select("script[src*=\"sndcdn.com/assets/\"][src$=\".js\"]");
            Collections.reverse(select);
            Map<String, List<String>> m = UByte$.ExternalSyntheticBackport0.m("Range", TypefaceCompat$.ExternalSyntheticBackport0.m("bytes=0-50000"));
            Iterator<Element> it = select.iterator();
            while (it.hasNext()) {
                String attr = it.next().attr("src");
                if (!Utils.isNullOrEmpty(attr)) {
                    try {
                        String matchGroup1 = Parser.matchGroup1(",client_id:\"(.*?)\"", downloader.get(attr, m).responseBody());
                        clientId = matchGroup1;
                        return matchGroup1;
                    } catch (Parser.RegexException unused) {
                        continue;
                    }
                }
            }
            throw new ExtractionException("Couldn't extract client id");
        }
    }

    public static OffsetDateTime parseDateFrom(String str) throws ParsingException {
        try {
            return OffsetDateTime.parse(str);
        } catch (DateTimeParseException e) {
            try {
                return OffsetDateTime.parse(str, DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss +0000"));
            } catch (DateTimeParseException e2) {
                throw new ParsingException("Could not parse date: \"" + str + "\", " + e.getMessage(), e2);
            }
        }
    }

    public static JsonObject resolveFor(@Nonnull Downloader downloader, String str) throws IOException, ExtractionException {
        try {
            return (JsonObject) JsonParser.object().from(downloader.get("https://api-v2.soundcloud.com/resolve?url=" + Utils.encodeUrlUtf8(str) + "&client_id=" + clientId(), ServiceList.SoundCloud.getLocalization()).responseBody());
        } catch (JsonParserException e) {
            throw new ParsingException("Could not parse json response", e);
        }
    }

    public static String resolveUrlWithEmbedPlayer(String str) throws IOException, ReCaptchaException {
        return Jsoup.parse(NewPipe.getDownloader().get("https://w.soundcloud.com/player/?url=" + Utils.encodeUrlUtf8(str), ServiceList.SoundCloud.getLocalization()).responseBody()).select("link[rel=\"canonical\"]").first().attr("abs:href");
    }

    public static String resolveIdWithWidgetApi(String str) throws IOException, ParsingException {
        if (ON_URL_PATTERN.matcher(str).find()) {
            try {
                str = NewPipe.getDownloader().head(str).latestUrl().split("\\?")[0];
            } catch (ExtractionException e) {
                throw new ParsingException("Could not follow on.soundcloud.com redirect", e);
            }
        }
        if (str.charAt(str.length() - 1) == '/') {
            str = str.substring(0, str.length() - 1);
        }
        try {
            try {
                return String.valueOf(JsonUtils.getValue((JsonObject) JsonParser.object().from(NewPipe.getDownloader().get("https://api-widget.soundcloud.com/resolve?url=" + Utils.encodeUrlUtf8(Utils.stringToURL(Utils.removeMAndWWWFromUrl(str.toLowerCase())).toString()) + "&format=json&client_id=" + clientId(), ServiceList.SoundCloud.getLocalization()).responseBody()), "id"));
            } catch (ExtractionException e2) {
                throw new ParsingException("Could not resolve id with embedded player. ClientId not extracted", e2);
            } catch (JsonParserException e3) {
                throw new ParsingException("Could not parse JSON response", e3);
            }
        } catch (MalformedURLException unused) {
            throw new IllegalArgumentException("The given URL is not valid");
        }
    }

    public static String getUsersFromApiMinItems(int i, ChannelInfoItemsCollector channelInfoItemsCollector, String str) throws IOException, ReCaptchaException, ParsingException {
        String usersFromApi = getUsersFromApi(channelInfoItemsCollector, str);
        while (!usersFromApi.isEmpty() && channelInfoItemsCollector.getItems().size() < i) {
            usersFromApi = getUsersFromApi(channelInfoItemsCollector, usersFromApi);
        }
        return usersFromApi;
    }

    @Nonnull
    public static String getUsersFromApi(ChannelInfoItemsCollector channelInfoItemsCollector, String str) throws IOException, ReCaptchaException, ParsingException {
        try {
            JsonObject jsonObject = (JsonObject) JsonParser.object().from(NewPipe.getDownloader().get(str, ServiceList.SoundCloud.getLocalization()).responseBody());
            Iterator it = jsonObject.getArray("collection").iterator();
            while (it.hasNext()) {
                Object next = it.next();
                if (next instanceof JsonObject) {
                    channelInfoItemsCollector.commit((ChannelInfoItemsCollector) new SoundcloudChannelInfoItemExtractor((JsonObject) next));
                }
            }
            return getNextPageUrl(jsonObject);
        } catch (JsonParserException e) {
            throw new ParsingException("Could not parse json response", e);
        }
    }

    public static String getStreamsFromApiMinItems(int i, StreamInfoItemsCollector streamInfoItemsCollector, String str) throws IOException, ReCaptchaException, ParsingException {
        String streamsFromApi = getStreamsFromApi(streamInfoItemsCollector, str);
        while (!streamsFromApi.isEmpty() && streamInfoItemsCollector.getItems().size() < i) {
            streamsFromApi = getStreamsFromApi(streamInfoItemsCollector, streamsFromApi);
        }
        return streamsFromApi;
    }

    @Nonnull
    public static String getStreamsFromApi(StreamInfoItemsCollector streamInfoItemsCollector, String str, boolean z) throws IOException, ReCaptchaException, ParsingException {
        Response response = NewPipe.getDownloader().get(str, ServiceList.SoundCloud.getLocalization());
        if (response.responseCode() >= 400) {
            throw new IOException("Could not get streams from API, HTTP " + response.responseCode());
        }
        try {
            JsonObject jsonObject = (JsonObject) JsonParser.object().from(response.responseBody());
            Iterator it = jsonObject.getArray("collection").iterator();
            while (it.hasNext()) {
                Object next = it.next();
                if (next instanceof JsonObject) {
                    JsonObject jsonObject2 = (JsonObject) next;
                    if (z) {
                        jsonObject2 = jsonObject2.getObject("track");
                    }
                    streamInfoItemsCollector.commit((StreamInfoItemExtractor) new SoundcloudStreamInfoItemExtractor(jsonObject2));
                }
            }
            return getNextPageUrl(jsonObject);
        } catch (JsonParserException e) {
            throw new ParsingException("Could not parse json response", e);
        }
    }

    @Nonnull
    private static String getNextPageUrl(@Nonnull JsonObject jsonObject) {
        try {
            String string = jsonObject.getString("next_href");
            if (string.contains("client_id=")) {
                return string;
            }
            return string + "&client_id=" + clientId();
        } catch (Exception unused) {
            return "";
        }
    }

    public static String getStreamsFromApi(StreamInfoItemsCollector streamInfoItemsCollector, String str) throws ReCaptchaException, ParsingException, IOException {
        return getStreamsFromApi(streamInfoItemsCollector, str, false);
    }

    public static String getInfoItemsFromApi(final MultiInfoItemsCollector multiInfoItemsCollector, String str) throws ReCaptchaException, ParsingException, IOException {
        Response response = NewPipe.getDownloader().get(str, ServiceList.SoundCloud.getLocalization());
        if (response.responseCode() >= 400) {
            throw new IOException("Could not get streams from API, HTTP " + response.responseCode());
        }
        try {
            JsonObject jsonObject = (JsonObject) JsonParser.object().from(response.responseBody());
            Collection.-EL.stream(jsonObject.getArray("collection")).filter(new BandcampCommentsExtractor$$ExternalSyntheticLambda0(JsonObject.class)).map(new BandcampCommentsExtractor$$ExternalSyntheticLambda1(JsonObject.class)).forEach(new Consumer() {
                @Override
                public final void accept(Object obj) {
                    SoundcloudParsingHelper.lambda$getInfoItemsFromApi$0(MultiInfoItemsCollector.this, (JsonObject) obj);
                }

                @Override
                public Consumer andThen(Consumer consumer) {
                    return Consumer.-CC.$default$andThen(this, consumer);
                }
            });
            try {
                String string = jsonObject.getString("next_href");
                if (string.contains("client_id=")) {
                    return string;
                }
                return string + "&client_id=" + clientId();
            } catch (Exception unused) {
                return "";
            }
        } catch (JsonParserException e) {
            throw new ParsingException("Could not parse json response", e);
        }
    }

    static void lambda$getInfoItemsFromApi$0(MultiInfoItemsCollector multiInfoItemsCollector, JsonObject jsonObject) {
        String string = jsonObject.getString("kind", "");
        string.hashCode();
        switch (string) {
            case "user":
                multiInfoItemsCollector.commit((MultiInfoItemsCollector) new SoundcloudChannelInfoItemExtractor(jsonObject));
                break;
            case "track":
                multiInfoItemsCollector.commit((MultiInfoItemsCollector) new SoundcloudStreamInfoItemExtractor(jsonObject));
                break;
            case "playlist":
                multiInfoItemsCollector.commit((MultiInfoItemsCollector) new SoundcloudPlaylistInfoItemExtractor(jsonObject));
                break;
        }
    }

    @Nonnull
    public static String getUploaderUrl(JsonObject jsonObject) {
        return Utils.replaceHttpWithHttps(jsonObject.getObject("user").getString("permalink_url", ""));
    }

    @Nonnull
    public static String getAvatarUrl(JsonObject jsonObject) {
        return Utils.replaceHttpWithHttps(jsonObject.getObject("user").getString("avatar_url", ""));
    }

    @Nonnull
    public static String getUploaderName(JsonObject jsonObject) {
        return jsonObject.getObject("user").getString("username", "");
    }

    @Nonnull
    public static List<Image> getAllImagesFromTrackObject(@Nonnull JsonObject jsonObject) throws ParsingException {
        String string = jsonObject.getString("artwork_url");
        if (string != null) {
            return getAllImagesFromArtworkOrAvatarUrl(string);
        }
        String string2 = jsonObject.getObject("user").getString("avatar_url");
        if (string2 != null) {
            return getAllImagesFromArtworkOrAvatarUrl(string2);
        }
        throw new ParsingException("Could not get track or track user's thumbnails");
    }

    @Nonnull
    public static List<Image> getAllImagesFromArtworkOrAvatarUrl(@Nullable String str) {
        if (Utils.isNullOrEmpty(str)) {
            return Collections.EMPTY_LIST;
        }
        return getAllImagesFromImageUrlReturned(str.replace("-large.", "-%s."), ALBUMS_AND_ARTWORKS_IMAGE_SUFFIXES);
    }

    @Nonnull
    public static List<Image> getAllImagesFromVisualUrl(@Nullable String str) {
        if (Utils.isNullOrEmpty(str)) {
            return Collections.EMPTY_LIST;
        }
        return getAllImagesFromImageUrlReturned(str.replace("-original.", "-%s."), VISUALS_IMAGE_SUFFIXES);
    }

    private static List<Image> getAllImagesFromImageUrlReturned(@Nonnull final String str, @Nonnull List<ImageSuffix> list) {
        return (List) Collection.-EL.stream(list).map(new Function() {
            @Override
            public Function andThen(Function function) {
                return Function.-CC.$default$andThen(this, function);
            }

            @Override
            public final Object apply(Object obj) {
                return SoundcloudParsingHelper.lambda$getAllImagesFromImageUrlReturned$1(str, (ImageSuffix) obj);
            }

            @Override
            public java.util.function.Function compose(java.util.function.Function function) {
                return Function.-CC.$default$compose(this, function);
            }
        }).collect(Collectors.toUnmodifiableList());
    }

    static Image lambda$getAllImagesFromImageUrlReturned$1(String str, ImageSuffix imageSuffix) {
        return new Image(String.format(str, imageSuffix.getSuffix()), imageSuffix.getHeight(), imageSuffix.getWidth(), imageSuffix.getResolutionLevel());
    }
}