自学内容网 自学内容网

Java 使用递归方法遍历B站下载文件并解析重命名

目录

背景        

操作方法 

声明


背景

        出于学习和日常使用方便的目的,且考虑到有的资源过一段时间会失效,所以有时会下载B站的音频,视频,进行存放保留,下面介绍下载和下载之后解析文件的方法,仅供学习交流使用,请勿未经许可盗取UP主视频盈利。(以下操作均以安卓手机为例,iOS和PC端方法可能不一样)

操作方法

        总的思路就是:将手机中下载好的B站视频,转到电脑上存储,并重命名即可(直接在电脑上下载,下载的文件都是加密过的,无法直接使用,当然,最简单的方法就是油猴上面下载两个插件,直接下载了,但是插件有的很不好用,而且一段时间后就不太稳定,下载画质也有的有限制,所以还是我想还是自己写一个方法,解决一下,并做一个分享,同时欢迎大佬有更简单更好的方法,在评论区可以留言交流)

例如,我使用PC端下载好一个鬼畜视频,将下载的目录打开后发现修改文件名后缀,并不能打开,文件内容应该是加密或者处理过的 (或者有其他办法,我暂时没有去找)

        这里我是直接用手机把文件都去下载好,然后将手机和电脑通过USB线进行数据传输,在电脑上,找到手机下载的文件路径是:

此电脑\手机名\内部存储设备\Android\data\tv.danmaku.bili\download

        与PC端不同的是手机端没有对文件进行加密,仅仅修改了文件的后缀名,反过来只要将音频和视频文件后缀名修改成正常的,即可直接观看使用了,但是文件很多的情况下,一个一个修改效率太低,于是我写了一个方法,使用Java去直接遍历这个文件夹,并根据文件信息进行重命名,效率将会大大提高很多。

package com.ss.system.util;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Scanner;


public class BilibiliUtils {

    public static void main(String[] args) {

        // 创建一个 File 对象,指向 "D:\\UP" 目录,这是程序开始搜索的根目录。
        File rootDir = new File("D:\\UP");
        // 调用 processDirectory 方法来处理该目录及其子目录。
        processDirectory(rootDir);
    }

    // 声明一个私有的静态方法 processDirectory,接受一个 File 对象作为参数。
    private static void processDirectory(File dir) {
        // if (dir.isDirectory()) 确保传入的 File 对象是一个目录。
        if (dir.isDirectory()) {
            // dir.listFiles() 返回一个 File 数组,包含目录中的所有文件和子目录。
            File[] files = dir.listFiles();
            if (files != null) {
                for (File file : files) {
                    // 递归处理子目录:如果是子目录,递归调用 processDirectory 方法来进一步处理。
                    if (file.isDirectory()) {
                        processDirectory(file);
                        // 如果找到名为 entry.json 的文件,调用 processJsonFile 方法进行处理。
                    } else if (file.getName().equalsIgnoreCase("entry.json")) {
                        processJsonFile(dir);
                    }
                }
            }
        }
    }


    // 声明一个私有的静态方法 processJsonFile,接受一个 File 对象作为参数,这个 File 对象应指向包含 entry.json 文件的目录。
    private static void processJsonFile(File jsonDir) {
        // new File(jsonDir, "entry.json") 创建一个指向 entry.json 文件的 File 对象。
        File jsonFile = new File(jsonDir, "entry.json");
        if (jsonFile.exists()) {
            // 使用 FileReader 和 Scanner 读取文件内容。
            try (FileReader reader = new FileReader(jsonFile);
                 Scanner scanner = new Scanner(reader)) {
                // scanner.useDelimiter("\\A").next() 读取整个文件内容为一个字符串。
                String jsonString = scanner.useDelimiter("\\A").next();
                // 使用 JsonParser 解析 JSON 字符串,并转换为 JsonObject。
                JsonObject jsonObject = JsonParser.parseString(jsonString).getAsJsonObject();
                String title = jsonObject.get("title").getAsString();
                String ownerName = jsonObject.get("owner_name").getAsString();
                String newBaseName = title + " - " + ownerName;
                System.out.println("New base name: " + newBaseName);
                // 调用 searchAndRenameFiles 方法,在当前目录中查找 video.m4s 和 audio.m4s 文件并进行重命名。
                searchAndRenameFiles(jsonDir, newBaseName);
            } catch (IOException e) {
                System.out.println("Failed to read or process JSON file: " + e.getMessage());
            }
        } else {
            System.out.println("entry.json not found in directory: " + jsonDir.getAbsolutePath());
        }
    }

    private static void searchAndRenameFiles(File startDir, String newBaseName) {
        File[] files = startDir.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    // Recursively search in subdirectories
                    searchAndRenameFiles(file, newBaseName);
                } else if (file.getName().equalsIgnoreCase("video.m4s")) {
                    renameFileIfNeeded(file, newBaseName + ".mp4");
                } else if (file.getName().equalsIgnoreCase("audio.m4s")) {
                    renameFileIfNeeded(file, newBaseName + ".mp3");
                }
            }
        }
    }

    private static void renameFileIfNeeded(File file, String newName) {
        if (file.exists()) {
            File newFile = new File(file.getParent(), newName);
            boolean success = file.renameTo(newFile);
            if (success) {
                System.out.println("Renamed to: " + newFile.getAbsolutePath());
            } else {
                System.out.println("Failed to rename: " + file.getAbsolutePath());
            }
        } else {
            System.out.println("File not found: " + file.getAbsolutePath());
        }
    }
}

