bilibili视频解析—Java

发布时间 2023-09-29 13:07:57作者: laremehpe
public class Bilibili {
    private static String url, videoUrl, audioUrl, saveName;
    private boolean type;


    Bilibili(String saveName) {
        this.saveName = saveName;
    }

    public static void main(String[] args) {
        String url = "https://www.bilibili.com/video/BV1wd4y1w7kK/?spm_id_from=333.337.search-card.all.click&vd_source=29e334761a3a467100b2c30e4b85aab1";
        new Bilibili("payphone").analyse(url)
                .audio("").download().video("").download();

//        audioUrl = "https://upos-sz-mirror08c.bilivideo.com/upgcxcode/47/52/1047445247/1047445247_nb3-1-30280.m4s?e=ig8euxZM2rNcNbdlhoNvNC8BqJIzNbfqXBvEqxTEto8BTrNvN0GvT90W5JZMkX_YN0MvXg8gNEV4NC8xNEV4N03eN0B5tZlqNxTEto8BTrNvNeZVuJ10Kj_g2UB02J0mN0B5tZlqNCNEto8BTrNvNC7MTX502C8f2jmMQJ6mqF2fka1mqx6gqj0eN0B599M=&uipk=5&nbs=1&deadline=1692127574&gen=playurlv2&os=08cbv&oi=2059574121&trid=4c3d337b3a7a466c81239501786ed71au&mid=0&platform=pc&upsig=b85a234388e3266e97def2c95d57468c&uparams=e,uipk,nbs,deadline,gen,os,oi,trid,mid,platform&bvc=vod&nettype=0&orderid=0,3&buvid=&build=0&agrr=0&bw=14239&logo=80000000";
//        new Bilibili().audio("What's_Up", "").download();
    }

    interface Promise {
        void resolve(String mes);

        void reject();
    }

    private void get(String url, Promise pro) {
        OkHttpClient okHttpClient = new OkHttpClient();
        Request.Builder builder = new Request.Builder();
        Request request = builder.get().url(url).build();
        Call call = okHttpClient.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                pro.reject();
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                assert response.body() != null;
                pro.resolve(response.body().string());
            }
        });
    }

    public Bilibili download() {
        try {
            OkHttpClient client = new OkHttpClient.Builder().build();
            Request request = new Request.Builder()
                    .header("Referer", "https://www.bilibili.com")
                    .url(url)
                    .build();
            Response response = client.newCall(request).execute();
            byte[] bytes = response.body().bytes();

            if (bytes.length > 0) {
                Files.write(filePath, bytes, StandardOpenOption.CREATE);
                System.out.println(response.message() + "-downloaded-" + url);
            } else {
                System.out.println(response.message() + "-failed-" + url);
                download();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return this;
    }

    private Bilibili analyse(String url) {
        get(url, new Promise() {
            @Override
            public void resolve(String str) {
                Pattern pat = Pattern.compile("__playinfo__.*?</script>");
                Matcher matcher = pat.matcher(str);
                if (matcher.find()) {
                    String group = matcher.group();
                    int start = group.indexOf("{");
                    int end = group.lastIndexOf("}") + 1;
                    String result = group.substring(start, end);
                    JSONObject obj = new JSONObject(result);
                    videoUrl = (String) obj.getJSONObject("data").getJSONObject("dash").getJSONArray("video").getJSONObject(0).get("baseUrl");
                    audioUrl = (String) obj.getJSONObject("data").getJSONObject("dash").getJSONArray("audio").getJSONObject(2).getJSONArray("backupUrl").get(1);
                    System.out.println("get url");
                } else {
                    System.out.println("no match");
                }
            }

            @Override
            public void reject() {
                System.out.println("request error");
            }
        });

        while (videoUrl == null) Thread.onSpinWait();

        return this;
    }

    private String folder;
    private Path filePath;

    private Bilibili video(String folder) {
        this.url = videoUrl;
        this.type = true;
        pathVerify(folder);
        return this;
    }

    private Bilibili audio(String folder) {
        this.url = audioUrl;
        this.type = false;
        pathVerify(folder);
        return this;
    }

    private void pathVerify(String folder) {
        this.folder = folder;
        if ("".equals(folder))
            this.folder = new File("").getAbsolutePath();

        if (!this.folder.endsWith("/"))
            this.folder = this.folder + "/";

        Path folderPath = Paths.get(this.folder);
        if (!Files.exists(folderPath)) {
            try {
                Files.createDirectories(folderPath);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

        filePath = Paths.get(folder + saveName + (type ? ".mp4" : ".mp3"));
        if (Files.exists(filePath, LinkOption.NOFOLLOW_LINKS))
            filePath.toFile().delete();
    }

}