zoukankan      html  css  js  c++  java
  • 批量修改bilibili客户端下载视频文件名

    代码已上传:Github

     

    版本已更新,最新请查看2.0版本:【重构】Bilibili UWP 客户端下载视频文件重命名 2.0

    起因

    昨天晚上从B站电脑客户端下了一个分集视频

    但是下载后的视频是这样的:

    视频名是这样的:

    这样既不直观又不美观,就算把视频文件放到一个文件夹内,连续看视频时也不容易记住看到哪个。所以就有了今天的事情。

    经过

    起初,我的想法是复制出来一个一个该文件名,但是当时我想到,作为一个优秀的程序员,怎么能干这种无脑的活呢?(其实是太懒了。。。)

    于是,,,就去百度了,百度确实找到一个,但是上面的方法根本没有写全,虽然我已经尽力补全,但是他还是漏了一个非常关键的一步,所以我就决定自己来写。

    分析

    根据下载的文件来看,在info文件中,可以找到原视频的所有介绍信息,其中当然就有原视频的文件名(PartName),所以我们只需要把info文件中的文件名提取出来,然后再对flv视频文件重命名不就完事了吗。

    具体可以分为以下步骤:

    1. 遍历我们下载好的视频目录,得到info文件集合和flv视频文件集合;

    2. 遍历读取info文件,从中提取我们需要的视频文件名;

    3. 循环遍历flv文件,提取视频序号,用来组装我们想要的视频名;

    4. 遍历flv,给每一个flv视频文件换上新名字;

    代码实现

    1. 遍历视频目录,将info文件存入list集合;

       1 /**
       2  * 遍历下载目录,将info文件存入list集合
       3  * - 目的:提供info文件给getPartNameList()方法,获得想要的视频文件名
       4  *
       5  * @param downloadPath
       6  * @return
       7  */
       8 public static List<File> getInfoList(String downloadPath) {
       9     File dir = new File(downloadPath);
      10 11     // 把下载目录下的所有文件(可能是目录也可能是文件)放到数组中
      12     File[] subDirOrFile = dir.listFiles();
      13 14     if (subDirOrFile != null) {
      15         for (int i = 0; i < subDirOrFile.length; i++) {
      16             String fileName = subDirOrFile[i].getName();
      17             // 判断是否是目录,如果是目录继续遍历
      18             if (subDirOrFile[i].isDirectory()) {
      19                 getInfoList(subDirOrFile[i].getAbsolutePath());
      20                 //   判断是否以info结尾
      21             } else if (fileName.endsWith("info")) {
      22                 infoList.add(subDirOrFile[i]);
      23             } else {
      24                 continue;
      25             }
      26         }
      27     }
      28     return infoList;
      29 }
    2. 遍历视频目录,把flv视频文件放入list集合;

       1 /**
       2  * 根据下载路径,遍历获取所有视频文件list集合
       3  * -目的:改名时需要知道原始文件对象
       4  *
       5  * @param downloadPath
       6  * @return
       7  */
       8 public static List<File> getFlvList(String downloadPath) {
       9     File dir = new File(downloadPath);
      10 11     // 把下载目录下的所有文件放到数组中
      12     File[] subDirOrFile = dir.listFiles();
      13 14     if (subDirOrFile != null) {
      15         for (int i = 0; i < subDirOrFile.length; i++) {
      16             String fileName = subDirOrFile[i].getName();
      17             if (subDirOrFile[i].isDirectory()) {
      18                 getFlvList(subDirOrFile[i].getAbsolutePath());
      19             } else if (fileName.endsWith("flv")) {
      20                 flvList.add(subDirOrFile[i]);
      21             } else {
      22                 continue;
      23             }
      24         }
      25     }
      26     return flvList;
      27 }
    3. 遍历读取info文件,提取需要的视频名集合;


      /**
       * 读取 info 文件,获取视频文件名
       *
       * @param infoFile
       * @return
       */
      public static String getPartName(File infoFile) {
          BufferedReader br = null;
          String partName = null;
          try {
              br = new BufferedReader(new FileReader(infoFile));
              String str;
              while (null != (str = br.readLine())) {
                  // 获取partName字段对应的文件名
                  partName = str.split(",")[17].split(":")[1].replace("\"", "");
              }
          } catch (FileNotFoundException e) {
              e.printStackTrace();
          } catch (IOException e) {
              e.printStackTrace();
          } finally {
              try {
                  if (br != null) {
                      br.close();
                  }
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
          return partName;
      }
      ​
      /**
       * 遍历info 文件list集合,获得视频文件名list集合
       *
       * @param infoList
       * @return
       */
      public static List<String> getPartNameList(List<File> infoList) {
          List<String> partNameList = new ArrayList<>();
          for (int i = 0; i < infoList.size(); i++) {
              // 调用获取视频名的方法
              String partName = getPartName(infoList.get(i));
              partNameList.add(partName);
          }
          return partNameList;
      }
      View Code
       
    4. 遍历flv文件集合,组装文件名;

       1 /**
       2  * 根据视频名,flv文件对象,av号来组装我们想要的文件对象
       3  * -用途:重命名的目标文件对象
       4  *
       5  * @param partName
       6  * @param flvFile
       7  * @param avNum
       8  * @return
       9  */
      10 public static File getDestFile(String partName, File flvFile, String avNum) {
      11     // 根据flv文件名截取视频的序号
      12     String index = flvFile.getName().split("_")[1];
      13 14     // 截取flv文件路径,作为重命名文件的路径 E:\Videos\75233634\
      15     String newPathTemp = flvFile.getPath().split(avNum + "_")[0];
      16     // 判断该路径最后有没有"\" ,没有则加上 E:\Videos\75233634\
      17     String newPath = newPathTemp.endsWith("\\") ? newPathTemp : newPathTemp + "\\";
      18     // 新的文件路径:即 E:\Videos\75233634\1_1、这阶段该如何学习.flv
      19     String newFilePath = newPath + index + "_" + partName + ".flv";
      20 21     File destFile = new File(newFilePath);
      22     return destFile;
      23 }
      View Code
    5. main方法,完成批量重命名;

       1 // 这两个属于类的私有属性,定义在方法外边,分别代表info文件集合和flv视频文件集合
       2 private static List<File> infoList = new ArrayList<>();
       3 private static List<File> flvList = new ArrayList<>();
       4  5 public static void main(String[] args) {
       6     // 视频的下载路径
       7     String downloadPath = "E:\\Videos\\Bilibili videos\\75233634";
       8     // 视频av号:就是路径的最后一级目录
       9     String avNum = null;
      10     Pattern pattern = Pattern.compile("\\d+");
      11     Matcher matcher = pattern.matcher(downloadPath);
      12     if (matcher.find()) {
      13         avNum = matcher.group();
      14     }
      15 16     List<File> infoList = getInfoList(downloadPath);
      17     List<File> flvList = getFlvList(downloadPath);
      18     List<String> partNameList = getPartNameList(infoList);
      19 20     for (int i = 0; i < flvList.size(); i++) {
      21         // System.out.println(flvList.get(i));
      22         // System.out.println(getDestFile(partNameList.get(i), flvList.get(i), avNum));
      23         String partName = partNameList.get(i);
      24         File flvFile = flvList.get(i);
      25         // 目标文件:E:\Videos\75233634\1_1、这阶段该如何学习.flv
      26         File destFile = getDestFile(partName, flvFile, avNum);
      27         //原始文件:E:\Videos\Captures\75233634\1\75233634_1_0.flv
      28         File originFile = flvList.get(i);
      29         if (originFile.renameTo(destFile)) {
      30             System.out.println("success!" + destFile.getName());
      31         }
      32     }
      33 }
      View Code

    代码已上传:Github

    结果

    结果当然成功了,这肯定毋庸置疑了。

    终于可以愉快的看视频了...

    坚定而缓慢地做自己力所能及的事。

    时间

    2019-12-12

    地点

    zut.north#5 2f

    人物

    me

    竟然顺带复习了一下记叙文的六要素。

    喜欢可以关注我,B站或微信公众号搜索 `Ep流苏`

    不会的东西只有怀着一颗狂妄的心,假装能把它看穿吧。
  • 相关阅读:
    《Python数据挖掘入门与实践》高清中文版PDF+英文版+源码下载
    discuz 论坛配置 QQ/163 网易邮箱
    Discuz! X3 去掉内容图片提示下载方法(去除图片提示下载附件)
    HTTPS的建立过程(SSL建立安全会话的过程)
    前端开发之走进Vue.js
    优雅统计代码耗时的4种方法!
    Maven配置多个远程仓库的实现方法
    idea maven 一直报错“Could not transfer artifact ......(系统找不到指定的路径。)”
    IntelliJ IDEA为类和方法自动添加注释
    maven “mvn clean package”和“mvn clean install”有什么不同?
  • 原文地址:https://www.cnblogs.com/zhangshuaiyin/p/12038131.html
Copyright © 2011-2022 走看看