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 subdirectoriessearchAndRenameFiles(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.xdnf.cn/news/1542198.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

C++20中头文件compare的使用

<compare>是C20中新增加的头文件&#xff0c;此头文件是language support库的一部分。它包括&#xff1a;concepts、classes、customization point objects、functions。 1.concepts&#xff1a;三向比较运算符<>&#xff0c;目的是简化比对对象的过程&#xff0c;…

【编程实践】利用高德地图开放平台制作简易地图规定半径范围

需求分析 [little demo] 使用高德地图API创建一个显示特定半径范围的简易地图。 注册高德开放平台账号&#xff0c;获取API Key。&#xff08;精度要求不高可不需要&#xff09; 创建HTML页面&#xff0c;引入高德地图API。 设置地图中心点和初始缩放级别。 编写代码绘制指定半…

本地电脑基于nginx的https单向认证和双向认证(自制证书+nginx配置)保姆级

目录 1、背景 2、运行环境 3、工具下载 3.1、OpenSSL下载 3.2、nginx下载 4、制作https证书&#xff1a; 4.1、CA与自签名&#xff1a; 4.2、制作CA根证书&#xff08;公钥&#xff09; 4.3、制作服务端证书&#xff1a; 4.4、制作客户端证书&#xff1a; 4.5、制作…

初识ZYNQ——FPGA学习笔记15

一、ZYNQ简介 ZYNQ&#xff1a;Zynq-7000 All Programmable SoC&#xff08;APSoC&#xff09;&#xff0c;赛灵思公司&#xff08;AMD Xilinx&#xff09;推出的新一代全可编程片上系统 PS&#xff1a;Processing System&#xff0c;处理系统 PL&#xff1a;Program Logic&…

828华为云征文 | 构建高效搜索解决方案,Elasticsearch Kibana的完美结合

前言 构建高效搜索解决方案&#xff0c;FlexusX服务器与Elasticsearch & Kibana的完美结合&#xff0c;为企业带来云端搜索新体验。FlexusX实例以其卓越性能与灵活扩展性&#xff0c;确保高并发搜索的流畅运行。部署Elasticsearch&#xff0c;享受分布式搜索的精准与快速&a…

MySQL:SQL语句执行过程

本篇文章会分析下一个 SQL 语句在 MySQL 中的执行流程&#xff0c;包括 SQL 的查询在 MySQL 内部会怎么流转&#xff0c;SQL 语句的更新是怎么完成的。 在分析之前我会先带着你看看 MySQL 的基础架构&#xff0c;知道了 MySQL 由那些组件组成以及这些组件的作用是什么&#xf…

9.22今日错题解析(软考)

前言 这是用来记录我每天备考软考设计师的错题的&#xff0c;大部分错题摘自希赛中的题目&#xff0c;但相关解析是原创&#xff0c;有自己的思考&#xff0c;为了复习&#xff1a;&#xff09;&#xff0c;最后希望各位报考软考的小伙伴都能上岸&#xff01;&#xff01;&…

掌上高考爬虫逆向分析

目标网站 aHR0cHM6Ly93d3cuZ2Fva2FvLmNuL3NjaG9vbC9zZWFyY2g/cmVjb21zY2hwcm9wPSVFNSU4QyVCQiVFOCU4RCVBRg 一、抓包分析 二、逆向分析 搜索定位加密参数 本地生成代码 var CryptoJS require(crypto-js) var crypto require(crypto);f "D23ABC#56"function v(t…

Redis数据结构之set

一.set集合特性 集合类型也是保存多个字符串类型的元素的&#xff0c;但和list列表不一样&#xff0c;集合中的元素是无序的&#xff0c;而且元素不能够重复&#xff0c;不仅支持增删查改&#xff0c;还支持交集并集等操作 二.相关命令 1.sadd sadd key members…… 咱们把…

华为HarmonyOS地图服务 9 - 如何在地图上绘制多边形?

场景介绍 本章节将向您介绍如何在地图上绘制多边形。 接口说明 添加多边形功能主要由MapPolygonOptions、addPolygon和MapPolygon提供&#xff0c;更多接口及使用方法请参见接口文档。 接口名 描述 MapPolygonOptions 用于描述MapPolygon属性。 addPolygon(options: mapC…

SOMEIP_ETS_122: SD_Interface_Version

测试目的&#xff1a; 验证DUT能够以正确的格式响应接口版本获取请求。 描述 本测试用例旨在确保DUT能够正确地返回其接口版本信息&#xff0c;这是SOME/IP协议中用于确定服务兼容性的关键信息。 测试拓扑&#xff1a; 具体步骤&#xff1a; TESTER&#xff1a;触发接口版…

高密原型验证系统解决方案(上篇)

0 引言 随着当今 SoC 设计规模的快速膨胀&#xff0c;仅仅靠几 颗当代最先进的 FPGA 已经无法满足原型验证的需求。简单的增加系统的容量&#xff0c;会遇到系统时钟复位同 步&#xff0c;设计分割以及高速接口和先进 Memory控制器 IP 验证等多重困难。此时&#xff0c;一个商用…

Contact Form 7最新5.9.8版错误修复方案

最近有多位用户反应Contact Form 7最新5.9.8版的管理页面有错误如下图所示 具体错误文件的路径为wp-content\plugins\contact-form-7\admin\includes\welcome-panel.php on line 153 找到welcome-panel.php这个文件编辑它&#xff0c;将如下图选中的部分删除 删除以后&#xf…

AUTOSAR入门篇

AUTOSAR简介 AUTomotive Open System ARchitecture 汽车开放系统结构 AUTOSAR背景 随着车载控制系统日益先进和复杂化,每辆汽车投入的软件开发工数(时间及人力)2010年将达到2002年的5-10倍。汽车电子系统设计复杂化造成的可靠性隐患导致汽车因安全隐患被“招回”的现象频繁…

洪涝洪水滑坡灾害数据集 灾害 2300张 带标注 voc yolo

洪涝洪水滑坡灾害数据集 灾害 2300张 带标注 voc yolo 洪涝洪水滑坡灾害数据集 数据集描述 该数据集是一个专门用于检测和识别洪涝、洪水和滑坡等自然灾害的数据集&#xff0c;旨在帮助研究人员和开发者训练和评估基于深度学习的目标检测模型。数据集涵盖了两种常见的自然灾害…

Java—SPI 机制详解

参考文章 Java常用机制 - SPI机制详解 | Java 全栈知识体系包含: Java 基础, Java 部分源码, JVM, Spring, Spring Boot, Spring Cloud, 数据库原理, MySQL, ElasticSearch, MongoDB, Docker, k8s, CI&CD, Linux, DevOps, 分布式, 中间件, 开发工具, Git, IDE, 源码阅读&a…

力扣之183.从不订购的客户

1. 183.从不订购的客户 1.1 题干 Customers 表&#xff1a; -------------------- | Column Name | Type | -------------------- | id | int | | name | varchar | -------------------- 在 SQL 中&#xff0c;id 是该表的主键。 该表的每一行都表示客户的 ID 和名称。 Ord…

有关shell指令练习2

写一个shell脚本&#xff0c;将以下内容放到脚本中 在家目录下创建目录文件&#xff0c;dir dir下创建dir1和dir2 把当前目录下的所有文件拷贝到dir1中&#xff0c; 把当前目录下的所有脚本文件拷贝到dir2中 把dir2打包并压缩为dir2.tar.xz 再把dir2.tar.xz移动到dir1中 …

MATLAB基于传统方法的车道线检测实现

MATLAB基于传统方法的车道线检测实现 本文实现的是基于传统方法的车道线检测&#xff0c;所谓传统方法就是没有涉及到深度学习算法&#xff0c;基于直观的手段和数学知识来实现&#xff0c;后期会实现基于深度学习的车道线检测方法。 实现步骤&#xff1a; Canny边缘检测手动…

html 几行的空间分成3个区域

1.代码 <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta name"viewport" content"widthdevice-width, initial-scale1.0"> <title>三个区域示例</title> …