当前位置: 首页 > article >正文

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站如果后期修复,将移动端文件也加密了那这个方法也不奏效了,破解加密那个跟现在文件解析重命名就不是一个等级的工作了,大家也且用且珍惜吧。

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


http://www.kler.cn/news/314766.html

相关文章:

  • Linux(ubuntu)(文件IO——fopen)
  • C++ | C++中与const相关的权限放大和缩小详解
  • 【医疗大数据】基于 B2B 的医疗保健系统中大数据信息管理的安全和隐私问题分析
  • Spring(三)Spring事件+计划任务+条件注解+SpringAware
  • 开源网安多城联动、多形式开展网安周公益活动,传播网络安全知识
  • 中断-MCU
  • HTML粉色烟花秀
  • python新手的五个练习题
  • MySQl索引事务(B树)
  • 基于 K8S kubernetes 的常见日志收集方案
  • 大模型如何学习数据
  • NLP 文本分类核心问题
  • LangChain教程 - 构建一个检索增强生成 (RAG) 应用程序
  • 面试金典题8
  • go webapi上传文件
  • 【Linux】Docker:离线主机部署
  • 【Temporal】日志打印控制
  • 【AI视频】AI虚拟主播制作网站推荐
  • 深度学习02-pytorch-06-张量的形状操作
  • 基于深度学习的智能电网优化
  • Java异常架构与异常关键字
  • Spring后端直接用枚举类接收参数,自定义通用枚举类反序列化器
  • IT行业:未来发展的无限可能
  • 【医学半监督】置信度指导遮蔽学习的半监督医学图像分割
  • 51单片机-系列-数码管中断和定时器
  • Lsposed Java HOOK原理及检测
  • 我的AI工具箱Tauri版-VideoIntroductionClipCut视频介绍混剪
  • Nacos与Eureka的区别:深入解析微服务中的服务注册与发现
  • npm切换为淘宝镜像源
  • GPU加速生物信息分析的尝试