CelestialCosmic / themeblog

blog articles by Celestial_Cosmic,source code by chanshiyucx
0 stars 0 forks source link

自制bilibili重命名工具 #15

Open CelestialCosmic opened 2 years ago

CelestialCosmic commented 2 years ago

一个拿 python 写的小工具

起源

在 B 站上下载了 HOI4 的原声带,但是高达 119P,如何命名是个难事,一个个手动来?我又不傻。要不,写个工具吧

第一阶段

在对文件结构有了一定了解(踩坑)后,没花太大功夫就搞了个能用的

import json
import os
num = 0
while True:
    if num == 120:
        break
    num += 1
    with open("/home/celestial/24011916/" + str(num) + "/entry.json", 'r') as raw:
        src = "/home/celestial/24011916/" + \
            str(num) + "/lua.mp4.bili2api.16"
        src2 = "/home/celestial/24011916/" + \
            str(num) + "/lua.flv360.bili2api.16"
        des = "/home/celestial/111"
        file = json.load(raw)
        fulltitle = file['page_data']['part']
        try:
            os.rename(os.path.join(src, "index.json"),
                      os.path.join(des, fulltitle+".mp3"))
            print("%d成功" % num)
        except FileNotFoundError:
            os.rename(os.path.join(src2, "index.json"),
                      os.path.join(des, fulltitle+".mp3"))
            print("%d成功" % num)
        except:
            print("%d失败" % num)
            continue

懂的人能一眼看出来:只是针对这视频的

我的目标达到了,但是我想要个通用的

第二阶段

一开始是照着“各分辨率有各分辨率的处理办法”来做的,于是写了数个函数,准备一个个处理问题,就像下面这样

import json
import os

def Rename1080(route,des):
    num = 0
    while True:
        num += 1
        with open(route + str(num) + "/entry.json", 'r') as raw:
            file = json.load(raw)
            part = file['page_data']['part']
            src = route + str(num) + "/lua.flv.bili2api.80"
            os.rename(os.path.join(src, "0.blv"),os.path.join(des, part+".mp4"))

def Rename360(route,des):
    num = 0
    while True:
        num += 1
        with open(route + str(num) + "/entry.json", 'r') as raw:
            file = json.load(raw)
            part = file['page_data']['part']
            src = route + str(num) + "/lua.flv.bili2api.80"
            os.rename(os.path.join(src, "0.blv"),os.path.join(des, part+".mp4"))

def main():
    print("输入视频文件夹的路径,精确到 av 号,如/home/user/114514")
    route = input()
    route = "/home/celestial/114"
    print("输入文件输出的路径")
    des = input()
    print("输入下载的画质")
    option = input("1为1080P,2为720P,3为480P,4为360P\n")
    if option == '1':
        Rename1080(route, des)
    elif option == '2':
         Rename720(route,des)
    elif option == '3':
         Rename480(route,des)
    elif option == '4':
         Rename360(route,des)
    else:
        print("未找到对应选项\n")
        KeyError

main()

随便下了几个视频测试的时候意识到不对:原来0.blv也不是一定的事!

稍作思考后,我试着改用遍历文件夹内容,然后刨去index.json的方式获得内容,成功了

......

那每 P 下面的文件夹为什么不能也用这个方式解决呢

第三阶段

灵光一现后,马上开始了尝试

这次还加上了错误处理

import json
import os

def Rename(route, des):
    try:
        pdir = os.listdir(route)
    except FileNotFoundError:
        print("文件夹不存在")
        return 0
    errlist = []
    for i in pdir:
        sdir = route + "/" + i
        pfiles = os.listdir(sdir)
        pfiles.remove('danmaku.xml')
        pfiles.remove('entry.json')
        pfile = pfiles[0]
        with open(route + "/" + i + "/entry.json", 'r') as raw:
            data = json.load(raw)
            sfiles = os.listdir(sdir + "/" + pfile)
            sfiles.remove('index.json')
            try:
                sfile = sfiles[0]
            except IndexError:
                errlist.append(int(i))
                print("第%sP视频文件已不存在" % i)
                continue
            try:
                os.rename(os.path.join(sdir + "/" + pfile, sfile),
                          os.path.join(des, data['page_data']['part']+".mp4"))
                print(i + "成功")
            except FileNotFoundError:
                errlist.append(int(i))
                print(i + "失败")
    print("如下分P未能成功:")
    errlist.sort()
    std = 0
    for i in errlist:
        if std == 5:
            std = 0
            print()
        print("%-4s" % str(i), end="")
        std += 1
    print("\n请手动重命名")

def main():
    print("输入视频文件夹的路径,精确到 av 号,如/home/user/114514")
    route = input()
    print("输入文件输出的路径")
    des = input()
    Rename(route, des)

main()

可以愉快地自动化命名了,尽管不知道下一次用是啥时候了,但大概总会派上用场的

开源

本文与本文涉及的所有代码均按 MIT 协议开源,玩得开心!