可以看到文件夹下面的所有文件,已经解析并重命名OK了。

更新(新增一个功能,将指定目录下所有 .mp3 文件复制到 D:\UP,可以在 searchAndRenameFiles 方法中添加复制逻辑。)

package com.ss.system.util;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.Scanner;


public class BilibiliUtils {

    public static void main(String[] args) {

        // 创建一个 File 对象,指向 "D:\\UP" 目录,这是程序开始搜索的根目录。
        File rootDir = new File("D:\\UP");
        // 调用 processDirectory 方法来处理该目录及其子目录。
        processDirectory(rootDir);
    }

    // 声明一个私有的静态方法 processDirectory,接受一个 File 对象作为参数。
    private static void processDirectory(File dir) {
        // if (dir.isDirectory()) 确保传入的 File 对象是一个目录。
        if (dir.isDirectory()) {
            // dir.listFiles() 返回一个 File 数组,包含目录中的所有文件和子目录。
            File[] files = dir.listFiles();
            if (files != null) {
                for (File file : files) {
                    // 递归处理子目录:如果是子目录,递归调用 processDirectory 方法来进一步处理。
                    if (file.isDirectory()) {
                        processDirectory(file);
                        // 如果找到名为 entry.json 的文件,调用 processJsonFile 方法进行处理。
                    } else if (file.getName().equalsIgnoreCase("entry.json")) {
                        processJsonFile(dir);
                    }
                }
            }
        }
    }


    // 声明一个私有的静态方法 processJsonFile,接受一个 File 对象作为参数,这个 File 对象应指向包含 entry.json 文件的目录。
    private static void processJsonFile(File jsonDir) {
        // new File(jsonDir, "entry.json") 创建一个指向 entry.json 文件的 File 对象。
        File jsonFile = new File(jsonDir, "entry.json");
        if (jsonFile.exists()) {
            // 使用 FileReader 和 Scanner 读取文件内容。
            try (FileReader reader = new FileReader(jsonFile);
                 Scanner scanner = new Scanner(reader)) {
                // scanner.useDelimiter("\\A").next() 读取整个文件内容为一个字符串。
                String jsonString = scanner.useDelimiter("\\A").next();
                // 使用 JsonParser 解析 JSON 字符串,并转换为 JsonObject。
                JsonObject jsonObject = JsonParser.parseString(jsonString).getAsJsonObject();
                String title = jsonObject.get("title").getAsString();
                String ownerName = jsonObject.get("owner_name").getAsString();
                String newBaseName = title + " - " + ownerName;
                System.out.println("New base name: " + newBaseName);
                // 调用 searchAndRenameFiles 方法,在当前目录中查找 video.m4s 和 audio.m4s 文件并进行重命名。
                searchAndRenameFiles(jsonDir, newBaseName);
            } catch (IOException e) {
                System.out.println("Failed to read or process JSON file: " + e.getMessage());
            }
        } else {
            System.out.println("entry.json not found in directory: " + jsonDir.getAbsolutePath());
        }
    }


    private static void searchAndRenameFiles(File startDir, String newBaseName) {
        File[] files = startDir.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    searchAndRenameFiles(file, newBaseName);
                } else if (file.getName().equalsIgnoreCase("video.m4s")) {
                    renameFileIfNeeded(file, newBaseName + ".mp4");
                } else if (file.getName().equalsIgnoreCase("audio.m4s")) {
                    renameFileIfNeeded(file, newBaseName + ".mp3");
                } else if (file.getName().toLowerCase().endsWith(".mp3")) {
                    copyMp3File(file);
                }
            }
        }
    }
    private static void renameFileIfNeeded(File file, String newName) {
        if (file.exists()) {
            File newFile = new File(file.getParent(), newName);
            boolean success = file.renameTo(newFile);
            if (success) {
                System.out.println("Renamed to: " + newFile.getAbsolutePath());
            } else {
                System.out.println("Failed to rename: " + file.getAbsolutePath());
            }
        } else {
            System.out.println("File not found: " + file.getAbsolutePath());
        }
    }

    private static void copyMp3File(File mp3File) {
        File destDir = new File("D:\\UP");
        if (!destDir.exists()) {
            destDir.mkdirs();
        }
        File destFile = new File(destDir, mp3File.getName());
        try {
            Files.copy(mp3File.toPath(), destFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
            System.out.println("Copied: " + mp3File.getAbsolutePath() + " to " + destFile.getAbsolutePath());
        } catch (IOException e) {
            System.out.println("Failed to copy: " + mp3File.getAbsolutePath() + " - " + e.getMessage());
        }
    }

}


声明

        下载文件的方法,网上帖子有很多,我只是借用了他们的方法,并简化了我自己保存文件的繁琐操作,请大家不要怀有恶意,也感谢B站的UP主上传分享的视频,B站如果后期修复,将移动端文件也加密了那这个方法也不奏效了,破解加密那个跟现在文件解析重命名就不是一个等级的工作了,大家也且用且珍惜吧。

        本文仅作为一个分享,希望大家在保存文件的时候,可以方便一点,减少不必要的手动操作,本着技术中立原则,仅作为学习交流,请大家自行使用,不要去以此盗取他人视频商用。


原文地址:https://blog.csdn.net/weixin_49171365/article/details/142433495

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!